/******************************* siemens' new web appearance script *****/
/******************************* Copyright (c) 2007-2008 Siemens AG *****/
/************************************************************************/
/************************************************ module gui select *****/
/************************************************************************/
/*************************************** author virtual identity AG *****/
/* $LastChangedDate: 2008-08-29 11:17:32 +0200 (Fr, 29 Aug 2008) $ *****/

/********************************************************************/
/* START: functional initalisation                                  */

function init_guiSelect(transformer) {

	if(Info.browser.isIEpre6) {
		// add onchange handler and abandon initialization
		var selects = document.getElementById('content-zone').getElementsByTagName("select");
		for (var i = 0, l = selects.length; i < l; ++i) {
			var select = selects[i];
			if (select.className.match(/\bgui-select\b/)) {
				select.onchange = function() {
					this.parentNode.parentNode.submit();
				}
			}
		}
		return;
	}
	
	var sliderCounter = 0;

	transformer = transformer || GuiSelect_DefaultTransformer;
	
	$A($("content-zone").getElementsByTagName("select")).each(
		function(select) {
			select = $(select);
			if (select.hasClassName("gui-select")) {

				// build html

				var options         = $A(select.getElementsByTagName("option"));
				var index           = select.selectedIndex;
				var titleClassNames = (index) ? "title selected-title" : "title";
				var text            = transformer.replaceTitle(options[index].text);
				var id              = select.id;

				var _html = '<div id="' + id + '" class="gui-select"><p class="' + titleClassNames + '"><a href="#">' + text + '</a></p>'
					+ '<input type="hidden" name="' + select.name + '" value="' + select.value + '" />'
					+ '<div class="content"><ul>';
				options.each(
					function(option) {
						if (option.selected) return; // the selected element should not be in the list
						var text = transformer.replaceOption(option.innerHTML);
						_html += '<li><span class="value">' + option.value + '</span><a href="#">' + text + '</a></li>';
					}
				);
				_html += "</ul></div></div>";

				// replace html select element with new gui select element

				var wrapper = select.parentNode;
				Element.remove(select);
				wrapper.innerHTML += _html;
				
				// optimised for IE6 and siemens search
				
				var div        = $(id);
				var form       = $(div.parentNode.parentNode);
				var input      = $(div.childNodes[1]);
				var contentDiv = $(div.childNodes[2]);
				var linkList   = $(contentDiv.firstChild);
				var links      = $A(contentDiv.getElementsByTagName("a"));
				var titleLink  = $(div.firstChild.firstChild);
				
				// init layer logic

				var layer   = new GuiSelectLayer(contentDiv);
				
				titleLink.observe("focus", function() {
					layer.open();
				});
				titleLink.observe("click", function(e) {
					if (layer._state == "open") {
						layer.close();
					} else if (layer._state == "closed") {
						layer.open();
					}
					Event.stop(e);
				});
				
				// add events to links to submit form with selected value

				links.each(function(a) {
					a = $(a);
					
					a.observe('focus', function(e) {
						if (layer != Layer.current) {
							layer.open();
							if (layer.scrollbar) {
								layer.scrollbar.scrollIntoView(a.up("li"));
							}
						}
					}.bind(a));

					a.observe('click', function(e) {
						input.value = this.previous("span.value").innerHTML;
						form.submit();
						Event.stop(e);
					}.bind(a));

					// show nicer link on status bar:
					a.href = "?" + input.name + "=" + encodeURIComponent(a.previousSibling.innerHTML);
				});
				
				// add scrollbar, if necessary

				if (linkList.getHeight() <= contentDiv.getHeight()) { // no slider needed

					contentDiv.style.height = "auto"; // for IE6

				} else {

					sliderCounter++;

					/// add slider gui elements

					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);

					// init scrollbar and add scrollbar object to layer

					layer.scrollbar = new GuiScrollbar("handle" + sliderCounter, "slider" + sliderCounter, layer);

					// add click events

					var elts = $(sliderWrapper).childElements();

					elts[0].observe("click", function() {
						layer.scrollbar.moveUp();
					});
					elts[2].observe("click", function() {
						layer.scrollbar.moveDown();
					});

					// add other evens

					var handler = (Info.browser.isIE) ? "activate" : "focus";

					links.each(function(a) {
						$(a).observe(handler, function(e) {
							layer.scrollbar.scrollIntoView($(this).up("li"));
						}.bind(a));
					});

				}
				
			}
		}
	);

	// init mousewheel

	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 = node.firstChild;
	},

	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 (this.scrollbar) {
			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.firstChild).getHeight();
		this.maxScroll    = this.innerHeight - this.outerHeight;
		this.itemHeight   = $(layer.node.firstChild.firstChild).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                                             */
/********************************************************************/
