/****************************** siemens' new web appearance script *****/
/****************************** Copyright (c) 2007-2009 Siemens AG *****/
/***********************************************************************/
/*********************************************** module gui select *****/
/***********************************************************************/
/************************************** author virtual identity AG *****/
/* $LastChangedDate: 2009-04-22 16:38:48 +0200 (Mi, 22 Apr 2009) $ *****/

/********************************************************************/
/* START: functional initalisation                                  */

function init_guiSelect(transformer, selector) {

	// register events for IE<6

	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;
	}
	
	// build and init gui select boxes
	
	GuiSelect.build($("content-zone").getElementsByTagName("select"), transformer, false, selector);

	// 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: GuiSelect class                                           */

var GuiSelect = Class.create();

GuiSelect.sliderCounter = 0;

GuiSelect.build = function(elements, transformer, openImmediately, selector) {
	transformer = transformer || GuiSelect.defaultTransformer;
	if(!selector) selector = "gui-select";

	$A(elements).filter(
		function(select) {
			return $(select).hasClassName(selector);
		}).each(
		function(select) {
			select = $(select);

			// build html

			var options        = $A(select.getElementsByTagName('option'));
			var index          = select.selectedIndex;
			var titleClassName = (index) ? 'title selected-title' : 'title';
			var text           = transformer.replaceTitle(options[index].text);
			var id             = select.id + '-gui';
			var className      = select.className;
			var wrappedText    = (select.disabled) ? '<span class="a">' + text + '</span>' : '<a href="#">' + text + '</a>';

			var _html = '<div id="' + id + '" class="' + className + '"><p class="' + titleClassName + '">' + wrappedText + '</p>'
				+ '<input type="hidden" name="' + select.name + '" value="' + select.value + '" />'
				+ '<div class="content">';
			
			if (!select.disabled) {
				var isFirst = true;
				_html += '<ul>';
				options.each(
					function(option) {
						var classes = [];
						if (isFirst) {
							classes.push('first-child');
						}
						if (option.selected) {
							classes.push('selected');
						}
						var classSnippet = (classes.length) ? ' class="' + classes.join(' ') + '"' : '';
						
						var text = transformer.replaceOption(option.innerHTML);
						_html += '<li' + classSnippet +'><span class="value '+option.className+'">' + option.value + '</span><a href="#">' + text + '</a></li>';
						isFirst = false;
					}
				);
				_html += '</ul>';
			}
			_html += '</div></div>';

			// replace html select element with new gui select element

			var wrapper = select.parentNode;
			Element.remove(select);
			wrapper.innerHTML += _html;
			
			if (select.disabled) {
				// if the select element is disabled, all is done
				return;
			}
			
			// init layer logic

			// optimized performance 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);
			
			var layer   = new GuiSelectLayer(contentDiv);
			
			// add events to title
//			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) {
					$(this.parentNode).addClassName('active');
					if (layer != Layer.current) {
						layer.open();
						if (layer.scrollbar) {
							layer.scrollbar.scrollIntoView(a.up('li'));
						}
					}
				}.bindAsEventListener(a));

				a.observe('blur', function(e) {
					$(this.parentNode).removeClassName('active');
				}.bindAsEventListener(a));
				
				a.observe('mouseover', function(e) {
					a.focus();
				}.bindAsEventListener(a));

				a.observe('mousemove', function(e) {
					a.focus();
				}.bindAsEventListener(a));

				a.observe('click', function(e) {
					if (this.up().hasClassName('selected')) {
						Layer.closeCurrent();
					} else {
						// if search filter gui select, submit form onchange
						if(this.up('#search-filter-zone'))
						{
							// set current selection to hidden field
							input.value = this.previous('span.value').innerHTML;
							form.submit();
						}
						else
						{
							// remove previously selected item class names
							this.up('ul').select('.selected').each(function(el){
								el.removeClassName('selected');
							});
							
							// add 'selected' class name to current selection
							this.up().addClassName('selected');
							
							// set current selection to hidden field
							input.value = this.previous('span.value').innerHTML;
							input.className = this.previous('span.value').className;
							
							// set current title tag
							this.up('div.gui-select').down('p.title a').innerHTML = this.innerHTML;
							Layer.closeCurrent();
							
							
						}
						
					}
					Event.stop(e);
				}.bindAsEventListener(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 {

				GuiSelect.sliderCounter++;
				
				linkList.addClassName('has-scrollbar');

				/// 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' + GuiSelect.sliderCounter + '"><div class="handle" id="handle' + GuiSelect.sliderCounter + '"></div></div><div class="arrow-down"></div>';
				contentDiv.appendChild(sliderWrapper);

				// init scrollbar and add scrollbar object to layer

				layer.scrollbar = new GuiScrollbar("handle" + GuiSelect.sliderCounter, "slider" + GuiSelect.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));
				});

			}
			
			// open immediately if option is true
			
			if (openImmediately) {
				layer.open();
			}
			
		}
	);	
}

GuiSelect.defaultTransformer = {
	replaceOption: Prototype.K,
	replaceTitle:  Prototype.K
}

/* END: GuiSelect 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.name = node.up().id.match(/^(filter-)?(.*)-gui$/)[2];
		this.initSuper(node, trigger);
		this.list = node.firstChild;
	},

	afterClose: function() {
		this.node.up().removeClassName("active-gui-select");
		this._state = "closed";

		var activeFilter = $('active-filter-'+this.name);
		if (typeof activeFilter !== 'undefined' && activeFilter !== null) {
			activeFilter.show();
			if($('active-filter-dropdown'))$('active-filter-dropdown').remove();
		}
	},

	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");
	},

	onkeydown: function(e) {
		var ITEMS_PER_PAGE = 9;

		if (Info.browser.isOpera) {
			// no key handling, since preventing default actions doesn't work with Opera
			// see: http://www.quirksmode.org/dom/events/keys.html
			return;
		}
		
		var activeListElement = this.getListElement();
		
		switch (e.keyCode) {
			case Event.KEY_UP:
				if (activeListElement && activeListElement.previous()) {
					this.setListElement(activeListElement.previous());
				}
				Event.stop(e);
				break;
				
			case Event.KEY_DOWN:
				if (activeListElement && activeListElement.next()) {
					this.setListElement(activeListElement.next());
				} else if (!activeListElement) {
					this.setListElement(this.node.select('ul li').first());
				}
				Event.stop(e);
				break;
			
			case Event.KEY_PAGEUP:
				if (activeListElement) {
					if (activeListElement.previous(ITEMS_PER_PAGE - 1)) {
						this.setListElement(activeListElement.previous(ITEMS_PER_PAGE - 1));
					} else {
						this.setListElement(this.node.select('ul li').first());
					}
				} else {
					this.setListElement(this.node.select('ul li').first());
				}
				Event.stop(e);
				break;
				
			case Event.KEY_PAGEDOWN:
				if (activeListElement) {
					if (activeListElement.next(ITEMS_PER_PAGE - 1)) {
						this.setListElement(activeListElement.next(ITEMS_PER_PAGE - 1));
					} else {
						this.setListElement(this.node.select('ul li').last());
					}
				} else {
					var length = this.node.select('ul li').length;
					this.setListElement(this.node.select('ul li')[Math.min(ITEMS_PER_PAGE, length)]);
				}
				Event.stop(e);
				break;

			case Event.KEY_HOME:
				this.setListElement(this.node.select('ul li').first());
				Event.stop(e);
				break;
				
			case Event.KEY_END:
				this.setListElement(this.node.select('ul li').last());
				Event.stop(e);
				break;
		}
	},

	getListElement: function() {
		var activeListElement = this.node.select('ul li.active');
		return activeListElement.length ? activeListElement[0]: null;
	},
	
	setListElement: function(newListElement) {
		if (newListElement) {
			$(newListElement).down('a').focus();
			if (this.scrollbar) {
				this.scrollbar.scrollIntoView(newListElement);
			}
		}
	},

	onmousescroll: function(value) {	
		var activeListElement = this.getListElement();
		if (value < 0) {
			this.scrollbar.moveUp();
			if (activeListElement && activeListElement.previous()) {
				this.setListElement(activeListElement.previous());
			}
		} else if (value > 0) {
			this.scrollbar.moveDown();
			if (activeListElement && activeListElement.next()) {
				this.setListElement(activeListElement.next());
			}
		}
		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.nextSibling).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);
	},

	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);
		var removeByPrefix = function(text) {
			return text.replace(/^by [^:]+:/, '');
		}
		return (matches) ? removeByPrefix(matches[1]) + ' <span class="no">' + matches[2] + '</span>' : removeByPrefix(text);
	},
	
	replaceTitle: function(text) {
		var matches = this.getMatches(text);
		return (matches) ? matches[1] : text;
	}
}

/* END: Transformer for selectbox replacing */
/********************************************************************/

document.observe('dom:loaded', init_guiSelectors);

function init_guiSelectors()
{
	if(!isiPad){
		if(typeof(init_customGuiSelect) == "function")
		{
			init_customGuiSelect();
		}
		else
		{
			init_guiSelect();
		}
	}
}
