// jquery.jparallax.js
// 0.5
// Stephen Band
//
// Dependencies:
// jquery.js
// jquery.dimensions.js
//
// Project and documentation site:
// http://webdev.stephband.info/parallax.html


// CLOSURE

(function(jQuery) {


// PRIVATE VARIABLES

var mouse = {
  		x:0, 
  		y:0, 
  		setxy: 		function(m){
  								mouse.x = m.pageX;
  								mouse.y = m.pageY;
  								// console.log(mouse.x+', '+mouse.y);
  							}
}

// PRIVATE FUNCTIONS

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

function stripFiletype(ref) {
  var x=ref.replace('.html', '');
  return x.replace('#', '');
}

function initOrigin(l) {
  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 setLayersToCentre(layer, viewport) {
	for (var i=0; i<layer.length; i++) {
		if (layer[i].xparallax) layer[i].x = layer[i].xoffset - (0.5*viewport.width) * layer[i].xdynamic;
		if (layer[i].yparallax) layer[i].y = layer[i].yoffset - (0.5*viewport.height) * layer[i].ydynamic;
	};
	positionLayers(layer)
}

function positionLayers(mouseport, layer, localmouse) {
	
	// Set where the layer SHOULD be and store in target
	for (var i=0; i<layer.length; i++) {
	  layer[i].xtarget = layer[i].xoffset - localmouse.x * layer[i].xdynamic;
	  layer[i].ytarget = layer[i].yoffset - localmouse.y * layer[i].ydynamic;
	}	
	// Set where the layer is going to be
  if (!mouseport.ontarget) {
    for (var i=0; i<layer.length; i++) {
    	layer[i].x = layer[i].xtarget+(layer[i].x-layer[i].xtarget)*mouseport.softfactor;
    	layer[i].y = layer[i].ytarget+(layer[i].y-layer[i].ytarget)*mouseport.softfactor;		
    }
    var difference = Math.ceil((layer[layer.length-1].x-layer[layer.length-1].xtarget)+(layer[layer.length-1].y-layer[layer.length-1].ytarget));
    
    // If the layer is inside the softlimit set ontarget to true
    if (difference < mouseport.softlimit && difference > mouseport.softlimit*-1) {
    	mouseport.ontarget=true;
    }
    else {
    	// console.log(difference+' '+mouseport.ontarget)
    };
  }
  
  // Set where the layer is if on target
  else {
    for (var i=0; i<layer.length; i++) {
    	layer[i].x = layer[i].xtarget;
    	layer[i].y = layer[i].ytarget;
    }
  }
  // Position Layers 
	for (var i=0; i<layer.length; i++) {
	  if (layer[i].xparallax) layer[i].element.css("left", layer[i].x);
	  if (layer[i].yparallax) layer[i].element.css("top", layer[i].y)
	}
}

// PLUGIN DEFINITION **********************************************************************

jQuery.fn.jparallax = function(options) {
	
	// Extend defaults with options.
	var settings = {
			viewport:	jQuery.extend({}, jQuery.fn.jparallax.settings.viewport, options.viewport),
			mouseport:	jQuery.extend({}, jQuery.fn.jparallax.settings.mouseport, options.mouseport),
			layer:		jQuery.extend({}, jQuery.fn.jparallax.settings.layer, options.layer),
			anim:		jQuery.extend({}, jQuery.fn.jparallax.settings.anim, options.anim)
	};
	
	// Populate layer array with settings
	var layersettings = [];
	
	for(var a=1; a<arguments.length; a++) {
  	layersettings.push(jQuery.extend({}, settings.layer, arguments[a]))
  }
	
	// Iterate matched elements
	return this.each(function() {

		var localmouse = {
					x:				0,
					y:				0
		};
		
		var timer = {
		  running:		false,
		  frame:			25,
		  fire:				function(x, y) {
		  	  				  // console.log('timer.fire! ');
		  	  				  positionLayers(mouseport, layer, localmouse);
		  	  				  this.running = setTimeout(function() {
		  	  				  	// console.log('x: '+localmouse.x+' '+x+' | y: '+localmouse.y+' '+y+' | ontarget: '+mouseport.ontarget);
		  	  				  	if ( localmouse.x!=x || localmouse.y!=y || !mouseport.ontarget ) {
		  	  				  		timer.fire(localmouse.x, localmouse.y)
		  	  				  	}
		  	  				  	else if (timer.running) {
		  	  				  		timer.running=false;
		  	  				  		// console.log('timer.running: '+timer.running);
		  	  				  	};
		  	  				  }, timer.frame)
		  	  				}
		}
		
		var element = jQuery(this);
		
		// Ports
		var viewport	=	jQuery.extend({}, {element: element}, settings.viewport);
		var mouseport = jQuery.extend({}, {element: viewport.element}, settings.mouseport);		
		jQuery.extend(viewport, {		
			width: 		viewport.element.width(),
			height: 	viewport.element.height()
		});
		jQuery.extend(mouseport, {
			width:		mouseport.element.width(),
			height:		mouseport.element.height(),
			top:		mouseport.element.offset().top,
			left:		mouseport.element.offset().left,
			xinside:	true,														// dynamically determines state of localmouse
			yinside:	true,
			active:		true															// dynamically determines state of mouseport
		});

		// Layers
		var layer			= [];
		
		element.children().css('position', 'absolute');
		
		for (var i=0; i<element.children().length; i++) {

			// Create layer from settings if it doesn't exist
			layer[i]=jQuery.extend({}, settings.layer, layersettings[i], {
				element:	element.children('*:eq('+i+')')
			});
			
			layer[i]=jQuery.extend({}, {
				width:		pxToInt(layer[i].element.css("width")),
				height:		pxToInt(layer[i].element.css("height")),
				xtravel:	pxToInt(layer[i].element.css("width")) - viewport.width,
				ytravel:	pxToInt(layer[i].element.css("height")) - viewport.height,
			}, layer[i]);
			
			jQuery.extend(layer[i], {	
				xoffset: 	(viewport.width - layer[i].width + layer[i].xtravel) * layer[i].xorigin,
				yoffset:	(viewport.height - layer[i].height + layer[i].ytravel) * layer[i].yorigin,
				xdynamic:	layer[i].xtravel / viewport.width,
				ydynamic:	layer[i].ytravel / viewport.height,
				xtarget:	0,
				ytarget:	0,
				x:				0,
				y:				0
			});	  	  
		
//		console.log('width: '+layer[i].width+' height: '+layer[i].height)+'\n'+
//								'xtravel: '+layer[i].xtravel+' ytravel: '+layer[i].ytravel)'\n'+
//								'xoffset: '+layer[i].xoffset+' yoffset: '+layer[i].yoffset)'\n'+
//								'xdynamic: '+layer[i].xdynamic+' ydynamic: '+layer[i].ydynamic);
		
		}

		//setLayersToCentre(layer, viewport);
		jQuery().mousemove(function(){
			// Is mouse inside?
			(mouse.x >= mouseport.left && mouse.x<mouseport.width+mouseport.left) ? mouseport.xinside = true : mouseport.xinside = false;
			(mouse.y >= mouseport.top && mouse.y<mouseport.height+mouseport.top)  ? mouseport.yinside = true : mouseport.yinside = false;
			// Then switch active on.
			if (mouseport.xinside && mouseport.yinside && !mouseport.active) {
				mouseport.ontarget = false;
				mouseport.active = true;
			}
			// If active is on give localmouse coordinates
			if (mouseport.active) {
				if (mouseport.xinside) localmouse.x = mouse.x-mouseport.left 
				else (mouse.x < mouseport.left) ? localmouse.x = 0 : localmouse.x = mouseport.width;
				if (mouseport.yinside) localmouse.y = mouse.y-mouseport.top 
				else (mouse.y < mouseport.top)  ? localmouse.y = 0 : localmouse.y = mouseport.height;
			}
			// console.log(localmouse.x+', '+localmouse.y+' | '+mouseport.active);
			
			// If mouse is inside, fire timer
			if (mouseport.xinside && mouseport.yinside)  { if (!timer.running) timer.fire(localmouse.x, localmouse.y) }
			else if (mouseport.active) { mouseport.active = false };			
		});
		
	});
};

// END OF PLUGIN DEFINITION **********************************************************************

// PLUGIN DEFAULTS

// jQuery.fn.jparallax.settings = {
// 	mouseResponse:		true,
// 	triggerResponse:	false,
// 	xparallax:			true,
// 	yparallax:			true,
// 	xorigin:			'centre',
// 	yorigin:			'centre',
// 	takeoverFactor:		0.75,
// 	takeoverThresh:		6
// }

jQuery.fn.jparallax.settings = {
	viewport:		{	},
	mouseport:	{	active: 	true,
					ontarget:	false,
					softfactor:	0.75,
					softlimit:	4
				},
	layer: 		{	xparallax: 	true,
					yparallax: 	true,
					xorigin:	'centre',
					yorigin:	'centre'
				},
	animation:	{	timerpause:	5000,
					duration:	600
				},
	trigger:		false
};

// RUN

initOrigin(jQuery.fn.jparallax.settings.layer);

jQuery(function() {

	jQuery().mousemove(mouse.setxy);
	
});

// END CLOSURE

})(jQuery);