var WebElements;

if(!WebElements) WebElements = {};

WebElements.DropDownBox = function(element, options) {
	
	this.element = element;
	
	this.name = "dropdownbox";
	this.state = 1;
	this.classname_opened = "opened";
	this.classname_closed = "closed";
	this.use_cookies = true;
	this.cookie_path = "";
	
	this.activator = null;
	this.reactor = null;
	
	this.height = null;
	this.height_opened = null;
	this.height_closed = null;
	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.DropDownBox.prototype.setOptions = function(options) {
	
	if(options) 
	{
		for(var optionname in options)
		{
			this[optionname] = options[optionname];
		}
		
		return true;
	}
	
	return false;
}

WebElements.DropDownBox.prototype.init = function() {
	
	if(this.activator == null)
	{
		this.activator = this.element.firstChild;
		
		// ensure that activator is an element node
		while(this.activator.nodeType != 1)
		{
			this.activator = this.activator.nextSibling;
		}
	}
	
	if(this.reactor == null)
	{
		this.reactor = this.activator.nextSibling;
		
		// ensure that reactor is an element node
		while(this.reactor.nodeType != 1)
		{
			this.reactor = this.reactor.nextSibling;
		}
	}
	
	this.height = this.reactor.offsetHeight;
	
	if(this.height_opened == null)
		this.height_opened = this.height;
		
	if(this.height_closed == null)
		this.height_closed = 0;
		
	this.setState(this.getState());
	
	if(this.state == 0)
	{
		this.reactor.style.overflow = "hidden";
		this.reactor.style.height = this.height_closed + this.unit;
		
		if(this.fade)
		{
			this.reactor.style.opacity = "0";
			this.reactor.style.filter = "alpha(opacity=0)";
		}
	}
	
	// this style will ensure, that elements inside the box will be cropped by the
	// drop down box, even if they are positioned absolute
	this.reactor.style.position = "relative";
}

WebElements.DropDownBox.prototype.attachBehaviors = function() {
	
	var self = this;
	
	WebElements.Utils.addEventListener(this.activator, "click", function(e) { self.toggleBox(); });
}

WebElements.DropDownBox.prototype.openBox = function() {
	
	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(); });
		
		// create animations to execute
		var animation_1 = new WebElements.AnimationObject(this.reactor, "height", this.height_closed, this.height_opened, this.unit, this.duration, null, this.form);
		var animation_2 = new WebElements.AnimationObject(this.reactor, "opacity", 0, 1, "", this.duration, null, this.form);
		var animation_3 = new WebElements.AnimationObject(this.reactor, "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
		this.animator.animation_chain.addAnimationGroup(new WebElements.AnimationGroup(animation_1));
		if(this.fade)
		{
			this.animator.animation_chain.getAnimationGroup(0).addAnimationObject(animation_2);
		}
		this.animator.animation_chain.addAnimationGroup(new WebElements.AnimationGroup(animation_3));
		
		this.animator.start();
		
		return true;
	}
	
	return false;
}

WebElements.DropDownBox.prototype.closeBox = function() {
	
	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(); });
		
		// create animations to execute
		var animation_1 = new WebElements.AnimationObject(this.reactor, "overflow", "", "hidden", "", 0);
		var animation_2 = new WebElements.AnimationObject(this.reactor, "height", this.height_opened, this.height_closed, this.unit, this.duration, null, this.form);
		var animation_3 = new WebElements.AnimationObject(this.reactor, "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.DropDownBox.prototype.toggleBox = function() {
	
	if(this.state == 0) this.openBox();
	if(this.state == 1) this.closeBox();
}

WebElements.DropDownBox.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.DropDownBox.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.DropDownBox.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;
}