// parallax.js
// 0.6
// Stephen Band
//
// Dependencies:
// jquery.js
// jquery.dimensions.js
//
// Required HTML:
// <div id="parallax">
//   Any number of children of #parallax will act as layers.
//	 Each must have width and height defined in CSS.
// </div>
//
// Define behaviour of parallax layers:
// layer[0]={
// xparallax:	boolean, 											Toggles parallax for this layer.
// xorigin:		'left'/'centre'/'right'/0-1,	'left'    aligns left edge of layer with left edge of viewport when mouse is at left edge of mouseport.
//																					'centre'  aligns centre of layer with centre of viewport when mouse is at centre of mouseport.
//																					'right'   aligns right edge of layer with right edge of viewport when mouse is at right edge of mouseport.
//																					0-1			  0 is left, 0.5 is centered, 1 is right, anything else is anything else.
// xtravel:		20 														Distance in px to move layer. If left undefined, layer moves left edge to viewport left, right edge to viewport right.
// }

// VAR

var layer=new Array();
var viewport;						// Whichever object you parallax inside, it must have a defined pixel dimensions.
var mouseport;          // Object that mouse co-ordinates are read from.

// Default Layer

layer[0]={
  	xparallax: true,
  	yparallax: true,
  	xorigin: 'centre',
  	yorigin: 'centre'
}

// FUNCTIONS

function pxToInt(thing) {
	return parseInt(thing.replace('px', ''))
}

function initOrigin(l) {
	  // Change origin strings to numeric values
  	if 			(l.xorigin=='left')         																				{l.xorigin=0}
  	else if (l.xorigin=='middle' || l.xorigin=='centre' || l.xorigin=='center')	{l.xorigin=0.5}
  	else if (l.xorigin=='right')  	 																						{l.xorigin=1};
  	if 			(l.yorigin=='top')          																				{l.yorigin=0}
  	else if (l.yorigin=='middle' || l.yorigin=='centre' || l.yorigin=='center')	{l.yorigin=0.5}
  	else if (l.yorigin=='bottom')  																							{l.yorigin=1};
}

function initLayers() {
  
  initOrigin(layer[0]);
  
  // Cycle through layers
	for (var i=0; i<jQuery('#parallax > *').length; i++) {
		
		// Setup layer if it is not already defined
		if (!layer[i+1]) {
			layer[i+1]={
				canvas:			jQuery('#parallax > *:eq('+i+')'),
				xparallax: 	layer[0].xparallax,
				yparallax:	layer[0].yparallax,
				xorigin: 		layer[0].xorigin,
				yorigin: 		layer[0].yorigin,
				xlock: 			false,
				ylock: 			false
			}
		}
		
		// Give layer some values if it is already defined
		else {
			layer[i+1]['canvas']=jQuery('#parallax > *:eq('+i+')');
			// Lock layers that have had travel already defined.
			if (layer[i+1].xtravel) layer[i+1]['xlock']=true;
			if (layer[i+1].ytravel) layer[i+1]['ylock']=true;
			// Use the default origin if layer origin is not already defined
			if (!layer[i+1].xorigin) layer[i+1]['xorigin'] = layer[0].xorigin;
			if (!layer[i+1].yorigin) layer[i+1]['yorigin'] = layer[0].yorigin;
			// There are cases when we dont need to run this, but hey-ho.
			initOrigin(layer[i+1]);
		}
	}
}

function createBaseLayer() {

	var position=mouseport.offset();

	// screen dimensions
	layer[0]={
		width: 					viewport.width(),
		height: 				viewport.height(),
		mousewidth:			mouseport.width(),
		mouseheight:		mouseport.height(),
		mousetop:				position.top,
		mouseleft:			position.left
	}
	
}

function createLayers() {

  // Cycle through layers
	for (var i=0; i<jQuery('#parallax > *').length; i++) {

		// Give layer some values
		layer[i+1]['width'] = 		                      pxToInt(layer[i+1].canvas.css("width"));
		layer[i+1]['height'] = 		                      pxToInt(layer[i+1].canvas.css("height"));
		if (!layer[i+1].xlock) layer[i+1]['xtravel'] =	pxToInt(layer[i+1].canvas.css("width")) - layer[0].width;
		if (!layer[i+1].ylock) layer[i+1]['ytravel'] =	pxToInt(layer[i+1].canvas.css("height")) - layer[0].height;
		
		// Define canvas offset
		layer[i+1]['xoffset'] = (layer[0].width - layer[i+1].width + layer[i+1].xtravel) * layer[i+1].xorigin;
		layer[i+1]['yoffset'] = (layer[0].height - layer[i+1].height + layer[i+1].ytravel) * layer[i+1].yorigin;
		
		// Define canvas dynamic
		layer[i+1]['xdynamic'] = layer[i+1].xtravel / layer[0].width;
		layer[i+1]['ydynamic'] = layer[i+1].ytravel / layer[0].height;
	}
}

function debugParallax() {
	alert("Window\nwidth: "+jQuery(window).width()+"\nheight: "+jQuery(window).height()+
    "\n\nDocument\nwidth: "+jQuery(document).width()+"\nheight: "+jQuery(document).height()+
    "\n\nViewport\nwidth: "+viewport.width()+"\nheight: "+viewport.height()+
    "\n\nMouseport\nwidth: "+mouseport.width()+"\nheight: "+mouseport.height()+"\nleft: "+layer[0].mouseleft+"\ntop: "+layer[0].mousetop+
    "\n\nLayer 1\nwidth: "+layer[1].width+"px\nheight: "+layer[1].height+"px\nxtravel: "+layer[1].xtravel+"px, locked: "+layer[1].xlock+"\nytravel: "+layer[1].ytravel+"px, locked: "+layer[1].ylock+"\nxoffset: "+layer[1].xoffset+"px\nyoffset: "+layer[1].yoffset+"px\nxorigin: "+layer[1].xorigin+"\nyorigin: "+layer[1].yorigin+
    "\n\nLayer 2\nwidth: "+layer[2].width+"px\nheight: "+layer[2].height+"px\nxtravel: "+layer[2].xtravel+"px, locked: "+layer[2].xlock+"\nytravel: "+layer[2].ytravel+"px, locked: "+layer[2].ylock+"\nxoffset: "+layer[2].xoffset+"px\nyoffset: "+layer[2].yoffset+"px\nxorigin: "+layer[2].xorigin+"\nyorigin: "+layer[2].yorigin+
    "\n\nLayer 3\nwidth: "+layer[3].width+"px\nheight: "+layer[3].height+"px\nxtravel: "+layer[3].xtravel+"px, locked: "+layer[3].xlock+"\nytravel: "+layer[3].ytravel+"px, locked: "+layer[3].ylock+"\nxoffset: "+layer[3].xoffset+"px\nyoffset: "+layer[3].yoffset+"px\nxorigin: "+layer[3].xorigin+"\nyorigin: "+layer[3].yorigin
	);
}

// RUN

jQuery(document).ready(function(){

	viewport=jQuery('#parallax');
  mouseport=jQuery('#parallax');
	
	initLayers();
	createBaseLayer();
	createLayers();
	
	jQuery(window).resize(function() {
		createBaseLayer();
		createLayers();
	});
	
	jQuery().mousemove(function(mouse){

		if (mouse.pageX>=layer[0].mouseleft && 
				mouse.pageX<=mouseport.width()+layer[0].mouseleft && 
				mouse.pageY>=layer[0].mousetop && 
				mouse.pageY<=mouseport.height()+layer[0].mousetop) {

    	// Cycle through layers
			for (var i=0; i<jQuery('#parallax > *').length; i++) {	
		  
		  	// Position layers based on mouse position
		  	if (layer[i+1].xparallax) layer[i+1].canvas.css("left", layer[i+1].xoffset - (mouse.pageX-layer[0].mouseleft) * layer[i+1].xdynamic);
		  	if (layer[i+1].yparallax) layer[i+1].canvas.css("top", layer[i+1].yoffset - (mouse.pageY-layer[0].mousetop) * layer[i+1].ydynamic);
	  	}
	  
	  }
	  
  });

});