/*****************************************************
 * 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
		}
		$extend(this.options,options);
		if(this.options.orientation=='horizontal'){
			this.flow = 'left';
			this.side = 'right';
			this.dim = 'width';
		}else{
			this.flow = 'top';
			this.side = 'bottom';
			this.dim = 'height';
		}
		this.bodies = bodies;
		this.tabs = tabs;
		this.tabs.setStyles({
			'position':'relative',
			'float':this.flow
		});
	
		this.tab_overflow = new Element('div').setProperty('id','tab_overflow');
		this.tab_overflow.injectBefore(this.tabs[0]);
	
		this.tab_container = new Element('div').setProperty('id','tab_container');
		this.tab_container.injectInside(this.tab_overflow);
		
		this.tab_body_container = new Element('div').setProperty('id','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.getHeight():window.getWidth;
			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.Style($(this.options.container),this.scroll_flow,{duration:500,wait:false});
		}
		
		this.body_fx = new Fx.Scroll(this.tab_body_container,{wait:false,duration:this.options.scroll_fx_duration});
		
		this.tab_items = [];
		this.tabs_dim = 0;
		var max_height = 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,
			wait:false,
			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();
			var position = this.options.orientation=='horizontal'?e.client.x-this.tab_overflow.getLeft():e.client.y-this.tab_overflow.getTop();
			position = position*(this.tab_container.getStyle(this.dim).toInt())/this.tab_overflow.getStyle(this.dim).toInt() - position;
			if(this.options.orientation=='horizontal')
				this.tab_fx.scrollTo(position);
			else
				this.tab_fx.scrollTo(0,position);
		}.bind(this));
		
		this.tab_overflow.addEvent('mouseleave',function(){
			this.tab_overflow.removeEvents('mousemove');
		}.bind(this));
		
		this.active_item = this.tab_items[0];
		this.tabs[0].addClass(this.options.active_tab_class)
		this.tab_body_container.setStyle(this.tab_items[0].dim,this.tab_items[0].body_dim);
	},
	mouse_move:function(e){
		e = new Event(e).stop();
		this.tab_fx.stop();
		if(this.options.orientation=='horizontal')
			var scrollPos = (document.all)?document.body.scrollLeft:window.pageXOffset
		else
			var scrollPos = (document.all)?document.body.scrollTop:window.pageYOffset
		var position = this.options.orientation=='horizontal'?e.client.x-this.tab_overflow.getLeft()+scrollPos:e.client.y-this.tab_overflow.getTop()+scrollPos;

		position = position*(this.tab_container.getStyle(this.dim).toInt())/this.tab_overflow.getStyle(this.dim).toInt() - position;
		if(this.options.orientation=='horizontal')
			this.tab_overflow.scrollLeft = position;
		else
			this.tab_overflow.scrollTop = 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_fx = new Fx.Style(this.item,'opacity',{duration:300,wait:false});
		
		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.container_flow+'px');
		}
		
		this.tab_obj.tab_body_container.effect(this.dim,{
			duration:500,
			wait:false,
			onComplete:function(){
				this.tab_obj.body_fx.toElement(this.body);
				this.tab_obj.active_item = this;
			}.bind(this)
		}).start(this.body_dim);
	}
});
