/*
 * Core Functions
 */

var jsImageFX = {

	effects : {}, 

	doEffects : function(oImg, oCanvasImg, strFilter) 
	{
		var bHasCanvas = false;
		var bHasCanvasImageData = false;
		var bIsIE = !!(window.attachEvent && !window.opera);  // ew..

		var oCanvas = document.createElement("canvas");
		if (oCanvas.getContext) {
			bHasCanvas = true;
			var oCtx = oCanvas.getContext("2d");
			if (oCtx.getImageData) {
				bHasCanvasImageData = true;
			}
		}

		var iWidth = parseInt(oImg.offsetWidth); 
		var iHeight = parseInt(oImg.offsetHeight);
		
		if (oImg.className == 'image' || oImg.className == 'Image'){
			iWidth=iWidth-10; 	// somehow it includes the border in the offsethighet and width
			iHeight=iHeight-10;
		}		
		
		var strFilterName = strFilter;
		var oOptions = {};

		var oArgs = {};
		if (strFilter.indexOf("(") > -1) {
			strFilterName = strFilter.substr(0, strFilter.indexOf("("));
			var aArg = strFilter.match(/\((.*?)\)/);
			if (aArg[1]) {
				aArg = aArg[1].split(";");
				for (var a=0;a<aArg.length;a++) {
					aThisArg = aArg[a].split("=");
					if (aThisArg.length == 2)
						oArgs[aThisArg[0]] = aThisArg[1];
				}
			}
		}

		if (typeof jsImageFX.effects[strFilterName] != "function") {
			return false;
		}
	
		if (bHasCanvas) {
			oCanvas.width = iWidth;			
			oCanvas.height = iHeight;			
			oCanvas.style.width = iWidth;
			oCanvas.style.height = iHeight;
	
			oCtx.drawImage(oCanvasImg, 0, 0, iWidth, iHeight);
		}

		var oImage = {
			image : oImg,
			canvas : oCanvas,
			width : iWidth,
			height : iHeight,
			client : {
				hasCanvas : bHasCanvas,
				hasCanvasImageData : bHasCanvasImageData,
				isIE : bIsIE
			},
			useData : true
		}

		var bRes = jsImageFX.effects[strFilterName](oImage, oArgs);

		if (bHasCanvas) {
			if (oImage.useData) {
				if (bHasCanvasImageData) {
					oCanvas.getContext("2d").putImageData(oImage.canvasData, 0, 0);
					// Opera doesn't seem to update the canvas until we draw something on it, lets draw a 0x0 rectangle.
					oCanvas.getContext("2d").fillRect(0,0,0,0);
				}
			}
			
			// copy properties and stuff from the source image
			oCanvas.title = oImg.title;
			oCanvas.alt  = oImg.alt;
			oCanvas.imgsrc = oImg.src;
			oCanvas.className = oImg.className;
			oCanvas.cssText = oImg.cssText;
			oCanvas.id = oImg.id;

			oImg.parentNode.replaceChild(oCanvas, oImg);
		}
	},

	// load the image file
	doImage : function(oImg, strFilter)
	{
		var oCanvasImg = new Image();
		oCanvasImg.src = oImg.src;
		if (oCanvasImg.complete) {
			jsImageFX.doEffects(oImg, oCanvasImg, strFilter);
		} else {
			oCanvasImg.onload = function() {
				jsImageFX.doEffects(oImg, oCanvasImg, strFilter)
			}
		}
	},

	processImages : function() 
	{
		var aImg = document.getElementsByTagName("img");
		var aImages = [];
		for (var i=0;i<aImg.length;i++) {
			aImages[i] = aImg[i];
		}

		for (var i=0;i<aImages.length;i++) {
			if (aImages[i].getAttribute("imagefx")) {
				jsImageFX.doImage(aImages[i], aImages[i].getAttribute("imagefx"));
			}
		}
	}

}

if (window.addEventListener) { 
	window.addEventListener("load", jsImageFX.processImages, false); 
} else if (window.attachEvent) { 
	window.attachEvent("onload", jsImageFX.processImages); 
}


/*
 * Desaturation filter
 */

jsImageFX.effects.desaturate = function(oImage)
{
	if (oImage.client.hasCanvas && oImage.client.hasCanvasImageData) {

		var oCtx = oImage.canvas.getContext("2d");
		var oDataSrc = oCtx.getImageData(0, 0, oImage.width, oImage.height);
		var oDataDst = oCtx.getImageData(0, 0, oImage.width, oImage.height);
		var aDataSrc = oDataSrc.data;
		var aDataDst = oDataDst.data;
		oImage.canvasData = oDataDst;

		var h = oImage.height;
		var w = oImage.width;
		var y = h;
		do {
			var iOffsetY = (y-1)*w*4;
			var x = w;
			do {
				var iOffset = iOffsetY + (x-1)*4;
				var iBrightness = Math.round(aDataSrc[iOffset]*0.299 + aDataSrc[iOffset+1]*0.587 + aDataSrc[iOffset+2]*0.114);

				aDataDst[iOffset] = iBrightness;
				aDataDst[iOffset+1] = iBrightness;
				aDataDst[iOffset+2] = iBrightness;
				aDataDst[iOffset+3] = aDataSrc[iOffset+3];
	
			} while (--x);
		} while (--y);
		return true;

	} else if (oImage.client.isIE) {
		oImage.image.style.filter += " gray";
		return true;
	}
}

/*
 * Sepia filter (does not work in internet explorer)
 */

jsImageFX.effects.sepia = function(oImage)
{
	if (oImage.client.hasCanvas && oImage.client.hasCanvasImageData) {

		var oCtx = oImage.canvas.getContext("2d");
		var oDataSrc = oCtx.getImageData(0, 0, oImage.width, oImage.height);
		var oDataDst = oCtx.getImageData(0, 0, oImage.width, oImage.height);
		var aDataSrc = oDataSrc.data;
		var aDataDst = oDataDst.data;
		oImage.canvasData = oDataDst;

		var h = oImage.height;
		var w = oImage.width;
		var y = h;
		do {
			var iOffsetY = (y-1)*w*4;
			var x = w;
			do {
				var iOffset = iOffsetY + (x-1)*4;

				var iOldR = aDataSrc[iOffset];
				var iOldG = aDataSrc[iOffset+1];
				var iOldB = aDataSrc[iOffset+2];

				var iR = (iOldR * 0.393 + iOldG * 0.769 + iOldB * 0.189);
				var iG = (iOldR * 0.349 + iOldG * 0.686 + iOldB * 0.168);
				var iB = (iOldR * 0.272 + iOldG * 0.534 + iOldB * 0.131);

				if (iR < 0) iR = 0; if (iR > 255) iR = 255;
				if (iG < 0) iG = 0; if (iG > 255) iG = 255;
				if (iB < 0) iB = 0; if (iB > 255) iB = 255;

				aDataDst[iOffset] = iR;
				aDataDst[iOffset+1] = iG;
				aDataDst[iOffset+2] = iB;
				aDataDst[iOffset+3] = aDataSrc[iOffset+3];
	
			} while (--x);
		} while (--y);
		return true;

	} else if (oImage.client.isIE) {
		// nothing for IE!
	}
}
