/* START: functional initalisation                                  */
function init_guiSelect(transformer) {
	if(Info.browser.isIEpre7) return;

	var sliderCounter = 0;

	transformer = transformer || GuiSelect_DefaultTransformer;

	$A($("content-zone").getElementsByTagName("select")).each(
		function(select) {
			select = $(select);
			if (select.hasClassName("gui-select")) {
/*				
				var div = document.createElement("div");
				div.id = select.id;
				div.className = "gui-select";
*/
				var options         = $A(select.getElementsByTagName("option"));
				var index           = select.selectedIndex;
				var titleClassNames = "title"; //(index) ? "title selected-title" : "title";
				var _default        = transformer.replaceTitle(options[0].text);
				var _title          = '';
				var _value          = '';
				var _html = '<div class="content"><ul>';
				options.each(
					function(option, index) {
						if (index == 0) return; // the selected element should not be in the list
						var text = transformer.replaceOption(option.innerHTML).replace(/^- /,'');
						
						if(option.title.substr(0,5) == "child")
						{
							_html += '<li id="'+option.value+'" class="childunchecked '+(option.title.search(/selected/)!=-1?"childchecked":"")+'"><a href="#" id="'+text.unescapeHTML()+'">' + text + '</a></li>';
						}
						else
						{
							_html += '<li id="'+option.value+'" class="unchecked '+(option.title.search(/selected/)!=-1?"checked":"")+'"><a href="#" id="'+text.unescapeHTML()+'">' + text + '</a></li>';
						}
						
						if(option.title.search(/selected/)!=-1)
						{
						    _title += (_title.length>0?', ':'') + text.unescapeHTML();
						    _value += (_value.length>0?', ':'') + option.value;
						} 
					}
				);
				_html += "</ul></div>";
				_html = '<p class="' + titleClassNames + '"><a href="#">' + (_title.length>0?_title:_default) + '</a></p>'
				      + '<input type="hidden" class="division" name="' + select.name + '" value="' + _value + '" />'
				      + _html;
/*
				div.innerHTML = _html;
				select.parentNode.replaceChild(div, select);
				div = $(div);
*/


				var div = new Element('div', {id: select.id, 'class': 'gui-select'}).update(_html);
				
				select.up().appendChild(div);

				select.id = select.id+'_replaced';
				select.name = select.name+'_replaced';
				select.style.display = 'none';
				select.hide();


				var form        = div.up("form");
				var input       = div.down("input");
				var contentDiv  = div.down("div.content");
				var linkList    = div.down("ul");

				var layer   = new GuiSelectLayer(div.down("div"));
				var trigger = div.down("a");

				trigger.observe("focus", function() {
					layer.open();
				});
				trigger.observe("click", function(e) {
					if (layer._state == "open") {
						layer.close();
					} else if (layer._state == "closed") {
						layer.open();
					}
					Event.stop(e);
				});

				$A(linkList.getElementsByTagName("a")).each(function(a) {
					a = $(a);
					
					a.observe("click", function(e){
						
                        var clickMode = true;
						
						//Check/Uncheck List Element via Style
						if(this.up("li.unchecked"))
						{
						    var targetLi = this.up("li.unchecked");
						    targetLi.hasClassName("checked") ? targetLi.removeClassName("checked") : targetLi.addClassName("checked");
						    clickMode = targetLi.hasClassName("checked");
						}
						if(this.up("li.childunchecked"))
						{
						    var targetLi = this.up("li.childunchecked");
						    targetLi.hasClassName("childchecked") ? targetLi.removeClassName("childchecked") : targetLi.addClassName("childchecked");
						    clickMode = targetLi.hasClassName("childchecked");
						}
						
						//Get selected item and update title/value
						var clickedValue = this.up("li",0).id;
						var clickedTitle = this.innerHTML;
						
						targetValue = this.up("div",1).down("input.division");
						targetTitle = this.up("div",1).down(".title").down("a");

						if(clickMode)
						{	//Add Value					
						    if( targetTitle.innerHTML == _default.strip()) targetTitle.innerHTML = '';
						    targetValue.value += (targetValue.value.length>0?", ":"") + clickedValue;
						    targetTitle.innerHTML += (targetValue.value.length>0?", ":"") + clickedTitle;
						}
						else
						{   //Remove Value
							targetValue.value = targetValue.value.replace(clickedValue,'');
							targetTitle.innerHTML = targetTitle.innerHTML.replace(clickedTitle,'');
						}
						targetTitle.innerHTML = targetTitle.innerHTML.replace(/^, /, '').replace(/, $/, '').replace(/, , /, ', ');
						
						if(targetTitle.innerHTML == '')
						    targetTitle.innerHTML = _default.strip();
						
						Event.stop(e);
						});
					
					a.observe("focus", function(e) {
						if (layer != Layer.current) {
							layer.open();
							if (layer.scrollbar) {
								layer.scrollbar.scrollIntoView(a.up("li"));
							}
						}
						Event.stop(e);
					}.bind(a));
				});

				if (linkList.getHeight() <= contentDiv.getHeight()) { // no slider needed

					contentDiv.style.height = "auto"; // for IE6

				} else {

					sliderCounter++;

					var sliderWrapper = $(document.createElement("div"));
					sliderWrapper.className = "slider-wrapper";
					sliderWrapper.innerHTML = '<div class="arrow-up"></div><div class="slider" id="slider' + sliderCounter + '"><div class="handle" id="handle' + sliderCounter + '"></div></div><div class="arrow-down"></div>';
					contentDiv.appendChild(sliderWrapper);
					layer.scrollbar = new GuiScrollbar("handle" + sliderCounter, "slider" + sliderCounter, layer);
					var elts = sliderWrapper.childElements();
					elts[0].observe("click", function() {
						layer.scrollbar.moveUp();
					});
					elts[2].observe("click", function() {
						layer.scrollbar.moveDown();
					});
					var handler = (Info.browser.isIE) ? "activate" : "focus";

					$A(div.down("ul").getElementsByTagName("a")).each(function(a) {
						$(a).observe(handler, function(e) {
							layer.scrollbar.scrollIntoView($(this).up("li"));
						}.bind(a));
					});

				}
			}
		}
	);

	var wheel = new MouseWheelObserver;
	wheel.register(
		function(value) {
			if (Layer.current && Layer.current.onmousescroll && Layer.current.scrollbar) {
				return Layer.current.onmousescroll(value);
			} else {
				return true;
			}
		}
	);

}

/* END: functional initalisation                                    */
/********************************************************************/
/* START: default transformer class                                 */

GuiSelect_DefaultTransformer = {
	replaceOption: Prototype.K,
	replaceTitle:  Prototype.K
}

/* END: default transformer class                                   */
/********************************************************************/
/* START: layer subclass for gui.select                             */

var GuiSelectLayer = Class.create();

GuiSelectLayer.prototype = Object.extend(new Layer, {

	list: null,
	scrollbar: null,
	_state: "closed",

	initialize: function(node, trigger) {
		this.initSuper(node, trigger);
		this.list = this.node.down("ul");
	},

	afterClose: function() {
		this.node.up().removeClassName("active-gui-select");
		this._state = "closed";
	},

	afterOpen: function() {
		window.setTimeout(function() {
			this._state = "open";
		}.bind(this), 200);
	},

	beforeOpen: function() {
		this._state = "opening";
		this.node.up().addClassName("active-gui-select");
		if (this.scrollbar) {
			this.scrollbar.setValue(0);
		}
		return true;
	},

	hide: function() {
		this.node.removeClassName("active-content");
	},

	jumpTo: function(startsWith) {
		// not implemented
	},

	onkeypress: function(e) {
		var code = e.keyCode;

		if (Info.browser.isOpera) {
			return; // no key handling, since preventing default actions seems to be impossible in Opera
		}

		if (code == Event.KEY_UP) {
			this.scrollbar.moveUp();
			Event.stop(e); // stops browser scrolling
		} else if (code == Event.KEY_DOWN) {
			this.scrollbar.moveDown();
			Event.stop(e);
		} else if (code == Event.KEY_PAGEUP) {
			this.scrollbar.pageUp();
			Event.stop(e);
		} else if (code == Event.KEY_PAGEDOWN) {
			this.scrollbar.pageDown();
			Event.stop(e);
		} else if (code == Event.KEY_HOME) {
			this.scrollbar.pageHome();
			Event.stop(e);
		} else if (code == Event.KEY_END) {
			this.scrollbar.pageEnd();
			Event.stop(e);
		}

		var chr = String.fromCharCode(e.charCode);
		if (/[a-zA-Z0-9]/.test(chr)) {
			this.jumpTo(chr);
		}
	},

	onmousescroll: function(value) {
		if (value < 0) {
			this.scrollbar.moveUp();
		} else if (value > 0) {
			this.scrollbar.moveDown();
		}
		return false;
	},

	scrollTo: function(offsetTop) {
		this.list.style.top = offsetTop + "px";
	},

	show: function() {
		this.node.addClassName("active-content");
	}

});

/* END: layer subclass for gui.select                               */
/********************************************************************/
/* START: scrollbar class                                           */

var GuiScrollbar = Class.create();

GuiScrollbar.prototype = {

	initialize: function(handle, slider, layer) {

		this.outerHeight  = layer.node.getHeight();
		this.innerHeight  = layer.node.down("ul").getHeight();
		this.maxScroll    = this.innerHeight - this.outerHeight;
		this.itemHeight   = layer.node.down("li").getHeight();
		this.sliderHeight = $(slider).getHeight();

		$(handle).style.height = Math.round(this.sliderHeight * this.outerHeight / this.innerHeight) + "px";

		this.slider = new Control.Slider(handle, slider, {
			axis: 'vertical',
			range: $R(0, this.maxScroll),
			onSlide: function(value) {
				layer.scrollTo(-value);
			},
			onChange: function(value) {
				layer.scrollTo(-value);
			}
		});
	},

	moveDown: function() {
		this.setValue(this.slider.value + this.itemHeight);
	},

	moveUp: function() {
		this.setValue(this.slider.value - this.itemHeight);
	},

	pageDown: function() {
		this.setValue(this.slider.value + this.outerHeight);
	},

	pageEnd: function() {
		this.setValue(this.maxScroll);
	},

	pageHome: function() {
		this.setValue(0);
	},

	pageUp: function() {
		this.setValue(this.slider.value - this.outerHeight);
	},

	scrollIntoView: function(liNode) {
		var offset = liNode.offsetTop;
		var minValue = this.slider.value;
		var maxValue = minValue + this.outerHeight;
		if (offset + this.itemHeight > maxValue) {
			this.setValue(offset + this.itemHeight - this.outerHeight);
		} else if (offset < minValue) {
			this.setValue(offset);
		}
	},

	setValue: function(value) {
		this.slider.setValue(value);
	}

}

/* END: scrollbar class                                             */
/********************************************************************/
/* START: Transformer for selectbox replacing */

GuiSelect_SearchTransformer = {
	getMatches: function(text) {

		return /^(.+)\s(\([^)]+\))$/.exec(text);
	},

	replaceOption: function(text) {
		var matches = this.getMatches(text);
		return (matches) ? matches[1] + ' <span class="no">' + matches[2] + '</span>' : text;
	},

	replaceTitle: function(text) {
		var matches = this.getMatches(text);
		return (matches) ? matches[1] : text;
	}
}

/* END: Transformer for selectbox replacing */