﻿/* Programming by Greg Thatcher, http://www.GregThatcher.com */

var itsCurrentState = 0;
var itsMessateDiv ;
var itsSpeed = 125;


var eStates = { eInitializeDivCache:0, eInitializeDivRows:1, eCreateStartTriangle:2, eGenerateMoreTriangles:3, eEraseAndStartAgain:10, eDone:9999};

var itsArrayOfTriangles = new Array ();


function findMidpoint (pt1, pt2)
{
    var x, y;
    x = (pt1.x + pt2.x) / 2;
    y = (pt1.y + pt2.y) / 2;
    return new Point(x, y);
}


function generateTriangles ()
{
    var currentTriangle;
    var newArray = new Array();
        
    if (itsArrayOfTriangles.length <= 0)
    {
        return false;
    }
    
    var triangle;
    var pt1;
    var pt2;
    var pt3;
    while ((currentTriangle = itsArrayOfTriangles.shift()) != null)
    {
        
        pt1 = findMidpoint(currentTriangle.vertices[0], currentTriangle.vertices[1]);
        pt2 = findMidpoint(currentTriangle.vertices[1], currentTriangle.vertices[2]);
        pt3 = findMidpoint(currentTriangle.vertices[0], currentTriangle.vertices[2]);
        
        triangle = new Triangle (pt1.x, pt1.y, pt2.x, pt2.y, pt3.x, pt3.y);
        FillTriangle (triangle, "black", "white");
        
        
        pt1 = findMidpoint(currentTriangle.vertices[0], currentTriangle.vertices[1]);
        pt2 = findMidpoint(currentTriangle.vertices[0], currentTriangle.vertices[2]);
        triangle = new Triangle(
            currentTriangle.vertices[0].x,
            currentTriangle.vertices[0].y,
            pt1.x, pt1.y,
            pt2.x, pt2.y);
        newArray.push(triangle);
                
        pt1 = findMidpoint(currentTriangle.vertices[1], currentTriangle.vertices[0]);
        pt2 = findMidpoint(currentTriangle.vertices[1], currentTriangle.vertices[2]);
        triangle = new Triangle(
            currentTriangle.vertices[1].x,
            currentTriangle.vertices[1].y,
            pt1.x, pt1.y,
            pt2.x, pt2.y);
        newArray.push(triangle);
        
        pt1 = findMidpoint(currentTriangle.vertices[2], currentTriangle.vertices[1]);
        pt2 = findMidpoint(currentTriangle.vertices[2], currentTriangle.vertices[0]);
        triangle = new Triangle(
            currentTriangle.vertices[2].x,
            currentTriangle.vertices[2].y,
            pt1.x, pt1.y,
            pt2.x, pt2.y);
        newArray.push(triangle);
        
    }
    while ((triangle = newArray.shift()) != null)
    {
        itsArrayOfTriangles.push (triangle);
    }
    triangle = itsArrayOfTriangles[0];
    if (Math.abs(triangle.vertices[0].x - triangle.vertices[1].x) < 6 ||
        Math.abs(triangle.vertices[0].y - triangle.vertices[1].y) < 6)
    {
        itsArrayOfTriangles.length = 0;
        return false;
    }
    return true;
}

function createStartTriangle ()
{
    var myTriangle;
/*    
    switch (parseInt(12*Math.random()))
    {
        case 0:
            myTriangle = new Triangle(
                GetStageWidth()*Math.random(), 0, 
                0, GetStageHeight()/2, 
                GetStageWidth(), GetStageHeight());
            break;
        case 1:
            myTriangle = new Triangle(
                GetStageWidth(), 0, 
                0, GetStageHeight()/2, 
                GetStageWidth()*Math.random(), GetStageHeight());
            break;
        case 2:
            myTriangle = new Triangle(
                GetStageWidth(), 0, 
                0, (GetStageHeight()/2)*Math.random(), 
                GetStageWidth(), GetStageHeight());
            break;

        case 3:
            myTriangle = new Triangle(0, 0, 
                0, GetStageHeight(), 
                GetStageWidth(), GetStageHeight()*Math.random());
            break;
        case 4:
            myTriangle = new Triangle((GetStageWidth()/2)*Math.random(), 0, 
                0, GetStageHeight(), 
                GetStageWidth(), GetStageHeight()/2);
            break;
        case 5:
            myTriangle = new Triangle(0, 0, 
                (GetStageWidth()/2)*Math.random(), GetStageHeight(), 
                GetStageWidth(), GetStageHeight()/2);
            break;
        case 6:
            myTriangle = new Triangle(0, GetStageHeight(), 
                Math.round(GetStageWidth()*Math.random()), 0, 
                GetStageWidth(), GetStageHeight());
            break;
        case 7:
            myTriangle = new Triangle(
                Math.round((GetStageWidth()/2)*Math.random()), GetStageHeight(), 
                GetStageWidth()/2, 0, 
                GetStageWidth(), GetStageHeight());
            break;
        case 8:
            myTriangle = new Triangle(0, GetStageHeight(), 
                GetStageWidth()/2, 0, 
                GetStageWidth()/2 + Math.round((GetStageWidth()/2)*Math.random()), GetStageHeight());
            break;
        case 9:
            myTriangle = new Triangle(0, 0, 
                Math.round(GetStageWidth()*Math.random()), GetStageHeight(), 
                GetStageWidth(), 0);
            break;
        case 10:
            myTriangle = new Triangle(
                Math.round((GetStageWidth()/2)*Math.random()), 0, 
                GetStageWidth()/2, GetStageHeight(), 
                GetStageWidth(), 0);
            break;
        default:
        case 11:
            myTriangle = new Triangle(0, 0, 
                GetStageWidth()/2, GetStageHeight(), 
                GetStageWidth()/2 + Math.round((GetStageWidth()/2)*Math.random()), 0);
            break;

    }
*/
    switch (parseInt(4*Math.random()))
    {
        default:
            myTriangle = new Triangle(
                0, 0, 
                GetStageWidth()/2, GetStageHeight(), 
                GetStageWidth(), 0);
            break;
        case 1:
            myTriangle = new Triangle(
                0, 0, 
                GetStageWidth(), GetStageHeight()/2, 
                0, GetStageHeight());
            break;
        case 2:
            myTriangle = new Triangle(
                0, GetStageHeight(), 
                GetStageWidth()/2, 0, 
                GetStageWidth(), GetStageHeight());
            break;
        case 3:
            myTriangle = new Triangle(
                GetStageWidth(), 0, 
                0, GetStageHeight()/2, 
                GetStageWidth(), GetStageHeight());
            break;
    }
         
    FillTriangle (myTriangle, "black", "black");

    itsArrayOfTriangles.push(myTriangle);
    
}

function stateMachineSierpinski()
{
    var messageDiv;
    switch (itsCurrentState)
    {
        case eStates.eInitializeDivCache:
            messageDiv = document.getElementById("message");
            messageDiv.innerHTML = "Loading.  Please wait...";
            // get this now, before we create lots of divs
            itsMessateDiv = document.getElementById("message");
            InitializeDivCache();
            itsCurrentState = eStates.eInitializeDivRows;
            break;
        case eStates.eInitializeDivRows:
            if (InitializeNextDivRow ("white"))
            {
                itsMessateDiv.innerHTML = "";
                itsCurrentState = eStates.eCreateStartTriangle;
            }
            break;           
        case eStates.eCreateStartTriangle:
            createStartTriangle ();
            itsCurrentState = eStates.eGenerateMoreTriangles;
            break;
        case eStates.eGenerateMoreTriangles:
            if (!generateTriangles ())
            {
                itsCurrentState = eStates.eDone;
            }
            break;            
        case eStates.eDone:
            itsCurrentState = eStates.eEraseAndStartAgain;
            break;
        case eStates.eEraseAndStartAgain:
            EraseStage("white"); // white
            itsCurrentState = eStates.eCreateStartTriangle;
            break;
    }
    switch (itsCurrentState)
    {
        case eStates.eDone:
           setTimeout("stateMachineSierpinski();", 5000);
            break;
        case eStates.eInitializeDivRows:
            setTimeout("stateMachineSierpinski();", 125);
            break;
        default:
            setTimeout("stateMachineSierpinski();", 1000);
            break;
    }
}

function InitializeStateMachine ()
{
    itsCurrentState = eStates.eInitializeDivCache;
    
    setTimeout("stateMachineSierpinski();", itsSpeed);
    
}






