/* ************************************************************************************* *\
 * The MIT License
 * Copyright (c) 2007 Fabio Zendhi Nagao - http://zend.lojcomm.com.br
 * 
 * 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.
 * 
\* ************************************************************************************* */
/* mod_ninjaeye
* By Richie Mortimer and Daniel Chapman
* http://www.ninjoomla.com 
* Based on mootools (www.mootools.net) and ifisheye (http://zend.lojcomm.com.br/ifisheye/)
* Copyright (C) 2007 Richie Mortimer and Daniel Chapman, www.ninjoomla.com - Code so sharp, it hurts.
* email: ravenlife@raven-webdesign.com, daniel@ninjoomla.com 
* date: December, 2007
* Release: 1.3
* PHP Code License : http://www.gnu.org/copyleft/gpl.html GNU/GPL 
* JavaScript Code & CSS  : http://creativecommons.org/licenses/by-nc-sa/3.0/
*
* Changelog
* 
* 1.3 January 7, 07 :
*		Auto Detect .js Added
*		Auto Detect Mootools Added
*		Module Parameter Added for Include CSS
*		Module Parameter Added for Include JS
*
* 1.2 December 12, 07 :
*		Module Parameters Added for HTML Validation
*		Module Parameter Added for PNG Fix
*		JS Code Updated to fix IE png fix bug
*
* 1.1 November 22, 07 : 
*       Module now validates for both CSS and XHTML 1.0
* 		Various performance enhancements
* 		Improved accessibility via Alt attributes on menu images
* 
* 1.0 September 2, 07 : 
*       Initial Version
* 
*/
//###################################################################
//Ninja Eye Module
//Copyright (C) 2007 Richie Mortimer and Daniel Chapman. Ninjoomla.com. All rights reserved.
//
//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.
//
//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.
//
//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
//###################################################################
var NinjaEye = new Class({
	options: {
			container: document,
			targetImageClass: ".ninjaeyeImg",
			targetCaptionClass: ".ninjaeyeCaption",
			dimThumb: {width:64, height:64},
			dimFocus: {width:128, height:128},
			eyeRadius: 192,
			pupilRadius: 50,
			useAxis: 'x',
			norm: "L1",

			onEyeOver: Class.empty,
			onEyeOut: Class.empty,
			onPupilOver: Class.empty,
			onPupilOut: Class.empty
	},

	initialize: function(options) {
		this.setOptions(options);
		this.imgs = $$(this.options.targetImageClass);
		this.captions = $A($$(this.options.targetCaptionClass));

		this.imgs.each(function(obj, i) {
			obj.setStyles({
				width: this.options.dimThumb.width +"px",
				height: this.options.dimThumb.height +"px"
			});

			var src = obj.getProperty("src");
			var ext = src.substr(src.length - 3);
			
			this.captions[i].setOpacity(0);
		}.bind(this));

		this.options.container.addEvents({
			"mousemove": function(event) {
				event = new Event(event);
				this._nextState(event);
			}.bind(this),

			"mouseleave": function() {
				this._initialState();
			}.bind(this)
		});
	},

	_initialState: function() {
		this.imgs.each(function(obj, i) {
			this.captions[i].setOpacity(0);
			
			if (MooTools.version.toFloat() == 1.3) {
	 			new Fx.Morph(obj,{duration: 300, transition: Fx.Transitions.Sine.easeInOut}).start({
					"width": [obj.getStyle("width").toInt(), this.options.dimThumb.width],
					"height": [obj.getStyle("height").toInt(), this.options.dimThumb.height]
				})
			
			} else {
				obj.effects({duration: 300, transition: Fx.Transitions.Sine.easeInOut}).start({
					"width": [obj.getStyle("width").toInt(), this.options.dimThumb.width],
					"height": [obj.getStyle("height").toInt(), this.options.dimThumb.height]
				})
			}
		}.bind(this))
	},

	_nextState: function(event) {
		this.imgs.each(function(obj, i) {
			var h = this._getDistance(event, obj);
			var objProperties = this._getDimensions(h);
			obj.setStyles({
				width: objProperties.width +"px",
				height: objProperties.height +"px"
			});

			if(h < this.options.eyeRadius) this.fireEvent("onEyeOver", obj, 20);
			else this.fireEvent("onEyeOut", obj, 20);

			if(h < this.options.pupilRadius) {
				this.captions[i].setOpacity(1);
				this.fireEvent("onPupilOver", obj, 20);
			} else {
				this.captions[i].setOpacity(0);
				this.fireEvent("onPupilOut", obj, 20);
			}
		}.bind(this));
	},

	_getDistance: function(event, obj) {
		var objProperties = obj.getCoordinates();
		var curProperties = {
			x: event.page.x,
			y: event.page.y
		};
		objProperties.center = {
			x: (objProperties.left + (objProperties.width / 2)),
			y: (objProperties.top + (objProperties.height / 2))
		};
		if(this.options.useAxis.length > 1) {
			switch(this.options.norm.toUpperCase()) {
				case "L1":
					return Math.abs(curProperties.x - objProperties.center.x) + Math.abs(curProperties.y - objProperties.center.y);
					break;
				case "L2":
					return Math.round(Math.sqrt(Math.pow((curProperties.x - objProperties.center.x), 2) + Math.pow((curProperties.y - objProperties.center.y),2)));
					break;
			};
		} else {
			return Math.abs(curProperties[this.options.useAxis] - objProperties.center[this.options.useAxis]);
		}
	},

	_getDimensions: function(h) {
		if(h < this.options.eyeRadius) {
			var width = (((this.options.dimThumb.width - this.options.dimFocus.width) / this.options.eyeRadius) * h) + this.options.dimFocus.width;
			var height = (((this.options.dimThumb.height - this.options.dimFocus.height) / this.options.eyeRadius) * h) + this.options.dimFocus.height;
		} else {
			var width = this.options.dimThumb.width;
			var height = this.options.dimThumb.height;
		}
		return {width:width, height:height};
	}
});
NinjaEye.implement(new Events); // Implements addEvent(type, fn), fireEvent(type, [args], delay) and removeEvent(type, fn)
NinjaEye.implement(new Options);// Implements setOptions(defaults, options)
