(function(jQuery,undefined){var plugin="parallax";var options={mouseport: 'body',xparallax: true,yparallax: true,xorigin: 0.5,yorigin: 0.5,decay: 0.66,frameDuration: 30,freezeClass: 'freeze'},value={left: 0,top: 0,middle: 0.5,center: 0.5,right: 1,bottom: 1},regex={px:/^\d+\s?px$/,percent:/^\d+\s?%$/},frameEvent='frame.'+plugin,abs=Math.abs,pointer=[0,0];function parseValue(value){return this.lib[value];}parseValue.lib=value;function parseBool(x){return typeof x==="boolean"?x :!!(parseFloat(x));}function Mouse(options,pointer){var parallax=[parseBool(options.xparallax),parseBool(options.yparallax)];this.ontarget=false;this.decay=options.decay;this.pointer=pointer||[0.5,0.5];this.update=function(pointer,threshold){if(this.ontarget){this.pointer=pointer;}else if((!parallax[0]||abs(pointer[0]-this.pointer[0])<threshold[0])&&(!parallax[1]||abs(pointer[1]-this.pointer[1])<threshold[1])){this.ontarget=true;this.pointer=pointer;}else{var lagPointer=[],x=2;while(x--){if(parallax[x]){lagPointer[x]=pointer[x]+this.decay*(this.pointer[x]-pointer[x]);}}this.pointer=lagPointer;}};}function Port(object,options){var self=this,elem=object instanceof jQuery?object : jQuery(object),parallax=[parseBool(options.xparallax),parseBool(options.yparallax)],inside=0,leaveCoords;this.pointer=[0,0];this.active=false;this.activeOutside=(options&&options.activeOutside)||false;this.update=function(coords){var pos=this.pos,size=this.size,pointer=[],x=2;if(inside>0){if(inside===2){inside=0;if(leaveCoords){coords=leaveCoords};}while(x--){if(parallax[x]){pointer[x]=(coords[x]-pos[x])/size[x];pointer[x]=pointer[x]<0?0 : pointer[x]>1?1 : pointer[x];}}this.active=true;this.pointer=pointer;}else{this.active=false;}};this.updateSize=function(){var width=elem.width(),height=elem.height();self.size=[width,height];self.threshold=[1/width,1/height];};this.updatePos=function(){var offset=elem.offset()||{left: 0,top: 0},left=parseInt(elem.css('borderLeftWidth'))+parseInt(elem.css('paddingLeft')),top=parseInt(elem.css('borderTopWidth'))+parseInt(elem.css('paddingTop'));self.pos=[offset.left+left,offset.top+top];};jQuery(window).bind('resize',self.updateSize).bind('resize',self.updatePos);elem .bind('mouseenter',function(e){inside=1;}).bind('mouseleave',function(e){inside=2;leaveCoords=[e.pageX,e.pageY];});this.updateSize();this.updatePos();}function Layer(elem,options){var px=[],parallax=[],offset=[],position=[];this.update=function(pointer){var pos=[],cssPosition,cssMargin,x=2,css={};while(x--){if(parallax[x]){pos[x]=parallax[x]*pointer[x]+offset[x];if(px[x]){cssPosition=position[x];cssMargin=pos[x]*-1;}else{cssPosition=pos[x]*100+'%';cssMargin=pos[x]*this.size[x]*-1;}if(x===0){css.left=cssPosition;css.marginLeft=cssMargin;}else{css.top=cssPosition;css.marginTop=cssMargin;}}}elem.css(css);};this.setParallax=function(xp,yp,xo,yo){var p=[xp||options.xparallax,yp||options.yparallax],origin=[xo||options.xorigin,yo||options.yorigin],i=2,css={};while(i--){px[i]=regex.px.test(p[i]);if(typeof origin[i]==='string'){origin[i]=regex.percent.test(origin[i])?parseFloat(origin[i])/100 : value[origin[i]]||1;}if(px[i]){parallax[i]=parseInt(p[i]);offset[i]=origin[i]*(this.size[i]-parallax[i]);position[i]=origin[i]*100+'%';}else{parallax[i]=p[i]===true?1 : regex.percent.test(p[i])?parseFloat(p[i])/100 : p[i];offset[i]=parallax[i]?origin[i]*(1-parallax[i]): 0;}}};this.getPointer=function(){var viewport=elem.offsetParent(),pos=elem.position(),position=[],pointer=[],i=2;while(i--){if(px[i]){position[i]=0;}else{position[i]=pos[i===0?'left' : 'top']/(viewport[i===0?'outerWidth' : 'outerHeight']()-this.size[i]);}pointer[i]=(position[i]-offset[i])/parallax[i];}return pointer;};this.setSize=function(x,y){this.size=[x||elem.outerWidth(),y||elem.outerHeight()];};this.setSize(options.width,options.height);this.setParallax(options.xparallax,options.yparallax,options.xorigin,options.yorigin);}function update(e){var elem=jQuery(this),global=e.data,local=elem.data(plugin),port=global.port,mouse=global.mouse,localmouse=local.mouse,process=global.timeStamp!==e.timeStamp;if(process){global.timeStamp=e.timeStamp;port.update(pointer);if(port.active||!mouse.ontarget){mouse.update(port.pointer,port.threshold);}}if(localmouse){localmouse.update(local.freeze?local.freeze.pointer : port.pointer,port.threshold);if(localmouse.ontarget){delete local.mouse;if(local.freeze){elem .unbind(frameEvent).addClass(global.freezeClass);}}mouse=localmouse;}else{if(mouse.ontarget&&!port.active){elem.unbind(frameEvent);}}local.layer.update(mouse.pointer);}jQuery.fn[plugin]=function(o){var global=jQuery.extend({},jQuery.fn[plugin].options,o),args=arguments,layers=this;if(!(global.mouseport instanceof jQuery)){global.mouseport=jQuery(global.mouseport);}global.port=new Port(global.mouseport,global);global.mouse=new Mouse(global);global.mouseport .bind("mouseenter",function(e){global.mouse.ontarget=false;layers .each(function(i){var layer=jQuery(this);if(!layer.data(plugin).freeze){layer .bind(frameEvent,global,update);}});});return layers .bind("freeze",function(e){var elem=jQuery(this),local=elem.data(plugin),mouse=local.mouse||local.freeze||global.mouse,x=regex.percent.exec(e.x)?parseFloat(e.x.replace(/%$/,''))/100 :(e.x||mouse.pointer[0]),y=regex.percent.exec(e.y)?parseFloat(e.y.replace(/%$/,''))/100 :(e.y||mouse.pointer[1]),decay=e.decay;local.freeze={pointer:[x,y]};local.mouse=new Mouse(global,mouse.pointer);if(decay!==undefined){local.mouse.decay=decay};elem .bind(frameEvent,global,update);}).bind("unfreeze",function(e){var elem=jQuery(this),local=elem.data(plugin),decay=e.decay,pointer;if(local.freeze){pointer=local.mouse?local.mouse.pointer : local.freeze.pointer;local.mouse=new Mouse(global);local.mouse.pointer=pointer;if(decay!==undefined)local.mouse.decay=decay;delete local.freeze;elem .removeClass(options.freezeClass).bind(frameEvent,global,update);}}).each(function(i){var elem=jQuery(this),layerOptions=args[i+1]?jQuery.extend({},global,args[i+1]): global,layer=new Layer(elem,layerOptions);elem.data(plugin,{layer: layer,mouse: new Mouse(layerOptions,layer.getPointer())});});};jQuery.fn[plugin].options=options;jQuery(document).ready(function(){jQuery(document).mousemove(function(e){pointer=[e.pageX,e.pageY];});});}(jQuery));
