//MooTools More, <http://mootools.net/more>. Copyright (c) 2006-2008 Valerio Proietti, <http://mad4milk.net>, MIT Style License.

/*

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.addEvent('complete', function(){

			this.open = (this.wrapper['offset' + this.layout.capitalize()] != 0);
			
			/* acker added */
				if(!this.open){
					this.wrapper.style.display='none';//Acker added
				}else{
					this.wrapper.style.height='';
					this.wrapper.style.display='';//Acker added
				}
			
				this.wrapper.style.position='static';
				this.wrapper.style.visibility='visible';
			/* end */


			if (this.open && Browser.Engine.webkit419) this.element.dispose().inject(this.wrapper);

		}, true);

		this.element = this.subject = $(element);

		this.parent(options);

		var wrapper = this.element.retrieve('wrapper');

		this.wrapper = wrapper || new Element('div', {

			styles: $extend(this.element.getStyles('margin', 'position'), {'overflow': 'hidden'})

		}).wraps(this.element);

		this.element.store('wrapper', this.wrapper).setStyle('margin', 0);

		this.now = [];

		this.open = true;
		
		this.runInitialDisplayScan();
	},

	runInitialDisplayScan: function(){
		if(this.element.style.display=='none'){
			this.open=false;
			
			if( this.options.mode == 'vertical'){
				this.wrapper.style.height=0;
				this.element.style.display='';
				this.start('in',this.options.mode);
			}else{
				this.wrapper.style.visibility='hidden';
				this.wrapper.style.position='absolute';
				this.element.style.display='';
				this.start('out',this.options.mode);
			}

			return;
		}
	},

	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.wrapper.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){

		/* Acker Added */
			this.wrapper.style.display	= '';
		/* end */

		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.wrapper.getStyle(this.layout).toInt();

		var caseIn = [[margin, layout], [0, this.offset]];

		var caseOut = [[margin, layout], [-this.offset, 0]];

		var start;

		switch (how){
			case 'in': start = caseIn; break;
			case 'out': start = caseOut; break;
			case 'toggle': start = (this.wrapper['offset' + this.layout.capitalize()] == 0) ? caseIn : caseOut;
		}

		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;

	}



});



/*
Script: Fx.Elements.js
	Effect to change any number of CSS properties of any number of Elements.

License:
	MIT-style license.
*/

Fx.Elements = new Class({

	Extends: Fx.CSS,

	initialize: function(elements, options){
		this.elements = this.subject = $$(elements);
		this.parent(options);
	},

	compute: function(from, to, delta){
		var now = {};
		for (var i in from){
			var iFrom = from[i], iTo = to[i], iNow = now[i] = {};
			for (var p in iFrom) iNow[p] = this.parent(iFrom[p], iTo[p], delta);
		}
		return now;
	},

	set: function(now){
		for (var i in now){
			var iNow = now[i];
			for (var p in iNow) this.render(this.elements[i], p, iNow[p], this.options.unit);
		}
		return this;
	},

	start: function(obj){
		if (!this.check(arguments.callee, obj)) return this;
		var from = {}, to = {};
		for (var i in obj){
			var iProps = obj[i], iFrom = from[i] = {}, iTo = to[i] = {};
			for (var p in iProps){
				var parsed = this.prepare(this.elements[i], p, iProps[p]);
				iFrom[p] = parsed.from;
				iTo[p] = parsed.to;
			}
		}

		return this.parent(from, to);
	}

});

/*

Script: Accordion.js

	An Fx.Elements extension which allows you to easily create accordion type controls.



License:

	MIT-style license.

*/

var Accordion = new Class({
	Extends: Fx.Elements,

	options: {/*

		onActive: $empty,

		onBackground: $empty,*/

		display: 0,

		show: false,

		height: true,

		width: false,

		opacity: true,

		fixedHeight: false,

		fixedWidth: false,

		wait: false,

		alwaysHide: false,
		
		isRollOverEnabled: true//Acker added, when click an already open area, instead of closing, it instead triggers the next area

	},



	initialize: function(){
	
		/* acker added so we can react to completed transitions, both user and acker defined */
			this.addEvent('complete', function(){
				if( arguments[this.previous].style.height!='0px' ){
					arguments[this.previous].style.overflow='visible';
					arguments[this.previous].style.height='';
				}
			} , true );
		/* end */
		

		var params = Array.link(arguments, {'container': Element.type, 'options': Object.type, 'togglers': $defined, 'elements': $defined});

		this.parent(params.elements, params.options);

		this.togglers = $$(params.togglers);

		this.container = $(params.container);

		this.previous = -1;

		if (this.options.alwaysHide)this.options.wait = true;

		if ($chk(this.options.show)){
			this.options.display = false;
			this.previous = this.options.show;
		}

		if (this.options.start){
			this.options.display = false;
			this.options.show = false;

		}

		this.effects = {};

		if (this.options.opacity) this.effects.opacity = 'fullOpacity';

		if (this.options.width) this.effects.width = this.options.fixedWidth ? 'fullWidth' : 'offsetWidth';

		if (this.options.height) this.effects.height = this.options.fixedHeight ? 'fullHeight' : 'scrollHeight';

		for (var i = 0, l = this.togglers.length; i < l; i++){
			this.addSection(this.togglers[i], this.elements[i]);
		}

		this.elements.each(function(el, i){
			if (this.options.show === i){
				if(this.elements[i].style.display=='none'){this.elements[i].style.display='';}//Acker Added
				this.fireEvent('active', [this.togglers[i], el]);
			}else{
				for (var fx in this.effects) el.setStyle(fx, 0);
			}

		}, this);

		if ($chk(this.options.display)) this.display(this.options.display);

	},



	addSection: function(toggler, element, pos){

		toggler = $(toggler);

		element = $(element);

		var test = this.togglers.contains(toggler);

		var len = this.togglers.length;

		this.togglers.include(toggler);

		this.elements.include(element);

		if (len && (!test || pos)){

			pos = $pick(pos, len - 1);

			toggler.inject(this.togglers[pos], 'before');

			element.inject(toggler, 'after');

		} else if (this.container && !test){

			toggler.inject(this.container);

			element.inject(this.container);

		}

		var idx = this.togglers.indexOf(toggler);

		toggler.addEvent('click', this.display.bind(this, idx));

		if (this.options.height) element.setStyles({'padding-top': 0, 'border-top': 'none', 'padding-bottom': 0, 'border-bottom': 'none'});

		if (this.options.width) element.setStyles({'padding-left': 0, 'border-left': 'none', 'padding-right': 0, 'border-right': 'none'});

		element.fullOpacity = 1;

		if (this.options.fixedWidth) element.fullWidth = this.options.fixedWidth;

		if (this.options.fixedHeight) element.fullHeight = this.options.fixedHeight;

		element.setStyle('overflow', 'hidden');

		if (!test){

			for (var fx in this.effects) element.setStyle(fx, 0);

		}

		return this;

	},



	display: function(index){
		index = ($type(index) == 'element') ? this.elements.indexOf(index) : index;
		
		/* Acker added, so that clicking the same tab will trigger going to the next slide */
			if(index === this.previous && !this.options.alwaysHide && this.options.isRollOverEnabled){
				index=index+1;
				if(index == this.togglers.length)index=this.togglers.length-2;
			}
		/* end */

		if(
			(this.timer && this.options.wait)
		||
			(index === this.previous && !this.options.alwaysHide)
		){
			return this;
		}
		this.previous = index;
		var obj = {};
		this.elements.each(function(el, i){
			obj[i] = {};
			if(this.elements[i].style.display=='none')this.elements[i].style.display='';//Acker Added
			this.elements[i].style.overflow='hidden';//acker added
			var hide = (i != index) || (this.options.alwaysHide && (el.offsetHeight > 0));
			this.fireEvent(hide ? 'background' : 'active', [this.togglers[i], el]);
			for (var fx in this.effects)obj[i][fx] = hide ? 0 : el[this.effects[fx]];
		}, this);

		return this.start(obj);
	}

});
