// this script checks that mootools exists before we do anything else;

if(window.addEvent){

// the Morph object - used by morph and morphToggle methods

Fx.Morph = Fx.Styles.extend({

 
	start: function(className){
 		
		var to = {};
 
		$each(document.styleSheets, function(style){
			var rules = style.rules || style.cssRules;
			$each(rules, function(rule){
				if (!rule.selectorText.test('\.' + className + '$')) return;
				Fx.CSS.Styles.each(function(style){
					if (!rule.style || !rule.style[style]) return;
					var ruleStyle = rule.style[style];
					to[style] = (style.test(/color/i) && ruleStyle.test(/^rgb/)) ? ruleStyle.rgbToHex() : ruleStyle;
				});
			});
		});
		return this.parent(to);
	}
 
});


 
Fx.CSS.Styles = ["backgroundColor", "backgroundPosition", "color", "width", "height", "left", "top", "bottom", "right", "fontSize", "letterSpacing", "lineHeight", "textIndent", "opacity"];
 
Fx.CSS.Styles.extend(Element.Styles.padding);
Fx.CSS.Styles.extend(Element.Styles.margin);
 
Element.Styles.border.each(function(border){
	['Width', 'Color'].each(function(property){
		Fx.CSS.Styles.push(border + property);
	});
});

// this stuff is for animating the clip property

Fx.CSS.select = function(property, to){
  if (property.test(/color/i)) return this.Color;
  if (property.test(/^clip$/i)) return this.Clip;	// this is the line that needs to be added
  var type = $type(to);
  if ((type == 'array') || (type == 'string' && to.contains(' '))) return this.Multi;
  return this.Single;
};
 
Fx.CSS.Clip = {
  parse: function(value){
    if (value.push) return value;
 var res = value.test('/rect\((\d+)px[,]?[ ]+(\d+)px[,]?[ ]+(\d+)px[,]?[ ]+(\d+)px\)', 'i');
 if (!res) return [0,100,100,0]; // Anything to give the developer feedback something's wrong
    return [parseInt(res[1]), parseInt(res[2]), parseInt(res[3]), parseInt(res[4])];
  },
 
  getNow: function(from, to, fx){
    var now = [];
    for (var i = 0; i < from.length; i++) now[i] = Math.round(fx.compute(from[i], to[i]));
    return now;
  },
 
  getValue: function(value){
    var ret = [];
    for (var i=0; i<value.length; i++) {
      if (i > 0) ret += " ";
      ret += value[i] + "px";
    }
    return 'rect(' + ret + ')';
  }
};

// this object is used as a container for all fx objects to save memory - is like element.storage in mootools 1.2
var storage = {};	
window.addEvent('unload', function(){ storage = ''; });


var options={
	fadeInDuration : 500,
	fadeOutDuration : 500,

	fadeInTransition: 'none',
	fadeOutTransition: 'none',

	flashDuration: 600,
	flashTransition: 'none',

	morphDuration:500,
	morphTransition: 'easeInOut',

	clipDuration: 1000,
	clipTransition: 'easeIn'

}

var utilities = {
	getTransition : function( type ){
		var transition;
		switch(type){
			case 'none':
				transition = Fx.Transitions.linear;
				break;
			case 'easeIn':
				transition = Fx.Transitions.Sine.easeIn;
				break;
			case 'easeOut':
				transition = Fx.Transitions.Sine.easeOut;
				break;
			case 'easeInOut':
				transition = Fx.Transitions.Sine.easeInOut;
				break;
			case 'bounce':
				transition = Fx.Transitions.Sine.easeOut;
				break;
			case 'elastic':
				transition = Fx.Transitions.Elastic.easeOut;
				break;
			case 'back':
				transition = Fx.Transitions.Back.easeOut;
				break;
			default:
				transition = Fx.Transitions.linear;
		}
		return transition;
	},

	flashIn: function(color){
		var tran = utilities.getTransition(options.flashTransition);
		var fc = new Color(color).invert();
		var fontColor = fc.hex;
		var dur = options.flashDuration / 2;
		if(storage[this.id + 'colorFlashInObject']){ storage[this.id + 'colorFlashInObject'] = ''; }
		storage[this.id + 'colorFlashInObject'] = new Fx.Styles(this, {duration: dur, transition:tran, onComplete:utilities.flashOut.bindAsEventListener(this) } );
		storage[this.id + 'colorFlashInObject'].start( { 'background-color' : color, 'color' : fontColor } );
	},

	flashOut: function(){
		var tran = utilities.getTransition(options.flashTransition);
		var oldColor;
		var oldBGColor;
		if( storage[this.id + 'oldColor'] && storage[this.id + 'oldBGColor'] ){
			oldColor = storage[this.id + 'oldColor'];
			oldBGColor = storage[this.id + 'oldBGColor'];
		}else{
			oldColor = '#000000';
			oldBGColor = '#FFFFFF';
		}
		var dur = options.flashDuration / 2;
		if(storage[this.id + 'colorFlashOutObject']){ storage[this.id + 'colorFlashOutObject'] = ''; }
		storage[this.id + 'colorFlashOutObject'] = new Fx.Styles(this, {duration: dur, transition:tran
			}).start(
			{
				'background-color' : oldBGColor,
				'color' : oldColor
			}
		);
	},

	performMorph: function(class1){
		if( arguments.length == 2 ){
			//new Event(ev).stop();
			var class2 = arguments[1];
			var currentClass;
			if(storage[this.id + 'morphObjectNewClass']){
				currentClass = storage[this.id + 'morphObjectNewClass'];
			}else{
				currentClass = class1;
			}
			var newClass;
			if(currentClass != class1 && currentClass != class2){
				newClass = class1;
			}else if(currentClass == class1){
				newClass = class2;
			}else if(currentClass == class2){
				newClass = class1;
			}
		}else{
			newClass = class1;
		}
		if(!storage[this.id + 'morphObject']){ 
			var tran = utilities.getTransition(options.morphTransition);
			var dur = options.morphDuration;
			storage[this.id + 'morphObject'] = new Fx.Morph(this, {wait:false, duration:dur, transition:tran} );
		}
		storage[this.id + 'morphObject'].stop();
		storage[this.id + 'morphObjectNewClass'] = newClass;
		storage[this.id + 'morphObject'].start(newClass);
	},

	placeCovering: function( element, colorHex ){
		var div = new Element('div');
		element = $(element);
		var position = element.getCoordinates();
		div.setStyles({
				'position' : 'absolute',
				'background-color' : colorHex,
				'width' : position.width,
				'height' : position.height,
				'top' : position.top,
				'left' : position.left
				});
		if( arguments.length == 3 ){
			div.setStyles(arguments[2]);
		}
		var b = $$('body')[0];
		div.injectInside(b);
		return div;
	},
	
	placeCoveringClone: function( element ){
		element = $(element);
		var el = element.clone();
		var position = element.getCoordinates();
		el.setStyles({
				'position' : 'absolute',
				'width' : position.width,
				'height' : position.height,
				'top' : position.top,
				'left' : position.left
				});
		
		var b = $$('body')[0];
		el.injectInside(b);
		return el;
	},
	
	animateClip: function(element, startClip, endClip){
		var tran = utilities.getTransition(options.clipTransition);
		var dur = options.clipDuration;
		if( !storage[element_id + 'clipAnim'] ){
			storage[element_id + 'clipAnim'] = new Fx.Style( element, 'clip', {duration: dur, transition: tran} );
		}
		storage[element_id + 'clipAnim'].start( startClip, endClip );
	}
	


	
}

	

		
		

				



Element.extend({
	
	
	fadeIn : function(){
		var tran = utilities.getTransition(options.fadeInTransition);
		if( arguments.length > 0 ){
                	storage[this.id + 'fadeObject'] = new Fx.Style(this, 'opacity', { duration: options.fadeInDuration, transition:tran, onComplete:arguments[0]}).start(0,1);
		}else{
			storage[this.id + 'fadeObject'] = new Fx.Style(this, 'opacity', { duration: options.fadeInDuration, transition:tran}).start(0,1);
		}
	},

	fadeOut : function(){
		var tran = utilities.getTransition(options.fadeOutTransition);
		if( arguments.length > 0 ){
			storage[this.id + 'fadeObject'] = new Fx.Style(this, 'opacity', { duration: options.fadeOutDuration, transition:tran, onComplete:arguments[0]}).start(1,0);
		}else{
			storage[this.id + 'fadeObject'] = new Fx.Style(this, 'opacity', { duration: options.fadeOutDuration, transition:tran}).start(1,0);

		}

	},

	flash: function( color ){
		storage[this.id + 'oldColor'] = this.getStyle('color');
		storage[this.id + 'oldBGColor'] = this.getStyle('background-color');
		utilities.flashIn.attempt(color, this);
	},

 	morph: function( className ){
		utilities.performMorph.attempt([ '', className], this );
	},

	
	toggleMorph:function(eventType, class1, class2){
		var trigger;
		if(arguments.length == 4){
			trigger = $(arguments[3]);
		}else{
			trigger = this;
		}
		if(eventType == 'mouseover'){
			trigger.addEvent('mouseover', utilities.performMorph.bind(this, [class1, class2]) );
			trigger.addEvent('mouseout', utilities.performMorph.bind(this, [class2, class1]) );
		}else{
			trigger.addEvent(eventType, utilities.performMorph.bind(this, [class1, class2]) );
		}
	}

	
		

});

var SmoothLoader = {
	
	selector:'',
	coveringColor:'#FFFFFF',

	fadeIn: function(){
		this.fadeIn();
	},
	
	setUpFade: function(){
		var els = $$(SmoothLoader.selector)
		els.each( function(el){
				el.setStyle('visibility', 'hidden');
				new Asset.image(el.src, { onload : SmoothLoader.fadeIn.bindAsEventListener(el) } );
			});
	},
	
	setUpRevealFromEdge: function(){
		var els = $$(SmoothLoader.selector);
		els.each( function(el){
				utilities.placeCovering(el, SmoothLoader.coveringColor);
				var height = el.getStyle('height').toInt();
				var width = el.getStyle('width').toInt();
				var wmid = Math.round(width / 2);
				var hmid = Math.round(height / 2);
				});
	},
				
	
	
	fade: function(selector){
		SmoothLoader.selector = selector;
		window.addEvent('domready', SmoothLoader.setUpFade);
	},
	
	revealFromEdge: function(selector, color){
		Smoothloader.coveringColor = arguments[1];
		SmoothLoader.selector = selector;
		window.addEvent('domready', SmoothLoader.setUpRevealFromEdge);
	}
}

var Rollover = new Class({
	options: {downSuffix:false},	

	initialize: function(selector, suffix, options){
		this.setOptions(options);
		this.objects = $$(selector);
		this.onSuffix = suffix;
		this.newExtensions = {active:true,
					offSrc:'',
					onSrc:'',
					downSrc:'',
					currentState:'off'
					};
		
		
		for(var i=0; i<this.objects.length; i++){
			$extend(this.objects[i], this.newExtensions);
			this.objects[i].offSrc = this.objects[i].src;
			this.objects[i].onSrc = this.swap(this.objects[i].src, this.onSuffix);
			if(this.options.downSuffix != false){
				this.objects[i].downSrc = this.swap(this.objects[i].src, this.options.downSuffix);
			}
			this.objects[i].addEvent('mouseover', this.swapSrc.bindAsEventListener(this.objects[i], 'on') );
			this.objects[i].addEvent('mouseout', this.swapSrc.bindAsEventListener(this.objects[i], 'off') );
			if(this.options.downSuffix != false){
				this.objects[i].addEvent('mousedown', this.swapSrc.bindAsEventListener(this.objects[i], 'down') );
				this.objects[i].addEvent('mouseup', this.swapSrc.bindAsEventListener(this.objects[i], 'on') );
			}
			this.preload.attempt(null, this);
		}
	},

	preload: function(){
		var img = new Asset.image(this.onSrc, {onerror:this.preloadError.bindAsEventListener(this)} );
		if(this.options.downSuffix != false){
			var img2 = new Asset.image(this.downSrc, {onerror:this.preloadError.bindAsEventListener(this)} );
		}

	},
	preloadError: function(){
		this.active = false;
		
	},
	swap: function(src, suffix){
		var s = src.split('.');
		var ext = s.getLast();
		return src.replace('.' + ext, suffix + '.'  + ext);
	},
	swapSrc: function(e, action){
	if(this.active == false){ return; }
		switch(action){
			case 'on':
				this.src = this.onSrc;
				this.currentState = 'on';
				break;
			case 'off':
				this.src = this.offSrc;
				this.currentState = 'off';
				break;
			case 'down':
				this.src = this.downSrc;
				this.currentState = 'down';
				break;
		}
	},
	extend: function(obj){
		return $extend(obj, this.newExtensions);
	}
			
	
	
});

Rollover.implement(new Options);
	

}
