/**
 * <br />
 * based on Blender 
 * thanks to by Marc Heiligers (marc@eternal.co.za) http://www.eternal.co.za<br />
 * <br />
 * @class Faded
 * @version 1.0.0
 * @author lamboap
 */
var Faded = Class.create();
Faded.prototype = {
	initialize: function(origimg, newimg, options) {
		this.img = $(origimg);
		this.newimg = newimg;
		this.fileNameRegExp = /((http|ftp):\/)?\/?([^:\/\s]+)((\/\w+)*\/)([\w\-\.]+\.[^#?\s]+)?/;
		

		this.options = Object.extend({
			id: this.img.id,
			fadeDuration: 1.0,
			displayDuration: 1.0,
			noWrap: true,
			wrapped:false,
			attributes: []
		}, options || {});

		if(this.options.noWrap) {
			this.container = this.img.up();
		} else {
			if (!this.options.wrapped){
				this.container = Element.extend(Builder.node("div")).setStyle({ position: "relative", width: this.img.width + "px", height: this.img.height + "px" });
				this.img.up().replaceChild(this.container, this.img);
				this.container.appendChild(this.img);
				this.options.wrapped = true;
			}
		}
		this.loadedObserver = this.loaded.bind(this);
		this.nextObserver = this.next.bind(this);

		this.stopped = true;
		this.getFaded();
		
	},

	getFaded: function() {
		
		var fileName = this.img.src.match(this.fileNameRegExp)[6];
		
		var newFilename = this.newimg.match(this.fileNameRegExp)[6];
		
		if (fileName == newFilename){
			return;
		}
		
		if(!this.stopped) {
			return;
		}
		this.stopped = false;
		this.next();
	},
	stop: function() {
		this.stopped = true;
		try { Effect.Queues.get(this.options.id).each(function(effect) { effect.cancel() }) } catch(ex) { }
		if(this.oldImg) {
			this.container.removeChild(this.oldImg);
			this.oldImg = null;
		}
		Element.setOpacity(this.img, 1);
	},
	
	/**
	 * Loads the next image in list
	 * @private
	 */
	next: function() {
		if(this.oldImg) {
			this.container.removeChild(this.oldImg);
		}
		this.oldImg = this.img;
		if(this.stopped) {
			return;
		}

		this.img = Builder.node("img", this.options.attributes);
		Event.observe(this.img, "load", this.loadedObserver);
		this.img.src = this.newimg;
		this.img.id = this.options.id;
	},
	/**
	 * Event listener for image loaded
	 * @private
	 */
	loaded: function() {
		Event.stopObserving(this.img, "load", this.loadedObserver);
		if(this.options.autoSize) {
			this.resize(this.img);
		}
		this.img.setOpacity(0);
		this.container.appendChild(this.img);
		//this.img.setStyle({ position: "absolute", top: this.container.getStyle("padding-top"), left: this.container.getStyle("padding-left") });
		new Effect.Opacity(this.oldImg, { duration: this.options.fadeDuration, from: 1.0, to: 0.0, queue: { scope: this.options.id } });
		new Effect.Opacity(this.img, { duration: this.options.fadeDuration, from: 0.0, to: 1.0, queue: { scope: this.options.id } });
		if(this.oldImg) {
			this.container.removeChild(this.oldImg);
			this.oldImg = null;
		}
		
	},
	/**
	 * Resize the image to the container while maintaining aspect ratio
	 * @private
	 */
	resize: function(img) {
		var dim = this.container.getDimensions();
		dim.width -= parseInt(this.container.getStyle("padding-left")) +
			parseInt(this.container.getStyle("padding-right")) +
			parseInt(this.container.getStyle("border-left-width")) +
			parseInt(this.container.getStyle("border-right-width"));
		dim.height -= parseInt(this.container.getStyle("padding-top")) +
			parseInt(this.container.getStyle("padding-bottom")) +
			parseInt(this.container.getStyle("border-top-width")) +
			parseInt(this.container.getStyle("border-bottom-width"));

		var dw = dim.width / img.width;
		var dh = dim.height / img.height;
		var w1 = img.width * dh;
		var h1 = img.height * dw;

		if(dw > dh) {
			img.width = w1;
			img.height = dim.height;
		} else {
			img.width = dim.width;
			img.height = h1;
		}
	}
};
