Type.registerNamespace("Controls");
Controls.FifteenPuzzle = function(element)
{
Controls.FifteenPuzzle.createProperty("width");
Controls.FifteenPuzzle.createProperty("height");
Controls.FifteenPuzzle.createProperty("xamlUrl");
Controls.FifteenPuzzle.createProperty("imageUrl");
Controls.FifteenPuzzle.createProperty("puzzleRenderMode");
Controls.FifteenPuzzle.initializeBase(this, [element]);
this.PuzzleSize = 100;
this.FontSize = 70;
this.positions = new Array();
for (var nRow=0;nRow<4;nRow++)
{
this.positions[nRow] = new Array();
for (var nCol=0;nCol<4;nCol++)
{
this.positions[nRow][nCol] = ((nRow*4) + nCol + 1);
}
}
}
Controls.FifteenPuzzle.prototype =
{
initialize : function()
{
Controls.FifteenPuzzle.callBaseMethod(this, "initialize");
this._renderControl();
},
dispose : function()
{
Controls.FifteenPuzzle.callBaseMethod(this, "dispose");
},
_getContentElement : function()
{
return $get(String.format("{0}_Content", this.get_id()));
},
_onXamlLoaded : function(plugIn, userContext, rootElement)
{
this._plugIn = plugIn;
this._rootElement = rootElement;
this._renderNumbers();
this._drawShuffleButton();
},
_getXPosition : function(nCol)
{
return (15 + (nCol*(this.PuzzleSize+1)))+2;
},
_getYPosition : function(nRow)
{
return (65 + (nRow*(this.PuzzleSize+1)))+2;
},
_drawShuffleButton : function()
{
var sb = new Sys.StringBuilder();
sb.append(String.format('<Canvas Name="{0}_btnShuffle" Canvas.Left="140" Canvas.Top="520" Width="160" Height="45" Background="White" Cursor="Hand">', this.get_id()));
sb.append('<Rectangle Fill="#80000000" Width="158" Height="43" Canvas.Top="2" Canvas.Left="2" RadiusX="15" RadiusY="15">');
sb.append('</Rectangle>');
sb.append('<Rectangle Width="160" Height="45" Canvas.Top="0" Canvas.Left="0" RadiusX="15" RadiusY="15">');
sb.append('<Rectangle.Fill>');
sb.append('<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">');
sb.append('<GradientStop Offset="0" Color="Orange"/>');
sb.append('<GradientStop Offset="0.6" Color="Red"/>');
sb.append('</LinearGradientBrush>');
sb.append('</Rectangle.Fill>');
sb.append('</Rectangle>');
sb.append('<Rectangle Width="158" Height="43" Canvas.Top="1" Canvas.Left="1" RadiusX="14" RadiusY="14">');
sb.append('<Rectangle.Fill>');
sb.append('<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">');
sb.append('<GradientStop Offset="0" Color="#FFFFFFFF"/>');
sb.append('<GradientStop Offset="1" Color="#00000000"/>');
sb.append('</LinearGradientBrush>');
sb.append('</Rectangle.Fill>');
sb.append('</Rectangle>');
sb.append('<TextBlock Canvas.Left="10" Canvas.Top="0" Canvas.ZIndex="1" Text="Shuffle" FontFamily="Verdana" FontSize="35" FontWeight="Bold"></TextBlock>');
sb.append('</Canvas>');
var buttonElement = this._plugIn.content.createFromXaml(sb.toString(), false);
this._rootElement.children.add(buttonElement);
buttonElement.AddEventListener("MouseLeftButtonDown", this._onShuffleClick)
},
_drawNumber : function(nRow, nCol)
{
var n = ((nRow*4)+nCol+1);
var sb = new Sys.StringBuilder();
if (this.get_puzzleRenderMode()==Controls.PuzzleRenderMode.Number)
{
sb.append(String.format('<Canvas Name="{0}_Cell_{1}" Canvas.Left="{2}" Canvas.Top="{3}" Canvas.ZIndex="3" Width="{4}" Height="{4}" Background="White" Cursor="Hand">', this.get_id(), n, this._getXPosition(nCol), this._getYPosition(nRow), this.PuzzleSize));
sb.append('<Rectangle Fill="#80000000" Width="98" Height="98" Canvas.Top="2" Canvas.Left="2" RadiusX="15" RadiusY="15">');
sb.append('</Rectangle>');
sb.append('<Rectangle Width="100" Height="100" Canvas.Top="0" Canvas.Left="0" RadiusX="15" RadiusY="15">');
sb.append('<Rectangle.Fill>');
sb.append('<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">');
sb.append('<GradientStop Offset="0" Color="Green"/>');
sb.append('<GradientStop Offset="0.6" Color="Lime"/>');
sb.append('</LinearGradientBrush>');
sb.append('</Rectangle.Fill>');
sb.append('</Rectangle>');
sb.append('<Rectangle Width="98" Height="98" Canvas.Top="1" Canvas.Left="1" RadiusX="14" RadiusY="14">');
sb.append('<Rectangle.Fill>');
sb.append('<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">');
sb.append('<GradientStop Offset="0" Color="#FFFFFFFF"/>');
sb.append('<GradientStop Offset="1" Color="#00000000"/>');
sb.append('</LinearGradientBrush>');
sb.append('</Rectangle.Fill>');
sb.append('</Rectangle>');
sb.append(String.format('<TextBlock Name="{0}_TextBlock_{1}_{2}" Canvas.Left="25" Canvas.Top="0" Canvas.ZIndex="1" FontFamily="Verdana" FontSize="{3}" Text="{4}" FontWeight="Bold" Cursor="Hand" />', this.get_id(), nRow, nCol, this.FontSize, n));
sb.append('</Canvas>');
}
else if (this.get_puzzleRenderMode()==Controls.PuzzleRenderMode.Image)
{
sb.append(String.format('<Image Name="{0}_Cell_{1}" Canvas.Left="{2}" Canvas.Top="{3}" Canvas.ZIndex="3" Width="{4}" Height="{4}" Cursor="Hand" Source="{5}">', this.get_id(), n, (17+nCol), (67+nRow), (this.PuzzleSize*4), this.get_imageUrl()));
sb.append('<Image.Clip>');
sb.append(String.format('<RectangleGeometry Rect="{0},{1},{2},{2}" RadiusX="15" RadiusY="15"></RectangleGeometry>', (nCol*this.PuzzleSize), (nRow*this.PuzzleSize), this.PuzzleSize));
sb.append('</Image.Clip>');
sb.append('<Image.RenderTransform>');
sb.append(String.format('<TranslateTransform Name="{0}_Cell_{1}_Transform" X="0" Y="0" />', this.get_id(), n));
sb.append('</Image.RenderTransform>');
sb.append('</Image>');
}
var numberElement = this._plugIn.content.createFromXaml(sb.toString(), false);
this._rootElement.children.add(numberElement);
var elementNumber = this._rootElement.findName(String.format("{0}_Cell_{1}", this.get_id(), n));
if (this.get_puzzleRenderMode()==Controls.PuzzleRenderMode.Number)
{
var textBlockNumber = this._rootElement.findName(String.format("{0}_TextBlock_{1}_{2}", this.get_id(), nRow, nCol));
textBlockNumber["Canvas.Left"] = ((this.PuzzleSize - textBlockNumber.ActualWidth) / 2).toString();
textBlockNumber["Canvas.Top"] = ((this.PuzzleSize - textBlockNumber.ActualHeight) / 2).toString();
}
elementNumber.AddEventListener("MouseLeftButtonDown", this._onNumberClick)
},
_getPuzzleNumber : function(nRow, nCol)
{
return this.positions[nRow][nCol];
},
_setPuzzleNumber : function(nRow, nCol, number)
{
this.positions[nRow][nCol]=number;
},
_getCellPosition : function(number)
{
var cellPosition = new Object();
for (var nRow=0;nRow<4;nRow++)
{
for (var nCol=0;nCol<4;nCol++)
{
if (this.positions[nRow][nCol]==number)
{
cellPosition.nRow = nRow;
cellPosition.nCol = nCol;
break;
}
}
}
return cellPosition;
},
_getNumberFromElement : function(elementNumber)
{
var values = elementNumber.Name.split('_');
return parseInt(values[values.length-1]);
},
_getElementFromNumber : function(number)
{
return this._rootElement.findName(String.format("{0}_Cell_{1}", this.get_id(), number));
},
_onShuffleClick : function(sender, mouseEventArgs)
{
var values = sender.Name.split('_');
var control = $find(values[0]);
for (var t=0;t<300;t++)
{
control._nextStepShuffle();
}
control._refreshNumbers();
},
_refreshNumbers : function()
{
for (var nRow=0;nRow<4;nRow++)
{
for (var nCol=0;nCol<4;nCol++)
{
var number = this.positions[nRow][nCol];
if (number<16)
{
var elementNumber = this._getElementFromNumber(number);
this._setPuzzlePosition(number, elementNumber, nRow, nCol);
}
}
}
},
_nextStepShuffle : function()
{
var end = false;
while (!end)
{
var randomNumber=(Math.floor(Math.random()*15)+1);
var cellPosition = this._getCellPosition(randomNumber);
end = this._tryToMove(false, cellPosition.nRow, cellPosition.nCol);
}
},
_onNumberClick : function(sender, mouseEventArgs)
{
var values = sender.Name.split('_');
var control = $find(values[0]);
var number = control._getNumberFromElement(sender);
var cellPosition = control._getCellPosition(number);
control._tryToMove(true, cellPosition.nRow, cellPosition.nCol);
},
_tryToMove : function(makeMove, nRow, nCol)
{
var number = this._getPuzzleNumber(nRow, nCol)
var numberElement = this._getElementFromNumber(number);
var nRowMove=-1;
var nColMove=-1;
if (nRow==3)
{
var aboveNumber = this._getPuzzleNumber(nRow-1, nCol);
if (aboveNumber==16)
{
nRowMove=nRow-1;
nColMove=nCol;
}
}
else if (nRow==0)
{
var belowNumber = this._getPuzzleNumber(nRow+1, nCol);
if (belowNumber==16)
{
nRowMove=nRow+1;
nColMove=nCol;
}
}
else
{
var aboveNumber = this._getPuzzleNumber(nRow-1, nCol);
var belowNumber = this._getPuzzleNumber(nRow+1, nCol);
if (aboveNumber==16)
{
nRowMove=nRow-1;
nColMove=nCol;
}
if (belowNumber==16)
{
nRowMove=nRow+1;
nColMove=nCol;
}
}
if (nCol==3)
{
var leftNumber = this._getPuzzleNumber(nRow, nCol-1);
if (leftNumber==16)
{
nRowMove=nRow;
nColMove=nCol-1;
}
}
else if (nCol==0)
{
var rightNumber = this._getPuzzleNumber(nRow, nCol+1);
if (rightNumber==16)
{
nRowMove=nRow;
nColMove=nCol+1;
}
}
else
{
var leftNumber = this._getPuzzleNumber(nRow, nCol-1);
var rightNumber = this._getPuzzleNumber(nRow, nCol+1);
if (leftNumber==16)
{
nRowMove=nRow;
nColMove=nCol-1;
}
if (rightNumber==16)
{
nRowMove=nRow;
nColMove=nCol+1;
}
}
if (nRowMove!=-1 && nColMove!=-1)
{
this._movePuzzleTo(makeMove, numberElement, nRowMove, nColMove);
return true;
}
else
{
return false;
}
},
_setPuzzlePosition : function(number, elementNumber, toNRow, toNCol)
{
if (this.get_puzzleRenderMode()==Controls.PuzzleRenderMode.Number)
{
elementNumber["Canvas.Left"] = this._getXPosition(toNCol);
elementNumber["Canvas.Top"] = this._getYPosition(toNRow);
}
else
{
var nCol = (number-1)%4;
var nRow = (number-1-nCol)/4;
var transformElement = this._rootElement.findName(String.format("{0}_Cell_{1}_Transform", this.get_id(), number));
transformElement["X"] = ((toNCol-nCol)*(this.PuzzleSize+1));
transformElement["Y"] = ((toNRow-nRow)*(this.PuzzleSize+1));
}
},
_movePuzzleTo : function(makeMove, elementNumber, toNRow, toNCol)
{
var number = this._getNumberFromElement(elementNumber);
var cellPosition = this._getCellPosition(number);
if (makeMove)
this._setPuzzlePosition(number, elementNumber, toNRow, toNCol);
this._setPuzzleNumber(toNRow, toNCol, number);
this._setPuzzleNumber(cellPosition.nRow, cellPosition.nCol, 16);
if (makeMove)
this._checkGameCompleted();
},
_checkGameCompleted : function()
{
var n = 1;
for (var nRow=0;nRow<4;nRow++)
{
for (var nCol=0;nCol<4;nCol++)
{
if (this.positions[nRow][nCol]!=n)
{
return;
}
n++;
}
}
alert("Game completed!");
},
_renderNumbers : function()
{
for (var nRow=0;nRow<4;nRow++)
{
for (var nCol=0;nCol<4;nCol++)
{
if (((nRow*4)+nCol+1)<=15)
{
this._drawNumber(nRow, nCol);
}
}
}
},
_renderControl : function()
{
this.get_element().innerHTML = String.format("<div id='{0}_Content' style='width:{1};height:{2}'></div>", this.get_id(), this.get_width(), this.get_height());
var hostId = String.format("{0}_Host", this.get_id());
var bounds = Sys.UI.DomElement.getBounds(this._getContentElement());
Silverlight.createObject(this.get_xamlUrl(), this._getContentElement(), hostId,
{ width:bounds.width.toString(), height:bounds.height.toString(), version:'1.0' },
{ onError:null, onLoad:Function.createDelegate(this, this._onXamlLoaded) },
null);
}
};
Controls.FifteenPuzzle.registerClass("Controls.FifteenPuzzle", Sys.UI.Control);
Controls.PuzzleRenderMode = function(){};
Controls.PuzzleRenderMode.prototype =
{
Number : 0,
Image : 1
}
Controls.PuzzleRenderMode.registerEnum("Controls.PuzzleRenderMode");
if (typeof (Sys) != "undefined")
{
Sys.Application.notifyScriptLoaded();
}