/***********************************

	Four Corners
	v1.0
	last revision: 11.08.2005
	steve@slayeroffice.com
	
	should you improve upon this code, please
	let me know so that I may update the version
	hosted at slayeroffice
	
	please leave this notice intact.


***********************************/

window.addEventListener?window.addEventListener("load",initGame,false):window.attachEvent("onload",initGame);

var d = document;
var pieces = new Array();
var clickTrack = 0;
var activeColor = null;
var activatedObjects = new Array();
var colors = new Array("#26A875","#8AD7BA","#AFDAEC","#C5DFC2");
var score = 0;
var lColor = null;
var timer = null;
var gameTime = 45;
var paused = false;
var pos = d.all && !window.opera

function initGame() {
	createTitleScreen();
	createGamePieces();
	mObj = d.getElementById("mContainer");
		
	function createGamePieces() {
		mObj = d.getElementById("mContainer");
		x=-6; y=-6;
		doc = document.createDocumentFragment();
		for(i=0;i<100;i++) {
			pieces[i] = d.createElement("div");
			pieces[i].className = "gamePiece";
			pieces[i].gColor = colors[Math.floor(Math.random() * colors.length)];
			pieces[i].xIndex = i;
			applyStyleString(pieces[i],"top:" + y + "px;left:" + x + "px;background-color:" + pieces[i].gColor);
			if(pos) pieces[i].style.backgroundImage = "url(ie_outline.gif)";
			pieces[i].onclick= function(){handleClick(parseInt(this.xIndex))};
			doc.appendChild(pieces[i]);
			x+=19;
			if(x>=170) {
				y+=19;
				x=-6;
			}
		}
		mObj.appendChild(doc);
	}
	
	function createTitleScreen() {
		mObj = d.getElementById("mContainer");
		ts = mObj.appendChild(d.createElement("div"));
		ts.setAttribute("id","titleScreen");
		ts.onclick = function() { startGame(); }
	}
}

function startGame() {
	createSupportObject(mObj,"div","Score: 0","scoreDiv");
	createSupportObject(mObj,"div","Time: 45","timerDiv");
	createSupportObject(mObj,"div","","popper");
	createSupportObject(mObj,"div","","popperShadow");
	
	d.getElementById("titleScreen").style.display = "none";
	timer = setInterval("countDown();",1000);
	
	function createSupportObject(parentObj,objType,objText,objID) {
		n = parentObj.appendChild(d.createElement(objType));
		n.setAttribute("id",objID);
		n.appendChild(d.createTextNode(objText));
	}
}

function endGame() {
	paused = true;
	clearInterval(timer);
	
	mObj = d.getElementById("mContainer");
	e = d.createElement("div");
	e.setAttribute("id","ender");
	e.appendChild(d.createTextNode("G A M E O V E R !"));
	e.appendChild(d.createElement("br"));
	a = e.appendChild(d.createElement("a"));
	a.setAttribute("href","javascript:location.reload();");
	a.appendChild(d.createTextNode("Play Again?"));
	mObj.appendChild(e);
}

function countDown() {
	gameTime--;
	tDiv = d.getElementById("timerDiv");
	tDiv.removeChild(tDiv.firstChild);
	tDiv.appendChild(d.createTextNode("Time: " + gameTime));
	if(gameTime<=0) endGame();
}

function handleClick(objIndex) {
	if(paused)return;
	
	if(pieces[objIndex].gColor == lColor) {
		if(lColor != null) return;
	}
	if(clickTrack == 0) {
		activeColor = pieces[objIndex].gColor;
		pieces[objIndex].style.backgroundColor = "red";
		activatedObjects[clickTrack] = parseInt(objIndex);
		clickTrack++;
		return;
	}
	
	nColor = pieces[objIndex].gColor;
	if(nColor != activeColor) {
		resetSelections();
		return;
	}
	
	pieces[objIndex].style.backgroundColor = "red";
	activatedObjects[clickTrack] = parseInt(objIndex);

	clickTrack++;

	if(clickTrack >= 4) {
		if(isSquare()) {
			clearSelections();
		} else {
			resetSelections();
		}	
	}
	
	function isSquare() {
		activatedObjects = activatedObjects.sort(numericSort);
		if(pieces[activatedObjects[1]].offsetTop != pieces[activatedObjects[0]].offsetTop || pieces[activatedObjects[2]].offsetTop != pieces[activatedObjects[3]].offsetTop) return false;
		if(pieces[activatedObjects[0]].offsetLeft != pieces[activatedObjects[2]].offsetLeft || pieces[activatedObjects[1]].offsetLeft != pieces[activatedObjects[3]].offsetLeft) return false;
		
		if((activatedObjects[1] - activatedObjects[0] == activatedObjects[3] - activatedObjects[2]) && (!isVertical() && !isHorizontal())) {
			return true;
		} else {
			return false;
		}
		
		function isHorizontal() {
			tp = pieces[activatedObjects[0]].offsetTop;
			for(h=1;h<activatedObjects.length;h++) {
				if(pieces[activatedObjects[h]].offsetTop != tp) return false;
			}
			return true;
		}
		
		function isVertical() {
			lft = pieces[activatedObjects[0]].offsetLeft;
			for(v=1;v<activatedObjects.length;v++) {
				if(pieces[activatedObjects[v]].offsetLeft != lft) return false;
			}
			return true;
		}
	}
	
	
	function clearSelections() {
		index = activatedObjects[0];
		endRow = activatedObjects[1];
		w = (activatedObjects[1] - activatedObjects[0]) + 1;
		h = ((activatedObjects[2] - activatedObjects[0])/10) + 1;
		toClear = new Array();
		for(i=0;i<w*h;i++) {
			pieces[index].style.backgroundColor = "gold";
			toClear[toClear.length] = pieces[index];
			index++;
			if(index>endRow) {
				index = ((index + 10) - (activatedObjects[1] - activatedObjects[0]))-1;
				endRow = (index + (activatedObjects[1] - activatedObjects[0]));
			}
		}
		score+=100*(w*h);
		gameTime+=Math.round((w*h)/4);
		clearInterval(timer);
		
		if(!pos) {
			p = d.getElementById("popper");
			clearInnerHTML(p);
		
			sp = p.appendChild(d.createElement("span"));
			sp.appendChild(d.createTextNode((100*(w*h)) + " points!"));
			sp.appendChild(d.createElement("br"));
			sp.appendChild(d.createTextNode(Math.round((w*h)/4) + " seconds added!"));
			p.style.opacity = .99;
			p.style.display = "block";
		}
		
		clearInnerHTML(d.getElementById("timerDiv"));
		clearInnerHTML(d.getElementById("scoreDiv"));
		d.getElementById("timerDiv").appendChild(d.createTextNode("Time: " + gameTime));
		d.getElementById("scoreDiv").appendChild(d.createTextNode("Score: " + score));
		transitionGamePieces(toClear);
	}
	
	function resetSelections() {
		clickTrack = 0;
		activeColor = null;
		for(i=0;i<activatedObjects.length;i++) {
			pieces[activatedObjects[i]].style.backgroundColor = pieces[activatedObjects[i]].gColor;
		}
		activatedObjects = new Array();
	}
}

function transitionGamePieces(objectArray) {
	paused = true;
	op = .95;
	colorArray = createColorPath(lColor,activeColor);
	colorIndex = 0;
	
	fn = function() { fadeOut(objectArray); }
	zInterval = setInterval(fn,10);
	
	function fadeOut(objs) {
		for(i=0;i<objs.length;i++) 	pos?objs[i].style.filter="alpha(opacity=" + (op*100) + ")":objs[i].style.opacity = op;
		for(i=0;i<pieces.length;i++) {
			if(pieces[i].gColor == activeColor) {
				if(!inArray(i,objs)) {
					pos?pieces[i].style.filter = "alpha(opacity=" + (op*100) + ")":pieces[i].style.opacity = op;
				}
			}
		}
		op-=0.08;
		d.getElementById("mContainer").style.backgroundColor = "rgb(" + colorArray[colorIndex][0] + "," + colorArray[colorIndex][1] + "," + colorArray[colorIndex][2] + ")";
		colorIndex+=2;
		if(op<=0.00) {
			clearInterval(zInterval);
			zInterval = null;
			for(k=0;k<pieces.length;k++) {
				if(pieces[k].gColor == activeColor) {
					pieces[k].style.width = "1px";
					pieces[k].style.height = "1px";
				}
			}
			resetGamePieces(objs);
			hide_show();
		}
	}
	
	function fadeIn(objs) {
		for(i=0;i<objs.length;i++) {
			pos?objs[i].style.filter="alpha(opacity=" + (op*100) + ")":objs[i].style.opacity = op;
		}
		for(i=0;i<pieces.length;i++) {
			if(pieces[i].offsetWidth < 15) {
				w = pieces[i].offsetWidth;
				h = pieces[i].offsetWidth;
				w+=2;h+=2;
				if(w>15) {
					w=15;h=15;
				}
				pieces[i].style.width = w + "px";
				pieces[i].style.height = h + "px";
			}
		}
		d.getElementById("mContainer").style.backgroundColor = "rgb(" + colorArray[colorIndex][0] + "," + colorArray[colorIndex][1] + "," + colorArray[colorIndex][2] + ")";
		if(!pos)d.getElementById("popper").style.opacity = .95-op;
		colorIndex+=2;
		if(op<0.95) op+=0.08;
		if(op>=0.95 && colorIndex>=colorArray.length) {
			clearInterval(zInterval);
			d.getElementById("popper").style.display = "none";
			paused = false;
			//op=0;
			timer = setInterval("countDown();",1000);
		}
	}
	
	function inArray(nValue,nArray) {
		for(t=0;t<nArray.length;t++)	if(nArray[t] == nValue) return true;
		return false;
	}
	
	function resetGamePieces(usedPieces) {
		for(i=0;i<usedPieces.length;i++) {
			do {
				nColor = colors[Math.floor(Math.random() * colors.length)];
			} while (nColor == lColor);
			usedPieces[i].gColor = nColor
			usedPieces[i].style.backgroundColor =  nColor;
		}
		
		activatedObjects = new Array();
		clickTrack = 0;
		lColor = activeColor;
		activeColor = null;
		fn = function() { fadeIn(usedPieces); }
		zInterval = setInterval(fn,10);
	}
	
	function hide_show() {
		for(p=0;p<pieces.length;p++) {
			if(pieces[p].gColor == lColor) {
				pieces[p].style.opacity = .00;
				pieces[p].style.filter = "alpha(opacity=0)";
				pieces[p].style.display = "none";
			} else {
				pieces[p].style.filter = "alpha(opacity=99)";
				pieces[p].style.display = "block";
				pieces[p].style.opacity = .99;
			}
		}
	}
}

function numericSort(a,b) {
	return a-b;
}

function applyStyleString(obj,str) {
	if(d.all && !window.opera) {
		obj.style.setAttribute("cssText",str);
	} else {
		obj.setAttribute("style",str);
	}
}

function clearInnerHTML(obj) {
	while(obj.firstChild) obj.removeChild(obj.firstChild);
}

// functions to handle color shifts
// http://slayeroffice.com/code/color_shift/

function createColorPath(color1,color2) {
	if(!color1) color1 = "FFFFFF";
	color1 = color1.replace(/#/g,""); color2 = color2.replace(/#/g,"");
	colorPath = new Array();
	colorPercent = 1.0;
	do {
		colorPath[colorPath.length]=setColorHue(longHexToDec(color1),colorPercent,longHexToDec(color2));
		colorPercent-=.01;
	} while(colorPercent>0);
	return colorPath;
	
	// calculates a color based on the it being a certain percentage of another color.
	function setColorHue(originColor,opacityPercent,maskRGB) {
		returnColor=new Array();
		for(w=0;w<originColor.length;w++) returnColor[w] = Math.round(originColor[w]*opacityPercent) + Math.round(maskRGB[w]*(1.0-opacityPercent));
		return returnColor;
	}

	// utility method to convert "FFFFFF" to an array of 255,255,255
	function longHexToDec(longHex) {
		r=toDec(longHex.substring(0,2));
		g=toDec(longHex.substring(2,4));
		b=toDec(longHex.substring(4,6));
		return new Array(r,g,b);	

		function toDec(hex) {	
			return parseInt(hex,16);
		}
	}
}
