var Dropdown = function()
{
	var EventColl = [];
	var counter = 0;

	function Dropdown()
	{
		var self = this;

		this.addEvent = function(oElement, handler, callback, capture)
		{
			if (oElement.addEventListener)
			{
			    oElement.addEventListener(handler, callback, capture);
			}
			else if(oElement.attachEvent)
			{
				var prop = [handler, callback].join("");
				if (oElement[prop]) return;

				if (!EventColl[oElement._eventid])
				{
					oElement._eventid = counter++;
					EventColl[oElement._eventid] = {'oElement' : oElement};
				}
				EventColl[oElement._eventid][prop] = [handler, callback];

				oElement[prop] = function()
				{
					callback.call(oElement, event);
				}
				oElement.attachEvent('on' + handler, oElement[prop]);
			}
		}

		this.removeEvent = function(oElement, handler, callback, capture)
		{
			if (oElement.removeEventListener)
			{
				oElement.removeEventListener(handler, callback, capture);
			}
			else if (oElement.detachEvent)
			{
				var prop = [handler, callback].join("");
				if (oElement[prop])
				{
					oElement.detachEvent('on' + handler, oElement[prop]);
					oElement[prop] = null;
					EventColl[oElement._eventid][prop] = null;
				}
			}
		}

		function breakEventLeak()
		{
			var curr = null;
			var j = null;
			for (var i = 0, len = EventColl.length; i < len; i++)
			{
				curr = EventColl[i];
				for (j in curr)
				{
					if (j != 'oElement')
					{
						self.removeEvent(curr.oElement, curr[j][0], curr[j][1]);
					}
				}
				curr.oElement._eventid = null;
			}
			EventColl = null;
			counter = null;
		}
		//if (window.attachEvent) window.attachEvent('onunload', breakEventLeak);
	}
	return new Dropdown();
}();

Dropdown.preventDefault = function(event)
{
	event.returnValue = false;
	if (event.preventDefault)
	{
		event.preventDefault();
	}
}

Dropdown.stopPropagation = function(event)
{
	if (event.stopPropagation)
	{
		event.stopPropagation();
		return;
	}
	//event.cancelBubble = true;
}

/*
	- Implements optgroup
	- Implements remove Option
	- Implements parse html select
	-Fix selected for IE
	-Implements disabled select
*/


function getOffsetElement(element)
{
	var top = 0;
	var left = 0;

	while(element)
	{
		top += element.offsetTop;
		left += element.offsetLeft;
		element = element.offsetParent;
	}

	var offset = [left, top];
	return offset;
}

function OptionItem(properties)
{
	var option = document.createElement('option');
	for (var i in properties)
	{
		option[i] = properties[i];
	}

	return option;
}

var ComboBox = function()
{
	var instance = false;
	var instance_coll = [];

	function ComboBox(properties, html_select)
	{
		var custom_combo_box = document.createElement('div');

			properties.className == '' ? custom_combo_box.className = 'comboBox' : custom_combo_box.className = ' comboBox';

			if (properties.width) custom_combo_box.style.width = properties.width + 'px';
			if (properties.height) custom_combo_box.style.height = properties.height + 'px';
			custom_combo_box.innerHTML = '<span class="dd_arrow"></span><label></label>';

		var combo_box = html_select || document.createElement('select');
			combo_box.className = 'hidden_component';
			if (properties.name) combo_box.name = properties.name;
			if (properties.id) combo_box.id = properties.id;
			if (properties.onChange || html_select.onchange) combo_box.onchange_listener = html_select.onchange || properties.onChange;
			combo_box.custom_combo_box = custom_combo_box;
			custom_combo_box.select = combo_box;
		var curr_parent = combo_box;

		this.addOption = function(OptionItem)
		{
			if (window.addEventListener)
			{
				curr_parent.appendChild(OptionItem);
				return;
			}
			combo_box.add(OptionItem);
		}

		/*this.addOptgroup = function(label_text)
		{
			curr_parent = document.createElement('optgroup');
			curr_parent.label = label_text || '';
			combo_box.appendChild(curr_parent);
		}*/

		this.flushOptions = function()
		{
			combo_box.options.length = 0;
		}

		this.renderComboBox = function(parentCombo)
		{
			var parent_combobox = document.getElementById(parentCombo) || parentCombo;
			ComboBox.setUpdateText.call(combo_box, null, true);

			if (combo_box.addEventListener)
			{
				combo_box.addEventListener('keyup', combo_box.blur, false);
				combo_box.addEventListener('keyup', combo_box.focus, false);
			}

			Dropdown.addEvent(combo_box, 'change', ObserverDropDown.moveKeySelected, false);
			Dropdown.addEvent(combo_box, 'change', ComboBox.setUpdateText, false);
			Dropdown.addEvent(combo_box, 'keydown', ObserverDropDown.checkKey, false);
			Dropdown.addEvent(combo_box, 'focus', ComboBox.focus, false);
			Dropdown.addEvent(combo_box, 'blur', ComboBox.blur, false);

			parent_combobox.appendChild(combo_box);

			Dropdown.addEvent(custom_combo_box, 'click', ObserverDropDown.showDropDown, false);

			parent_combobox.appendChild(custom_combo_box);
		}

		if (!instance)
		{
			if (document.body)
			{
				ObserverDropDown.initDropDown();
			}
			else
			{
				Dropdown.addEvent(window, 'load', ObserverDropDown.initDropDown, false);
			}

			instance = true;
		}

		if (!window.XMLHttpRequest)
		{
			instance_coll[instance_coll.length] = custom_combo_box;
		}

	}

	/*Prevent memory leak in IE6*/
	if (!window.XMLHttpRequest)
	{
		window.attachEvent('onunload', function()
		{
			for (var i = 0, len = instance_coll.length; i < len; i++)
			{
				instance_coll[i].select.custom_combo_box = null;
				instance_coll[i].select = null;
			}
		});
	}

	return ComboBox;
}();

ComboBox.setUpdateText = function(event, onchange_flag)
{
	if (this.selectedIndex >= 0)
	{
		var option = this.options[this.selectedIndex];
		this.custom_combo_box.getElementsByTagName('label')[0].innerHTML =
		(option.title ? '<img src="' + option.title + '" alt="" />' : '') + option.text;
		if (!onchange_flag && this.onchange_listener instanceof Function)
		{
			this.onchange_listener(this);
		}
	}
}

ComboBox.setSelectedIndex = function(index)
{
	if (index >= 0)
	{
		this.selectedIndex = index;
		ComboBox.setUpdateText.call(this);
	}
}

ComboBox.focus = function() {
    this.custom_combo_box.getElementsByTagName('label')[0].className = 'combo_box_focus'
}

ComboBox.blur = function()
{
	this.custom_combo_box.getElementsByTagName('label')[0].className = '';
}

var ObserverDropDown = function() {
    function ObserverDropDown() {
        var drop_down_id = 'dropDownComboBox';
        var selected_class_name = 'selectedIndex';

        var drop_down = null;
        var curr_combo_box = null;
        var default_selected_index = null;
        var old_selected_index = null;
        var self = this;

        this.initDropDown = function() {
            drop_down = document.createElement('div');
            drop_down.id = drop_down_id;
            var drop_down_style = drop_down.style;
            drop_down_style.position = 'absolute';
            drop_down_style.zIndex = '388';
            drop_down_style.display = 'none';

            Dropdown.addEvent(drop_down, 'scroll', self.focusSelect, false);

            document.body.appendChild(drop_down);
        }

        this.showDropDown = function(event) {
            var scroll = document.documentElement.scrollTop;
            if (typeof scroll != 'undefined') {
                this.select.style.top = scroll + 'px';
            }

//            this.select.focus();  //bug in FF when the select is focussed and one of the parent element is position="relative"
            if (this != curr_combo_box) {
                curr_combo_box = this;
                default_selected_index = old_selected_index = curr_combo_box.select.selectedIndex;
                positionResizeDropDown();
                renderOptions();
                $j(drop_down).fadeIn(400,function(){
					drop_down.scrollTop = getSelectedOffset();
					Dropdown.stopPropagation(event);
					Dropdown.addEvent(document, 'click', self.hideDropDown, false);
					Dropdown.addEvent(window, 'resize', self.hideDropDown, false);
				});
            }


        }

        this.hideDropDown = function(event) {
            $j(drop_down).fadeOut(400,function(){
				if (curr_combo_box) {
					if (curr_combo_box.select.selectedIndex != default_selected_index) {
						curr_combo_box.select.selectedIndex = default_selected_index;
					}
	//                curr_combo_box.select.focus();    //bug in FF when the select is focussed and one of the parent element is position="relative"
					curr_combo_box = null;
					Dropdown.removeEvent(document, 'click', self.hideDropDown, false);
					Dropdown.removeEvent(window, 'resize', self.hideDropDown, false);
				}
			});
        }

        this.moveSelected = function(index) {
            if (index != old_selected_index) {
                var obj = drop_down.getElementsByTagName('label');
                obj[old_selected_index].className = obj[old_selected_index].className.replace(selected_class_name, '');
                obj[index].className += ' '+selected_class_name;
                curr_combo_box.select.selectedIndex = old_selected_index = index;
            }
        }

        this.moveKeySelected = function() {
            if (curr_combo_box) {
                default_selected_index = curr_combo_box.select.selectedIndex;
                self.moveSelected(default_selected_index);
                drop_down.scrollTop = getSelectedOffset();
            }
        }

        this.setSelectedIndex = function(index) {
            default_selected_index = index;
            ComboBox.setSelectedIndex.call(curr_combo_box.select, index);
        }

        this.checkKey = function(event) {
            var code = event.keyCode;
            if (curr_combo_box && (code == 9 || code == 13)) {
                self.hideDropDown();
            }
        }

        this.focusSelect = function() {
//            curr_combo_box.select.focus();
        }

        function positionResizeDropDown() {
            var pos = getOffsetElement(curr_combo_box);
            drop_down.style.left = pos[0] + 'px';
            drop_down.style.top = pos[1] + curr_combo_box.offsetHeight - 3 + 'px';
            drop_down.style.width = curr_combo_box.clientWidth - 8 + 'px';
        }

        function getSelectedOffset() {
            if (default_selected_index > -1) {
                var obj = drop_down.getElementsByTagName('label')[curr_combo_box.select.selectedIndex];
                var scroll = drop_down.scrollTop;
                var obj_top = obj.offsetTop;
                var obj_height = obj.offsetHeight;

                if (obj_top < scroll) {
                    return obj_top;
                }

                if (obj_top > scroll + drop_down.offsetHeight - obj_height) {
                    return obj_top - (drop_down.offsetHeight - obj_height);
                }
                return scroll;
            }
        }

        function renderOptions() {
            var index = -1;
            var option = null;
			var testClassName = 'odd';
            function replaceOption(match) {
                index++;
                option = curr_combo_box.select.options[index];
				if (index % 2 == 0){
					testClassName = 'odd';
				}else{
					testClassName = 'even';
				}
				return '<label class="'+ testClassName +'" onmouse' + (window.ActiveXObject ? 'over' : 'move') + '=ObserverDropDown.moveSelected(' + index + ') onclick=ObserverDropDown.setSelectedIndex(' + index + ')>' +
				(option.title ? '<img src="' + option.title + '" alt="" />' : '');
            }

            var html_code = curr_combo_box.select.innerHTML;
            html_code = html_code.replace(/<option[^>]*>/ig, replaceOption);
            html_code = html_code.replace(/<\/option/ig, '</label');
            drop_down.innerHTML = html_code;
            if (index > -1) {
                drop_down.getElementsByTagName('label')[curr_combo_box.select.selectedIndex].className += ' '+selected_class_name;
            }

        }

    }

    return new ObserverDropDown();
} ();

function Checkbox(name, value, checked, id)
{
	this.button = null;
	this.button_flag = false;
	if (arguments.length > 1)
	{
		this.initializedComponent();
		this.button.className = 'hidden_component';
		this.button.name = name;
		this.button.value = value;
		this.button.id = id;
		this.checked = checked;
		this.button.defaultChecked = checked;
	}
	if (arguments[0])
	{
		this.button = arguments[0];
		this.button.className = 'hidden_component';
		this.checked = this.button.checked;
		this.button_flag = true;
	}
	if (arguments.length)
	{
		this.custom_button = document.createElement('span');
		this.custom_button.par_button = this.button;
		this.custom_button.className = 'checkbox' + (this.checked ? ' ch_checked' : '');
		this.custom_button.onclick = function(){this.par_button.click();};

		this.button.custom_button = this.custom_button;
		this.changeCheckedListener();
	}
}

Checkbox.prototype.changeCheckedListener = function()
{
	this.button.onclick = function()
	{
		this.custom_button.className = 'checkbox' + (this.checked ? ' ch_checked' : '');
	}
}

Checkbox.prototype.writeComponent = function(id_element)
{
	var obj = document.getElementById(id_element) || id_element;
	if (!this.button_flag) obj.appendChild(this.button);
	obj.insertBefore(this.custom_button, this.button);
}

Checkbox.prototype.initializedComponent = function()
{
	this.button = document.createElement('input');
	this.button.type = 'checkbox';
}

var radio_button_reference = [];
function changeRadioButtonChecked(sender)
{
	if (radio_button_reference[sender.name])
	{
		radio_button_reference[sender.name].custom_button.className = 'radio';
		radio_button_reference[sender.name].checked = false;
		radio_button_reference[sender.name].defaultChecked = false;
	}

	sender.checked = sender.defaultChecked = true;
	sender.custom_button.className = 'radio r_checked';
	radio_button_reference[sender.name] = sender;
}

RadioButton.prototype = new Checkbox;
RadioButton.constructor = RadioButton;

function RadioButton(name, value, checked, id)
{
	Checkbox.call(this, name, value, checked, id);
	this.custom_button.className = 'radio';
	if (this.checked)
	{
		changeRadioButtonChecked(this.button);
	}
}

RadioButton.prototype.changeCheckedListener = function()
{
	this.button.onclick = function()
	{
		changeRadioButtonChecked(this);
	}
}

RadioButton.prototype.initializedComponent = function()
{
	this.button = document.createElement((!window.ActiveXObject ? 'input' : '<input type="radio">'));
	this.button.type = 'radio';
}
/*end radio button and checkbox*/


function parseFormElements(layout)
{
    if (layout.type) layout = document;
    var obj = layout.getElementsByTagName('select');
	var felem = null;
	var combo_box = null;
	for (var i = 0, len = obj.length; i < len; i++)
	{
		if (!obj[i].multiple)
		{
			var test_select = document.getElementById('test_select');
			combo_box = new ComboBox({'className' : obj[i].className}, obj[i]);
			combo_box.renderComboBox(obj[i].parentNode);
		}
	}

	obj = document.getElementsByTagName('input');
	for (var i = 0, len = obj.length; i < len; i++)
	{
		if (obj[i].type.toLowerCase() == 'radio')
		{
			new RadioButton(obj[i]).writeComponent(obj[i].parentNode);
		}
		if (obj[i].type.toLowerCase() == 'checkbox')
		{
			new Checkbox(obj[i]).writeComponent(obj[i].parentNode);
		}
	}
}
Dropdown.addEvent(window, 'load', function(){ parseFormElements( document.getElementById('content') ); }, false);
