// ..\..\Js\Life.cs

// Startup class - entry point of the application
var mainClass = 0;
// Class 'Main'
var Main = new Class({
    
    /*Life*/     theLife: 0,
    /*bool*/     IsTimerRunning: false,
    /*int*/      Speed: 500,
    
    TimerElapsed: function() // returns void
    {
        
        if(this.IsTimerRunning)
        {
            
            this.theLife.RunOneStep();
            // Restart timer
            Timer.Start(this.Speed, function() {
                
                Main.GetMain().TimerElapsed();
                
            });
            
        }
        
    },
    ChangeSize: function(newSize) // int newSize - returns void
    {
        
        this.theLife = new Life();
        this.theLife.Start(newSize);
        this.theLife.Randomize();
        
    },
    
    
    end: function() {}
});
// Static functions
Main.GetMain = function() // returns Main
{
    
    if(mainClass == 0) {mainClass = new Main();}
    return mainClass;
    
};
Main.Start = function() // returns void
{
    
    /*Main*/ var m = this.GetMain();
    m.ChangeSize(10);
    MooElement.Get("btnGo").AddEvent("click", function() {
        
        m.theLife.RunOneStep();
        
    });
    MooElement.Get("btnRandomize").AddEvent("click", function() {
        
        m.theLife.Randomize();
        
    });
    MooElement.Get("btnClear").AddEvent("click", function() {
        
        m.theLife.Clear();
        
    });
    /*MooElement*/ var dropSize = MooElement.Get("dropSize");
    dropSize.AddEvent("change", function() {
        
        /*string*/ var sizeStr = MooElement.Get("dropSize").GetSelectedText();
        /*int*/ var size = 10;
        if(sizeStr == "Large")
        {
            
            size = 30;
            
        }
        if(sizeStr == "Medium")
        {
            
            size = 20;
            
        }
        if(sizeStr == "Small")
        {
            
            size = 10;
            
        }
        Main.GetMain().ChangeSize(size);
        
    });
    /*MooElement*/ var dropSpeed = MooElement.Get("dropSpeed");
    dropSpeed.AddEvent("change", function() {
        
        //MooElement cur = null; //JS: cur = this.MooElement;
        /*int*/ var speed = 500;
        /*string*/ var speedStr = MooElement.Get("dropSpeed").GetSelectedText();
        if(speedStr == "Cheetah")
        {
            
            speed = 25;
            
        }
        if(speedStr == "Fast")
        {
            
            speed = 250;
            
        }
        if(speedStr == "Llama")
        {
            
            speed = 1000;
            
        }
        if(speedStr == "Turtle")
        {
            
            speed = 2000;
            
        }
        Main.GetMain().Speed = speed;
        
    });
    /*MooElement*/ var btnStart = MooElement.Get("btnStart");
    btnStart.AddEvent("click", function() {
        
        /*MooElement*/ var cur = null;
        cur = this.MooElement;
        m.IsTimerRunning = !m.IsTimerRunning;
        if(m.IsTimerRunning)
        {
            
            m.TimerElapsed();
            MooElement.Get("btnGo").Set("disabled", "true");
            cur.SetHtml("Stop");
            
        }else {
            
            MooElement.Get("btnGo").Set("disabled", "");
            cur.SetHtml("Start");
            
        }
        
    });
    
};



// Class 'Cell'
var Cell = new Class({
    
    /*string*/   Id: "",
    /*int*/      X: 0,
    /*int*/      Y: 0,
    /*bool*/     Alive: false,
    /*bool*/     NextState: false,
    /*bool*/     JustDied: false,
    /*bool*/     JustBorn: false,
    /*MooElement*/ Element: 0,
    
    UpdateHtml: function() // returns void
    {
        
        /*string*/ var src = "";
        if(this.Alive)
        {
            
            if(this.JustBorn)
            {
                
                src = "Images/new10.gif";
                this.Element.SetHtml("<img src='' alt='' />");
                
            }else {
                
                src = "Images/filled10.gif";
                this.Element.SetHtml("<img src='' alt='' />");
                
            }
            
        }else {
            
            if(this.JustDied)
            {
                
                src = "Images/killed10.gif";
                this.Element.SetHtml("<img src='I' alt='' />");
                
            }else {
                
                src = "Images/blank10.gif";
                
            }
            
        }
        /*string*/ var cls = "";
        if(this.Y == 0)
        {
            
            cls = "lifeImageTop";
            
        }
        if(this.X == 0)
        {
            
            cls = "lifeImageLeft";
            
        }
        if(this.Y == 0 && this.X == 0)
        {
            
            cls = "lifeImageTopLeft";
            
        }
        this.Element.SetHtml("<img src='" + src + "' alt='' class='" + cls + "' />");
        
    },
    
    
    end: function() {}
});
// Static functions



// Class 'Life'
var Life = new Class({
    
    /*MooList*/  Cells: new MooList(),
    /*int*/      Size: 20,
    
    Start: function(size) // int size - returns void
    {
        
        /*MooElement*/ var e = MooElement.Get("divLife");
        e.SetHtml("");
        // Clear
        this.Size = size;
        // Initialize our cells
        for(/*int*/ var i = 0; i < this.Size; i++)
        {
            
            for(/*int*/ var j = 0; j < this.Size; j++)
            {
                
                /*Cell*/ var c = new Cell();
                c.X = j;
                c.Y = i;
                c.Element = MooElement.Create("span");
                c.Element.inject(e, "bottom");
                c.Element.SetTag(c);
                this.Cells.Add(c);
                //if ((i == 3 && j == 3) || (i == 3 && j == 4) || (i == 4 && j == 4))
                //{
                //   c.Alive = true;
                // }
                c.UpdateHtml();
                c.Element.AddEvent("click", function() {
                    
                    /*MooElement*/ var cur = null;
                    cur = this.MooElement;
                    /*Cell*/ var c2 = /*(Cell)*/cur.GetTag();
                    c2.Alive = !c2.Alive;
                    c2.UpdateHtml();
                    
                });
                
            }
            
            /*MooElement*/ var br = MooElement.Create("br");
            br.inject(e);
            
        }
        
        
    },
    Clear: function() // returns void
    {
        
        // Reverse everything
        for(/*int*/ var i = 0; i < this.Size; i++)
        {
            
            for(/*int*/ var j = 0; j < this.Size; j++)
            {
                
                /*Cell*/ var c = /*(Cell)*/this.Cells.Get(i + j * this.Size);
                c.Alive = false;
                c.UpdateHtml();
                
            }
            
            
        }
        
        
    },
    Save: function() // returns void
    {
        
        
    },
    RunOneStep: function() // returns void
    {
        
        // Update if our cells live or die
        for(/*int*/ var i = 0; i < this.Size; i++)
        {
            
            for(/*int*/ var j = 0; j < this.Size; j++)
            {
                
                /*Cell*/ var cur = /*(Cell)*/this.Cells.Get(i + j * this.Size);
                /*int*/ var neighbors = 0;
                /*Cell*/ var n;
                n = this.GetCell(i, j - 1);
                if(null != n && n.Alive)
                {
                    
                    neighbors++;
                    
                }
                n = this.GetCell(i, j + 1);
                if(null != n && n.Alive)
                {
                    
                    neighbors++;
                    
                }
                n = this.GetCell(i - 1, j);
                if(null != n && n.Alive)
                {
                    
                    neighbors++;
                    
                }
                n = this.GetCell(i + 1, j);
                if(null != n && n.Alive)
                {
                    
                    neighbors++;
                    
                }
                n = this.GetCell(i - 1, j - 1);
                if(null != n && n.Alive)
                {
                    
                    neighbors++;
                    
                }
                n = this.GetCell(i - 1, j + 1);
                if(null != n && n.Alive)
                {
                    
                    neighbors++;
                    
                }
                n = this.GetCell(i + 1, j - 1);
                if(null != n && n.Alive)
                {
                    
                    neighbors++;
                    
                }
                n = this.GetCell(i + 1, j + 1);
                if(null != n && n.Alive)
                {
                    
                    neighbors++;
                    
                }
                cur.NextState = cur.Alive;
                if(neighbors < 2)
                {
                    
                    cur.NextState = false;
                    
                }
                if(neighbors == 3)
                {
                    
                    cur.NextState = true;
                    
                }
                if(neighbors > 3)
                {
                    
                    cur.NextState = false;
                    
                }
                
            }
            
            
        }
        
        // Set each cell to the next state
        for(/*int*/ var i = 0; i < this.Size; i++)
        {
            
            for(/*int*/ var j = 0; j < this.Size; j++)
            {
                
                /*Cell*/ var c = /*(Cell)*/this.Cells.Get(i + j * this.Size);
                c.JustDied = (c.NextState == false && c.Alive == true);
                c.JustBorn = (c.NextState == true && c.Alive == false);
                c.Alive = c.NextState;
                c.UpdateHtml();
                
            }
            
            
        }
        
        
    },
    Invert: function() // returns void
    {
        
        // Reverse everything
        for(/*int*/ var i = 0; i < this.Size; i++)
        {
            
            for(/*int*/ var j = 0; j < this.Size; j++)
            {
                
                /*Cell*/ var c = /*(Cell)*/this.Cells.Get(i + j * this.Size);
                c.Alive = !c.Alive;
                c.UpdateHtml();
                
            }
            
            
        }
        
        
    },
    Randomize: function() // returns void
    {
        
        // Reverse everything
        for(/*int*/ var i = 0; i < this.Size; i++)
        {
            
            for(/*int*/ var j = 0; j < this.Size; j++)
            {
                
                /*Cell*/ var c = /*(Cell)*/this.Cells.Get(i + j * this.Size);
                c.Alive = JsMath.Chance(0.3);
                c.UpdateHtml();
                
            }
            
            
        }
        
        
    },
    GetCell: function(x, y) // int x, int y - returns Cell
    {
        
        if(x < 0)
        {
            
            return null;
            
        }
        if(x >= this.Size)
        {
            
            return null;
            
        }
        if(y < 0)
        {
            
            return null;
            
        }
        if(y >= this.Size)
        {
            
            return null;
            
        }
        return /*(Cell)*/this.Cells.Get(x + y * this.Size);
        
    },
    
    
    end: function() {}
});
// Static functions




// EOF ..\..\Js\Life.cs


