// $Id: $

var Effects_Instances = new Array();
var MAX_FX_STEPS = 30;

function MyEffects(old_img_id) {
	this.clock = null;
	this.new_src = null;
	
	this.id = Effects_Instances.length;
	Effects_Instances[this.id] = this;
	
	this.rotate = new Rotate();
//	this.reflect = new Reflection();
	
	//copy the image object 
	this.old_img_id = old_img_id;
	this.old_img = document.getElementById(old_img_id);
	
	//store the supported form of opacity
	if (typeof this.old_img.style.opacity != 'undefined'){
		this.opac_type = 'w3c';
	}else if (typeof this.old_img.style.MozOpacity != 'undefined'){
		this.opac_type = 'moz';
	}else if (typeof this.old_img.style.KhtmlOpacity != 'undefined'){
		this.opac_type = 'khtml';
	}else if (typeof this.old_img.filters == 'object'){
		//weed out win/ie5.0 by testing the length of the filters collection (where filters is an object with no data)
		//then weed out mac/ie5 by testing first the existence of the alpha object (to prevent errors in win/ie5.0)
		//then the returned value type, which should be a number, but in mac/ie5 is an empty string
		this.opac_type = (this.old_img.filters.length > 0 && typeof this.old_img.filters.alpha == 'object' && typeof this.old_img.filters.alpha.opacity == 'number') ? 'ie' : 'none';
	}else{
		this.opac_type = 'none';
	}
	
	this.start_effect = function(effect,variant,new_src,duration,start_delay) {
		//if the timer is not already going
		if (this.clock == null)
		{
			this.effect = effect;			
			this.duration = duration;
			
			if (typeof start_delay == 'undefined') {
				this.start_delay = 0;
			} else {
				this.start_delay = start_delay;
			}
			
			//copy the image object 
			this.old_img = document.getElementById(this.old_img_id);
			this.size = { 'w': this.old_img.width, 'h': this.old_img.height };

			if ((typeof variant == 'undefined') || (variant == null))
				this.variant = null;
			else
				this.variant = variant;
				
			if ((typeof new_src == 'undefined') || (new_src == null)) {
				this.new_src = null;
				this.new_img = null;
			} else {
				//copy the image src argument 
				this.new_src = new_src;
				
				//create a new image object and append it to body
				//detecting support for namespaced element creation, in case we're in the XML DOM	
	
				if (typeof document.createElementNS != 'undefined')
					this.new_img = document.createElementNS('http://www.w3.org/1999/xhtml', 'img');
				else
					this.new_img = document.createElement('img');

				this.new_img.fx=this;
				this.new_img.old_img=this.old_img;
				this.old_parent=this.old_img.parentNode;

				with (this.new_img){
					id = this.old_img.id + '_dupe';
	
					style.position = this.old_img.style.position;
					
					//move it to superimpose original image
	
					if (!this.old_img.style.left)
						this.old_img.style.left = findPos(this.old_img).left + 'px';
					
					if (!this.old_img.style.top)
						this.old_img.style.top = findPos(this.old_img).top + 'px';
	
					style.left = this.old_img.style.left;
					style.top = this.old_img.style.top;
		
					style.visibility = 'hidden';
					style.display = 'inline';
	
					if (typeof this.old_img.style.zIndex == 'undefined') {
						this.old_img.style.zIndex = '1';
					}
					
					style.zIndex = String(parseInt(this.old_img.style.zIndex)+1);
				}

				if (this.old_img.angle){
					this.new_img.onload = function () {
						this.fx.rotate.rotate_img(this,this.old_img.angle,null,function(old_pic,new_pic,obj){
							obj.new_img=new_pic;
							obj.old_parent.appendChild(new_pic);					
	
							obj.count = 1;
							//create fade resolution argument as 20 steps per transition
							obj.resolution = obj.duration / MAX_FX_STEPS;
							
							obj.curr_tick = 0;
							obj.skip_ticks = obj.start_delay / obj.resolution;
							
							obj.clock = setInterval('Effects_Instances['+obj.id+'].do_transition()', obj.resolution);
						}, this.fx);
					};
					
					//set src to new image src
					this.new_img.src = new_src;
				}else{
					this.new_img.src = new_src;
					this.old_parent.appendChild(this.new_img);					

					this.count = 1;
					//create fade resolution argument as 20 steps per transition
					this.resolution = this.duration / MAX_FX_STEPS;
					
					this.curr_tick = 0;
					this.skip_ticks = this.start_delay / this.resolution;
					
					this.clock = setInterval('Effects_Instances['+this.id+'].do_transition()', this.resolution);				
				}
			}
		}
		
		return true;
	};
	
	
	this.set_opac = function(obj,opac) {
		//set new opacity value on both elements
		//using whatever method is supported
		
		if (obj!=null){
			switch (this.opac_type){
				case 'ie' :
					obj.filters.alpha.opacity = opac * 100;
					return true;
					break;
					
				case 'khtml' :
					obj.style.KhtmlOpacity = opac;
					return true;
					break;
					
				case 'moz' : 
					//restrict max opacity to prevent a visual popping effect in firefox
					obj.style.MozOpacity = (opac == 1 ? 0.9999999 : opac);
					return true;
					break;
					
				case 'none':
					return false;
					
				default : 
					//restrict max opacity to prevent a visual popping effect in firefox
					obj.style.opacity = (opac == 1 ? 0.9999999 : opac);
					return true;
			}
		}
	}
	
	// transition timer function
	this.do_transition = function()
	{
		var cont_transition = true;
		
		
		if (this.curr_tick < this.skip_ticks) {
			this.curr_tick++;
		} else {		
			//decrease the counter on a linear scale
			this.count -= (1 / MAX_FX_STEPS);
		
			cont_transition = this.perform_effect(this.count);
			this.old_img.style.visibility = 'visible';
			
			// do selected effect
	
			if (this.new_img != null) {
				//now that we've gone through one fade iteration 
				//we can show the image that's fading in
				this.new_img.style.visibility = 'visible';
				
				//keep new image in position with original image
				//in case text size changes mid transition or something
			
//				this.new_img.style.left = findPos(this.old_img).left + 'px';
//				this.new_img.style.top = findPos(this.old_img).top + 'px';

				this.new_img.style.left = this.old_img.style.left;
				this.new_img.style.top = this.old_img.style.top;
			}
			
			//if the counter has reached the bottom
			if ((this.count <= (1 / MAX_FX_STEPS)) || (!cont_transition)){
				//clear the timer
				clearInterval(this.clock);
				this.perform_effect(0);
				
				if (this.new_img != null) {
					//remove the duplicate image
					try{
						this.old_parent.removeChild(this.old_img);
					} catch(err) {}

					this.new_img.id=this.old_img.id;
					this.new_img.style.zIndex = this.old_img.style.zIndex;
				} else {
					this.old_img.style.visibility = 'visible';
				}
				
				this.clock = null;
			}
		}
	}
	
	this.perform_effect = function(count) {
		switch (this.effect) {
			case 'fade-in':
				return this.set_opac(this.old_img, 1 - count);				
				break;
				
			case 'fade-out':
				return this.set_opac(this.old_img, count);				
				break;
				
			case 'x-fade':
				if (this.set_opac(this.old_img, count))
					return this.set_opac(this.new_img, 1 - count);
				else
					return false;
			
				break;

			case 'x-wipe':
				this.new_img.style.clip = 'rect(' +
					( (/bt|bltr|brtl/.test(this.variant)) ? (this.size.h * count) : (/che|cc/.test(this.variant)) ? ((this.size.h * count) / 2) : (0) ) + 'px, ' +
					( (/lr|tlbr|bltr/.test(this.variant)) ? (this.size.w - (this.size.w * count)) : (/cve|cc/.test(this.variant)) ? (this.size.w - ((this.size.w * count) / 2)) : (this.size.w) ) + 'px, ' +
					( (/tb|tlbr|trbl/.test(this.variant)) ? (this.size.h - (this.size.h * count)) : (/che|cc/.test(this.variant)) ? (this.size.h - ((this.size.h * count) / 2)) : (this.size.h) ) + 'px, ' +
					( (/lr|tlbr|bltr/.test(this.variant)) ? (0) : (/tb|bt|che/.test(this.variant)) ? (0) : (/cve|cc/.test(this.variant)) ? ((this.size.w * count) / 2) : (this.size.w * count) ) + 'px)';
					
				return true;
				break;
			
			default:
				return false;
				break;
		}
	}
}	

