﻿/* Programming by Greg Thatcher, http://www.GregThatcher.com */
var itsCurrentState = 0;
var itsMessageDiv ;
var itsSpeed = 125;
var itsJuliaSet;
var itsCurrentRow = 0;
var itsCurrentColumn = 0;
var itsAllBlank = 0;

var eStates = { eInitialize:0, eInitializeDivRows:1, eSetup:2, eDrawJuliaSet:3, eEraseAndStartAgain:10, eDone:9999};

var itsColorWheel;

var itsRedMax;
var itsRedMin;
var itsBlueMax;
var itsBlueMin;
var itsGreenMax;
var itsGreenMin;

function SetupColorWheel ()
{
/*
    itsColorWheel = new Array();
    itsColorWheel.push("#FF0000");
    itsColorWheel.push("#FF8080");
    itsColorWheel.push("#FFBFBF");
    itsColorWheel.push("#AA3939");
    itsColorWheel.push("#551C1C");
    itsColorWheel.push("#BF6060");
    itsColorWheel.push("#DFA7A7");
    */
    itsRedMax = parseInt(Math.random() * 256);
    itsRedMin = parseInt(Math.random() * (itsRedMax/2));
    itsBlueMax = parseInt(Math.random() * 256);
    itsBlueMin = parseInt(Math.random() * (itsBlueMax/2));
    itsGreenMax = parseInt(Math.random() * 256);
    itsGreenMin = parseInt(Math.random() * (itsGreenMax/2));
    
    itsBackground = "black";
}
function GetEscapeColor(radius, bound)
{
    var color;
/*
    var fraction = radius/bound;
    fraction *= 256;
    color = "rgb(0, 0, " + parseInt(fraction) + ")";
  */
  /*
    var red, green, blue;
    var temp = radius;
    radius *= 1000.0;
    red = parseInt(radius) % 256;
    
    radius = radius - red;
    radius *= 1000.0;
    green = parseInt(radius) % 256;
    
    radius = radius - green;
    radius *= 1000.0;
    blue = parseInt(radius) % 256;
    red = green = 0;
    color = "rgb(" + red + ", " + green + ", " + blue + ")";
    */
    /*
    var choice = parseFloat(itsJuliaSet.currentIteration) / parseFloat(itsJuliaSet.itsMaxIteration);
    choice = parseInt(100 * choice);
    var temp = choice % itsColorWheel.length;
    color = itsColorWheel[temp];
    return color;    
    */
    
    var red, green, blue;
    
    var choice = parseFloat(itsJuliaSet.currentIteration) / parseFloat(itsJuliaSet.itsMaxIteration);
    blue = parseInt(itsBlueMax * choice) + itsBlueMin;
    blue = blue % itsBlueMax;
    if (isNaN(blue))
    {
        blue = 0;
    }
    red = parseInt(itsRedMax * choice) + itsRedMin;
    red = red % itsRedMax;
    if (isNaN(red))
    {
        red = 0;
    }
    
    green = parseInt(itsGreenMax * choice) + itsGreenMin;
    green = green % itsGreenMax;
    if (isNaN(green))
    {
        green = 0;
    }
    
    color = "rgb(" + red + ", " + green + ", " + blue + ")";
    
    return color;
}

function WalkSquare()
{
    var color;
    for (itsCurrentColumn = 0; itsCurrentColumn < GetStageWidth(); itsCurrentColumn++)
    {
        itsJuliaSet.SetZ(parseFloat(2 * (itsCurrentRow   -(GetStageWidth ()/2)))/(GetStageWidth()), 
                         parseFloat(2 * (itsCurrentColumn-(GetStageHeight()/2)))/(GetStageHeight()));
        
        while (!itsJuliaSet.NextIteration())
        {
        }
        if (itsJuliaSet.Escape())
        {
            itsAllBlank++;
            color = GetEscapeColor(itsJuliaSet.GetRadius (), itsJuliaSet.Bound);
            PlotPixel(itsCurrentColumn, itsCurrentRow, color) ;
        }
        else
        {
            // itsMessageDiv.innerHTML = color + " : " + itsJuliaSet.GetRadius ();
            PlotPixel(itsCurrentColumn, itsCurrentRow, itsBackground) ;
        }
    }
    
    itsCurrentRow++;
    return (itsCurrentRow >= GetStageHeight());
}

function stateMachineJuliaSet()
{
    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.eInitializeDivRows;
            InitializeDivCache();
            break;
        case eStates.eInitializeDivRows:
            if (InitializeNextDivRow ("white"))
            {
                itsCurrentState = eStates.eSetup;
            }
            break;           
        case eStates.eSetup:
            // Note, state width and height should be equal
            itsJuliaSet = new JuliaSet(GetStageWidth());
            itsMessageDiv.innerHTML = "Setup";
            itsCurrentState = eStates.eDrawJuliaSet;
            itsCurrentRow = 0;
            itsCurrentColumn = 0;
            itsSpeed = 125;
            itsAllBlank = 0;
            itsMessageDiv.innerHTML = "Generate Julia Set For: " + itsJuliaSet.ToString();
            SetupColorWheel ()
            break;
        case eStates.eDrawJuliaSet:
            //itsSpeed = 5000;
            if (WalkSquare())
            {
                itsCurrentState = eStates.eDone;
                itsSpeed = 125;
            }
            break;            
        case eStates.eDone:
            if (itsAllBlank <= 20)
            {
                itsSpeed = 3000;
                itsMessageDiv.innerHTML = "Sorry, didn't generate anything interesting that time.  Let me try again.";
            }
            else
            {
                itsSpeed = 5000;
                itsMessageDiv.innerHTML = "Done -- Pausing for 5 seconds; " + itsJuliaSet.ToString();
            }
            //itsCurrentState = eStates.eEraseAndStartAgain;
            itsCurrentState = eStates.eSetup;
            break;
            // Skipping this, for now
        case eStates.eEraseAndStartAgain:
            itsSpeed = 125;
            itsMessageDiv.innerHTML = "Erase and Start Again";
            EraseStage("white"); // white
            itsCurrentState = eStates.eSetup;
            break;
    }
    setTimeout("stateMachineJuliaSet();", itsSpeed);
}

function InitializeStateMachine ()
{
    itsCurrentState = eStates.eInitialize;
    
    setTimeout("stateMachineJuliaSet();", itsSpeed);
    
}

