var WebElements;

if(!WebElements) WebElements = {};

WebElements.ComboDropDownBox = function(element, panels, switches, options) {
	
	this.element = element;
	
	this.name = "combodropdownbox";
	this.state = 1;							// indicating the state of the box (closed = 0 | opened = 1)
	this.current = 0;						// index of the currently opened box-panel 
	this.classname_opened = "opened";		// classname that will be inserted into the element if the box is opened
	this.classname_closed = "closed";		// classname that will be inserted into the element if the box is closed
	this.use_cookies = true;				// cookies will be used to store state and selected panel
	this.cookie_path = "";					// path of the cookie
	
	this.panels = panels;					// array that holds the different panels (has to be given as parameter)
	this.switches = switches;				// array that holds the switches for the different panels (has to be given as parameter)
	this.classnames = null;					// array with the classnames that will be inserted into the element if the corresponding panel is opened
	this.heights_opened = null;				// heights of the opened panels
	this.heights_closed = null;				// heights of the closed panels
	
	this.unit = "px";
	this.fade = "true";
	this.fps = 60;
	this.duration = 1000;
	this.form = "linear";
	this.callback = null;
	this.animator = null;
	
	this.setOptions(options);
	
	this.init();
	
	this.attachBehaviors();
}

WebElements.ComboDropDownBox.prototype.setOptions = function(options) {
	
	if(options) 
	{
		for(var optionname in options)
		{
			this[optionname] = options[optionname];
		}
		
		return true;
	}
	
	return false;
}

WebElements.ComboDropDownBox.prototype.init = function() {
	
	if(this.heights_opened == null)
	{
		this.heights_opened = new Array();
		
		for(var i = 0; i < this.panels.length; i++)
		{
			var height = this.panels[i].offsetHeight;
			
			this.heights_opened.push(height);
		}
	}
	
	if(this.heights_closed == null)
	{
		this.heights_closed = new Array();
		
		for(var i = 0; i < this.panels.length; i++)
		{
			this.heights_closed.push(0);
		}
	}
	
	if(this.classnames == null)
	{
		this.classnames = new Array();
		
		for(var i = 0; i < this.panels.length; i++)
		{
			this.classnames.push("");
		}
	}
	
	this.setState(this.getState());
	this.setCurrent(this.getCurrent());
	
	for(var i = 0; i < this.panels.length; i++)
	{
		//this.panels[i].style.position = "absolute";
		
		if(this.current != i || this.state == 0)
		{
			this.panels[i].style.overflow = "hidden";
			this.panels[i].style.height = this.heights_closed[i];
			
			if(this.current != i)
			{
				this.panels[i].style.display = "none";
			}
			
			if(this.fade)
			{
				this.panels[i].style.opacity = "0";
				this.panels[i].style.filter = "alpha(opacity=0)";
			}
		}
	}
}

WebElements.ComboDropDownBox.prototype.attachBehaviors = function() {
	
	for(var i = 0; i < this.switches.length; i++)
	{
		WebElements.Utils.addEventListener(this.switches[i], "click", this.createBehaviorFunction(this, i));
	}
}

// this function is needed to get the arguments for the ComboDropDownBox instance 
// and the current panel index into the event listener function
// defining these values in the loop in attachBehaviors() causes problems with the indicies of the panels
WebElements.ComboDropDownBox.prototype.createBehaviorFunction = function(element, index) {
	
	return function() { element.toggleBox(index); };
}

// opens the panel with the given index 'current'
WebElements.ComboDropDownBox.prototype.openBox = function(current) {
	
	if(!this.animator || !this.animator.running)
	{
		var self = this;
		
		// check if a different panel is opened
		if(this.state == 1 && this.current != current)
		{
			// if this is true close that panel and pass the index of the panel to be opened to the closeBox function
			// this will cause the closeBox function to call the openBox function for the new panel
			this.closeBox(this.current, current);
			
			// leave function here
			return true;
		}
		
		// create animator object with initial animation chain (empty),
		// defined frames per second and a callback function
		this.animator = new WebElements.Animator(new WebElements.AnimationChain(), this.fps, function() { self.changeState(); self.setCurrent(current); if(self.callback != null && typeof self.callback == "function") self.callback(); });
		
		// create animations to execute
		if(this.current != current)
		{
			// if the panel that should be opened now is not the active (current) panel
			// hide the previous panel and unhide the new panel
			var animation_01 = new WebElements.AnimationObject(this.panels[this.current], "display", "", "none", "", 0);
			var animation_02 = new WebElements.AnimationObject(this.panels[current], "display", "none", "", "", 0);
			
			this.animator.animation_chain.addAnimationGroup(new WebElements.AnimationGroup(new Array(animation_01, animation_02)));
		}
		var animation_1 = new WebElements.AnimationObject(this.panels[current], "height", this.heights_closed[current], this.heights_opened[current], this.unit, this.duration, null, this.form);
		var animation_2 = new WebElements.AnimationObject(this.panels[current], "opacity", 0, 1, "", this.duration, null, this.form);
		var animation_3 = new WebElements.AnimationObject(this.panels[current], "overflow", "hidden", "", "", 0);
		
		// all the animations have to be executed sequential
		// so create a group for each one and put them into
		// the animation chain
		if(this.fade)
		{
			this.animator.animation_chain.addAnimationGroup(new WebElements.AnimationGroup(new Array(animation_1, animation_2)));
		}
		else this.animator.animation_chain.addAnimationGroup(new WebElements.AnimationGroup(animation_1));
		
		this.animator.animation_chain.addAnimationGroup(new WebElements.AnimationGroup(animation_3));
		
		this.animator.start();
		
		return true;
	}
	
	return false;
}

// closes the panel with the given index 'current'
// if newcurrent is specified, it will automatically call 'openBox()' with 'newcurrent' as index
WebElements.ComboDropDownBox.prototype.closeBox = function(current, newcurrent) {
	
	if(!this.animator || !this.animator.running)
	{
		var self = this;
		
		// create animator object with initial animation chain (empty),
		// defined frames per second and a callback function
		this.animator = new WebElements.Animator(new WebElements.AnimationChain(), this.fps, function() { self.changeState(); if(self.callback != null && typeof self.callback == "function") self.callback(); });
		
		// if another panel has to be opened after the current one was closed, 
		// attach the openBox function for this panel as a callback to this animation
		if(newcurrent != null)
		{
			this.animator.addCallback(function() { self.openBox(newcurrent); })
		}
		
		// create animations to execute
		var animation_1 = new WebElements.AnimationObject(this.panels[current], "overflow", "", "hidden", "", 0);
		var animation_2 = new WebElements.AnimationObject(this.panels[current], "height", this.heights_opened[current], this.heights_closed[current], this.unit, this.duration, null, this.form);
		var animation_3 = new WebElements.AnimationObject(this.panels[current], "opacity", 1, 0, "", this.duration, null, this.form);
		
		// all the animations have to be executed sequential
		// so create a group for each one and put them into
		// the animation chain
		this.animator.animation_chain.addAnimationGroup(new WebElements.AnimationGroup(animation_1));
		this.animator.animation_chain.addAnimationGroup(new WebElements.AnimationGroup(animation_2));
		if(this.fade)
		{
			this.animator.animation_chain.getAnimationGroup(1).addAnimationObject(animation_3);
		}
		
		this.animator.start();
		
		return true;
	}
	
	return false;
}

WebElements.ComboDropDownBox.prototype.toggleBox = function(current) {
	
	if(this.state == 0) this.openBox(current);
	if(this.state == 1 && this.current == current) this.closeBox(current);
	if(this.state == 1 && this.current != current) this.openBox(current);
}

WebElements.ComboDropDownBox.prototype.changeState = function() {
	
	if(this.state == 1)
	{
		this.state = 0;
		this.element.className = this.element.className.replace((this.classname_opened), "") + " " + this.classname_closed;
	}
	else
	{
		this.state = 1;
		this.element.className = this.element.className.replace((this.classname_closed), "") + " " + this.classname_opened;
	}
	
	if(this.use_cookies) WebElements.Utils.setCookie(this.name + "_state", this.state, null, this.cookie_path);
}

WebElements.ComboDropDownBox.prototype.setState = function(state) {
	
	this.state = state;
	
	if(this.state == 1)
	{
		this.element.className = this.element.className.replace((this.classname_closed), "") + " " + this.classname_opened;
	}
	else
	{
		this.element.className = this.element.className.replace((this.classname_opened), "") + " " + this.classname_closed;
	}
	
	if(this.use_cookies) WebElements.Utils.setCookie(this.name + "_state", this.state, null, this.cookie_path);
}

WebElements.ComboDropDownBox.prototype.getState = function() {
	
	var state = null;
	
	if(this.use_cookies) state = WebElements.Utils.getCookie(this.name + "_state");
	
	if(state == null) state = this.state;
	
	return state;
}

WebElements.ComboDropDownBox.prototype.setCurrent = function(current) {
	
	// remove the classname from the previous panel
	this.element.className = this.element.className.replace((this.classnames[this.current]), "");
	
	// add the classname from the current panel and set the cookie
	this.current = current;
	
	this.element.className = this.element.className + " " + this.classnames[this.current];
	
	if(this.use_cookies) WebElements.Utils.setCookie(this.name + "_current", this.current, null, this.cookie_path);
}

WebElements.ComboDropDownBox.prototype.getCurrent = function() {
	
	var current = null;
	
	if(this.use_cookies) current = WebElements.Utils.getCookie(this.name + "_current");
	
	if(current == null) current = this.current;
	
	return current;
}
