/* ************************************************************************************* *\
 * 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.
 * 
\* ************************************************************************************* */

var iFishEye = new Class({
	options: {
			container: document,
			targetImageClass: ".iFishEyeImg",
			targetCaptionClass: ".iFishEyeCaption",
			dimThumb: {width:0, height:64},
			// dimFocus: {width:128, height:128},
			magnify: 2,
			maxWidth: 300,
			eyeRadius: 192,
			pupilRadius: 50,
			useAxis: 'x',
			norm: "L1",
			blankPath: "images/blank.gif",
			wrapper: 'encBg',
			wrapperHeight: 0,
			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));
		
		// evaluate sizes
		var resize = 1
		if(this.options.maxWidth != 0){
			var totalWidth = 0;
			this.imgs.each(function(obj, i) {
				totalWidth += (this.options.dimThumb.width ? this.options.dimThumb.width : obj.getSize().x);
			}.bind(this));
			resize = this.options.maxWidth/totalWidth;
			
		}

		this.imgs.each(function(obj, i) {
			obj.w = Math.floor((this.options.dimThumb.width ? this.options.dimThumb.width : obj.getSize().x) * resize);
			obj.h = Math.floor((this.options.dimThumb.height ? this.options.dimThumb.height : obj.getSize().y) * resize);
			obj.animate = true;
			
			obj.setStyle('height', obj.h);
			
			this.options.wrapperHeight = obj.h;

			var src = obj.get("src");
			var ext = src.substr(src.length - 3);
			if(ext == "png" && Browser.Engine.trident4) {
				obj.setStyle("filter", "progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+ src +"',sizingMethod='scale')");
				obj.setProperty("src", this.options.blankPath);
			}

			this.captions[i].setOpacity(0);
		}.bind(this));
		
		$(this.options.wrapper).setStyle('height', this.options.wrapperHeight)
		
		this.options.container.addEvents({
			"mousemove": function(event) {
				this._nextState(event);
			}.bind(this),

			"mouseleave": function(e) {
				this._initialState(e);
			}.bind(this)
		});
	},

	_initialState: function(e) {
		this.imgs.each(function(obj, i) {
			if(e.type == 'mouseout') this.captions[i].setStyle('opacity', 0);
			
 			obj.set('tween', {duration: 150, transition: Fx.Transitions.Sine.easeInOut});
 			obj.tween("height", [obj.getStyle("height").toInt(), obj.h]);

		}.bind(this));
	},

	_startAnimation: function(event) {// alert(this.imgs.length)
		this.imgs.each(function(obj, i) {
			var h = this._getDistance(event, obj);
			var objProperties = this._getDimensions(h, obj);
			
			obj.set('tween', {duration: 150, transition: Fx.Transitions.Sine.easeInOut});
 			obj.tween("height", objProperties.height);

		}.bind(this));
	},
	
	_nextState: function(event) {
		this.imgs.each(function(obj, i) {
			this.captions[i].setStyle('opacity', 1);
			
			if(obj.animate){
				var h = this._getDistance(event, obj);
				var objProperties = this._getDimensions(h, obj);
				obj.setStyle('height', objProperties.height);

				if(h < this.options.eyeRadius) 
					this.fireEvent("onEyeOver", obj, 20);
				else 
					this.fireEvent("onEyeOut", obj, 20);

				if(h < this.options.pupilRadius) {
					this.captions[i].setStyle('opacity', Browser.Engine.trident ? 1 : 0.8);
					this.fireEvent("onPupilOver", obj, 20);
				} else {
					this.captions[i].setStyle('opacity', 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(d, obj) {
		var w = obj.w;
		var h = obj.h;

		if(d < this.options.eyeRadius) {
			var width = (((w - w * this.options.magnify) / this.options.eyeRadius) * d) + w * this.options.magnify;
			var height = (((h - h * this.options.magnify) / this.options.eyeRadius) * d) + h * this.options.magnify;
		} else {
			var width = w;
			var height = h;
		}
		
		return {width:width, height:height};
	}
});
iFishEye.implement(new Events); // Implements addEvent(type, fn), fireEvent(type, [args], delay) and removeEvent(type, fn)
iFishEye.implement(new Options);// Implements setOptions(defaults, options)
