/*
Script: Fx.Slide.js
	Effect to slide an element in and out of view.

License:
	MIT-style license.
*/

Fx.Slide = new Class({

	Extends: Fx,

	options: {
		mode: 'vertical'
	},

	initialize: function(element, options){
		this.isDeploy = true;
		if(this.isDeploy) this.templatePath = '/templates/mosaic';
		else this.templatePath = '/templates/mosaic';
		
		if(BrowserDetect.browser == 'Explorer' && BrowserDetect.version == 6){
			this.marginString = '0 0 0 -96px';
			this.parentMarginString = '0 0 0 -100px';
		  this.pillarHeightFix = 9;
		  this.pillarVerticalFix = 89;
			this.clipRegion = 'rect(auto)';
		} else if(BrowserDetect.browser == 'Explorer' && BrowserDetect.version == 7){
			this.marginString = '0 0 0 -96px';
			this.parentMarginString = '0 0 0 -100px';
		  this.pillarHeightFix = 43;
		  this.pillarVerticalFix = 89;
			this.clipRegion = 'rect(-500px, 200px, 0, 0)';
		} else {
			this.parentMarginString = '0';
			this.marginString = '0';
		  this.pillarHeightFix = 36;	
		  this.pillarVerticalFix = 67;
			this.clipRegion = 'rect(-500px, 200px, 0, 0)';
		}
		
		this.addEvent('complete', function(){
			this.open = (this.pillarWrapper['offset' + this.layout.capitalize()] != 0);
			if (this.open && Browser.Engine.webkit419) this.element.dispose().inject(this.pillarWrapper);
		}, true);
		this.element = this.subject = $(element);
		this.parent(options);
		
		var pillarWrapper = this.element.retrieve('pillarWrapper');
		this.pillarWrapper = pillarWrapper || new Element('div', { 'class' : 'pillarWrapper',
			styles: $extend(this.element.getStyles('margin', 'position'), {
				'overflow'	: 'hidden',
				'margin' 		: this.marginString,
				'position' 	: 'absolute',
				'top'				: -(this.element.getStyles('height').height.toInt() + this.pillarHeightFix)
			})
		}).wraps(this.element);
    
		this.element.store('pillarWrapper', this.pillarWrapper).setStyle('margin', 0);
		
		if(BrowserDetect.browser != 'Explorer'){
			var pillarParent = this.pillarWrapper.getParent();
			this.pillarWrapperWrapper = new Element('div', {'class' : 'pillarWrapperWrapper',
																					'styles' : {
																						'width'				: '200px',
																						'height' 			: '0px',
																						'position'		: 'absolute',
																						'top'					: '0px',
																						'margin' 			: this.parentMarginString,
																						'clip'				: this.clipRegion
																					}
																	}).wraps(this.pillarWrapper);
		}
		
		this.element.setStyle('margin', 0);
		this.element.setStyle('padding', 0); // make sure tiles are aligned with their parents
		this.now = [];
		this.open = true;
	},
	
	vertical: function(){
		this.margin = 'margin-top';
		this.layout = 'height';
		this.offset = this.element.offsetHeight;
	},

	horizontal: function(){
		this.margin = 'margin-left';
		this.layout = 'width';
		this.offset = this.element.offsetWidth;
	},

	set: function(now){
		this.element.setStyle(this.margin, now[0]);
		this.pillarWrapper.setStyle(this.layout, now[1]);
		return this;
	},

	compute: function(from, to, delta){
		var now = [];
		var x = 2;
		x.times(function(i){
			now[i] = Fx.compute(from[i], to[i], delta);
		});
		return now;
	},

	start: function(how, mode){
		if (!this.check(arguments.callee, how, mode)) return this;
		this[mode || this.options.mode]();
		var margin = this.element.getStyle(this.margin).toInt();
		var layout = this.pillarWrapper.getStyle(this.layout).toInt();
		
		var caseIn;
		var caseOut;
		if (BrowserDetect.browser == 'Explorer'){
			switch(BrowserDetect.version){
			  case 6: caseIn = [[480, 480], [0, 480]]; break;
				case 7: caseIn = [[492, 492], [0, 492]]; break;
			}
			// ie cant handle animating out, so we just kill the pillar
			caseOut = [[0, 0], [0, 0]];	
		} else {
		  caseIn = [[this.offset, this.offset], [layout, this.offset]];
			caseOut = [[0, -this.offset], [this.offset, 0]];
		}
		var start;
		switch (how){
			case 'in': start = caseIn; break;
			case 'out': start = caseOut; break;
			case 'toggle': 
				if(this.pillarWrapper.offsetHeight == 0){
					start = caseIn;
				} else {
					start = caseOut;
				}
				
        // set the button highlights
				var myBttn;
				if(BrowserDetect.browser == 'Explorer'){
					myBttn = this.element.getParent().getParent().getElement('a');
				} else {
					myBttn = this.element.getParent().getParent().getParent().getElement('a');
				}
				
				if(this.pillarWrapper.offsetHeight == 0){
					// sliding in
					myBttn.setStyles({
						'color' : '#330099',
						'background' : '#34a02c url('+this.templatePath+'/images/pillarsNavBG-li-190x29_o.png) no-repeat'
				  });
				} else {
					//sliding out
					myBttn.setStyles({
						'color' : '#FFFFFF',
						'background' : '#34a02c url('+this.templatePath+'/images/pillarsNavBG-li-190x29.png) no-repeat'
				  });
				}
				
				break;
		}
		
		return this.parent(start[0], start[1]);
	},

	slideIn: function(mode){
		return this.start('in', mode);
	},

	slideOut: function(mode){		
		return this.start('out', mode);
	},

	hide: function(mode){
		this[mode || this.options.mode]();
		this.open = false;
		return this.set([-this.offset, 0]);
	},

	show: function(mode){
		this[mode || this.options.mode]();
		this.open = true;
		return this.set([0, this.offset]);
	},

	toggle: function(mode){
		return this.start('toggle', mode);
	}

});

Element.Properties.slide = {

	set: function(options){
		var slide = this.retrieve('slide');
		if (slide) slide.cancel();
		return this.eliminate('slide').store('slide:options', $extend({link: 'cancel'}, options));
	},

	get: function(options){
		if (options || !this.retrieve('slide')){
			if (options || !this.retrieve('slide:options')) this.set('slide', options);
			this.store('slide', new Fx.Slide(this, this.retrieve('slide:options')));
		}
		return this.retrieve('slide');
	}

};

Element.implement({

	slide: function(how, mode){
		how = how || 'toggle';
		var slide = this.get('slide'), toggle;
		switch (how){
			case 'hide': slide.hide(mode); break;
			case 'show': slide.show(mode); break;
			case 'toggle':
				var flag = this.retrieve('slide:flag', slide.open);
				slide[(flag) ? 'slideOut' : 'slideIn'](mode);
				this.store('slide:flag', !flag);
				toggle = true;
			break;
			default: slide.start(how, mode);
		}
		if (!toggle) this.eliminate('slide:flag');
		return this;
	}

});

