window.onload = function(){	
	myCanvas = new MyCanvas( document.getElementById('canvas') );
	var debug = new myDebug(myCanvas);
	
	myCanvas.drawImage( document.getElementById('image') );
	myCanvas.save();
	
	var walls = new Walls();
		
	var leftWall = new Wall(myCanvas, walls, 'leftWall', 'lIntensity', 'lColorPicker');
	var frontWall = new Wall(myCanvas, walls, 'frontWall', 'fIntensity', 'fColorPicker');
	var rightWall = new Wall(myCanvas, walls, 'rightWall', 'rIntensity', 'rColorPicker');
	var upWall = new Wall(myCanvas, walls, 'upWall', 'uIntensity', 'uColorPicker');
};

function getParamFromUrl(index){
	var from = window.location.href.search('#');
	
	if( from == -1)
		return false;
	
	return window.location.href.slice(from+1).split(',')[index];	
}

function updateLink(data){
	var link = document.getElementById('link');
	var to = window.location.href.search('#');
	link.value = window.location.href.slice(0, to) + '#';

	for( var i in data)
		link.value += data[i] + ',';
}

function MyCanvas(canvas){
	this.canvas = canvas;
	this.draw = this.canvas.getContext("2d");
	
	this.height = this.canvas.height;
	this.width = this.canvas.width;
	
	this.savedData = '';
	
	this.drawImage = drawImage;
	function drawImage(img, x, y){
		x = typeof x !== 'undefined' ? x : 0;
		y = typeof y !== 'undefined' ? y : 0;
		
		this.draw.drawImage(img, x, y, this.width, this.height);
	}
	
	this.save = save;
	function save(){
		this.savedData = this.draw.getImageData(0, 0, this.width, this.height);
	}
	
	this.restore = restore;
	function restore(){
		this.putImageData( this.savedData );
	}
	
	this.clearAll = clearAll;
	function clearAll(){
		this.draw.clearRect (0, 0, this.width, this.height); // clear all
	}
	
	this.getImageData = getImageData;
	function getImageData(image){
		var tmp = this.draw.getImageData(0, 0, this.width, this.height);
		this.clearAll();	
		
		this.drawImage(image);
		var imgData = this.draw.getImageData(0, 0, this.width, this.height);	//Get our image data
		
		this.clearAll();	
		
		this.putImageData(tmp); //Redraw old image		
		
		return imgData;
	}
	
	this.putImageData = putImageData;
	function putImageData(imgData, x, y){
		x = typeof x !== 'undefined' ? x : 0;
		y = typeof y !== 'undefined' ? y : 0;
		
		this.draw.putImageData(imgData, x, y);
	}
	
	this.combineImageData = combineImageData;
	function combineImageData(imgData, intensity){
		var tmpCanvas = document.createElement('canvas'); //Create new canvas
		tmpCanvas.width = this.width;
		tmpCanvas.height = this.height;
		
		var tmpDraw = tmpCanvas.getContext("2d");
		
		tmpDraw.putImageData(imgData, 0, 0);
		
		this.draw.globalAlpha = intensity;
		this.drawImage(tmpCanvas);
		this.draw.globalAlpha = 1;
		
		
		//tmpCanvas.parentNode.removeChild( tmpCanvas ); //Remove tmpCanvas
	}
	
	
}

function Walls(){
	this.walls = new Array();

	this.add = add;
	function add(wall){
		this.walls.push(wall);
	}
	
	this.allRedraw = allRedraw
	function allRedraw(){
		myCanvas.restore(); //Restore original image
		
		var data = new Array();
		for( var i = 0; i < this.walls.length; i++){
			this.walls[i].drawWall();
			data.push(this.walls[i].colorPicker.value);
			data.push(this.walls[i].intensityRange.value);
		}
		
		updateLink(data);
	}
}

function Wall(myCanvas, walls, imageId, intensityId, colorPickerId){
	this.myCanvas = myCanvas;
	this.image = document.getElementById( imageId );
		
	this.walls = walls;	
	this.walls.add(this);
		
	this.imageData = this.myCanvas.getImageData(this.image);
	
	this.drawWall = drawWall;
	this.changeImgDataColor = changeImgDataColor;
	this.color = new Array(255, 255, 255);
	this.intensity = 0.5;
	
	var _this = this;
	this.intensityRange = document.getElementById(intensityId);
	this.intensityRange.addEventListener('mouseup', function(e){ _this.changeIntensity(e) }, false);
	
	this.colorPicker = document.getElementById(colorPickerId);
	this.colorPicker.addEventListener('change', function(e){ _this.changeColorPicker(e) }, false);
	
	this.initParams = initParams;
	this.initParams();	
	this.walls.allRedraw();
	
	this.drawWall = drawWall;
	function drawWall(){
		this.myCanvas.combineImageData( this.changeImgDataColor(), this.intensity );
	}
	
	function initParams(){		
		var color = getParamFromUrl( ( this.walls.walls.length - 1) * 2);
		var intensity =  getParamFromUrl( ( ( this.walls.walls.length - 1) * 2 ) + 1);
		
		if( typeof color !== 'undefined' && color){
			this.colorPicker.value = color;		
			this.color = hexToRgb(color);
		}
			
		if( typeof intensity !== 'undefined' && intensity){
			this.intensity = intensity/100;
			this.intensityRange.value = intensity;
		}
	}
	
	this.changeColor = changeColor;
	function changeColor(color){
		this.color = color;
	}
	
	function changeImgDataColor(){
		var newImgData = this.imageData;
		
		for( var i = 0; i < newImgData.data.length; i += 4 ){
			if( newImgData.data[i] <= 0	){ //If it is black color
				newImgData.data[i+3] = 0;
				continue;
			}
			
			newImgData.data[i] = this.color[0];
			newImgData.data[i+1] = this.color[1];
			newImgData.data[i+2] = this.color[2];
			
		}
		
		return newImgData;
	}
	
	this.changeIntensity = changeIntensity;
	function changeIntensity(e){
		this.intensity = e.currentTarget.value/100;
		this.walls.allRedraw();
	}
	
	this.changeColorPicker = changeColorPicker;
	function changeColorPicker(e){
		var r = Math.round( e.currentTarget.color.rgb[0] * 255 );
		var g = Math.round( e.currentTarget.color.rgb[1] * 255 );
		var b = Math.round( e.currentTarget.color.rgb[2] * 255 );
		var color = new Array(r, g, b);
		
		this.changeColor(color);
		this.walls.allRedraw();
	}
	
}

function hexToRgb(hex) {
    var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
    return new Array(	
		parseInt(result[1], 16),
		parseInt(result[2], 16),
		parseInt(result[3], 16)
	)
}

//Debug functions
function getRelativePosition(e, element){
	var evt = e || window.event;

	var x = evt.clientX + window.pageXOffset;
	var y = evt.clientY + window.pageYOffset;
	
	x -= element.offsetLeft;
    y -= element.offsetTop;
	
	return new Array(x, y);
}

function showPosition(e, canvas){
	var debug = document.getElementById('debug');
	
	var event = e;
	var curPos = getRelativePosition(event, canvas);
	
	debug.getElementsByTagName('div')[0].innerHTML = 'X: ' + curPos[0] + ' Y: ' + curPos[1];
}

function savePosition(e){
	var debug = document.getElementById('debug');

	var posDiv = debug.getElementsByTagName('div')[0].innerHTML;
	var myDiv = debug.getElementsByTagName('div')[1];
	
	switch( e.keyCode ){
		case 115:
			myDiv.innerHTML += '| ' + posDiv;
		break;
		case 100:
			var parsed = myDiv.innerHTML.split('|');
			myDiv.innerHTML = '';
			
			for(i in parsed){
				if( i >= parsed.length - 1)
					break;
				if( parsed[i] == '')
					continue;
				
				myDiv.innerHTML +=  '|' + parsed[i];
			}
		break;
	}
}

function myDebug(myCanvas){
	this.myCanvas = myCanvas;
	
	var debug = document.getElementById('debug');

	window.addEventListener('mousemove', function(e){ showPosition(e, myCanvas.canvas); }, true);
	window.addEventListener('keypress', savePosition, true);
	
	this.debugPoint = debugPoint;
	function debugPoint(x, y, color, size){
		color = typeof color !== 'undefined' ? color : '#ff0000';
		size = typeof size !== 'undefined' ? size : 10;

		this.myCanvas.draw.fillStyle = color;	
		
		this.myCanvas.draw.save();
		this.myCanvas.draw.translate( x, y );
		this.myCanvas.draw.fillRect( -0.5 * size, -0.5 * size, size, size);
		
		this.myCanvas.draw.fillStyle = '#000000';
		this.myCanvas.draw.fillRect( 0, 0, 1, 1);	
		
		this.myCanvas.draw.restore();
	}

}