var MorphTabs = new Class({
	Implements: [Events, Options, Chain],
 
	version: '1.0',
 
	options: {
		width: '300px',
		height: '200px',
		changeTransition: {
			transition: 'linear',
			duration: 'short'
		},
		panelStartFx: 'blind:up',
		panelEndFx: 'blind:down',
		mouseOverClass: 'over',
		activateOnLoad: 'first',
		useHighslide: false,
		useAjax: false,
		ajaxUrl: '',
		ajaxOptions: {
			method:'get',
			evalScripts: true
		},
		ajaxLoadingText: 'Loading...'
	},
 
	initialize: function(element, options) {
		if(options) this.setOptions(options);
		if (this.options.height == 'none') {
			this.options.changeTransition = 'none';
		}
		this.panelStartFx = this.options.panelStartFx;
		this.panelEndFx = this.options.panelEndFx;
		this.el = $(element);
		this.elid = element;
		
		if (this.options.height == 'none') {
			this.el.setStyles({
				'width': this.options.width
			});
		} else {
			this.el.setStyles({
				'height': this.options.height,
				'width': this.options.width
			});
		}
		
		this.titles = $$('#' + this.elid + ' ul.morphtabs_title li');
		this.panelHeight = this.options.height.toInt() - (this.titles[0].getSize().y + 4);
		this.panelWidth = this.el.getSize().x;	
		//this.el.getSize().y
		if (this.options.height == 'none') {
			this.panel = new Element('div', {
				'id': 'morphPanel',
				'class': 'morphtabs_panel',
				'styles': {
					'width': this.panelWidth + 'px'
				}
			}).inject(this.el.getFirst(), 'after');
		} else {
			this.panel = new Element('div', {
				'id': 'morphPanel',
				'class': 'morphtabs_panel',
				'styles': {
					'width': this.panelWidth + 'px',
					'height': this.panelHeight + 'px'
				}
			}).inject(this.el.getFirst(), 'after');
		}
		this.panelWrapBorder = this.panel.getStyle('border-width').toInt() * 2;	
		if (this.options.height == 'none') {
			this.panelWrap = new Element('div', {
				'id': 'morphPanelWrap',
				'class': 'morphtabs_panelwrap',
				'styles': {
					'width': (this.panelWidth + this.panelWrapBorder) + 'px'
				}
			}).wraps(this.panel);
		} else {
			this.panelWrap = new Element('div', {
				'id': 'morphPanelWrap',
				'class': 'morphtabs_panelwrap',
				'styles': {
					'height': (this.panelHeight + this.panelWrapBorder) + 'px',
					'width': (this.panelWidth + this.panelWrapBorder) + 'px'
				}
			}).wraps(this.panel);
		}
		this.panelTop = this.panelWrap.getStyle('top').toInt();
		if (this.panelTop == 'NaN') this.panelTop = 0;
		if (this.options.height == 'none') {
			this.panelWrap.setStyle('top', (Browser.Engine.trident5) ? (this.panelTop + 0) + 'px' : this.panelTop + 'px'); // fix for ie7.
		} else {
			this.panelWrap.setStyle('top', (Browser.Engine.trident5) ? (this.panelTop + 4) + 'px' : this.panelTop + 'px'); // fix for ie7.
		}
		this.attach(this.titles);
		if(this.options.activateOnLoad != 'none') {
			this.firstRun = true;
			if(this.options.activateOnLoad == 'first') {
				this.activate(this.titles[0]);
			} else {
				this.activate(this.options.activateOnLoad);
			}
		}
	},
 
	attach: function(elements) {
		$$(elements).each(function(element) {
			var enter = element.retrieve('tab:enter', this.elementEnter.bindWithEvent(this, element));
			var leave = element.retrieve('tab:leave', this.elementLeave.bindWithEvent(this, element));
			var mouseclick = element.retrieve('tab:click', this.elementClick.bindWithEvent(this, element));
			element.addEvents({
				mouseenter: enter,
				mouseleave: leave,
				click: mouseclick
			});
			var el = $(element.get('title'));
			element.store('panel:html', el.get('html'));
			element.store('panel:id', el.id);
			var elementDispose = $(element.get('title')).dispose();
		}, this);
		return this;
	},
 
	detach: function(elements) {
		$$(elements).each(function(element){
			element.removeEvent('mouseenter', element.retrieve('tab:enter') || $empty);
			element.removeEvent('mouseleave', element.retrieve('tab:leave') || $empty);
			element.removeEvent('mouseclick', element.retrieve('tab:click') || $empty);
			element.eliminate('tab:enter').eliminate('tab:leave').eliminate('tab:click').eliminate('panel:html').eliminate('panel:id');
			var elementDispose = element.dispose();
		});
		return this;
	},
 
	activate: function(tab) {
		if($type(tab) == 'string') {
			myTab = $$('#' + this.elid + ' ul li').filter('[title=' + tab + ']')[0];
			tab = myTab;
		}
		if($type(tab) == 'element') {
			var html = tab.retrieve('panel:html');
			this.panel.id = tab.retrieve('panel:id');
			this.titles.removeClass('active');
			tab.addClass('active');
			this.activeTitle = tab;
			this.panel.setStyle('overflow', 'hidden');
			if ($type(this.options.changeTransition) == 'object' && !this.firstRun) {
				this.getPanelFx(this.options.panelStartFx)
				.chain(function() {
					this.fill(this.panel, html);
					this.getPanelFx(this.options.panelEndFx)
					.chain(function() {
						this.panel.setStyle('overflow', 'auto');
					}.bind(this));
				}.bind(this));
			} else if ($type(this.options.changeTransition) == 'object' && this.firstRun) {
				this.fill(this.panel, html);
				this.panel.store('flag', 'end');
				this.getPanelFx(this.options.panelEndFx)
				.chain(function() {
					this.panel.setStyle('overflow', 'auto');
				}.bind(this));
			} else {
				this.fill(this.panel, html);
				this.panel.setStyle('overflow', 'auto');
			}
		}
	},
 
	getPanelFx: function(fx) {
		var flag = (this.firstRun) ? this.panel.retrieve('fxEffect:flag', 'show') : this.panel.retrieve('fxEffect:flag');
		var styles = {
			'margin-top': [0, 0],
			'margin-left': [0, 0],
			'width': [this.panelWidth, this.panelWidth],
			'height': [this.panelHeight, this.panelHeight],
			'opacity': [1, 1]
		};
		var fxEffect = this.panel.get('morph', this.options.changeTransition);
		switch(fx) {
			case 'blind:up':
				if (flag == 'hide') {
					styles = fxEffect.start($merge(styles, {
						'height': [this.panelHeight, 0]
					}));
				} else {
					styles = fxEffect.start($merge(styles, {
						'margin-top': [this.panelHeight, 0],
						'height': [0, this.panelHeight]
					}));
				}
				break;
			case 'blind:down':
				if (flag == 'hide') {
					styles = fxEffect.start($merge(styles, {
						'margin-top': [this.panelHeight],
						'height': [0]
					}));	
				} else {
					styles = fxEffect.start($merge(styles, {
						'height': [0, this.panelHeight]
					}));
				}
				break;
			case 'blind:left':
				if (flag == 'hide') {
					styles = fxEffect.start($merge(styles, {
						'width': [this.panelWidth, 0]
					}));
				} else {
					styles = fxEffect.start($merge(styles, {
						'margin-left': [this.panelWidth, 0],
						'width': [0, this.panelWidth]
					}));
				}
				break;
			case 'blind:right':
				if (flag == 'hide') {
					styles = fxEffect.start($merge(styles, {
						'margin-left': [this.panelWidth],
						'width': [0]
					}));
				} else {
					styles = fxEffect.start($merge(styles, {
						'width': [0, this.panelWidth]
					}));
				}
				break;
			case 'slide:up':
				if (flag == 'hide') {
					styles = fxEffect.start($merge(styles, {
						'margin-top': [0, -this.panelHeight],
						'width': [this.panelWidth],
						'height': [this.panelHeight]
					}));
				} else {
					styles = fxEffect.start($merge(styles, {
						'margin-top': [this.panelHeight, 0]
					}));
				}
				break;
			case 'slide:down':
				if (flag == 'hide') {
					styles = fxEffect.start($merge(styles, {
						'margin-top': [0, this.panelHeight],
						'width': [this.panelWidth],
						'height': [this.panelHeight]
					}));
				} else {
					styles = fxEffect.start($merge(styles, {
						'margin-top': [-this.panelHeight, 0]
					}));
				}
				break;
			case 'slide:left':
				if (flag == 'hide') {
					styles = fxEffect.start($merge(styles, {
						'margin-left': [0, -this.panelWidth],
						'width': [this.panelWidth],
						'height': [this.panelHeight]
					}));
				} else {
					styles = fxEffect.start($merge(styles, {
						'margin-left': [this.panelWidth, 0]
					}));
				}
				break;
			case 'slide:right':
				if (flag == 'hide') {
					styles = fxEffect.start($merge(styles, {
						'margin-left': [0, this.panelWidth],
						'width': [this.panelWidth],
						'height': [this.panelHeight]
					}));
				} else {
					styles = fxEffect.start($merge(styles, {
						'margin-left': [-this.panelWidth, 0]
					}));
				}
				break;
			case 'fade':
				if (flag == 'hide') {
					styles = fxEffect.start($merge(styles, {
						'opacity': [1, 0]
					}));
				}
				break;
			case 'appear':
				if (flag == 'show') {
					styles = fxEffect.start($merge(styles, {
						'opacity': [0, 1]
					}));
				}
				break;
			case 'none:start':
				if (flag == 'hide') {
					styles = fxEffect.set($merge(styles, {
						'opacity': [1, 0]
					}));
				}
				break;
			case 'none:end':
				if (flag == 'show') {
					styles = fxEffect.set($merge(styles, {
						'opacity': [0, 1]
					}));
				}
				break;
		}
		this.panel.store('fxEffect:flag', (flag == 'hide') ? 'show' : 'hide');
		if (this.firstRun) this.firstRun = false;
		return styles;
	},
 
	elementEnter: function(event, element) {
		if(element != this.activeTitle) {
			element.addClass(this.options.mouseOverClass);
		}
	},
 
	elementLeave: function(event, element) {
		if(element != this.activeTitle) {
			element.removeClass(this.options.mouseOverClass);
		}
	},
 
	elementClick: function(event, element) {
		if(element != this.activeTitle) {
			element.removeClass(this.options.mouseOverClass);
			this.activate(element);
		}
	},
 
	fill: function(element, contents) {
		if(this.options.useAjax) {
			this.getContent();
		} else {
			element.set('html', contents);
			if (this.options.useHighslide) {
				//collapsible dates
				$$('div.collapsible').setStyle('display','block');
				$$('div.module.dates').each(function(e,i) {
					var el = e.getNext('div.collapsible');
					if (el.hasClass("keepOpen")) {
						e.getFirst('a').addClass('active');
						e.getFirst('a').setProperty('title','active');
						var myslide = new Fx.Slide(el).show();
					} else {
						var myslide = new Fx.Slide(el).hide();
					}
					e.addEvent('click', function() {
						myslide.toggle();
						if (e.getProperty('title') == "active") {
							e.setProperty('title','inactive');
							e.getFirst('a.dates').removeClass('active');
							return false;
						} else {
							e.setProperty('title','active');
							e.getFirst('a.dates').addClass('active');
							return false;
						}
						return false;
					});
				});
				//store titles and text  
				$$('a.leaderTips').each(function(element,index) {  
					var content = element.get('title').split('::');  
					element.store('tip:title', content[0]);  
					element.store('tip:text', content[1]);  
				});
				//create tips
				var leaderTips = new Tips('.leaderTips',{
					className: 'leadertips',
					hideDelay: 2000,
					offsets: {'x':-110,'y':50},
					fixed: true 
				});
				if($chk($('sl-inc'))) {
					$('sl-inc').addEvent('click', function() {
						return hs.htmlExpand(this, { wrapperClassName: 'highslide-page', objectType: 'ajax' } );
					});
				}
				
				$$('a.hotelinfo').each(function(e,index) {
					var eLink = e.getProperty('href');
					
					e.addEvent('click', function() {
						return hs.htmlExpand(e, {src:eLink, preserveContent: true, wrapperClassName: 'highslide-hotel', objectType: 'iframe' } );
					});
				});
			}
		}
	},
 
	getContent: function() {
		this.panel.set('html', this.options.ajaxLoadingText);
		var newOptions = {
			url: this.options.ajaxUrl + 'tab=' + this.activeTitle.getProperty('title'),
			update: this.panel
		};
		this.options.ajaxOptions = $merge(this.options.ajaxOptions, newOptions);
		var tabRequest = new Request.HTML(this.options.ajaxOptions);
		tabRequest.send();
	},
 
	addTab: function(title, label, content) {
		var newTitle = new Element('li', {
			'title': title
		});
		newTitle.appendText(label);
		this.titles.include(newTitle);
		$$('#' + this.elid + ' ul').adopt(newTitle);
		var newPanel = new Element('div', {
			'id': title,
			'class': 'mootabs_panel'
		});
		if(!this.options.useAjax) {
			newPanel.set('html',content);
		}
		this.el.adopt(newPanel);
		this.attach(newTitle);
	},
 
	removeTab: function(title){
		if(this.activeTitle.title == title) {
			this.activate(this.titles[0]);
		}
		var tab = $$('#' + this.elid + ' ul li').filter('[title=' + title + ']')[0];
		this.detach(tab);
	},
 
	next: function() {
		var nextTab = this.activeTitle.getNext();
		if(!nextTab) {
			nextTab = this.titles[0];
		}
		this.activate(nextTab);
	},
 
	previous: function() {
		var previousTab = this.activeTitle.getPrevious();
		if(!previousTab) {
			previousTab = this.titles[this.titles.length - 1];
		}
		this.activate(previousTab);
	}
});