/**
    * createDropDown Class
    *
    * Class for creating drop-down menus. Tested on IE6 and NS6
    * Usage: createDropDown("body-ID","control-ID","align","event");
    * align: "left","top","right","bottom"
    * event: "over","click"
    *
    * @author Jan Lengowski <Jan.Lengowski@4fb.de>
    * @copyright four for business AG 2002
    * @version 2.0
    * @link http://www.4fb.de
    */
function createDropDown(body, control, align, event) {

  /**
    * Create object references
    * @access private
    */
    oBody = document.getElementById(body);
    oControl = document.getElementById(control);

    /**
    * Set the object properties
    * @access private
    */
    oBody.style.position = "absolute";
    oBody.style.visibility = "hidden";
    oBody.oAlign = align;

    oControl.event = event;
    oControl.oBody = oBody;
    oControl.oBody.open = false;

    oBody.event = event;
    oBody.oBody = oBody;

//    oBody.style.width = oControl.offsetWidth;
    oBody.style.minWidth = oControl.offsetWidth;


    /**
    * Define class methods
    * @access private
    */
    oControl.open = createDropDown_open;
    oControl.close = createDropDown_close;
    oControl.getPos = createDropDown_getPos;

    /**
    * Set event handlers depending on type (over/click)
    * @access private
    */
    if (event == "over") {
        oControl.onmouseover = createDropDown_open;
        oControl.onmouseout = createDropDown_close;
        oBody.onmouseover = createDropDown_open;
        oBody.onmouseout = createDropDown_close;
    } else {
        oControl.onclick = createDropDown_open;
    }

    /**
    * Get the position of the control element
    * @access private
    */
    oControl.getPos();
    oBody.style.left = oBody.x;
    oBody.style.top = oBody.y;
}

function createDropDown_getPos() {

    /**
    * Method getPos()
    *
    * This method calculates the position
    * of the control element
    *
    * @access private
    */

    this.x = 0;
    this.y = 0;
    var el = this;

    while (el.tagName != "BODY") {
        this.x += el.offsetLeft;
        this.y += el.offsetTop;
        el = el.offsetParent;
    }

    switch (this.oBody.oAlign) {

        case "top":
            this.oBody.x = this.x;
            this.oBody.y = this.y - this.oBody.offsetHeight;
            break;

        case "right":
            this.oBody.x = this.x + this.offsetWidth;
            this.oBody.y = this.y;
            break;

        case "bottom":
            this.oBody.x = this.x;
            this.oBody.y = this.y + this.offsetHeight;
            break;

        case "left":
            this.oBody.x = this.x - this.offsetWidth;
            this.oBody.y = this.y;
            break;

    }

    this.oBody.style.left = this.oBody.x + "px";
    this.oBody.style.top = this.oBody.y + "px";

}

function createDropDown_open() {

    /**
    * Method for opening the menu
    * @access private
    */

    oControl.getPos();

    if (this.event == "over") {
        this.oBody.style.visibility = "visible";

    } else {
        if (!this.oBody.open) {
            this.oBody.style.visibility = "visible";
                this.oBody.open = true;
        } else {
            this.oBody.style.visibility = "hidden";
            this.oBody.open = false;
        }
    }
}

function createDropDown_close() {

    /**
    * Method for closing the menu
    * @access private
    */

    this.oBody.style.visibility = "hidden";
}

function zoomImage(path, text, alignObj) {	
	var gray = document.getElementById("gray");

        if(!Assert.isNull(gray))
        {
                gray.style.filter= "Gray()";
        }

	var zoomGMap = document.getElementById("zoomGMap");

        if(!Assert.isNull(zoomGMap))
        {
                zoomGMap .style.visibility = "hidden";	
        }

	document.getElementById("zoom").style.visibility = "visible";	
	document.getElementById("image").innerHTML = '<img src="' + path + '" />';
	document.getElementById("descr").innerHTML = text;	
	var pos = Element.getPosition(alignObj);
	document.getElementById("zoom").style.top = pos.y + "px";
	document.getElementById("zoom").style.left = pos.x - 455 + "px";
}

function zoomGMap(alignObj) {	
	document.getElementById("gray").style.filter= "Gray()";	
	document.getElementById("zoom").style.visibility = "hidden";	
	document.getElementById("zoomGMap").style.visibility = "visible";
	var pos = Element.getPosition(alignObj);
	document.getElementById("zoomGMap").style.top = pos.y + "px";
	document.getElementById("zoomGMap").style.left = pos.x - 455 + "px";
}

/**
 * Element object, provides cross browser methods for dom methods
 * 
 * @author		Jan Lengowski <jan.lengowski@gmail.com>
 * @copyright	Jan Lengowski
 * 
 * @version		1.0
 */

var Element = {
	
	/**
	 * Creates a new DOM Element object with the given Tag name, 
	 * class name and with the attributes passed in the attribs
	 * 
	 * @param		tagName		Name of the tag
	 * @param		className	Class name to be used
	 * @param		attribs		Object containing attributes as name->value pairs
	 * 
	 * @return		HTML DOM Object
	 * @version		1.0
	 */
	
	create: function(tagName, className, attribs) {	
		var elm = document.createElement( tagName.toUpperCase() );	
		var attributes = attribs || {};
		for (var name in attributes)
			elm[name] = attributes[name];
		if (className)
			elm.className = className;	
		return elm;	
	},
	
	/**
	 * Adds specific content to an elment, if the content is an object 
	 * then it will be appended using document.appendChild, otherwise
	 * the content will be inserted using innerHTML.
	 * 
	 * @param		element		Element (id or object)
	 * @param		content		Content to add (string/html or object)
	 * 
	 * @return		HTML DOM Object
	 * @version		1.0
	 */
	 
	insert: function(element, content) {
		var elm = Element.get(element);
		if (Assert.isObject(content)) elm.appendChild(content);
		else elm.innerHTML = content;		
	},
	
	/**
	 * Adds a classname to a specific element
	 * 
	 * @param		element		Element reference
	 * @param		className	Class name to add
	 * 
	 * @return		void
	 * @version		1.1
	 */
	addClassName: function(element, className) {
		var el = Element.get(element);
		if (el.className == className || el.className.indexOf(className) != -1) return;
		el.className = el.className.split(" ").push(className).join(" ");
	},
	
	/**
	 * Removes a classname from a specific element
	 * 
	 * @param		element		Element reference
	 * @param		className	Class name to add
	 * 
	 * @return		void
	 * @version		1.1
	 */
	removeClassName: function(element, className) {
		var el = Element.get(element);
		if (el.className.indexOf(className) == -1) return;
		el.className = el.className.split(" ").remove(className).join(" ");
	},
	
	/**
	 * Creates a new DOM TextNode Element object 
	 * 
	 * @param		text		Text
	 * 
	 * @return		HTML DOM Object
	 * @version		1.0
	 */
	
	textNode: function(text) {	
		return document.createTextNode( text );
	},
	 
	/**
	 * Returns a reference to the element with the given id, 
	 * simple wrapper function for document.getElementById()
	 * 
	 * @param		id		Id of the Element
	 * 
	 * @return		HTML DOM Object
	 * @version		1.0
	 */
	 
	get: function(id) {	
		if (Assert.isObject(id)) return id;
		return document.getElementById(id);
	},
	
	/**
	 * Calculates the position of the object relative to the viewport, 
	 * i.e. the page itself and returns it as object with the properties
	 * x and y, i.e. var pos = ... pos.x and pos.y can be used.
	 * 
	 * @param		elm		Target object
	 * 
	 * @return		HTML DOM Object
	 * @version		1.0
	 */
	
	getPosition: function(id) {		
		var x = 0, y = 0, srcElm = Element.get(id);
		while (srcElm.tagName != "BODY" && srcElm.tagName != "HTML") {			
			/* GET POSITION FOR ABSOLUTE POSITIONED OBJECTS */	
			if (Element.getStyle(srcElm, "position") == "absolute") {
				x += parseInt(Element.getStyle(srcElm, "left")) || 0;
				y += parseInt(Element.getStyle(srcElm, "top"))  || 0;				
				srcElm = srcElm.parentNode || srcElm.offsetParent;
			} else {				
				x += srcElm.offsetLeft;
				y += srcElm.offsetTop;
				srcElm = srcElm.offsetParent;		
			}
		}						
		return { "x": x, "y": y };		
	},
	
	/**
	 * Returns the currently active style value for a given object
	 * 
	 * @param		elm			Target object
	 * @param		property	The CSS property to select
	 * 
	 * @return		string / mixed
	 * @version		1.0
	 */
	
	getStyle: function(elm, property) {	
		if (elm.currentStyle)
			return elm.currentStyle[property];
		else if (document.documentElement && document.defaultView)
			return document.defaultView.getComputedStyle(elm,"").getPropertyValue(property);		
	},
	
	/**
	 * Calculates the position, width and height of the given object and 
	 * returns a new object with the properties x, y, w, h which can be 
	 * used to access the values, the object has a method includes(x, y) 
	 * which can be used to check whether a cooridnate collides with the 
	 * object.
	 * 
	 * @param		elm			Target object
	 * 
	 * @return		Object		Generic object with the attributed x, y, w, h and includes()
	 * @version		1.0
	 */
	
	getDimensions: function(elm) {
		var pos = Element.getPosition(elm);
		return { 
			x: pos.x, 
			y: pos.y, 
			w: elm.offsetWidth, 
			h: elm.offsetHeight,
			includes: function(x, y) {
				return x >= this.x && x <= (this.x + this.w) && y >= this.y && y <= (this.y + this.h);	
			}
		};
	},
	
	/**
	 * Returns an array containing the child nodes of the given element
	 * which node type equals the requested node type, basically a work
	 * around for moz/ns returning the text nodes as well.
	 *
	 *  1 - ELEMENT_NODE
	 *  2 - ATTRIBUTE_NODE
	 *  3 - TEXT_NODE
	 *  4 - CDATA_SECTION_NODE
	 *  5 - ENTITY_REFERENCE_NODE
	 *  6 - ENTITY_NODE
	 *  7 - PROCESSING_INSTRUCTION_NODE
	 *  8 - COMMENT_NODE
	 *  9 - DOCUMENT_NODE
	 * 10 - DOCUMENT_TYPE_NODE
	 * 11 - DOCUMENT_FRAGMENT_NODE
	 * 12 - NOTATION_NODE 
	 * 
	 * @param		node		Node object
	 * @param		nodeType	Nodetype, see top
	 * 
	 * @return		Array
	 * @version		1.0
	 */
	 
	getChildNodes: function( node, nodeType ) {
		for (var i = 0, nodes = []; i < node.childNodes.length; i++)
			if (node.childNodes[i].nodeType == nodeType)
				nodes[nodes.length] = node.childNodes[i];			
		return nodes;
	},
	
	/**
	 * Returns the previous sibling of the given node which matches the
	 * requested node type. Will iterate over all previous siblings, if
	 * no match could be found null is returned.
	 *
	 *  1 - ELEMENT_NODE
	 *  2 - ATTRIBUTE_NODE
	 *  3 - TEXT_NODE
	 *  4 - CDATA_SECTION_NODE
	 *  5 - ENTITY_REFERENCE_NODE
	 *  6 - ENTITY_NODE
	 *  7 - PROCESSING_INSTRUCTION_NODE
	 *  8 - COMMENT_NODE
	 *  9 - DOCUMENT_NODE
	 * 10 - DOCUMENT_TYPE_NODE
	 * 11 - DOCUMENT_FRAGMENT_NODE
	 * 12 - NOTATION_NODE 
	 * 
	 * @param		node		Node object
	 * @param		nodeType	Nodetype, see top
	 * 
	 * @return		Array
	 * @version		1.0
	 */

	getPreviousSibling: function( node, nodeType ) {		
		if (document.all && node) // IE SPECIFIC
			return (node.previousSibling) ? node.previousSibling : null;				
		var elm = node;				
		while (elm && elm.previousSibling && node.parentNode.firstChild != elm.previousSibling) {
			elm = elm.previousSibling;
			if (elm.nodeType == nodeType)
				return elm;
		}		
		return null;		
	},
		 
	/**
	 * Returns the next sibling of the given node which matches the
	 * requested node type. Will iterate over all previous siblings, if
	 * no match could be found null is returned.
	 *
	 *  1 - ELEMENT_NODE
	 *  2 - ATTRIBUTE_NODE
	 *  3 - TEXT_NODE
	 *  4 - CDATA_SECTION_NODE
	 *  5 - ENTITY_REFERENCE_NODE
	 *  6 - ENTITY_NODE
	 *  7 - PROCESSING_INSTRUCTION_NODE
	 *  8 - COMMENT_NODE
	 *  9 - DOCUMENT_NODE
	 * 10 - DOCUMENT_TYPE_NODE
	 * 11 - DOCUMENT_FRAGMENT_NODE
	 * 12 - NOTATION_NODE 
	 * 
	 * @param		node		Node object
	 * @param		nodeType	Nodetype, see top
	 * 
	 * @return		Array
	 * @version		1.0
	 */
	
	getNextSibling: function( node, nodeType ) {		
		if (document.all && node && node.nextSibling) // IE SPECIFIC
			return (node.nextSibling && node.parentNode.lastChild != node.nextSibling)	? node.nextSibling : null;	
		var elm = node;		
		while (elm && elm.nextSibling && node.parentNode.lastChild != elm.nextSibling) {
			elm = elm.nextSibling;
			if (elm.nodeType == nodeType) {
				return elm;
			} 
		}		
		return null;				
	}
	
}

/**
 * Assert object, provides several method to check values for their type
 * 
 * @author		Jan Lengowski <jan.lengowski@gmail.com>
 * @copyright	Jan Lengowski
 * 
 * @version		1.0
 */

var Assert = {
	
	/**
	 *  Checks if the value is a Function
	 * 
	 * @param		value	Value to check
	 * 
	 * @return		boolean
	 * @version		1.0
	 */
	
	isFunction: function(value) {
		return typeof value == "function";	
	},
	
	/**
	 *  Checks if the value is empty / null
	 * 
	 * @param		value	Value to check
	 * 
	 * @return		boolean
	 * @version		1.0
	 */
	
	isNull: function(value) {
	    return value == null;
	},
	
	/**
	 *  Checks if the value is a String
	 * 
	 * @param		value	Value to check
	 * 
	 * @return		boolean
	 * @version		1.0
	 */
	
	isString: function(value) {
	    return typeof value == "string";
	},
	
	/**
	 *  Checks if the value is an Array
	 * 
	 * @param		value	Value to check
	 * 
	 * @return		boolean
	 * @version		1.0
	 */ 
	 
	isArray: function(value) {
		return Assert.isObject(value) && value.constructor == Array;	
	},
		
	/**
	 *  Checks if the value is an Object
	 * 
	 * @param		value	Value to check
	 * 
	 * @return		boolean
	 * @version		1.0
	 */ 
	
	isObject: function(value) {
		return typeof value == "object" && !Assert.isNull(value);	
	},
	
	/**
	 *  Checks if the value is a number
	 * 
	 * @param		value	Value to check
	 * 
	 * @return		boolean
	 * @version		1.0
	 */ 
	
	isNumber: function(value) {
		return typeof value == "number";	
	},

	/**
	 *  Checks if the value is boolean
	 * 
	 * @param		value	valuealue to check
	 * 
	 * @return		boolean
	 * @version		1.0
	 */ 
	 
	isBoolean: function(value) {
		return typeof value == "boolean";
	},
		
	/**
	 *  Checks if the value is defined
	 * 
	 * @param		value	Value to check
	 * 
	 * @return		boolean
	 * @version		1.0
	 */ 
	 
	isDefined: function(value) {
		return typeof value != "undefined";
	}	
		
}
