var Container = new Class({
	props : null,
	state : null,
	div : null, inner : null, wrapper : null,

	initialize : function( wrapper, props ){
		this.props = props;
		this.state = {};
		this.wrapper = wrapper;
		
		this.div = new Element("div", {"id" : props.id, "class" : props["class"]});
	    this.inner = new Element("div", {"class" : "wrapper"});
		
		wrapper.adopt( this.div.adopt( this.inner ) );		
    },
	
	fill : function( filler, interval ){
		if($type(filler) == 'element'){
			this.inner.adopt(filler);
		}
		
		else if($type(filler) == 'object'){
			filler.display( this.inner ); 
		}
		
		else if($type(filler) == 'string'){
			this.inner.setHTML( filler );
		}
			
		this.div.removeClass("hidden");
		this.state.bVisible = true;
		
		if( interval ){
			setTimeout( this.close.bind(this), interval);
		}
	},
	
	close : function(){
		this.div.addClass("hidden");
		this.state.bVisible = false;
		
		this.toggleScroll( false );
	},
	
	isVisible : function(){
		return this.state.bVisible;
	},

	toggleScroll : function( bLockScroll ){
		if( bLockScroll ){
			document.body.setStyle( 'overflow', 'hidden' );
		}
		
		else{
			document.body.setStyle( 'overflow', 'auto' );
		}
	},

	clear : function(){
		this.inner.empty();
	}
});

var ModalDialog = Container.extend({
	initialize : function( id ){
		this.parent( $(document.body), {"id" : id, "class" : "hidden modal"} );
    }
});

var DialogPlus = Container.extend({
	overlay : null,
	
	position: function(){
		//this.overlay.setStyles({'top': 0, 'height': window.getWidth()});
		this.overlay.setStyles({'top': 0, 'height': 1500});
	}
});

var ModalDialogPlus = DialogPlus.extend({
	initialize : function( id ){
		this.parent( $(document.body), {"id" : id, "class" : "hidden modal_plus"} );

		this.overlay = new Element('div', {'id': 'modal_overlay', "class" : "hidden overlay" }).injectInside( this.wrapper );
    },
	
	fill : function( filler, interval ){
		this.position();
		this.overlay.setStyles({'opacity': 0.8 });
	
		if($type(filler) == 'element'){
			this.inner.adopt(filler);
		}
		
		else if($type(filler) == 'object'){
			filler.display( this.inner ); 
		}
		
		else if($type(filler) == 'string'){
			this.inner.setHTML( filler );
		}
			
		this.div.removeClass("hidden");
		this.overlay.removeClass("hidden");
		this.state.bVisible = true;
		this.toggleScroll( true );
		
		if( interval ){
			setTimeout( this.close.bind(this), interval);
		}
	},
	
	close : function(){
		this.div.addClass("hidden");
		this.state.bVisible = false;
	
		this.overlay.addClass("hidden");
		this.toggleScroll( false );
	}
});

var Dialog = DialogPlus.extend({
	initialize : function( id, cb ){
		this.parent( $(document.body), {"id" : id, "class" : "hidden modal_plus_escapable"} );
		
		cb = ( cb ) ? cb : this.close.bind(this);
		
		this.overlay = new Element('div', {'class': 'overlay'}).injectInside( this.wrapper );
		this.overlay.addEvent( 'click', cb ).addClass('pointer');
		
		this.fx = {
			overlay: this.overlay.effect('opacity', {duration: 1000}).hide()
		};
    },
	
	fill : function( filler ){
		this.position();
		this.fx.overlay.start(0.75).chain( function(){ 
			if($type(filler) == 'element'){
				this.inner.adopt(filler);
			}
			
			else if($type(filler) == 'object'){
				filler.display( this.inner ); 
			}
			
			else if($type(filler) == 'string'){
				this.inner.setHTML( filler );
			}
			
			this.div.toggleClass("hidden");
			this.state.bVisible = true;
			this.toggleScroll( true );
			
		 }.bind(this) );
	},
	
	close : function(){
		if( !this.isVisible() ){
			return false;
		}
		
		this.div.addClass("hidden");
		this.state.bVisible = false;
		this.toggleScroll( false );
		
		this.fx.overlay.stop();
		this.fx.overlay.chain( this.setup.pass(false, this)).start(0);
	},	

	setup : function(){
		return false;
	}
});

var SideBar = Container.extend({
	initialize : function( wrapper, id ){
		this.parent( wrapper, {"id" : id, "class" : "hidden sidebar"} );
    }
});

var SideBarPlus = SideBar.extend({
	initialize : function( wrapper, id ){
		this.wrapper = wrapper;
		
		this.props = {"id" : id, "class" : "hidden sidebarPlus"};
		this.state = {};
		
		this.div = new Element("div", {"id" : this.props.id, "class" : this.props["class"]});
	    this.handle = this.createHandle();
		
		this.inner = new Element("div", {"class" : "wrapper"});
		
		wrapper.adopt( this.div.adopt( this.handle ).adopt(this.inner ) );		
    },
	
	createHandle : function(){
		var handle = new Element( 'div', { 'class' : 'v_handle' } );
		
		handle.addEvent( 'keypress', this.adjust.bindWithEvent( this ) );
		
		handle.makeDraggable({
			onDrag : this.adjust.bind(this),
			// onComplete : this.adjusted.bind(this),
			modifiers : {y: false}
		});
		
		return handle;
	},
	
	adjustHelper: function(){
		this.div.fireEvent( 'keypress' );
	},
	
	adjust : function(){
	
	},
	
	adjusted : function(){
		
	}
});

//// TAB VARIANTS

var BaseTabEl = new Class({
	settings : null, state : null, controller : null, callbacks : null,
	pull : null, pane : null, paneInner : null,

	initialize : function( controller, settings, index ){
		this.controller = controller;
		this.settings = settings;
		this.index = index;
		
		this.state = {
			'activated' : false,
			'loaded' : false,
			'live' : true
		};
	},
	
	setCallbacks : function( callbacks ){
		this.callbacks = callbacks;
	},
	
	execCallback : function( key, args ){
		if( $chk( this.callbacks ) && $chk( this.callbacks[ key ] ) ){
			this.callbacks[ key ]( args );
		}
	},
	
	display : function( pullValue, paneContent ){												
		this.pull = new Element( 'li', { 
											'class' : 'tab',
											'events' : {
												'click' : this.controller.tabEvent.bindWithEvent( this.controller, this.index ) 
											}
										} );
	
		this.paneInner = new Element( 'div', { 'class' : '' } );
		this.pane = new Element( 'div', { 'class' : 'section' } ).adopt( this.paneInner );
		
		this.fill( pullValue, paneContent );
	
		this.controller.layout.pull.adopt( this.pull );
		this.controller.layout.pane.adopt( this.pane );
	
		return this;
	},
	
	fill : function( pullValue, paneContent ){
		if( $chk( pullValue ) ){
			this.pull.setHTML( pullValue );
		}
		
		if( $chk( paneContent ) ){
			this.paneInner.adopt( paneContent );
		}
	},
	
	activate : function(){
		this.state.activated = true;
		this.pull.addClass( 'selectedTab' );
		this.pane.setStyle( 'display', 'block' );
		
		this.execCallback( 'activate', this );
	},
	
	deactivate : function(){
		this.state.activated = false;
		this.pull.removeClass( 'selectedTab' );
		this.pane.setStyle( 'display', 'none' );
	},
	
	remove : function(){
		this.controller.removeTab( this.index );
	}	
});

var FauxTab = BaseTabEl.extend({
	
	initialize : function( controller, settings, index ){
		this.parent( controller, settings, index );
	},
	
	display : function( pullValue, pullLink){
		//this.pull = new Element( 'div', { 'class' : 'pull', 'events' : { 'click' : function(){ window.location = pullLink;}		}} )
						//.adopt( new Element( 'a', { 'class' : 'pullee', 'href' : pullLink } ).setHTML( pullValue ) );
		this.pull = new Element( 'li', { 'class' : 'tab', 'events' : { 'click' : function(){ window.location = pullLink;}		}} )
						.adopt( new Element( 'a', {'href' : pullLink } ).setHTML( pullValue ) );
	
		this.controller.layout.pull.adopt( this.pull );
			
		return this;
	}
});

var BaseTabMan = new Class({
	activeTab : null, aTabs : null, callbacks : null, layout : null, state : null,

	initialize : function( settings, parentDiv, layout ){
		this.aTabs = [];
		this.callbacks = {};
		
		this.state = $extend( {}, this.state );
		 		
		this.layout = layout;
		this.settings = settings;
	
		parentDiv.adopt( layout.main );
	},
	
	setCallbacks : function( callbacks ){
		this.callbacks = callbacks;
	},
	
	execCallback : function( key, args ){
		if( $chk( this.callbacks ) && $chk( this.callbacks[ key ] ) ){
			this.callbacks[ key ]( args );
		}
	},
	
	getMaxHeight : function(){
		var maxHeight = -1;
		this.aTabs.each( function( tabEl ){
			var bToggled = false;
			if( tabEl.pane.hasClass('hidden') ){
				tabEl.pane.toggleClass('hidden');
				bToggled = true;
			}
			
			var h = tabEl.pane.getSize().size.y;
			if( h > maxHeight ){
				maxHeight = h;
			}
			
			if( bToggled ){
				tabEl.pane.toggleClass('hidden');
			}
		});
		
		return maxHeight;
	},
	
	reset : function(){
		this.aTabs.each( function( t ){
			this.removeTab( t );
			// delete this.aTabs[ t.index ];
		}, this);
	
		this.execCallback( 'reset' );
	},
	
	removeTab : function( t ){
	
		
	},
	
	tabDelete : function( index ){
		this.aTabs[ index ].deactivate();
		this.aTabs[ index ].remove();
		
		this.activeTab = null;
		
		this.execCallback( 'kill', this.aTabs[ index ] );
	},
	
	addTab : function( tabSettings ){
		var t = new BaseTabEl( this, tabSettings, this.aTabs.length );
		this.aTabs.push( t );
		
		this.execCallback( 'addTab', [ t ] );
		
		return this.aTabs.getLast();
	},
	
	addLinkTab : function( tabSettings ){
		var t = new FauxTab( this, tabSettings, this.aTabs.length );
		this.aTabs.push( t );
		
		this.execCallback( 'addTab', [ t ] );
		
		return this.aTabs.getLast();
	},

	tabEvent : function( ev, key ){
		this.tabActivation( key );
	},	

	tabActivation : function( index ){
		if( $chk( this.activeTab ) ){
			this.aTabs[ this.activeTab ].deactivate();
		}
		
		this.activeTab = index;
		this.aTabs[ index ].activate();
	}	
});

var HorizontalTabMan = BaseTabMan.extend({
	initialize : function( settings, parentDiv ){
		this.state = { 'bMinSet' : false };
		
		this.parent( settings, parentDiv, GLayout.horizontalTab() );
	},

	setMinHeight : function( height, bAutoKnow ){
		this.state.bMinSet = true;
		
		if( height ){
			this.aTabs.each( function( tabEl ){
				this.layout.pull.setStyle( 'min-height', height + 'px');
			}, this );
		}
		
		if( bAutoKnow ){		
			this.setMinHeight( this.getMaxHeight(), false );
		}
	},
	
	tabEvent : function( ev, key ){
		var e = new Event( ev );
		
		this.tabActivation( key );
		this.activationAdjustment();
	},
		
	activationAdjustment : function(){
		if( !this.state.bMinSet ){
			this.layout.pull.setStyle( 'min-height', this.layout.pane.getStyle('height') );
		}
	}
});

var VerticalTabMan = BaseTabMan.extend({
	initialize : function( settings, parentDiv ){
		this.state = { 'bMinSet' : false };
		
		this.parent( settings, parentDiv, GLayout.verticalTab() );
	},

	setMinHeight : function( height, bAutoKnow ){
		this.state.bMinSet = true;
		
		if( height ){
			this.aTabs.each( function( tabEl ){
				//tabEl.pane.setStyle( 'min-height', height + 'px');
				tabEl.pane.setStyle( 'height', height + 'px');
			}, this );
		}
		
		if( bAutoKnow ){
			this.setMinHeight( this.getMaxHeight(), false );
		}
	},
	
	tabEvent : function( ev, key ){
		var e = new Event( ev );
		
		this.tabActivation( key );
	}
});

