/*  zSelector: give flexibility to select tag. version 0.1
 *  no any "c" word. 2008, Taihwan Hah (duecorda@gmail.com)
 *
 *  I don't know shit about copyright or something.
 *	No limitation And No responsibility.
 *
 *	If you don't mind, Please, Don't remove my e-mail address for feedback.
 *
 *--------------------------------------------------------------------------*/


//
// DOWN ARROW IMAGE PATH
//
var DownArrow = "";

//
// utils
//
// from prototype
var invisibleDom = function(element) {
	var invisible = ( 
		element.style.display == "none" ||
		!element.style.display ||
		element.style.display.replace(/\s/g, '').length <= 0
	)

	return invisible;
}
var toggleDisplay = function(element) {
	var invisible = invisibleDom(element);

	if(invisible) element.style.display = "block";
	else element.style.display = "none";

	return invisible;
}
String.prototype.space_to_nbsp = function() {
	return this.replace(/\s+/g, "&nbsp;");
}

var CrossSelect = function(select) {
	this.obs_select = select;
	this.id = select.id || new Date().getTime();
	this.name = select.name;
	this.title = select.title;
	this.fit_on = false;

	this.dynamic_title = !/static_title/i.test(this.obs_select.className);

	this.options_count = 0;
	this.max_options = Number(/max_options_([0-9]+)/.exec(this.obs_select.className).last());

	this.createElements();
	this.generateOptions(this.obs_select);
	this.finalize();
};

CrossSelect.prototype.createElements = function() {
	this.select = document.createElement("div");
	this.select.id = this.id + "_z_select";
	this.select.className = "z_select " + this.obs_select.className;

	OnEvent.add(this.select, "click", BindEvent(this, function(ev) {
		if(!this.fit_on) {
			var _xy = $(this.select).positionedOffset();
			this.opt_container.style.top = _xy[1] + this.select.offsetHeight - 1 + "px";
			this.opt_container.style.left = _xy[0] + "px";
		}
		var container = document.getElementById(this.select.id.replace(/_z_select$/, '') + "_opt_container");
		if(container) var visible = toggleDisplay(container);
	}), "select_actions")

	this.title_container = document.createElement("div");
	this.title_container.className = "title_container";
	this.select.appendChild(this.title_container);

	this.select_display = document.createElement("span");
	this.select_display.id = this.id + "_select_display";
	this.select_display.className = "display";
	this.select_display.innerHTML = this.title || this.name;
	this.title_container.appendChild(this.select_display);

	this.select_icon = document.createElement("span");
	this.select_icon.className = "icon";
	this.select_icon.innerHTML = "&darr;";
	this.title_container.appendChild(this.select_icon);

	this.field = document.createElement("input");
	this.field.type = "hidden";
	this.field.id = this.id;
	this.field.name = this.name;
	this.field.cb = this.obs_select.onchange;
	this.field.value = this.obs_select.value;
	this.title_container.appendChild(this.field);

	this.opt_container = document.createElement("div");
	this.opt_container.id = this.id + "_opt_container";
	this.opt_container.className = "opt_container fragile do_hide";
	this.opt_container.style.width = (this.obs_select.clientWidth) + "px";
};

CrossSelect.prototype.generateOptions = function(stack_node, particular_container) {
	for(var i=0; i<stack_node.childNodes.length; i++) {
		if(stack_node.childNodes[i].nodeType != 1) continue;
		++this.options_count;

		var obs_option = stack_node.childNodes[i];
		var __selected = obs_option.selected;
		if(__selected && this.dynamic_title) this.select_display.innerHTML = obs_option.innerHTML;

		if(/optgroup/i.test(obs_option.tagName)) {
			var optgroup = document.createElement("div");
			optgroup.className = "optgroup";
			optgroup.innerHTML = "<h5>" + obs_option.getAttribute("label").space_to_nbsp() + "</h5>";
			this.opt_container.appendChild(optgroup);
			this.generateOptions(obs_option, optgroup);
		} else if(/option/i.test(obs_option.tagName)) {
			var option = document.createElement("div");
			option.className = "option";
			option.setAttribute('longdesc', obs_option.value);
			if(this.image_select) option.innerHTML = "<img class='image_option' src='" + obs_option.innerHTML + "'>";
			else option.innerHTML = obs_option.innerHTML.space_to_nbsp();
			option.onmouseover = function() {
				this.style.backgroundColor = "#ff8";
			};
			option.onmouseout = function() {
				this.style.backgroundColor = "";
			};
			option.onclick = BindEvent(this, function(ev) {
				var refer = ev.target || ev.srcElement;
				if(!/div/i.test(refer.tagName) || !/option/.test(refer.className)) refer = $(refer).up(".option")
				this.field.value = refer.getAttribute("longdesc");
				if(this.dynamic_title) this.select_display.innerHTML = refer.innerHTML;
				if(this.field.cb) this.field.cb();
			});

			if(particular_container) particular_container.appendChild(option);
			else this.opt_container.appendChild(option);
		}
	}
};

CrossSelect.prototype.finalize = function() {
	this.select.appendChild(this.opt_container);
	this.obs_select.parentNode.insertBefore(this.select, this.obs_select);

	this.obs_select.parentNode.removeChild(this.obs_select);
	this.obs_select.style.display = "none";

	// set height if need
	if(this.max_options && this.options_count <= this.max_options) return;
	var _option_height = 25; // 16 + 1 + 8 == height + border-bottom + padding(bottom and top)
	this.opt_container.style.height = (_option_height * this.max_options) + "px";
	this.opt_container.style.overflowX = "hidden";
	this.opt_container.style.overflowY = "scroll";
};

//
// self initialize
// new function() {
	// var select = null;
	// while(select = document.getElementsByTagName("select")[0]) new CrossSelect(select);
// };
