// Node-Objekt-Erweiterung um die Funktion contains()
// Ist für IsMouseEnter/IsMouseLeave notwendig
if (window.Node && Node.prototype && !Node.prototype.contains) {
	Node.prototype.contains = function (arg) {
		return !!(this.compareDocumentPosition(arg) & 16);
	}
}

mdxGetElementsByClassName = function (searchClass, node, tag) {
	if (node === undefined)	{ node = document; }
	if (tag === undefined)	{ tag = '*'; }

	if (typeof(node.getElementsByClassName) === 'function') {
		return node.getElementsByClassName(searchClass);
	} else {
		var classElements = [];
	
		var els = node.getElementsByTagName(tag);
		var elsLen = els.length;
		var pattern = new RegExp("(^|\\s)" + searchClass + "(\\s|$)");
		for (i = 0, j = 0; i < elsLen; i++) {
			if (pattern.test(els[i].className)) {
				classElements[j] = els[i];
				j++;
			}
		}
		return classElements;
	}
}

function GraphicalExtension(_config) {
	var _this = this;

	// Create a dummy-config-object if the _config object is invalid
	if (!_config || typeof _config !== 'object') { _config = {}; }

	this.searchForm = _config.searchForm || document.getElementById('suchmaske');		// SearchForm-Object
	this.maxDropDownHeight = _config.maxDropDownHeight || 200;					// max. height of the DropDown-box
	this.showResetButtons = (typeof _config.showResetButtons === 'boolean' ? _config.showResetButtons : true);
	this.position = (typeof _config.position === 'string' ? _config.position : 'absolute');
	this.noFloatClear = (typeof _config.noFloatClear === 'boolean' ? _config.noFloatClear : false);

	this.dropDown = {
		elem:null,
		select:'',
		preventOpen:false
	};

	this.openDropDown = function (selectId) {
		var searchForm = document.getElementById(_this.searchForm.id);
		if (searchForm.elements[selectId].disabled) { return; }
		if (_this.dropDown.elem !== null) {
			document.body.removeChild(_this.dropDown.elem);
			_this.dropDown.elem = null;
		}
		if (_this.dropDown.preventOpen) {
			_this.dropDown.preventOpen = false;
			return;
		}
		_this.dropDown.select = selectId;

		var dropDownElem = document.createElement("DIV");
		dropDownElem.style.position = _this.position;

		var pos = _getAbsPos(document.getElementById(selectId + 'GSelect'));
		dropDownElem.className = 'graphicalSelectDropDown';
		dropDownElem.style.overflow = 'auto';
		dropDownElem.style.left = pos.x + 'px';
		dropDownElem.style.top = (pos.y + document.getElementById(selectId + 'GSelect').offsetHeight) + 'px';
		dropDownElem.style.width = document.getElementById(selectId + 'GSelect').offsetWidth + 'px';

		for (var i = 0; i < searchForm.elements[selectId].options.length; i++) {
			var dropDownItem = document.createElement("DIV");		
			dropDownItem.setAttribute('value', searchForm.elements[selectId].options[i].value);
			if (i == searchForm.elements[selectId].selectedIndex) { dropDownItem.className = 'active'; }
			dropDownItem.innerHTML = searchForm.elements[selectId].options[i].innerHTML;
			_addEvent(dropDownItem, 'mouseover', function () { _this.addClass(this, 'hover'); });
			_addEvent(dropDownItem, 'mouseout', function () { _this.removeClass(this, 'hover'); });
			dropDownElem.appendChild(dropDownItem);
		}

		_this.dropDown.elem = document.body.appendChild(dropDownElem);
		if (dropDownElem.offsetHeight > _this.maxDropDownHeight) {
			dropDownElem.style.height = _this.maxDropDownHeight + 'px';
		}
	}

	this.updateGSelect = function (selectId) {
		var searchForm = document.getElementById(_this.searchForm.id);
		var select = searchForm.elements[/([a-zA-Z0-9_]+)GSelect/.exec(selectId)[1]];
		document.getElementById(selectId + 'Text').innerHTML = select.options[select.selectedIndex].innerHTML;

		document.getElementById(selectId).className = 'graphicalSelect' + (select.disabled ? ' disabled' : '');
	}

	this.customizeField = function (which, justReset) {
		var searchForm = document.getElementById(_this.searchForm.id);
		var field = searchForm.elements[which];

		document.write('<div id="' + which + 'GSelect" class="graphicalSelect"><div id="' + which + 'GSelectText">' + field.options[field.selectedIndex].innerHTML + '</div></div>');
		var elem = document.getElementById(which + 'GSelect');
		_addEvent(elem, 'mouseover', function () { if (!_this.hasClass(this, 'disabled')) { _this.addClass(this, 'hover'); } });
		_addEvent(elem, 'mouseout', function () { _this.removeClass(this, 'hover'); });
		_addEvent(elem, 'click', (function (which) { return function () { _this.openDropDown(which); } })(which));

		_setUnselectable(document.getElementById(which + 'GSelect'));

		if (_this.showResetButtons) {
			_insertRefreshButton(which, justReset);
			if (!_this.noFloatClear) {
				document.write('<div style="clear:both;"></div>');
			}
		}
	}

	/* --- Internal Function --- */

	function _insertRefreshButton(field, justReset) {
		var searchForm = document.getElementById(_this.searchForm.id);

		var resetElem = document.createElement('div');
		resetElem.className = 'reset' + (searchForm.elements[field].selectedIndex != 0 ? 'Enabled' : 'Disabled');
		resetElem.onclick = function () {
			if (this.className === 'resetEnabled') {
				document.getElementById(_this.searchForm.id).elements[field].selectedIndex = 0;
				if (!justReset) {
					_this.searchForm.refresh(field);
				} else {
					this.className = 'resetDisabled';
				}
			}
			_this.updateGSelect(field + 'GSelect');
		}
		_this.searchForm.resetFields[field] = searchForm.elements[field].parentNode.appendChild(resetElem);
	}

	this.hasClass = function (elem, className) {
		return elem.className.match(new RegExp('(\\s|^)' + className + '(\\s|$)'));
	}

	this.addClass = function (elem, className) {
		var _f = function (elem) {
			if (typeof elem === 'string') {
				elem = document.getElementById(elem);
			}

			if (!_this.hasClass(elem, className)) {
				elem.className += ' ' + className;
			}
		}

		if (Object.prototype.toString.call(elem) === '[object Array]') {
			for (var i = 0; i < elem.length; i++) {
				_f(elem[i]);
			}
			return;
		}
		_f(elem);
	}

	this.removeClass = function (elem, className) {
		var _f = function (elem) {
			if (typeof elem === 'string') {
				elem = document.getElementById(elem);
			}

			if (_this.hasClass(elem, className)) {
				var regEx = new RegExp('(\\s|^)' + className + '(\\s|$)');
				elem.className = elem.className.replace(regEx,' ');
			}
		}

		if (Object.prototype.toString.call(elem) === '[object Array]') {
			for (var i = 0; i < elem.length; i++) {
				_f(elem[i]);
			}
			return;
		}
		_f(elem);
	}

	function _addEvent(obj, type, func) {
		if (obj.attachEvent) {
			var rnd = parseInt(Math.random() * 0xffffffff, 16).toString() + parseInt(Math.random() * 0xffffffff, 16).toString() + parseInt(Math.random() * 0xffffffff, 16).toString() + parseInt(Math.random() * 0xffffffff, 16).toString();
			obj['e' + type + func + rnd] = func;
			obj[type + func + rnd] = function() { obj['e' + type + func + rnd](window.event); }
			obj.attachEvent('on' + type, obj[type + func + rnd]);
		} else {
			obj.addEventListener(type, func, false);
		}
	}

	function _getAbsPos(elem) {
		var x = 0, y = 0;
		while (elem != null) {
			x += elem.offsetLeft;
			y += elem.offsetTop;
			elem = elem.offsetParent;
		}

		return { "x":x, "y":y };
	}

	function _setUnselectable(elem) {
		if (elem == undefined) { return; }
		_addEvent(elem, "selectstart", function () { return false; });
		elem.style.MozUserSelect = "none";
		elem.style.KhtmlUserSelect = "none";
		elem.unselectable = "on";
	}

	_addEvent(document, 'mousedown', function (e) {
		if (_this.dropDown.elem !== null) {
			var searchForm = document.getElementById(_this.searchForm.id);

			if (!e) { e = window.event; }
			if (_this.dropDown.elem == (e.target || e.srcElement)) {
				return;
			}

			if (_this.dropDown.elem.contains(e.target || e.srcElement)) {
				value = (e.target || e.srcElement).getAttribute('value');

				var select = searchForm.elements[_this.dropDown.select];
				for (var i = 0; i < select.options.length; i++) {
					if (select.options[i].value === value) {
						select.selectedIndex = i;
					}
				}
				document.getElementById(_this.dropDown.select + 'GSelectText').innerHTML = (e.target || e.srcElement).innerHTML;
				if (typeof(searchForm.elements[_this.dropDown.select].onchange) === 'function') { searchForm.elements[_this.dropDown.select].onchange(); }
			}

			if ((document.getElementById(_this.dropDown.select + 'GSelect') == (e.target || e.srcElement)) || (document.getElementById(_this.dropDown.select + 'GSelectText') == (e.target || e.srcElement))) {
				_this.dropDown.preventOpen = true;
			}

			document.body.removeChild(_this.dropDown.elem);
			_this.dropDown.elem = null;
		}
	});

	_this.searchForm.preProcess.push(function (query, json) {
		var elems = mdxGetElementsByClassName('graphicalSelect', document.getElementById(_this.searchForm.id));
		for (var i = 0; i < elems.length; i++) {
			_this.updateGSelect(elems[i].id);
		}

		if (_this.dropDown.elem !== null) {
			_this.openDropDown(_this.dropDown.select);
		}
	});
	_this.searchForm.postProcess.push(function (query, json) {
		var elems = mdxGetElementsByClassName('graphicalSelect', document.getElementById(_this.searchForm.id));
		for (var i = 0; i < elems.length; i++) {
			_this.updateGSelect(elems[i].id);
		}

		if (_this.dropDown.elem !== null) {
			_this.openDropDown(_this.dropDown.select);
		}
	});
}
