/**
 * @author nick (tweaked by nico)
 */
var DropDown = Class.create( {
	sub_items		:[],						/* dropdown is built off this list */
	sub_container	:undefined,					/* id of the container holding the sub nav */
	closed			:true,						/* should the nav be closed */
	bfx				:null,						/* bound function handles clicks on page */
	sub_selected	:undefined,					/* current selection */
	trigger			:null,						/* trigger element to fire the dropdown */
	container_class	:undefined,
	over_class		:'drop-option-over',
	on_class		:'drop-option-on',
	last_class		:'drop-option-last',
	check_class_on	:'checkbox-on',
	check_class_off	:'checkbox-off',
	check_class_half:'checkbox-half',
	boxy_style		:false,						/* nice rounded .png corners */
	left			:-15,
	top				:-10,
	top_anchor		:true,
	use_values		:false,						/* whether to use the values passes or the text, when filling the bound form field */
	use_checks		:false,						/* whether to use checkboxes */
	show_label		:false,						/* show header label (boxy only) */
	label_item_out	:null,						/* outer linked label object (label updates with selected value) */
	label_item		:null,						/* innner top label object */
	note_label		:false,						/* show header note (boxy only) */
	note_item_out	:null,						/* outer linked note object (note is static) */
	note_item		:null,						/* innner top note object */
	on_select_change:null,						/* event to be fired when selection changes */
	on_get_check_state:null,					/* event to be fired to retrieve check state of each item on dropdown */
	initialize:function(trigger, sub_container, boxy_style, use_values, use_checks, label_item_out, note_item_out, on_select_change, on_get_check_state){
		this.trigger			= $(trigger);
		this.sub_container		= sub_container;
		this.boxy_style			= boxy_style;		//builds a curved edge box
		if (boxy_style) this.container_class = 'boxy';
		this.use_values			= use_values;
		this.use_checks			= use_checks;
		this.on_select_change	= on_select_change;
		this.on_get_check_state	= on_get_check_state;
		if (label_item_out) {
			this.show_label		 	 = true;
			this.label_item_out		 = $(label_item_out);
		}
		if (note_item_out) {
			this.show_note		 	 = true;
			this.note_item_out		 = $(note_item_out);
		}
		// binding
		this.bfx = this.check_state.bindAsEventListener(this);
	},
	add_items:function(orray)
	{
		this.sub_items = orray;
		this.build_dropdown();
	},
	build_dropdown:function()
	{
		// event handling
		if (this.trigger) {
			Event.observe(this.trigger,"mouseover",this.mouseover.bindAsEventListener(this));
			Event.observe(this.trigger,"mouseout",this.mouseout.bindAsEventListener(this));
			Event.observe(this.trigger,"click",this.showDrop.bindAsEventListener(this));
		}
		if (this.label_item_out) {
			Event.observe(this.label_item_out,"mouseover",this.mouseover.bindAsEventListener(this));
			Event.observe(this.label_item_out,"mouseout",this.mouseout.bindAsEventListener(this));
			Event.observe(this.label_item_out,"click",this.showDrop.bindAsEventListener(this));
		}
		if (this.note_item_out) {
			Event.observe(this.note_item_out,"mouseover",this.mouseover.bindAsEventListener(this));
			Event.observe(this.note_item_out,"mouseout",this.mouseout.bindAsEventListener(this));
			Event.observe(this.note_item_out,"click",this.showDrop.bindAsEventListener(this));
		}
		
		// build the container
		var containerOut = MyBuilder.make('div',{id:this.sub_container},this.container_class,null);
		
		if (this.boxy_style) {
			//build Boxy container (need to wrap in table due to IE6)
			var table = $(containerOut).appendChild(MyBuilder.make('table',{cellpadding:0,cellspacing:0,border:0},null,null));
			var tbody = $(table).appendChild(MyBuilder.make('tbody',null,null,null));
			var tr = $(tbody).appendChild(MyBuilder.make('tr',null,null,null));
			var td = $(tr).appendChild(MyBuilder.make('td',null,null,null));
			var hd = $(td).appendChild(MyBuilder.make('div',null,'hd',null));
			$(hd).appendChild(MyBuilder.make('div',null,'c',null));
			var bd = $(td).appendChild(MyBuilder.make('div',null,'bd',null));
			var c = $(bd).appendChild(MyBuilder.make('div',null,'c',null));
			var s = $(c).appendChild(MyBuilder.make('div',null,'s',null));
			var ft = $(td).appendChild(MyBuilder.make('div',null,'ft',null));
			$(ft).appendChild(MyBuilder.make('div',null,'c',null));
			if (this.show_label) {	//show label in dropdown
				this.label_item = $(s).appendChild(MyBuilder.make('div',null,'boxyLabel',null));
			}
			if (this.show_note) {	//show note in dropdown
				this.note_item = $(s).appendChild(MyBuilder.make('div',null,'boxyNote',this.note_item_out.innerHTML));
			}
			var container = $(s).appendChild(MyBuilder.make('ol',null,null,null));
			
		} else {
			var container = $(containerOut).appendChild(MyBuilder.make('ol',null,null,null));
		}
		
		//always auto select first item if we have a label
		if (this.show_label) {
			var selected_id = -1
			for (var i=0; i<this.sub_items.length; i++) {
				if (this.sub_items[i][2]) selected_id = i;
			}
			if (selected_id == -1 && this.sub_items[0]) {
				this.sub_items[0][2] = true;
			}
		}
		
		// add the items
		var item;
		for (var i=0; i<this.sub_items.length; i++) {
		
			//Update labels with initial selected value
			if (this.show_label) {
				if (this.sub_items[i][2] && this.label_item)
					this.label_item.innerHTML = this.sub_items[i][0];
				if (this.sub_items[i][2] && this.label_item_out)
					this.label_item_out.innerHTML = this.sub_items[i][0];
			}
			
			//Add option and convert array into objs
			if (this.use_checks) {
				//Add checkboxes
				var strCheck = this.sub_items[i][2] ? ( (this.sub_items[i][2] == 2) ? this.check_class_half : this.check_class_on) : this.check_class_off;
				var strTxt = this.sub_items[i][0];
				this.sub_items[i] = $(container).appendChild(MyBuilder.make('li', {id:this.sub_container+'_'+i,dropvalue:this.sub_items[i][1]}, 'dropdown-option', null));
				$(this.sub_items[i]).appendChild(MyBuilder.make('div',null,strCheck,null));
				$(this.sub_items[i]).appendChild(MyBuilder.make('span',null,null,strTxt));
			} else {
				this.sub_items[i] = $(container).appendChild(MyBuilder.make('li', {id:this.sub_container+'_'+i,dropvalue:this.sub_items[i][1]}, 'dropdown-option' + (this.sub_items[i][2] ? ' ' + this.on_class : ''), this.sub_items[i][0]));
			}
			
			// event handlers
			item = $(this.sub_items[i]);
			Event.observe(item, 'click', this.subitem_select.bindAsEventListener(this));
			Event.observe(item, 'mouseover', this.subitem_over.bindAsEventListener(this,item));
			Event.observe(item, 'mouseout', this.subitem_out.bindAsEventListener(this,item));
		}
		if (item) item.addClassName(this.last_class);	//modify last item class
		// add the dropdown to the body
		var b = document.getElementsByTagName("body").item(0);
		b.appendChild(containerOut);
		Position.absolutize($(containerOut));
		// find the position
		this.position();
		this.hideDrop();
	},
	position:function()
	{
		var firer;
		if (this.label_item_out) {
			firer = this.label_item_out;
		} else if (this.note_item_out) {
			firer = this.note_item_out;
		} else {
			firer = this.trigger;
		}
		pos 	= Position.cumulativeOffset(firer);
		dim 	= firer.getDimensions();
		var left	= pos[0] + this.left;
		var top	 	= pos[1] + this.top + (this.top_anchor ? 0 : dim.height);
		$(this.sub_container).setStyle({left:left+'px',top:top+'px'});
	},
	check_state:function(e)
	{
		// For clicking anywhere to close it... make sure the button clicked isn't the options drop down
		if(Event.element(e)==this.trigger){return;}
		this.toggle();
	},
	toggle:function()
	{
		if(!this.closed) {
			this.showDrop();
		} else {
			this.hideDrop();
		}
	},
	showDrop:function()
	{
		// clicking anywhere else on the page will toggle the drop down
		Event.observe(document,"mousedown",this.bfx);
		this.position();
		$(this.sub_container).setStyle({visibility:'visible'});	//always need to
		this.closed = true;
		
		//fire callback to get checkbox values and update, either 0, 1, or 2
		if (this.use_checks && this.on_get_check_state) {
			for (var i=0; i<this.sub_items.length; i++) {
				var checkval = this.on_get_check_state(this.sub_items[i].down('span').innerHTML, this.sub_items[i].readAttribute('dropvalue'));
				
				this.sub_items[i].down('div').removeClassName(this.check_class_on);
				this.sub_items[i].down('div').removeClassName(this.check_class_half);
				this.sub_items[i].down('div').removeClassName(this.check_class_off);
				if (checkval == 2) {
					this.sub_items[i].down('div').addClassName(this.check_class_half);
				} else if (checkval) {
					this.sub_items[i].down('div').addClassName(this.check_class_on);
				} else {
					this.sub_items[i].down('div').addClassName(this.check_class_off);
				}
			}
		}
	},
	hideDrop:function()
	{
		// remove the mousedown observer
		Event.stopObserving(document,"mousedown",this.bfx);
		$(this.sub_container).setStyle({visibility:'hidden'});
		this.closed = false;
	},
	subitem_over:function()
	{
		this.sub_selected = $($A(arguments)[1]);
		this.sub_selected.addClassName(this.over_class);
		this.closed = false;
	},
	subitem_out:function()
	{
		this.sub_selected = $($A(arguments)[1]);
		this.sub_selected.removeClassName(this.over_class);
		this.closed = true;
	},
	subitem_select:function()
	{
		//set value
		var strValue;
		if (this.use_values) {
			strValue = this.sub_selected.readAttribute('dropvalue');
		} else {
			strValue = (this.use_checks ? this.sub_selected.down('span').innerHTML : this.sub_selected.innerHTML);
		}
		
		if (this.trigger) {
			this.trigger.value = strValue
		}
		
		//Update in-drop label
		if (this.label_item)
			this.label_item.innerHTML = this.sub_selected.innerHTML;
		//Update out-drop label
		if (this.label_item_out)
			this.label_item_out.innerHTML = this.sub_selected.innerHTML;

		var state = true;	//track item state (always true for non-checkbox dropdowns)

		//Update item state
		if (this.use_checks) {
			if (this.sub_selected.down('div').hasClassName(this.check_class_on)) {
				this.sub_selected.down('div').removeClassName(this.check_class_on);
				this.sub_selected.down('div').addClassName(this.check_class_off);
				state = false;
			} else {
				this.sub_selected.down('div').removeClassName(this.check_class_half);
				this.sub_selected.down('div').removeClassName(this.check_class_off);
				this.sub_selected.down('div').addClassName(this.check_class_on);
			}
		} else {
			for(var i=0; i<this.sub_items.length; i++) {
				$(this.sub_items[i]).removeClassName(this.on_class);
			}
			this.sub_selected.addClassName(this.on_class);
		}
		
		this.toggle();
		//fire callback
		if (this.on_select_change) {
			this.on_select_change((this.use_checks ? this.sub_selected.down('span').innerHTML : this.sub_selected.innerHTML), strValue, state);
		}
	},
	mouseout:function(e){ Event.element(e).setStyle({cursor:''});},
	mouseover:function(e){ Event.element(e).setStyle({cursor:'pointer'});}
});


