///////////////////////////////////////////////////////////////////////////////
//
//  scene.xaml.js
//
// 
// © 2007 Microsoft Corporation. All Rights Reserved.
//
// This file is licensed as part of the Silverlight 1.0 SDK, for details look 
// here: http://go.microsoft.com/fwlink/?LinkID=89144&clcid=0x409
//
///////////////////////////////////////////////////////////////////////////////

if (!window.TileText)
    window.TileText = {};

TileText.Scene = function() {}

TileText.Scene.prototype = 
{

    handleLoad: function(control, userContext, rootElement) 
    {
        this.button = rootElement.findName("button");
        this.root = rootElement;
        this.control = control;
        
        // Hook up the button event handlers
        this.button.addEventListener("MouseEnter", Silverlight.createDelegate(this, this.handleMouseEnter));
        this.button.addEventListener("MouseLeftButtonDown", Silverlight.createDelegate(this, this.handleMouseDown));
        this.button.addEventListener("MouseLeftButtonUp", Silverlight.createDelegate(this, this.handleMouseUp));
        this.button.addEventListener("MouseLeave", Silverlight.createDelegate(this, this.handleMouseLeave));

        // Initialize the tiles
        this.tileEntries = new Array(26);
        this.setupTileEntries();

        // Make the HTML text input visible
        var textInput = document.getElementById("textInput");
        textInput.style.visibility = "visible";

        // Process the default string
        this.processString(textInput.value);
    },

    handleMouseEnter: function(sender, eventArgs)
    {
        var buttonBG = sender.findName("buttonBG");
        buttonBG.fill = "#FFa0a0a0";
    },

    handleMouseLeave: function(sender, eventArgs)
    {
        var buttonBG = sender.findName("buttonBG");
        buttonBG.fill = "#FF808080";
    },

    handleMouseUp: function(sender, eventArgs)
    {
        var buttonBG = sender.findName("buttonBG");
        buttonBG.fill = "#FFa0a0a0";

        var textInput = document.getElementById("textInput");
        this.processString(textInput.value);
    },

    handleMouseDown: function(sender, eventArgs)
    {
        var buttonBG = sender.findName("buttonBG");
        buttonBG.fill = "#FF606060";
    },
    

    // Takes a string and turns it into tiles
    processString: function(text)
    {
        this.clearTree();

        // Protect from characters that our XML parser doesn't like
        text = text.replaceAll("<", "_");
        text = text.replaceAll("&", "_");
        text = text.replaceAll("'", "_");
        text = text.toUpperCase();

        // Determine if this will fit in one line
        var multiline = false;
        var top = 65;
        if (text.length > 11)
        {
            multiline = true;
            top = 25;
        }

        // If we're multiline, determine how to break the lines
        var breakIndex = 0;
        if (multiline)
        {
            var spaceIndex = text.lastIndexOf(' ');

            if ((spaceIndex > -1) && (text.length - spaceIndex < 11))
            {
                breakIndex = spaceIndex;
            }
            if (breakIndex > 11 || text.length - breakIndex > 11)
            {
                breakIndex = 11;
            }
        }

        var leftPosition;
        var leftPosition2;

        if (multiline)
        {
            leftPosition = (600 - (breakIndex * 52)) / 2;
            leftPosition2 = ((600 - (text.length - breakIndex) * 52)) / 2;
        }
        else 
        {
            leftPosition = (600 - (text.length * 52)) / 2;
        }

        for (var i = 0; i < text.length; i++)
        {
            if (multiline && i == breakIndex)
            {
               top = 100;
               leftPosition = leftPosition2;
            }
            if (text.charAt(i) == ' ')
            {
                leftPosition += 10;
                continue;
            }
            var charCode = text.charCodeAt(i) - 65;

            if (charCode < 0 || charCode > 25)
            {
                this.addTile(i, text.charAt(i), (Math.floor(Math.random()*8)) + 1, top + (Math.floor(Math.random()*9)), leftPosition, "", 17, "00:00:0" + ((i + 1) * .2).toString().substr(0,3));
            }
            else 
            {
                this.addTile(i, text.charAt(i), (Math.floor(Math.random()*8)) + 1, top + (Math.floor(Math.random()*9)), leftPosition, this.tileEntries[charCode].value, 12 + this.tileEntries[charCode].offset, "00:00:0" + ((i + 1) * .2).toString().substr(0,3));
            }
            leftPosition += 52 + Math.floor(Math.random()*2);
        }
    },

    addTile: function(tileNumber, letter, grainIndex, top, left, value, letterOffset, beginTime)
    {
        //this is the template for tiles
        // $0: index of this tile
        // $1: letter on this tile
        // $2: image file for this tile
        // $3: top coordinate this tile
        // $4: left coordinate of this tile
        // $5: point value of this tile
        // $6: left letter offset

        // if beginTime is an integer > 0, assume user wants resources
        // if beginTime is "xx:yy:zz" with xx > 0 assume user want a resources
        var isResource = false;
        var re1 = /(\d+):\d+:\d+/;
        if(beginTime.match(re1))
        {
            var arr = re1.exec(beginTime);
            if(arr.length > 1 && arr[1] > 0)
            {
                // Waiting > 1 hour, move to resources
                isResource = true;
            }
        }
        else
        {
            if(beginTime > 0)
            {
                  // huge Waiting time, move to resources
                  isResource = true;
            }
        }


        xamlString = "<Canvas xmlns='http://schemas.microsoft.com/client/2007' xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' x:Name='tile$0' Canvas.Top='0' Canvas.Left='0' RenderTransformOrigin='0.5,0.5' Height='53' Width='53'>";
        xamlString = xamlString + "<Canvas x:Name='tileTarget$0' Canvas.Top='-100'>";
        if(isResource)
        {
            xamlString = xamlString + "  <Canvas.Resources>";
            xamlString = xamlString + "  <Storyboard BeginTime='0'>";
            xamlString = xamlString + "  <DoubleAnimationUsingKeyFrames BeginTime='00:00:00' Storyboard.TargetName='tileTarget$0' Storyboard.TargetProperty='(Canvas.Left)'>";
            xamlString = xamlString + "  <SplineDoubleKeyFrame KeyTime='00:00:00.6' KeySpline='.75,0,0,.75' Value='$4'/>";
            xamlString = xamlString + "  </DoubleAnimationUsingKeyFrames>";
            xamlString = xamlString + "  <DoubleAnimationUsingKeyFrames BeginTime='00:00:00' Storyboard.TargetName='tileTarget$0' Storyboard.TargetProperty='(Canvas.Top)'>";
            xamlString = xamlString + "  <SplineDoubleKeyFrame KeyTime='00:00:00.6' KeySpline='.75,0,0,.75' Value='$3'/>";
            xamlString = xamlString + "  </DoubleAnimationUsingKeyFrames>";
            xamlString = xamlString + "  </Storyboard>";
            xamlString = xamlString + "  </Canvas.Resources>"; 
        }
        else
        {
            xamlString = xamlString + "  <Canvas.Triggers>";
            xamlString = xamlString + "  <EventTrigger RoutedEvent='Canvas.Loaded'>";
            xamlString = xamlString + "  <BeginStoryboard>";
            xamlString = xamlString + "  <Storyboard BeginTime='$7'>";
            xamlString = xamlString + "  <DoubleAnimationUsingKeyFrames BeginTime='00:00:00' Storyboard.TargetName='tileTarget$0' Storyboard.TargetProperty='(Canvas.Left)'>";
            xamlString = xamlString + "  <SplineDoubleKeyFrame KeyTime='00:00:00.6' KeySpline='.75,0,0,.75' Value='$4'/>";
            xamlString = xamlString + "  </DoubleAnimationUsingKeyFrames>";
            xamlString = xamlString + "  <DoubleAnimationUsingKeyFrames BeginTime='00:00:00' Storyboard.TargetName='tileTarget$0' Storyboard.TargetProperty='(Canvas.Top)'>";
            xamlString = xamlString + "  <SplineDoubleKeyFrame KeyTime='00:00:00.6' KeySpline='.75,0,0,.75' Value='$3'/>";
            xamlString = xamlString + "  </DoubleAnimationUsingKeyFrames>";
            xamlString = xamlString + "  </Storyboard>";
            xamlString = xamlString + "  </BeginStoryboard>";
            xamlString = xamlString + "  </EventTrigger>";
            xamlString = xamlString + "  </Canvas.Triggers>";
        }
        xamlString = xamlString + "  <Image Source='images/$2.png' />";
        xamlString = xamlString + "  <TextBlock Canvas.Top='9' Canvas.Left='$6' FontFamily='Arial' FontSize='34' FontWeight='bold' Text='$1' />";
        xamlString = xamlString + "  <TextBlock Canvas.Top='36' Canvas.Left='37.5' FontFamily='Arial' FontSize='12' FontWeight='bold' Text='$5' />";
        xamlString = xamlString + "</Canvas>";
        xamlString = xamlString + "</Canvas>";


        xamlString = xamlString.replaceAll("$0", tileNumber);
        xamlString = xamlString.replaceAll("$1", letter);
        xamlString = xamlString.replaceAll("$2", grainIndex);
        xamlString = xamlString.replaceAll("$3", top);
        xamlString = xamlString.replaceAll("$4", left);
        xamlString = xamlString.replaceAll("$5", value);
        xamlString = xamlString.replaceAll("$6", letterOffset);
        xamlString = xamlString.replaceAll("$7", beginTime); 

        var tile = this.control.content.createFromXaml(xamlString);
        this.root.children.add(tile);
    },

    // Removes the current tiles so that a new string can be processed
    clearTree: function()
    {
        while (this.root.children.getItem(this.root.children.count - 1).name != "button")
        {
            this.root.children.removeAt(this.root.children.count - 1);
        }
    },

    // Initializes the tile array of tile values
    setupTileEntries: function()
    {
        // Helper function for defining tile values
        function tileEntry(value, offset)
        {
            this.value = value;
            this.offset = offset;
        }
    
        this.tileEntries[0] = new tileEntry(1, 1);
        this.tileEntries[1] = new tileEntry(3, 0);
        this.tileEntries[2] = new tileEntry(3, 0);
        this.tileEntries[3] = new tileEntry(2, 0);
        this.tileEntries[4] = new tileEntry(1, 0);
        this.tileEntries[5] = new tileEntry(4, 0);
        this.tileEntries[6] = new tileEntry(2, 0);
        this.tileEntries[7] = new tileEntry(4, 1);
        this.tileEntries[8] = new tileEntry(1, 8);
        this.tileEntries[9] = new tileEntry(8, 1);
        this.tileEntries[10] = new tileEntry(5, 0);
        this.tileEntries[11] = new tileEntry(1, 2);
        this.tileEntries[12] = new tileEntry(3, -2);
        this.tileEntries[13] = new tileEntry(1, 0);
        this.tileEntries[14] = new tileEntry(1, 0);
        this.tileEntries[15] = new tileEntry(3, 0);
        this.tileEntries[16] = new tileEntry(10, -2);
        this.tileEntries[17] = new tileEntry(1, 0);
        this.tileEntries[18] = new tileEntry(1, 0);
        this.tileEntries[19] = new tileEntry(1, 1);
        this.tileEntries[20] = new tileEntry(1, 0);
        this.tileEntries[21] = new tileEntry(4, 1);
        this.tileEntries[22] = new tileEntry(4, -3);
        this.tileEntries[23] = new tileEntry(8, 1);
        this.tileEntries[24] = new tileEntry(4, 2);
        this.tileEntries[25] = new tileEntry(10, 2);
    }
    
}

// Replaces all instances of the given substring.
String.prototype.replaceAll = function(strTarget, strSubString)
{
    var strText = this;
    var intIndexOfMatch = strText.indexOf( strTarget );

    // Keep looping while an instance of the target string
    // still exists in the string.
    while (intIndexOfMatch != -1)
    {
        // Relace out the current instance.
        strText = strText.replace( strTarget, strSubString )

        // Get the index of any next matching substring.
        intIndexOfMatch = strText.indexOf( strTarget );
    }

    // Return the updated string with ALL the target strings
    // replaced out with the new substring.
    return( strText );
}
