
		var IE6;
		var pnlInfo;	
		var dlgHelp;
		var tipRating			
		var imgFull;
		var imgNext;
		var tmrLoading;
		var rtadivs;	//star rating overlays
		var rtctrdivs;	//star rating containers
		var rtleft;		//star rating ctr x-position
		var histlist = [];
		var keylist = [];
		var histptr = 0;
		var diffDivs;
		var resized = false;
		
		var out, ctr, mask, clock, st, tm, moves, loadtm;
		
		//timers
		var rtm; //rate-out timer	
		
		var state = {
			solving: false,
			auto: false
		};		
				
		var pdata = {
			id: '',
			lnk: '',
			sz: '',
			h: 0,
			w: 0,
			list: '',
			t: [],
			r: 0,
			c: 0,
			m: 0,
			th: 0,
			tw: 0,
			loaded: 0,
			c1: '',
			c2: '',
			vx: 300,
			vy: 300,
			avr: 0,
			rtd: 0
		};

		var ddels = []; //dragdrop elements		
		var ViewSize = {			
			vx : function() {
				var x = YAHOO.util.Dom.getViewportWidth();
				x-=400; 
				if(x < 300) x = 300;
				return x;
			},
				 
			vy : function() {
				var y = YAHOO.util.Dom.getViewportHeight();			
				y-=150;
				if(y < 300) y = 300;
				return y;
			}
		};								

		function initPage()
		{
			clock = document.getElementById('clock');
			out = document.getElementById('outer');
			ctr = document.getElementById('ctr');
			mask = document.getElementById('mask');	
			rtadivs = YAHOO.util.Dom.getElementsByClassName('rta', 'div');
			rtctrdivs = YAHOO.util.Dom.getElementsByClassName('rtctr', 'div');
						
			var icohelp = document.getElementById('icohelp');
			var icohint = document.getElementById('icohint');
			var icotime = document.getElementById('icotime');
			
			if(IE6)
			{
				icohelp.src = YAHOO.Scramble.baseurl + 'img/help.gif';
				icohint.src = YAHOO.Scramble.baseurl + 'img/wand.gif';
				icotime.src = YAHOO.Scramble.baseurl + 'img/time.gif';
			}
			else
			{
				icohelp.src = YAHOO.Scramble.baseurl + 'img/help.png';
				icohint.src = YAHOO.Scramble.baseurl + 'img/wand.png';
				icotime.src = YAHOO.Scramble.baseurl + 'img/time.png';			
			}
							
			pnlInfo = new YAHOO.widget.Panel("pnlInfo", {
					modal:false,
					close:true,
					visible:false,
					draggable:true,
					fixedcenter:true,
					constraintoviewport:true,	
					width: 280,				
					zIndex: 9999
				});
				var pnlInfoListeners = new YAHOO.util.KeyListener(document, { keys : 27 }, {fn:function(){pnlInfo.hide();}} );
				pnlInfo.cfg.queueProperty("keylisteners", pnlInfoListeners);
				//pnlInfo.moveEvent.subscribe(setStatsPos);
				pnlInfo.moveEvent.subscribe(resize);
				pnlInfo.hideEvent.subscribe(resize);
				pnlInfo.render();
				
				non_modals[non_modals.length] = pnlInfo;	
								
			dlgHelp = new YAHOO.widget.Dialog("dlgHelp", { 
					modal:false, 
					close:true,
					visible:false, 
					draggable:true, 			
					fixedcenter:true, 
					constraintoviewport:true, 
					width:500,
					zIndex: 9999				 
				});
				var dlgHelpListeners = new YAHOO.util.KeyListener(document, { keys : 27 }, {fn:function(){dlgHelp.hide();}} );
				dlgHelp.cfg.queueProperty("keylisteners", dlgHelpListeners);
				dlgHelp.cfg.queueProperty("buttons", [ { text:'Close', handler:function(){dlgHelp.hide();}} ]);
				dlgHelp.render();	
				
				non_modals[non_modals.length] = dlgHelp;								
						
				diffDivs = YAHOO.util.Dom.getElementsByClassName('imgdiff', 'div', 'tblctls');
				YAHOO.util.Event.addListener(diffDivs, 'mouseover', diffOver);
				YAHOO.util.Event.addListener(diffDivs, 'mouseout', diffOut);
				YAHOO.util.Dom.addClass(diffDivs, 'rti');				
				setDiff();
				
				YAHOO.util.Event.addListener(window, "resize", resize);
				
			tipRating = new YAHOO.widget.Tooltip("tipRating", {
				context: rtctrdivs,
				text: "Click to rate this puzzle",
				showDelay: 500,
				autodismissdelay: 2500,
				zIndex: 99999
				} );
		}
		
		function setDiff()
		{
			YAHOO.util.Dom.removeClass(diffDivs, 'rtio');
			YAHOO.util.Dom.removeClass(diffDivs, 'lock');
			var d = document.getElementById('diff').value;
			var ddiv = document.getElementById('diff'+d);
			YAHOO.util.Dom.addClass(ddiv, 'rtio');	
			YAHOO.util.Dom.addClass(ddiv, 'lock');			
		}
				
		function resize()
		{
			resized = true;
		}		
		
		function setRatePos(ctr)
		{
			rtleft = YAHOO.util.Dom.getX(ctr);
			resized = false;
		}
				
		function rmov(e)
		{	
			if(rtm) clearTimeout(rtm)		
			var x = YAHOO.util.Event.getPageX(e);			
			var d = (x - rtleft);
			if(d < 0 || d > 80 || resized == true)
			{
				setRatePos(this);
				return false;
			}			
			d = parseInt(d / 14) * 14 + 14;
			var rta = this.getElementsByTagName('div')[0];
			
			rta.style["width"] = d + "px";
			rta.style["backgroundPosition"] = "0 -30";
		}
				
		function rout()
		{
			if(rtm) clearTimeout(rtm)
			rtm = setTimeout(ratereset, 100);
		}
		
		function ratereset()
		{
			if(rtm) clearTimeout(rtm)
			for(var i=0; i<rtadivs.length; i++)
			{
				rtadivs[i].style["width"] = pdata.avr * 14 + "px";	
				rtadivs[i].style["backgroundPosition"] = "0 0";
			}		
			tipRating.hide();
		}
										
		function diffOver()
		{
			if(YAHOO.util.Dom.hasClass(this, 'lock')) return false;
			YAHOO.util.Dom.addClass(this, 'rtio');
		}
		
		function diffOut()
		{
			if(YAHOO.util.Dom.hasClass(this, 'lock')) return false;
			YAHOO.util.Dom.removeClass(this, 'rtio');
		}
				
		function showInfo(e)
		{
			if(e) YAHOO.util.Event.preventDefault(e);						
			pnlInfo.show();
		}
		
		function help(e)
		{
			if(e) YAHOO.util.Event.preventDefault(e);
			dlgHelp.show();
		}
				
		function rate(e)
		{				
			if(pdata.rtd > 0) return false;
			
			var x = YAHOO.util.Event.getPageX(e);			
			var r = (x - rtleft);
			r = parseInt((r + 14) / 14);			
			
			YAHOO.util.Event.removeListener(rtctrdivs, 'mousemove');
			YAHOO.util.Event.removeListener(rtctrdivs, 'mouseout');			
			YAHOO.util.Event.removeListener(rtadivs, 'mouseout');	
			YAHOO.util.Event.removeListener(rtadivs, 'click');	
						
			for(var i=0; i<rtadivs.length; i++)
			{
				rtadivs[i].style["width"] = r * 14 + "px";
				rtadivs[i].style["backgroundPosition"] = "0 -30";
			}						
			
			var callback = {
				success: rateSuccess,
				failure: rateFailure,
				argument: [pdata.id]
			};
						
			var request = YAHOO.util.Connect.asyncRequest('GET', YAHOO.Scramble.baseurl + 'scramble_server.aspx?do=ratepuzzle&i=' + pdata.id + '&r=' + r, callback, null);
			
		}
		
		function rateSuccess(o) 
		{
			var xmlRating = o.responseXML.documentElement.childNodes[0];
			var v = xmlRating.attributes.getNamedItem("Votes").value;
			var r = xmlRating.attributes.getNamedItem("Rating").value;			
			
			pdata.rtd = r;
			//document.getElementById('rtctr').setAttribute('title', 'Thank you! Avg. Rating: ' + Math.round(r * 1000) / 1000 + ' (' + v + ' votes).');								
			tipRating.cfg.setProperty('text', 'Thank you!<br>Avg. Rating: ' + Math.round(r * 1000) / 1000 + ' (' + v + ' votes).', false);
			tipRating.show();
		}
		
		function rateFailure(o)
		{
		}
		
		
		function viewUploaded(e)
		{
			if(e) YAHOO.util.Event.preventDefault(e);
			pnlPreview.hide();
			var id = document.getElementById('hdnUploadKey').value;
			histptr = histlist.length;
			document.getElementById('imgid').value = id;
			YAHOO.util.Dom.removeClass(mask, 'loaded');
			YAHOO.util.Dom.addClass(mask, 'loading');
			mask.style['visibility'] = 'visible';
			document.getElementById('cap2ctr').style['display'] = "none";			
			clear();			
			init();			
		}
		
		/*	DRAG-DROP MANAGEMENT	*/
		function initDragDrop() {

			//subclass DDProxy
			ddElProxy.prototype = new YAHOO.util.DD();

			//Add an object property to hold XY coordinates
			ddElProxy.prototype.initXY = new Object();

			//add event handlers
			ddElProxy.prototype.onDragDrop = dropObject;

			ddElProxy.prototype.onDragEnter = function(e, id) {
				var lyrB = document.getElementById(id);
				YAHOO.util.Dom.addClass(lyrB, 'under');
			}

			ddElProxy.prototype.onDragOut = function(e, id) {
				var lyrB = document.getElementById(id);
				YAHOO.util.Dom.removeClass(lyrB, 'under');
			}

			ddElProxy.prototype.startDrag = function(e) {
				//save position so it can be restored after the drag
				hideNonModals();
				//this.initXY = YAHOO.util.Dom.getXY(this.id);
				this.getDragEl().innerHTML = this.getEl().innerHTML;
				YAHOO.util.Dom.addClass(this.getEl(), 'selected');
			}

			ddElProxy.prototype.endDrag = function(e) {				
				YAHOO.util.Dom.removeClass(this.getEl(), 'selected');
				YAHOO.util.Dom.setXY(this.id, this.initXY);
			}
		}
		
		function ddElProxy(id, group, type)
		{
			this.init(id);
			this.scroll = false;
		}

		function dropObject(e, id)
		{
			var srcdiv = this.getEl();
			var tgtdiv = document.getElementById(id);
			swap('','',{s: srcdiv, t: tgtdiv});
		}

		function swap(a,b,o)
		{
			//swap
			moves++;

			var srcdiv = o.s;
			var tgtdiv = o.t;

			var srctag = srcdiv.getElementsByTagName('IMG')[0];
			var tgttag = tgtdiv.getElementsByTagName('IMG')[0];

			YAHOO.util.Dom.removeClass(tgtdiv, 'under');
			YAHOO.util.Dom.removeClass(srcdiv, 'selected');

			tgtdiv.removeChild(tgttag);
			srcdiv.removeChild(srctag);
			tgtdiv.appendChild(srctag);
			srcdiv.appendChild(tgttag);

			var tmp = tgtdiv.style["backgroundPosition"];
			tgtdiv.style["backgroundPosition"] = srcdiv.style["backgroundPosition"];
			srcdiv.style["backgroundPosition"] = tmp;

			if(a == 'complete') //coming from a hint, not a user-drop
			{
				YAHOO.util.DragDropMgr.unlock();
				YAHOO.util.Dom.setXY(srcdiv, o.i);
			}

			var sdi = srcdiv.id.substr(1);
			var tdi = tgtdiv.id.substr(1);
			var sii = srctag.id;
			var tii = tgttag.id;

			sii = sii.substr(1);
			tii = tii.substr(1);

			if(tdi == sii)
			{
				//dropped div is correct
				//YAHOO.util.Dom.addClass(tgtdiv, 'solved');
				ddels[tgtdiv.id].unreg();
				setSolved(tgtdiv.id,0);
			}

			if(sdi == tii)
			{
				//div replacing the dropped div is correct
				//YAHOO.util.Dom.addClass(srcdiv, 'solved');
				ddels[srcdiv.id].unreg();
				setSolved(srcdiv.id,0);
			}

			if(tdi != sii && sdi != tii) return false;

			checkSolved();

		}

		function setSolved(divId,i)
		{
			var div = document.getElementById(divId);
			if(state.solving == false)
			{
				if(i % 2 == 0)
				{
					YAHOO.util.Dom.addClass(div, 'solved');
				}
				else
				{
					YAHOO.util.Dom.removeClass(div, 'solved');
				}
			}

			if(i < 6 && state.auto == false)
			{
				i++;
				setTimeout('setSolved("' + divId + '",' + i + ')', 100);
			}
			else
			{
				if(moves == 0) 
				{
					if(state.auto == true)
					{
						setTimeout(next, 3000);
					}
					else
					{										
						YAHOO.util.DragDropMgr.unlock();					
						document.getElementById('spnSolved').style["display"] = "block";
						document.getElementById('divRate').style["display"] = pdata.rtd == 0 ? "block" : "none";
						setTimeout('showInfo(null)', 1000);
					}
				}
			}
		}

		function checkSolved()
		{
			//check for solved
			var tags = ctr.getElementsByTagName('IMG');
			var src, idx;

			for(var i=0; i<tags.length; i++)
			{

				src = tags[i].id;
				idx = src.substr(1);

				if(idx != i.toString())
				{
					if(state.solving == true)
					{
						hint();
					}
					return false;
				}
			}

			solved();
		}

		function solved()
		{
			YAHOO.util.DragDropMgr.lock();
			tick();
			clearInterval(tm);						

			var divs = ctr.getElementsByTagName('DIV');
			for(var i=pdata.m-1; i>0; i--)
			{
				ctr.removeChild(divs[i]);
			}
			divs[0].removeChild(divs[0].childNodes[0]);
			divs[0].appendChild(imgFull);

			divs[0].style["top"] = pdata.r + 2;
			divs[0].style["left"] = pdata.c + 2;
			divs[0].style["cursor"] = 'default';
			divs[0].style["overflow"] = 'visible';

			var dt = new Date();
			var diff = dt - st;

			document.getElementById('dt_s').value = 1;
			document.getElementById('dt_i').value = pdata.id;
			document.getElementById('dt_u').value = '';
			document.getElementById('dt_d').value = pdata.m;
			document.getElementById('dt_m').value = moves;
			document.getElementById('dt_t').value = diff;
			
			if(state.solving == false)
			{
				var s = parseInt(document.getElementById('st_t').innerHTML);
				s++;
				document.getElementById('st_t').innerHTML = s;

				var callback = {
					success: updateDataSuccess,
					failure: updateDataFailure,
					argument: [1]
				};

				YAHOO.util.Connect.setForm('data');
				var request = YAHOO.util.Connect.asyncRequest('POST', YAHOO.Scramble.baseurl + 'scramble_server.aspx?do=setpuzzledata', callback, null);
			}
			
			state.solving = false;
			
			moves = 0; //so the 'next' function doesn't re-write the same data

			setSolved(divs[0].id,-2);
		}

		function updateDataSuccess(o)
		{

		}

		function updateDataFailure(o)
		{

		}

		function start()
		{
			YAHOO.util.Event.removeListener(mask, 'click', start);
			mask.style["visibility"] = "hidden";

			tm = setInterval(tick, 1000);
			st = new Date();
			moves = 0;
		}

		function tick()
		{
			if(moves == 0) return false;
			var dt = new Date();
			var diff = dt - st;

			diff = formatTime(diff);

			clock.innerHTML = diff + ' / ' + moves;
		}


		function init()
		{
		
//			YAHOO.util.DragDropMgr.lock();
			YAHOO.util.Event.removeListener(mask, 'click', start);
			
			pdata.vx = ViewSize.vx();
			pdata.vy = ViewSize.vy();
			
			var d = document.getElementById('diff').value;	
			var replace = false;
			
			document.getElementById('spnback').style["visibility"] = (histptr > 0) ? "visible" : "hidden";
			document.getElementById('spnSolved').style["display"] = "none";
			document.getElementById('divRate').style["display"] = "none";
			
			for(var i=0; i<rtadivs.length; i++)
			{
				rtadivs[i].style["width"] = "0px";
				rtadivs[i].style["backgroundPosition"] = "0 0";
			}
			
			if(histptr < histlist.length)
			{
				//see if the difficulty or viewport size has changed
				var o = histlist[histptr];
				var d1 = o.argument[0];
				var x1 = o.argument[1];
				var y1 = o.argument[2];
				var shortkey = o.responseXML.documentElement.childNodes[0].attributes.getNamedItem('ShortKey').value;
				var id = o.responseXML.documentElement.childNodes[0].attributes.getNamedItem('Id').value;
				var imgid = document.getElementById('imgid').value;
				//reload if difficulty changed on the CURRENT picture, else use the prior difficulty				
				if((d1 == d || imgid != id) && x1 == pdata.vx && y1 == pdata.vy)
				{
					getImage(o, true);
					return false;
				}
				else
				{
					//debug('<br>changed environment, reload');					
					document.getElementById('imgid').value = shortkey;
					replace = true;
					if(histptr >= histlist.length-2)
					{						
						//changed difficulty on the current puzzle, or changed viewport size
						//the next one was preloaded at the prior difficulty / size
						//so delete it.
						histlist.pop();
						keylist.pop();
						imgNext = null;
						//debug('<br>remove next. len: ' + keylist.length + ', ' + keylist.join());
					}
				}	
			}
					
			var callback = {
				success: getImage,
				failure: loaderror,
				argument: [d, pdata.vx, pdata.vy, replace]
			}
			
			//set the exlude list to avoid repeats
			document.getElementById('exlst').value = keylist.join();
			//debug('<br>Request, exclude: ' + keylist.join());
			YAHOO.util.Connect.setForm('frm');
			var request = YAHOO.util.Connect.asyncRequest('POST', YAHOO.Scramble.baseurl + 'scramble_server.aspx?do=getpuzzle&x='+pdata.vx+'&y='+pdata.vy, callback, null);
		}
			
		function preloadNext()
		{						
			var d = document.getElementById('diff').value;
			var u = document.getElementById('imgusr').value;
			
			var x = ViewSize.vx();
			var y= ViewSize.vy();
			
			var callback = {
				success: preloadNextSuccess,				
				argument: [d, x, y, false]
			}
			var ex = keylist.join();
			//debug('<br>Request, exclude: ' + ex);
			var request = YAHOO.util.Connect.asyncRequest('GET', YAHOO.Scramble.baseurl + 'scramble_server.aspx?do=getpuzzle&x='+x+'&y='+y+'&d='+d+'&u='+u+'&e='+ex, callback, null);
			
		}
		
		function preloadNextSuccess(o)		
		{
			var x = o.argument[1];
			var y = o.argument[2];
			
			//see if size changed
			if(ViewSize.vx() != x || ViewSize.vy() != y)
			{
				imgNext = null;
				return false;
			}
			
			var shortkey = o.responseXML.documentElement.childNodes[0].attributes.getNamedItem('ShortKey').value;
			var id = o.responseXML.documentElement.childNodes[0].attributes.getNamedItem('Id').value;
			var idx = histlist.length;
			histlist[idx] = o;
			keylist[idx] = shortkey
									
			//prefetch next image

			if(imgNext) imgNext = null;										
			imgNext = document.createElement('IMG');			
			imgNext.setAttribute('src', YAHOO.Scramble.baseurl + 'img.aspx?x='+x+'&y='+y+'&id='+id);
			imgNext.setAttribute('id', 'pre_' + id);
			
			while(keylist.length > 15)
			{
				histlist.shift();
				keylist.shift();
				histptr--;
				//debug('<br>trimming array. len: ' + histlist.length + ', keys: ' + keylist.join());				
			}
		}

		function getImage(o,repeat)
		{
	
			var xml = o.responseXML.documentElement;
			var diff = o.argument[0];
			var replace = o.argument[3];
			var xmlPuzzle = xml.childNodes[0];
			//debug('<br>get; repeat: ' + repeat + ', replace: ' + replace);			
			
			pdata.id = xmlPuzzle.attributes.getNamedItem('Id').value;
			pdata.lnk = xmlPuzzle.attributes.getNamedItem('ShortKey').value;
			pdata.sz = xmlPuzzle.attributes.getNamedItem('Size').value;
			pdata.h = parseInt(xmlPuzzle.attributes.getNamedItem('Height').value);
			pdata.w = parseInt(xmlPuzzle.attributes.getNamedItem('Width').value);
			pdata.r = parseInt(xmlPuzzle.attributes.getNamedItem('Rows').value);
			pdata.c = parseInt(xmlPuzzle.attributes.getNamedItem('Cols').value);
			pdata.list = xmlPuzzle.attributes.getNamedItem('Order').value;
			pdata.t = pdata.list.split(',');
			pdata.m = pdata.r * pdata.c;
			pdata.th = Math.floor(pdata.h / pdata.r);
			pdata.tw = Math.floor(pdata.w / pdata.c);
			pdata.c1 = xmlPuzzle.attributes.getNamedItem('PreCaption').value;
			pdata.c2 = xmlPuzzle.attributes.getNamedItem('PostCaption').value;
			
			//if(!repeat) debug('<br>received: ' + pdata.lnk);


			if(!repeat || replace)
			{
				var idx = replace ? histptr : histlist.length;
				histlist[idx] = o;
				keylist[idx] = pdata.lnk
				//if(!replace) debug('<br>added. ptr: ' + histptr + '[' + keylist[histptr] + '], len: ' + histlist.length + ', keys: ' + keylist.join())	
				//if(replace) debug('<br>replace. ptr: ' + histptr + '[' + keylist[histptr] + '], len: ' + histlist.length + ', keys: ' + keylist.join())	
			}
			
			document.getElementById('diff').value = diff;
			setDiff();
			
			out.style.width = pdata.w + (pdata.c * 2) + 4;
			out.style.height = pdata.h + (pdata.r * 2) + 4;

			ctr.style.width = pdata.w + (pdata.c * 2) + 2;
			ctr.style.height = pdata.h + (pdata.r * 2) + 2;

			mask.style.width = pdata.w + (pdata.c * 2) + 2;
			mask.style.height = pdata.h + (pdata.r * 2) + 2;

			ctr.style['visibility'] = 'visible';
			mask.style['visibility'] = 'visible';
			
			var capwidth = pdata.w + (pdata.c * 2) + 2;	
			if(capwidth < 320) capwidth = 320;
			
			document.getElementById('cap1ctr').style['width'] = capwidth;			
			if(pdata.c1 != "")
			{
				document.getElementById('cap1').innerHTML = pdata.c1;
				document.getElementById('cap1').style["display"] = "block";
			}
			else
			{
				document.getElementById('cap1').innerHTML = '';
				document.getElementById('cap1').style["display"] = "none";				
			}				

			
			document.getElementById('cap2ctr').style['width'] = capwidth;
			document.getElementById('cap2ctr').style['display'] = "block";
			//document.getElementById('st_l').value = YAHOO.Scramble.baseurl + '?' + pdata.lnk;
			document.getElementById('st_l').innerHTML = 'Link to this puzzle: <a href="' +  YAHOO.Scramble.baseurl + '?' + pdata.lnk + '">' + YAHOO.Scramble.baseurl + '?' + pdata.lnk + '</a>';

			YAHOO.util.Event.removeListener(rtctrdivs, 'mousemove');
			YAHOO.util.Event.removeListener(rtctrdivs, 'mouseout');
			YAHOO.util.Event.removeListener(rtadivs, 'click');							
			
			if(pdata.rtd == 0)
			{
				YAHOO.util.Event.addListener(rtctrdivs, 'mousemove', rmov);
				YAHOO.util.Event.addListener(rtctrdivs, 'mouseout', rout);							
				YAHOO.util.Event.addListener(rtadivs, 'click', rate);
			}			
			
			if(imgFull) 
			{				
				YAHOO.util.Event.removeListener(imgFull, 'load');
				imgFull = null;				
			}
			
			if(imgNext != null && imgNext.id == 'pre_' + pdata.id)
			{
				imgFull = imgNext;
				//debug('<br>using preloaded image');
				buildPuzzle();
				return false;
			}
			else
			{			
				imgFull = document.createElement('IMG');
				//imgFull.setAttribute('src', YAHOO.Scramble.baseurl + 'img.aspx?s='+pdata.sz+'&id='+pdata.id);
				imgFull.setAttribute('src', YAHOO.Scramble.baseurl + 'img.aspx?x='+pdata.vx+'&y='+pdata.vy+'&id='+pdata.id);
			}		
			
			if(document.getElementById('imgid').value == pdata.id) 
			{
				buildPuzzle();				
			}
			else
			{									
				YAHOO.util.Event.addListener(imgFull, 'load', buildPuzzle);	
				//ie7 doesn't always want to fire the load event..
				loadtm = setTimeout(forceBuild, 3000)	
				
			}			
		}
		
		function forceBuild()
		{
			if(pdata.loaded == 0) buildPuzzle();
		}

		function buildPuzzle()
		{
			clearTimeout(loadtm);
			
			if(pdata.loaded >= pdata.m) return false;

			var i = pdata.loaded;

			var div = document.createElement('DIV');
			div.setAttribute('id', 'd'+i);

			div.style['width'] = pdata.tw;
			div.style['height'] = pdata.th;
			div.style['position'] = 'absolute';

			var rowIdx = parseInt(i / pdata.c);
			var colIdx = i % pdata.c;

			var rowIdxI = parseInt(pdata.t[i] / pdata.c);
			var colIdxI = pdata.t[i] % pdata.c;

			var left = colIdx * pdata.tw + (colIdx * 2) + 3;
			var top = rowIdx * pdata.th + (rowIdx * 2) + 3;
			
			div.style['top'] = top;
			div.style['left'] = left;
			div.setAttribute('tabindex', i);

			var img = document.createElement('IMG');
			img.setAttribute('id', 'i'+pdata.t[i]);
			
			if(IE6 == false)
			{			
				img.setAttribute('src', YAHOO.Scramble.baseurl + 'img/blank.gif');
				img.setAttribute('height', '1');
				img.setAttribute('width', '1');

				div.style["backgroundImage"] = 'url(' + imgFull.src + ')';
				div.style["backgroundRepeat"] = 'no-repeat';
				div.style["backgroundPosition"] = '-' + parseInt(colIdxI * pdata.tw) + 'px -' + parseInt(rowIdxI * pdata.th) + 'px';
			}
			else
			{
				div.style["overflow"] = 'hidden';				
				img.setAttribute('src', imgFull.src);
				
				img.style["position"] = 'relative';
				img.style["top"] = '-' + parseInt(rowIdxI * pdata.th) + 'px'
				img.style["left"] = '-' + parseInt(colIdxI * pdata.tw) + 'px'
			}
			
			div.appendChild(img);
			ctr.appendChild(div);

			YAHOO.util.Dom.addClass(div, 'tile');
			ddels[div.id] = new ddElProxy(div.id, 'tiles', div);			
			ddels[div.id].initXY = YAHOO.util.Dom.getXY(div.id);

			pdata.loaded++;
			if(pdata.loaded == pdata.m)
			{				
				if(state.auto == true) 
				{
					solve();
				}
				else
				{
					YAHOO.util.Dom.addClass(mask, 'loaded');
					YAHOO.util.Event.addListener(mask, 'click', start);				
				}
				
				var callback = {
					success: getStatsSuccess,
					failure: getStatsFailure,
					argument: []
				};

				var request = YAHOO.util.Connect.asyncRequest('GET', YAHOO.Scramble.baseurl + 'scramble_server.aspx?do=getpuzzlestats&i='+pdata.id+'&t='+pdata.m, callback, null);
				
			}
			else
			{
				var diffchange = document.getElementById('imgid').value == pdata.id ? true : false;
				if(state.auto == true || diffchange == true)
				{
					tmrLoading = setTimeout(buildPuzzle, 20);
				}
				else
				{
					tmrLoading = setTimeout(buildPuzzle, 100);
				}
			}
		}

		function getStatsSuccess(o)
		{
			var xml = o.responseXML.documentElement;
			var xmlStats = xml.childNodes[0];
			var xmlLine = xmlStats.childNodes[0];

			var sk = xmlLine.attributes.getNamedItem('ImageShortKey').value;
			var dt = xmlLine.attributes.getNamedItem('ImageUploadDate').value;
			var un = xmlLine.attributes.getNamedItem('UserName').value;
			var st = xmlLine.attributes.getNamedItem('Starts').value;
			var ns = xmlLine.attributes.getNamedItem('TotalSolved').value;
			var nu = xmlLine.attributes.getNamedItem('TotalUnsolved').value;
			var ps = xmlLine.attributes.getNamedItem('PercentSolved').value;
			var pu = xmlLine.attributes.getNamedItem('PercentUnsolved').value;
			var ams = xmlLine.attributes.getNamedItem('AverageSolvedMoves').value;
			var amu = xmlLine.attributes.getNamedItem('AverageUnsolvedMoves').value;
			var ats = xmlLine.attributes.getNamedItem('AverageSolvedTime').value;
			var atu = xmlLine.attributes.getNamedItem('AverageUnsolvedTime').value;
			var lm = xmlLine.attributes.getNamedItem('LowestSolvedMoves').value;
			var lt = xmlLine.attributes.getNamedItem('LowestSolvedTime').value;
			var rt = xmlLine.attributes.getNamedItem('Votes').value;
			var ra = xmlLine.attributes.getNamedItem('Rating').value;
			
			document.getElementById('st_d').innerHTML = dt;
			document.getElementById('st_u').innerHTML = '<a href="' + YAHOO.Scramble.baseurl + un + '">' + un + '</a>';
			document.getElementById('st_t').innerHTML = ns;
			document.getElementById('st_a').innerHTML = formatTime(ats) + ' / ' + ams;
			document.getElementById('st_f').innerHTML = formatTime(lt) + ' / ' + lm;
			document.getElementById('lnk_widget').setAttribute('href', YAHOO.Scramble.baseurl + 'tools/widget/' + sk);
			clock.innerHTML = '00:00 / 0';
			
			//document.getElementById('rtctr').setAttribute('title', 'Click to rate this puzzle. Avg. Rating: ' + Math.round(ra * 1000) / 1000 + ' (' + rt + ' votes).');
			tipRating.cfg.setProperty('text', 'Click to rate this puzzle.<br> Avg. Rating: ' + Math.round(ra * 1000) / 1000 + ' (' + rt + ' votes).', false);
			
			pdata.avr = ra;
			for(var i=0; i<rtadivs.length; i++)
			{
				rtadivs[i].style["width"] = ra * 14 + "px";
			}
			
			if(histptr == histlist.length-1) preloadNext();
		}

		function getStatsFailure(o)
		{
			if(histptr == histlist.length-1) preloadNext();
		}

		function loaderror(o)
		{

		}
		
		function auto()
		{
			if(state.auto == false)
			{
				state.auto = true;
				solve();
			}
			else
			{
				state.auto = false;
				state.solving = false;
				//YAHOO.util.DragDropMgr.unlock();
			}
		}
		
		function solve()
		{
			state.solving = true;
			//YAHOO.util.DragDropMgr.unlock();
			mask.style["visibility"] = "hidden";
			setTimeout(hint, 500);
		}
		
		function hint(e)
		{			
			if(e) YAHOO.util.Event.preventDefault(e);
			if(YAHOO.util.DragDropMgr.isLocked()) return false;
			if(pdata.loaded < pdata.m) return false;
			
			if(mask.style["visibility"] == "visible")
			{
				start();
			}
			
			hideNonModals();

			YAHOO.util.DragDropMgr.lock();
			
			moves++; //one is already added on in the swap function, this make it two
			st -= 3000; //subtract 3000 milliseconds from start time to increase elapsed time by 5 seconds, after hint animation is over						
			
			var tags = ctr.getElementsByTagName('IMG');
			var src, idx1, idx2, srcDiv, tgtDiv;

			var i = Math.floor(Math.random() * tags.length);

			while(true)
			{
				src = tags[i].id;
				idx1 = src.substr(1);
				if(idx1 != i.toString())
				{
					tgtDiv = tags[i].parentNode;
					idx2 = i;
					break;
				}
				i++;
				if(i>=tags.length) i=0;
			}
			for(var i=0; i<tags.length; i++)
			{
				src = tags[i].id;
				idx1 = src.substr(1);
				if(idx1 == idx2)
				{
					srcDiv = tags[i].parentNode;
					break;
				}
			}
			if(srcDiv && tgtDiv)
			{
				move(srcDiv, tgtDiv);
			}			
		}

		function move(src, tgt)
		{
			YAHOO.util.Dom.addClass(src, 'selected');
			YAHOO.util.Dom.addClass(tgt, 'under');

			var xy0 = YAHOO.util.Dom.getXY(src);
			var xy1 = YAHOO.util.Dom.getXY(tgt);
			var xy2 = YAHOO.util.Dom.getXY(out);

			var x = xy1[0] - xy2[0];
			var y = xy1[1] - xy2[1];
			var initXY = ddels[src.id].initXY;
			var t = 2;
			if(state.solving == true) t = 30 / pdata.m;
			var anim = new YAHOO.util.Anim(src, {
					left: { to: x },
					top: { to: y }
				}, t, YAHOO.util.Easing.easeOut);
			anim.onComplete.subscribe(swap, {s: src, t: tgt, i:xy0});
			anim.animate();
		}

		function clear()
		{
			clearInterval(tm);
			clearInterval(tmrLoading);
			tm = null;

			var divs = ctr.getElementsByTagName('DIV');
			for(var i=divs.length-1; i>=0; i--)
			{
				ctr.removeChild(divs[i]);
			}

			moves = 0;
			ddels = [];
			pdata = {
				id: '',
				lnk: '',
				sz: '',
				h: 0,
				w: 0,
				list: '',
				t: [],
				r: 0,
				c: 0,
				m: 0,
				th: 0,
				tw: 0,
				loaded: 0,
				c1: '',
				c2: '',
				avr: 0,
				rtd: 0	
			};
			
			if(state.auto == false) state.solving = false;
		}

		function changediff(d)
		{	
			var p = document.getElementById('diff').value;
			if(p == d) return false;
			
			var olddiv = document.getElementById('diff'+p);
			var newdiv = document.getElementById('diff'+d);						
			
			YAHOO.util.Dom.removeClass(olddiv, 'lock');
			YAHOO.util.Dom.removeClass(olddiv, 'rtio');			
			YAHOO.util.Dom.addClass(newdiv, 'lock');			
			
			hideNonModals();
			YAHOO.util.Dom.removeClass(mask, 'loaded');
			YAHOO.util.Dom.addClass(mask, 'loading');
			mask.style['visibility'] = 'visible';
			document.getElementById('imgid').value = pdata.id;			
			document.getElementById('diff').value = d;
			clear();			
			init();			
		}

		function next(e, dir)
		{
			if(e) YAHOO.util.Event.preventDefault(e);
			if(dir == -1 && histptr == 0) return false;			
			
			hideNonModals();			
			YAHOO.util.Dom.removeClass(mask, 'loaded');
			YAHOO.util.Dom.addClass(mask, 'loading');
			mask.style['visibility'] = 'visible';
			document.getElementById('cap2ctr').style['display'] = "none";
			document.getElementById('imgid').value = '';

			if(moves > 0)
			{
				var dt = new Date();
				var diff = dt - st;

				document.getElementById('dt_s').value = 0;
				document.getElementById('dt_i').value = pdata.id;
				document.getElementById('dt_u').value = '';
				document.getElementById('dt_d').value = pdata.m;
				document.getElementById('dt_m').value = moves;
				document.getElementById('dt_t').value = diff;

				var callback = {
					success: updateDataSuccess,
					failure: updateDataFailure,
					argument: [0]
				};

				YAHOO.util.Connect.setForm('data');
				var request = YAHOO.util.Connect.asyncRequest('POST', YAHOO.Scramble.baseurl + 'scramble_server.aspx?do=setpuzzledata', callback, null);
			}
			
			histptr+=dir;
			//debug('<br>move ' + dir +', ptr: ' + histptr + '[' + keylist[histptr] + ']');
			clear();
			init();
		}

		function debug(msg)
		{
			document.getElementById('spndbg').style["display"] = "block";
			document.getElementById('spndbg').innerHTML += msg;
		}
			
		YAHOO.util.Event.onDOMReady(initDragDrop);
		YAHOO.util.Event.onDOMReady(initPage);
		YAHOO.util.Event.onDOMReady(init);		

