/*****************************************************
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * <http://www.gnu.org/licenses/>
 * 
 * Copyright 2007 Matthew Weltman <meweltman@yahoo.com>
 *
 *
 * options:
 * The third argument (much like many mootools plugins) are options, they are:
 * active_tab_class - The className of the active tab.
 * scroll_fx_duration - The duration of the scroll between tabs.  For no effect set to 0. Defaults to 500.
 * 
 * To create horizontal tabs:
 * orientation - set to 'horizontal'
 * tab_margin_left - The margin to the left of the left-most tab
 * tab_margin_right - The margin to the right of the right-most tab
 * 
 * To create vertical tabs (note: your tabs must have a set height):
 * orientation - set to 'vertical'
 * tab_margin_top - The margin to the left of the left-most tab
 * tab_margin_bottom - The margin to the right of the right-most tab
 * 
 * -silding tabs can reposition itself to the center of a container or window (see below).
 * to accomplish this you need to enable 3 options
 * container_reposition - set this to true
 * container - the container your tabs are in
 * outer_container - the container you want the tabs to center inside of.  To center in the window, set to 'window'
 * offset - The offset +/- where the container will be centered
 *
 */
var sliding_tabs = new Class({
	initialize:function(tabs, bodies, options){
		this.options = {
			active_tab_class: 'active_tab',
			tab_margin_left: '10px',
			tab_margin_right: '10px',
			tab_margin_top: '10px',
			tab_margin_bottom: '10px',
			scroll_fx_duration:500,
			event:'click',
			orientation:'horizontal',
			scroll_orientation:'vertical',
			//used for container repositioning
			container_reposition: false,
			container:null,
			offset:null,
			outer_container:null,
            initial_tab:0,
            classes:{
				tab_overflow:'tab_overflow',
				tab_container:'tab_container',
				tab_body_container:'tab_body_container'
			}
		}
		var classes = this.options.classes;
		$extend(classes,options.classes);
		$extend(this.options,options);
		this.options.classes=classes;
		if(this.options.orientation=='horizontal'){
			this.flow = 'left';
			this.side = 'right';
			this.dim = 'width';
			this.cart = 'x';
		}else{
			this.flow = 'top';
			this.side = 'bottom';
			this.dim = 'height';
			this.cart = 'y';
		}
		this.bodies = bodies;
		this.tabs = tabs;
		this.tabs.setStyles({
			'position':'relative',
			'float':this.flow
		});
	
		this.tab_overflow = new Element('div').setProperty('class',this.options.classes.tab_overflow);
		this.tab_overflow.injectBefore(this.tabs[0]);
	
		this.tab_container = new Element('div').setProperty('class',this.options.classes.tab_container);
		this.tab_container.injectInside(this.tab_overflow);
		
		this.tab_body_container = new Element('div').setProperty('class',this.options.classes.tab_body_container);
		this.tab_body_container.injectBefore(this.bodies[0]);
		if(this.options.orientation!='horizontal')
			this.tab_overflow.setStyle('float','left');
		
		this.bodies.each(function(el,i){
			el.injectInside(this.tab_body_container);
		}.bind(this));
		
		if(this.options.container_reposition){
			if(this.options.outer_container.toLowerCase() == 'window')
				this.outer_container_dim = this.options.scroll_orientation=='vertical'?Window.getSize().height:Window.getSize().width;
			else
				this.outer_container_dim = this.options.scroll_orientation=='vertical'?$(this.options.outer_container).getStyle('height').toInt():$(this.options.outer_container).getStyle('width').toInt();
			this.scroll_flow=this.options.scroll_orientation=='vertical'?'top':'left';
			this.container_fx = new Fx.Tween($(this.options.container),{link:'cancel'});
		}
		
		this.body_fx = new Fx.Scroll(this.tab_body_container,{link:'cancel',duration:this.options.scroll_fx_duration});
		
		this.tab_items = [];
		this.tabs_dim = 0;
		
		this.tabs.each(function(el,i){
			this.tabs_dim += el.getStyle(this.dim).toInt()
				+ el.getStyle('border-'+this.side+'-width').toInt()
				+ el.getStyle('border-'+this.flow+'-width').toInt()
				+ el.getStyle('margin-'+this.flow).toInt()
				+ el.getStyle('margin-'+this.side).toInt()
				+ el.getStyle('padding-'+this.flow).toInt()
				+ el.getStyle('padding-'+this.side).toInt()
			el.injectInside(this.tab_container);
			el.setStyle(this.flow,this.options['tab_margin_'+this.flow]);
			this.tab_items[i] = new tab_item(el,this.bodies[i],this);
		}.bind(this));
		
		this.tab_container.setStyle(this.dim,(this.tabs_dim+this.options['tab_margin_'+this.flow].toInt()+this.options['tab_margin_'+this.side].toInt())+'px');
		
		this.tab_fx = new Fx.Scroll(this.tab_overflow,{
			duration:300,
			link:'cancel',
			onComplete:function(){
				this.tab_overflow.addEvent('mousemove',this.mouse_move.bind(this));
			}.bind(this)
		});
		
		this.tab_overflow.addEvent('mouseenter',function(e){
			e = new Event(e).stop();
			if(this.options.orientation=='horizontal')
				this.tab_fx.start(this.get_position(e));
			else
				this.tab_fx.start(0,this.get_position(e));
		}.bind(this));
		
		this.tab_overflow.addEvent('mouseleave',function(){
			this.tab_overflow.removeEvents('mousemove');
		}.bind(this));
		
		this.active_item = this.tab_items[this.options.initial_tab];
		this.tabs[this.options.initial_tab].addClass(this.options.active_tab_class)
		this.tab_body_container.setStyle(this.tab_items[this.options.initial_tab].dim,this.tab_items[this.options.initial_tab].body_dim);
		this.body_event_fx = new Fx.Tween(this.tab_body_container,{duration:500,link:'cancel'});
        new Fx.Scroll(this.tab_body_container,{link:'cancel',duration:0}).toElement(this.tab_items[this.options.initial_tab].body);
        new Fx.Scroll(this.tab_overflow,{link:'cancel',duration:0}).toElement(this.tab_items[this.options.initial_tab].item);
	},
	mouse_move:function(e){
		e = new Event(e).stop();
		this.tab_fx.cancel();
		if(this.options.orientation=='horizontal')
			this.tab_overflow.scrollLeft = this.get_position(e);
		else
			this.tab_overflow.scrollTop = this.get_position(e);
	},
	get_position:function(e){
		var pos = this.tab_overflow.getPosition();
		var scroll = this.tab_overflow.getScroll();
		var scrollPos = Window.getScroll()[this.cart]+e.client[this.cart]-(pos[this.cart]+scroll[this.cart]);
		var position = scrollPos*(this.tab_container.getStyle(this.dim).toInt())/this.tab_overflow.getStyle(this.dim).toInt() - scrollPos;
		return position;
	}
});

var tab_item = new Class({
	initialize:function(item,body,tab_obj){
		this.item = item;
		this.body = body;
		this.tab_obj = tab_obj;
		this.dim=this.tab_obj.options.scroll_orientation=='vertical'?'height':'width';
		if(this.tab_obj.options.scroll_orientation=='vertical')
			this.body_dim =
				(
				this.body.getStyle('height').toInt()
				+ this.body.getStyle('border-bottom-width').toInt()
				+ this.body.getStyle('border-top-width').toInt()
				+ this.body.getStyle('margin-bottom').toInt()
				+ this.body.getStyle('margin-top').toInt()
				+ this.body.getStyle('padding-bottom').toInt()
				+ this.body.getStyle('padding-top').toInt()
				)+'px';
		else{
			this.body_dim =
				(
				this.body.getStyle('width').toInt()
				+ this.body.getStyle('border-right-width').toInt()
				+ this.body.getStyle('border-left-width').toInt()
				+ this.body.getStyle('margin-right').toInt()
				+ this.body.getStyle('margin-left').toInt()
				+ this.body.getStyle('padding-right').toInt()
				+ this.body.getStyle('padding-left').toInt()
				)+'px';
			this.body.setStyle('float','left');
		}
		
		this.item.addEvent(this.tab_obj.options.event,this.on_event.bind(this));
		
		this.container_flow = (
			this.tab_obj.outer_container_dim-
			this.body_dim.toInt()+
			this.tab_obj.options.offset
			)/2;
	},
	on_event:function(e){
		e = new Event(e).stop();
		if($defined(this.tab_obj.active_item))
    		this.tab_obj.active_item.item.removeClass(this.tab_obj.options.active_tab_class);
		this.item.addClass(this.tab_obj.options.active_tab_class);
		
		if(this.tab_obj.options.container_reposition){
			this.tab_obj.container_fx.start(this.tab_obj.scroll_flow,this.container_flow+'px');
		}
		this.tab_obj.body_event_fx.removeEvents('complete');
		this.tab_obj.body_event_fx.addEvent('complete',function(){
				this.tab_obj.body_fx.toElement(this.body);
				this.tab_obj.active_item = this;
			}.bind(this)
		);
		this.tab_obj.body_event_fx.start(this.dim,this.body_dim);
	}
});

