/*
 * jQuery Proximity Plugin
 * Author: Ed Everett - http://edeverett.co.uk
 * Version: 0.2
 * Demo/Documentation: http://edeverett.co.uk/experiments/proximity
 * 
 * Copyright (c) 2009 Ed Everett http://edeverett.co.uk
 * 
 * Permission is hereby granted, free of charge, to any person
 * obtaining a copy of this software and associated documentation
 * files (the "Software"), to deal in the Software without
 * restriction, including without limitation the rights to use,
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following
 * conditions:
 * 
 * The above copyright notice and this permission notice shall be
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE. 
 */

/*
 
 function findPos(obj) {
	var curleft = curtop = 0;
	if (obj.offsetParent) {
	do {
			curleft += obj.offsetLeft;
			curtop += obj.offsetTop; 	
 	} while (obj = obj.offsetParent);
 
 	return [curleft,curtop];
 }
 
 */

jQuery.fn.proximity = function(callback) {

	if(!callback)
		return "callback function is required";
	
	var p = jQuery.fn.proximity;

	//target class for the elements that the plugin is watching.
	function target(el){		
		this.el = el;		
		//attach the callback function to the target so we can call it on mousemove.
		this.callback = callback;				
	};	
	
	target.prototype.getCentre = function(){		
		
		 function findPos(obj){
		 	var curleft = curtop = 0;
		 	if (obj.offsetParent) {
		 		do {
		 			curleft += obj.offsetLeft;
		 			curtop += obj.offsetTop;
		 		}
		 		while (obj = obj.offsetParent);
		 		
		 	}return [curleft, curtop];
		 }
		
		var pos = findPos(this.el);
		
		return {
			x:pos[0] + (this.el.clientWidth / 2),
			y:pos[1] + (this.el.clientHeight / 2)
		}		
	}
	
	//some pythagorus
	target.prototype.getDistance = function(){		
		var c = this.getCentre();		
		return {
				x:p.e.pageX-c.x,
				y:p.e.pageY-c.y,
				diagonal:Math.sqrt(Math.pow(p.e.pageX-c.x,2) + Math.pow(p.e.pageY-c.y,2))
				}		
	}
	
	//some trignometry
	target.prototype.getAngle = function(){  
		var d = this.getDistance();
		var angleInRadians = Math.atan2(d.x , d.y) + Math.PI;
		return -((angleInRadians / (2 * Math.PI)) * 360) + 360;  
	 }

	
	//Add a mousemove event to the document which calls the callback method on the targets.
	jQuery(document).mousemove(function(e){	
		
		//throttle the speed at which this function can run
		var interval = 50 //milliseconds
		var thisTime = new Date().getTime();
	
		if(!p.lastTime)
			p.lastTime = 0;
		
		if(thisTime - p.lastTime < interval)			
			return false;
		else
			p.lastTime = thisTime;
			
		p.e = e;	
		for(var i = 0; i < p.targets.length; i++){
			p.targets[i].callback(p.targets[i]);
		}
	});
	
	//Store the targets so we can loop through or remove them.
	if(!p.targets)
		p.targets = []; 	
	
	//Takes a jQuery object. Removes the elements inside it.
	p.remove = function(j){		
		//console.log('dffd');
		j.each(function(){						
			for(var i = 0; i < p.targets.length; i++){				
				if(p.targets[i].el == this){
					p.targets.splice(i,1);					
				}
			}			
		});	
		
		if(p.targets.length == 0){						
			jQuery(document).unbind('mousemove');						
		}		
	}
	
	//set up
	this.each(function(){
		
		//if an element is already a target remove it.
		for(var i = 0; i < p.targets.length; i++){				
			if(p.targets[i].el == this){
				p.targets.splice(i,1);					
			}
		}	
		
		p.targets.push(new target(this));
		
	});
	
	return this;
};