/**
 * @author Brian Sutliffe
 */

//set up the namespace
if(typeof window.gentleGlide === 'undefined') window.gentleGlide = {};
gentleGlide.ImageMasker = function(image, mask, width, height, fallback){
	var self = this,
		_maskedImage,
		bufferCanvas,
		buffer,
		outputCanvas,
		output,
		
		contents = null,
		imageData = null,
		alphaData = null;
	
	var init = function() {
		// check we have Canvas, and return the unmasked image if not
		if (!document.createElement('canvas').getContext) { 
			if (typeof fallback === 'string') {
				var img = new Image();
				img.width = width;
				img.height = height;
				img.src = fallback;
				_maskedImage = img;
			} else if(typeof fallback === 'object'){
				_maskedImage = fallback;
			} else {
				_maskedImage = image;
			}
			return;
		}
		
		bufferCanvas = document.createElement('canvas');
		buffer = bufferCanvas.getContext('2d');
		outputCanvas = document.createElement('canvas');
		output = outputCanvas.getContext('2d');
		
		//if strings were passed for the images, preload them first
		if(typeof image === 'string' || typeof mask === 'string'){
			var imageLoaded = typeof image !== 'string';
			var maskLoaded = typeof mask !== 'string';
			//preload the image
			if(!imageLoaded){
				var imgPath = image;
				image = new Image();
				image.onload = function(){
					imageLoaded = true;
					if(maskLoaded)
						performMaskOperation();
				}
				image.src = imgPath;
			}
			//preload the mask
			if(!maskLoaded){
				var maskPath = mask;
				mask = new Image();
				mask.onload = function(){
					maskLoaded = true;
					if(imageLoaded)
						performMaskOperation();
				}
				mask.src = maskPath;
			}
		} else {
			performMaskOperation();
		}
		
		_maskedImage = outputCanvas;
	}
	
	//function for performing the actual masking
	var performMaskOperation = function(){
		// set sizes to ensure all pixels are drawn to Canvas
		bufferCanvas.width = width;
		bufferCanvas.height = height * 2;
		outputCanvas.width = width;
		outputCanvas.height = height;
			
		// draw the base image
		buffer.drawImage(image, 0, 0);
		// draw the mask directly below
		buffer.drawImage(mask, 0, height);
		// grab the pixel data for base image
		contents = buffer.getImageData(0, 0, width, height);
		// store pixel data array seperately so we can manipulate
		imageData = contents.data;
		// store mask data
		alphaData = buffer.getImageData(0, height, width, height).data;
		// loop through alpha mask and apply alpha values to base image
		for (var i = 3, len = imageData.length; i < len; i = i + 4) {
			imageData[i] = alphaData[i];
		}
		
		output.putImageData(contents, 0, 0);
	}
	
	this.maskedImage = function(){ return _maskedImage; }
	
	init();
}
gentleGlide.ImageMasker.prototype.toString = function(){ return '[object ImageMasker]'; };

gentleGlide.ImageMasker.instances = [];

gentleGlide.ImageMasker.applyCanvasMask = function(image, mask, width, height, fallback){
	var masker = new gentleGlide.ImageMasker(image, mask, width, height, fallback);
	gentleGlide.ImageMasker.instances.push(masker);
	return masker.maskedImage();
}

