var LiteTabGroup = new Class( {
	
	  Extends: Swapper
	
	, initialize: function( ) {
		this.parent( );
		
		this.ctls = new Element( 'ul', { 'class': 'labels clean flatten' } );
		this.tabs = new Element( 'div', { 'class': 'tabs', tween: { duration: 'short', onComplete: this.didEndTabTween.bind( this ) } } );
		this.request = new Request.HTML( { link: 'cancel' } );
	  }
	
	, id: 'tab'
	, rendered: false
	, request: null
	, container: null
	, ctls: null
	, tabs: null
	
	, getID: function( ) { return this.id; }
	, setID: function( id ) { this.id = id; return this; }
	
	, getTabBox: function( ) { return this.tabs; }
	
	, add: function( tab ) {
		tab.setTabGroup( this );
		this.parent( tab );
	  }
	
	, swap: function( to ) {
		this.parent( this.a.indexOf( to ) );
	  }
	
	, shouldSwap: function( from, to ) {
		if( from == to ) {
			return from instanceof LiteAjaxTab && from.shouldRequest( );
		}
		return true;
	  }
	
	, shouldRender: function( ) {
		return !!this.a.length;
	  }
	
	, didClick: function( tab ) {
		var from = this.current( );
		var to = tab;
		
		if( this.shouldSwap( from, to ) ) {
			this.didBeginSwap( to );
			
			if( to instanceof LiteAjaxTab
			&& to.shouldRequest( ) ) {
				this.didBeginRequest( );
				this.swap( to );
				this.makeRequest(
					  to
					, this.didEndRequest.bind( this, to )
					, this.didCancelRequest.bind( this, to )
				);
			}
			else {
				this.swap( to );
				this.didEndSwap( );
			}
		}
	  }
	
	, makeRequest: function( tab, successCallback, cancelCallback ) {
		this.request.options.update = tab.getTab( );
		this.request
			.removeEvents( 'success' )
			.addEvent( 'success', [ successCallback, Function.from( ) ].pick( ) );
		this.request
			.removeEvents( 'cancel' )
			.addEvent( 'cancel', [ cancelCallback, Function.from( ) ].pick( ) );
		this.request.send( { url: tab.uri } );
	  }
	
	, didBeginRequest: function( ) { }
	
	, didCancelRequest: function( tab ) { }
	
	, didEndRequest: function( tab ) {
		uv_attach_links.attempt( tab.getTab( ), tab );
		this.didEndSwap( );
	  }
	
	, didBeginSwap: function( to ) {
		var current = this.current( );
		
		current.getTab( ).fade( 'hide' );
		current.getTab( ).setStyle( 'z-index', 0 );
		this.container.addClass( 'loading' );
		current.getCtl( ).addClass( 'hoverable' ).removeClass( 'selected' );
		to.getTab( ).setStyle( 'z-index', 1 );
		to.getCtl( ).addClass( 'selected' ).removeClass( 'hoverable' );
	  }
	
	, didEndSwap: function( ) {
		this.tabs.tween( 'height', this.current( ).getTab( ).getSize( ).y );
	  }
	
	, didEndTabTween: function( ) {
		this.container.removeClass( 'loading' );
		this.current( ).getTab( ).fade( 'show' );
	  }
	  
	, didBeginRender: function( ) {
		this.container.addClass( 'liteTabBox init' );
	  }
	
	, didEndRender: function( ) {
		var current = this.first( );
		
		var initGroupHeight = function( ) {
			this.tabs.setStyle( 'height', this.getTabHeight( current ) );
		}.bind( this );
		
		if( current instanceof LiteAjaxTab ) {
			this.didClick( this.first( ) );
//			this.makeRequest( current, initGroupHeight );
		}
		else {
			initGroupHeight( );
		}
		
		uv_attach_links.attempt( current.getTab( ), current );
		
		this.rendered = true;
		this.container.removeClass( 'init' );
	  }
	
	, getTabHeight: function( tab ) {
		return tab.getTab( ).getSize( ).y
	  }
	
	, render: function( container ) {
		this.container = container;
		
		if( this.shouldRender( ) ) {
			this.didBeginRender( );
			
			this.a.each( function( tab, i ) {
				if( i === 0 ) {
					tab.getTab( ).setStyle( 'z-index', 1 );
				}
				else {
					tab.getTab( ).fade( 'hide' );
					tab.getTab( ).setStyle( 'z-index', 0 );
				}
				
				this.ctls.grab(
					tab.getCtl( )
						.addEvent( 'click', this.didClick.bind( this, tab ) )
				);
				
				if( this.size ) {
					this.setSize( tab.getTab( ) );
				}
				
				this.tabs.grab( tab.getTab( ) );
			}, this );
			
			this.ctls.getFirst( ).addClass( 'first' );
			this.ctls.getLast( ).addClass( 'last' );
			
			this.first( ).getCtl( )
				.addClass( 'selected' )
				.removeClass( 'hoverable' );
			
			container.empty( );
			
//			if( this.count( ) > 1 ) {
				container.grab( this.ctls );
//			}
			
			container.grab( this.tabs );
			
			var uriFragment = new URI( document.location ).get( 'fragment' );
			if( uriFragment ) {
				var first = this.a.filter( function( tab ) {
					return uriFragment === this.getID( )+':'+tab.getID( );
				}, this );
				
				if( first[0] ) {
					this.didClick( first[0] );
				}
			}
			
			this.didEndRender( );
		}
	  }
	
} );

var LiteTabGroupWithFixedSize = new Class( {
	
	  Extends: LiteTabGroup
	
	, initialize: function( x, y ) {
		this.parent( );
		this.getTabBox( ).setStyles( { width: x, height: y } );
		this.size = { x: x, y: y };
	  }
	
	, size: { }
	
	, setSize: function( node ) {
		node.setStyles( { width: this.size.x, height: this.size.y } );
	  }
	
} );

var LiteTab = new Class( {
	
	  initialize: function( id, label ) {
	  	this.id = id;
		this.label = label;
		this.ctl = new Element( 'li', { 'class': 'hoverable', html: label } );
		this.tab = new Element( 'div', { 'class': 'tab' } );
	  }
	
	, id: null
	, group: null
	, label: ''
	, ctl: null
	, tab: null
	
	, setID: function( id ) { this.id = id; return this; }
	, getID: function( ) { return this.id; }
	
	, getCtl: function( ) { return this.ctl; }
	, getTab: function( ) { return this.tab; }
	
	, setSize: function( x, y ) {
		this.size.x = x;
		this.size.y = y;
		return this;
	  }
	, getSize: function( ) {
		return this.size;
	  }
	, setX: function( x ) { this.size.x = x; return this; }
	, setY: function( y ) { this.size.y = y; return this; }
	, getX: function( ) { return this.size.x; }
	, getY: function( ) { return this.size.y; }
	
	, setTabGroup: function( group ) {
		this.group = group;
		return this;
	  }
	
	, getContent: function( ) {
		return this.get( 'html' );
	  }
	
	, setContent: function( string ) {
		this.tab.set( 'html', string );
		return this;
	  }
	
	, getNode: function( ) {
		return this.tab;
	  }
	
	// Should be of $type 'element', 'textnode', or 'collection'
	, setNode: function( node ) {
		this.tab.grab( node );
		return this;
	  }
	
} );

var LiteAjaxTab = new Class( {
	
	  Extends: LiteTab
	
	, initialize: function( id, label, uri ) {
		this.uri = uri;
		this.parent( id, label );
	  }
	
	, uri: ''
	
	, shouldRequest: function( ) {
		return this.tab.getChildren( ).length === 0;
	  }
	
} );
