﻿/* Programming by Greg Thatcher, http://www.GregThatcher.com */

var itsCurrentState = 0;
var itsMessageDiv ;
var itsSpeed = 1000;


var eStates = { eInitialize:0, eSetup:1, eDrawRectangles:2, eEraseAndStartAgain:10, eDone:9999};

var itsArrayOfSegments = new Array ();

var itsLineColor = "blue";

var itsCounter = 0;

function CreateSegment (segment, lineColor)
{
    var x1, x2, y1, y2;
    if (segment.pt1.x < segment.pt2.x)
    {
        x1 = segment.pt1.x;
        x2 = segment.pt2.x;
    }
    else
    {
        x1 = segment.pt2.x;
        x2 = segment.pt1.x;
    }
    if (segment.pt1.y < segment.pt2.y)
    {
        y1 = segment.pt1.y;
        y2 = segment.pt2.y;
    }
    else
    {
        y1 = segment.pt2.y;
        y2 = segment.pt1.y;
    }
    var eDiv=document.createElement("div");
    
    eDiv.id = itsCounter;
    itsCounter++;
    if ((x2 - x1) > 0)
    {
        eDiv.style.width    =   (x2 - x1) + "px";
        eDiv.style.height   =   1 + "px";
    }
    else
    {
        eDiv.style.width    =   1 + "px";
        eDiv.style.height   =   (y2 - y1) + "px";
    }
            
    eDiv.style.position= "absolute";
    eDiv.style.backgroundColor=lineColor;
    eDiv.style.left = x1 + "px";
    eDiv.style.top = y1 + "px";
    itsStageDiv.appendChild(eDiv);
}

function TryToAddSeg(seg)
{
    if (Math.abs(seg.pt1.x - seg.pt2.x) > 2 ||
        Math.abs(seg.pt1.y - seg.pt2.y) > 2)
    {
        itsArrayOfSegments.push(seg);
        return true;
    }
    return false;
}

function generateRectangles ()
{
    var currentSegment;
    var numberOfSegments = itsArrayOfSegments.length;
    var i;
    var firstSeg, secondSeg, thirdSeg;
    var newSegWidth = 0;
    var newSegHeight = 0;
    var newSeg;
    
    if (numberOfSegments <= 0)
    {
        return false;
    }
    
    for (i = 0; i < numberOfSegments; i++)
    {
        currentSegment = itsArrayOfSegments.shift();
    
        // if vertical
        if (currentSegment.pt1.x == currentSegment.pt2.x)
        {
            newSegHeight = parseInt(Math.abs(currentSegment.pt2.y - currentSegment.pt1.y) / 3);
            newSegWidth = 0;
        }
        else // horizontal
        {
            newSegWidth = parseInt(Math.abs(currentSegment.pt2.x - currentSegment.pt1.x) / 3);
            newSegHeight = 0;
        }               
        firstSeg = new Segment(
            currentSegment.pt1.x, 
            currentSegment.pt1.y,
            currentSegment.pt1.x + newSegWidth, 
            currentSegment.pt1.y + newSegHeight);
        secondSeg = new Segment(
            currentSegment.pt1.x + newSegWidth, 
            currentSegment.pt1.y + newSegHeight,
            currentSegment.pt1.x + (2 * newSegWidth), 
            currentSegment.pt1.y + (2 * newSegHeight));
        thirdSeg = new Segment(
            currentSegment.pt1.x + (2 * newSegWidth), 
            currentSegment.pt1.y + (2 * newSegHeight),
            currentSegment.pt2.x, 
            currentSegment.pt2.y);
            
        TryToAddSeg(firstSeg);
        TryToAddSeg(thirdSeg);
        if (TryToAddSeg(secondSeg))
        {
            CreateSegment (secondSeg, itsLineColor)
            // now, create 6 more segs to create a rectangle
            if (newSegWidth > 0)
            {
                newSeg = new Segment(
                    secondSeg.pt1.x, 
                    secondSeg.pt1.y,
                    secondSeg.pt1.x,
                    secondSeg.pt1.y + newSegWidth);
                TryToAddSeg(newSeg);
                CreateSegment (newSeg, itsLineColor)
                
                newSeg = new Segment(
                    secondSeg.pt2.x, 
                    secondSeg.pt1.y,
                    secondSeg.pt2.x,
                    secondSeg.pt1.y + newSegWidth);
                TryToAddSeg(newSeg);
                CreateSegment (newSeg, itsLineColor)
                
                newSeg = new Segment(
                    secondSeg.pt1.x, 
                    secondSeg.pt1.y - newSegWidth,
                    secondSeg.pt1.x,
                    secondSeg.pt1.y);
                TryToAddSeg(newSeg);
                CreateSegment (newSeg, itsLineColor)
                
                newSeg = new Segment(
                    secondSeg.pt2.x, 
                    secondSeg.pt1.y - newSegWidth,
                    secondSeg.pt2.x,
                    secondSeg.pt1.y);
                TryToAddSeg(newSeg);
                CreateSegment (newSeg, itsLineColor)
                
                newSeg = new Segment(
                    secondSeg.pt1.x, 
                    secondSeg.pt1.y - newSegWidth,
                    secondSeg.pt2.x,
                    secondSeg.pt1.y - newSegWidth);
                TryToAddSeg(newSeg);
                CreateSegment (newSeg, itsLineColor)
                
                newSeg = new Segment(
                    secondSeg.pt1.x, 
                    secondSeg.pt1.y + newSegWidth,
                    secondSeg.pt2.x,
                    secondSeg.pt1.y + newSegWidth);
                TryToAddSeg(newSeg);
                CreateSegment (newSeg, itsLineColor)
                
            }
            else
            {
                newSeg = new Segment(
                    secondSeg.pt1.x, 
                    secondSeg.pt1.y,
                    secondSeg.pt1.x + newSegHeight,
                    secondSeg.pt1.y);
                TryToAddSeg(newSeg);
                CreateSegment (newSeg, itsLineColor)
                
                newSeg = new Segment(
                    secondSeg.pt1.x, 
                    secondSeg.pt2.y,
                    secondSeg.pt1.x + newSegHeight,
                    secondSeg.pt2.y);
                TryToAddSeg(newSeg);
                CreateSegment (newSeg, itsLineColor)
                
                newSeg = new Segment(
                    secondSeg.pt1.x - newSegHeight, 
                    secondSeg.pt1.y,
                    secondSeg.pt1.x,
                    secondSeg.pt1.y);
                TryToAddSeg(newSeg);
                CreateSegment (newSeg, itsLineColor)
                
                newSeg = new Segment(
                    secondSeg.pt1.x - newSegHeight, 
                    secondSeg.pt2.y,
                    secondSeg.pt1.x,
                    secondSeg.pt2.y);
                TryToAddSeg(newSeg);
                CreateSegment (newSeg, itsLineColor)
                
                newSeg = new Segment(
                    secondSeg.pt1.x - newSegHeight, 
                    secondSeg.pt1.y,
                    secondSeg.pt1.x - newSegHeight,
                    secondSeg.pt2.y);
                TryToAddSeg(newSeg);
                CreateSegment (newSeg, itsLineColor)
                
                newSeg = new Segment(
                    secondSeg.pt1.x + newSegHeight, 
                    secondSeg.pt1.y,
                    secondSeg.pt1.x + newSegHeight,
                    secondSeg.pt2.y);
                TryToAddSeg(newSeg);
                CreateSegment (newSeg, itsLineColor)
            }
        }
        
    }
    return true;
    
}

function stateMachinePeanoCurve()
{
    switch (itsCurrentState)
    {
        case eStates.eInitialize:
            itsMessageDiv = document.getElementById("message");
            itsMessageDiv.innerHTML = "Initializing.  Please wait...";
            // get this now, before we create lots of divs
            itsCurrentState = eStates.eSetup;
            break;
        case eStates.eSetup:
            itsMessageDiv.innerHTML = "Setup";
            itsCurrentState = eStates.eDrawRectangles;
            var segment = new Segment(GetStageWidth()/6, GetStageHeight()/2, 5 * GetStageWidth()/6, GetStageHeight()/2);
            itsArrayOfSegments.push(segment);
            CreateSegment (segment, itsLineColor)
            break;
        case eStates.eDrawRectangles:
            itsMessageDiv.innerHTML = "Drawing Rectangles";
            if (!generateRectangles ())
            {
                itsCurrentState = eStates.eDone;
            }
            break;            
        case eStates.eDone:
            itsMessageDiv.innerHTML = "Done";
            itsCurrentState = eStates.eEraseAndStartAgain;
            break;
        case eStates.eEraseAndStartAgain:
            itsMessageDiv.innerHTML = "Erase and Start Again";
            itsCurrentState = eStates.eSetup;
            itsStageDiv.innerHTML = "";
            itsCounter = 0;
            itsArrayOfSegments.length = 0;
            break;
    }
    if (itsCurrentState == eStates.eDrawRectangles)
    {
        setTimeout("stateMachinePeanoCurve();", 1000);
    }
    else
    {
        setTimeout("stateMachinePeanoCurve();", itsSpeed);
    }
}

function InitializeStateMachine ()
{
    itsCurrentState = eStates.eInitialize;
    
    setTimeout("stateMachinePeanoCurve();", itsSpeed);
    
}





