/* ***********************************************************
Example 4-3 (DHTMLapi.js)
"Dynamic HTML:The Definitive Reference"
2nd Edition
by Danny Goodman
Published by O'Reilly & Associates  ISBN 1-56592-494-0
http://www.oreilly.com
Copyright 2002 Danny Goodman.  All Rights Reserved.
************************************************************ */
// DHTMLapi.js custom API for cross-platform
// object positioning by Danny Goodman (http://www.dannyg.com).
// Release 2.0. Supports NN4, IE, and W3C DOMs.

// Global variables
var isCSS, isW3C, isIE4, isNN4;
// initialize upon load to let all browsers establish content objects
function initDHTMLAPI() {
    if (document.images) {
        isCSS = (document.body && document.body.style) ? true : false;
        isW3C = (isCSS && document.getElementById) ? true : false;
        isIE4 = (isCSS && document.all) ? true : false;
        isNN4 = (document.layers) ? true : false;
        isIE6CSS = (document.compatMode && document.compatMode.indexOf("CSS1") >= 0) ? true : false;
    }
}
// set event handler to initialize API
window.onload = initDHTMLAPI;

// Seek nested NN4 layer from string name
function seekLayer(doc, name) {
    var theObj;
    for (var i = 0; i < doc.layers.length; i++) {
        if (doc.layers[i].name == name) {
            theObj = doc.layers[i];
            break;
        }
        // dive into nested layers if necessary
        if (doc.layers[i].document.layers.length > 0) {
            theObj = seekLayer(document.layers[i].document, name);
        }
    }
    return theObj;
}

// Convert object name string or object reference
// into a valid element object reference
function getRawObject(obj) {
    var theObj;
    if (typeof obj == "string") {
        if (isW3C) {
            theObj = document.getElementById(obj);
        } else if (isIE4) {
            theObj = document.all(obj);
        } else if (isNN4) {
            theObj = seekLayer(document, obj);
        }
    } else {
        // pass through object reference
        theObj = obj;
    }
    return theObj;
}

// Convert object name string or object reference
// into a valid style (or NN4 layer) reference
function getObject(obj) {
    var theObj = getRawObject(obj);
    if (theObj && isCSS) {
        theObj = theObj.style;
    }
    return theObj;
}

// Position an object at a specific pixel coordinate
function shiftTo(obj, x, y) {
    var theObj = getObject(obj);
    if (theObj) {
        if (isCSS) {
            // equalize incorrect numeric value type
            var units = (typeof theObj.left == "string") ? "px" : 0 
            theObj.left = x + units;
            theObj.top = y + units;
        } else if (isNN4) {
            theObj.moveTo(x,y)
        }
    }
}

// Move an object by x and/or y pixels
function shiftBy(obj, deltaX, deltaY) {
    var theObj = getObject(obj);
    if (theObj) {
        if (isCSS) {
            // equalize incorrect numeric value type
            var units = (typeof theObj.left == "string") ? "px" : 0 
            theObj.left = getObjectLeft(obj) + deltaX + units;
            theObj.top = getObjectTop(obj) + deltaY + units;
        } else if (isNN4) {
            theObj.moveBy(deltaX, deltaY);
        }
    }
}

function moveAndScaleElemBy(obj, deltaLeft, deltaTop, deltaWidth, deltaHeight) {
    var theObj = getObject(obj);
    if (theObj) {
        if (isCSS) {
            // equalize incorrect numeric value type
            var units = (typeof theObj.left == "string") ? "px" : 0 ;
            theObj.left = getObjectLeft(obj) + deltaLeft + units;
            theObj.top  = getObjectTop(obj) + deltaTop + units;
            theObj.width  = getObjectWidth(obj) + deltaWidth + units;
            theObj.height = getObjectHeight(obj) + deltaHeight + units;
        } else if (isNN4) {
            theObj.moveBy(deltaLeft, deltaTop);
            theObj.resizeBy(deltaWidth, deltaHeight);
        }
    }
}


function moveAndScaleElemTo(obj, left, top, width, height) {
    var theObj = getObject(obj);
    if (theObj) {
        if (isCSS) {
            // equalize incorrect numeric value type
            var units = (typeof theObj.left == "string") ? "px" : ""; 
            theObj.left = left + units;
            theObj.top  = top + units;
            theObj.width  = width + units;
            theObj.height = height + units;
        } else if (isNN4) {
            theObj.moveiTo(left, top);
            theObj.resizeTo(width, height);
        }
    }
}


// Set the z-order of an object
function setZIndex(obj, zOrder) {
    var theObj = getObject(obj);
    if (theObj) {
        theObj.zIndex = zOrder;
    }
}

// Set the background color of an object
function setBGColor(obj, color) {
    var theObj = getObject(obj);
    if (theObj) {
        if (isNN4) {
            theObj.bgColor = color;
        } else if (isCSS) {
            theObj.backgroundColor = color;
        }
    }
}

// Set the visibility of an object to visible
function show(obj) {
    var theObj = getObject(obj);
    if (theObj) {
        theObj.visibility = "visible";
    }
}

// Set the visibility of an object to hidden
function hide(obj) {
   var theObj = getObject(obj);
    if (theObj) {
        theObj.visibility = "hidden";
    }
}


function setVisibility(obj, visible) {
//  var theObj = getRawObject(obj); 
  if(document.layers){
    obj.visibility  =
        (visible == true) ? 'show' : 'hide';
  } else {
    obj.style.visibility =
        (visible == true) ? 'visible' : 'hidden';
  }
}


// Retrieve the x coordinate of a positionable object
function getObjectLeft(obj)  {
    var elem = getRawObject(obj);
    var result = 0;
    if (document.defaultView) {
        var style = document.defaultView;
        var cssDecl = style.getComputedStyle(elem, "");
        result = cssDecl.getPropertyValue("left");
    } else if (elem.currentStyle) {
        result = elem.currentStyle.left;
    } else if (elem.style) {
        result = elem.style.left;
    } else if (isNN4) {
        result = elem.left;
    }
    return parseInt(result);
}

// Retrieve the y coordinate of a positionable object
function getObjectTop(obj)  {
    var elem = getRawObject(obj);
    var result = 0;
    if (document.defaultView) {
        var style = document.defaultView;
        var cssDecl = style.getComputedStyle(elem, "");
        result = cssDecl.getPropertyValue("top");
    } else if (elem.currentStyle) {
        result = elem.currentStyle.top;
    } else if (elem.style) {
        result = elem.style.top;
    } else if (isNN4) {
        result = elem.top;
    }
    return parseInt(result);
}

// Retrieve the rendered width of an element
function getObjectWidth(obj)  {
    var elem = getRawObject(obj);
    var result = 0;
    if (elem.offsetWidth) {
        result = elem.offsetWidth;
    } else if (elem.clip && elem.clip.width) {
        result = elem.clip.width;
    } else if (elem.style && elem.style.pixelWidth) {
        result = elem.style.pixelWidth;
    }
    return parseInt(result);
}

// Retrieve the rendered height of an element
function getObjectHeight(obj)  {
    var elem = getRawObject(obj);
    var result = 0;
    if (elem.offsetHeight) {
        result = elem.offsetHeight;
    } else if (elem.clip && elem.clip.height) {
        result = elem.clip.height;
    } else if (elem.style && elem.style.pixelHeight) {
        result = elem.style.pixelHeight;
    }
    return parseInt(result);
}


// Return the available content width space in browser window
function getInsideWindowWidth() {
    if (window.innerWidth) {
        return window.innerWidth;
    } else if (isIE6CSS) {
        // measure the html element's clientWidth
        return document.body.parentElement.clientWidth
    } else if (document.body && document.body.clientWidth) {
        return document.body.clientWidth;
    }
    return 0;
}
// Return the available content height space in browser window
function getInsideWindowHeight() {
    if (window.innerHeight) {
        return window.innerHeight;
    } else if (isIE6CSS) {
        // measure the html element's clientHeight
        return document.body.parentElement.clientHeight
    } else if (document.body && document.body.clientHeight) {
        return document.body.clientHeight;
    }
    return 0;
}

function getPageEventCoords ( evt ) {
    var coords = {left:0, top:0};
    if (evt.pageX) {
        coords.left = evt.pageX;
        coords.top = evt.pageY;
    } else if (evt.clientX) {
        coords.left =
            evt.clientX + document.body.scrollLeft - document.body.clientLeft;
        coords.top =
            evt.clientY + document.body.scrollTop - document.body.clientTop;
        // include html element space, if applicable
        if (document.body.parentElement && document.body.parentElement.clientLeft) {
            var bodParent = document.body.parentElement;
            coords.left += bodParent.scrollLeft - bodParent.clientLeft;
            coords.top += bodParent.scrollTop - bodParent.clientTop;
        }
    }
    return coords;
}

function getPosEventCoords ( evt ) {
    var elem = (evt.target) ? evt.target : evt.srcElement;
    var coords = {left:0, top:0};
    if (evt.layerX) {
        var borders = {left:parseInt(getElementStyle("progressBar",
                       "borderLeftWidth", "border-left-width")),
                       top:parseInt(getElementStyle("progressBar",
                       "borderTopWidth", "border-top-width"))};
        coords.left = evt.layerX - borders.left;
        coords.top = evt.layerY - borders.top;
    } else if (evt.offsetX) {
        coords.left = evt.offsetX;
        coords.top = evt.offsetY;
    }
    evt.cancelBubble = true;
    return coords;
}
function _getX() {
	return this.x;
}

function _getY() {
	return this.y;
}

function _setX(x){
	this.x = x;
}

function _setY(y) {
	this.y = y;
}

function Point(x,y) {
	this.x = x;
	this.y = y;
	this.getX = _getX;
	this.getY = _getY;
	this.setX = _setX;
	this.setY = _setY;	
}
//***************************************************************************
//Programme Entwicklung von Yue Zhang                                       *
//                                                                          *
//2006, LVG                                                                 *
//                                                                          *
//***************************************************************************

var gk_new  = new Array(), pkt = new Array();
var p_nr = 0, letztpkt = 0, polygon_pktmove = "nein";
var p_nr_text = "leer", Polygonzu = "nein", Polygonschlossen = "nook", p_nr_s, pktmove = 0;

function getClickPoint(evt) {
        evt = (evt) ? evt : event;

        var tmp = "";
        var gk  = document.gkpunkte;
        var theObj = getRawObject("map");

        var x, y;
        if (evt.pageX) {
            x = evt.pageX - theObj.offsetLeft;
            y = evt.pageY - theObj.offsetTop-95;
        } else if (evt.offsetX || evt.offsetY) {
            x = evt.offsetX;
            y = evt.offsetY;
        } else if (evt.clientX) {
            x = evt.clientX;
            y = evt.clientY;
        }
        
        if(browserName != 'ie'){
        	x -= 12;
        	y -= 12;
        }
	return new Point(x,y);
}

function getGKofClickPoint(evt) {
	evt = (evt) ? evt : event;

	var p = getClickPoint(evt);

        var width = parseFloat(document.formImg.width.value);
        var height = parseFloat(document.formImg.height.value);
        var ru = parseFloat(document.formImg.ru.value);
        var hu = parseFloat(document.formImg.hu.value);
        var ro = parseFloat(document.formImg.ro.value);
        var ho = parseFloat(document.formImg.ho.value);

        var dR = parseFloat(ro) - parseFloat(ru);
        var dH = parseFloat(ho) - parseFloat(hu);

        var tmp = s2gk ( p.getX() , p.getY(), width, height, dR, dH, ru, hu );

	return new Point(tmp.getX(), tmp.getY());
}

function runden ( num, s) {
	var fact = 1;
        for(var i = 0; i < s; i++){
                fact *= 10;
        }
        return parseFloat ( Math.round(num*fact) / parseFloat (fact) );
}

function s2gk ( x, y, width, height, dR, dH, ru, hu ) {
        x = parseFloat(x);
        y = parseFloat(y);
        width = parseFloat(width);
        height = parseFloat(height);
        dR = parseFloat(dR);
        dH = parseFloat(dH);
        ru = parseFloat(ru);
        hu = parseFloat(hu);

        var r = (dR / width * x) + ru ;
        var h = (dH / height * (height - y)) + hu;
        return new Point(r,h);
}

function gk2s ( r, h, width, height, dR, dH, ru, hu ) {
        r = parseFloat(r);
        h = parseFloat(h);
        dR = parseFloat(dR);
        dH = parseFloat(dH);
        width = parseFloat(width);
        height = parseFloat(height);
	ru = parseFloat(ru);
        hu = parseFloat(hu);
	var x = parseInt(width / dR * (r - ru));
	var y = parseInt(height * (1-(( h - hu ) / dH )));
	return new Point(x,y); 
}

function createGKPoly( width, height, dR, dH, ru, hu, closed ) {
        var gk = document.gkpunkte;
        var p1 = "";
        var p2 = "";

        if(gk.length > 2 ){
			document.gkDrawPunkte = new Array();
            p1 = gk2s( gk[0].getX(), gk[0].getY(), width, height, dR, dH, ru, hu);
            if(isIE4) {
            	addDrawPoint(new Point( p1.getX()+31, p1.getY()+31 ), width, height, dR, dH, ru, hu);
            }
            else{
                        addDrawPoint(p1, width, height, dR, dH, ru, hu);
            }

			p1 = gk2s( gk[0].getX(), gk[0].getY(), width, height, dR, dH, ru, hu);
            p2 = gk2s( gk[1].getX(), gk[1].getY(), width, height, dR, dH, ru, hu);
            berechneZwischenpunkte(p1, p2, width, height, dR, dH, ru, hu);
            for(var i = 2; i < gk.length; i++){
            	p1 = gk2s( gk[i-1].getX(), gk[i-1].getY(), width, height, dR, dH, ru, hu);
                p2 = gk2s( gk[i].getX(),   gk[i].getY(),   width, height, dR, dH, ru, hu);
                berechneZwischenpunkte(p1, p2, width, height, dR, dH, ru, hu);
			}
			if(closed == true){
	        	p1 = gk2s( gk[gk.length-1].getX(), gk[gk.length-1].getY(), width, height, dR, dH, ru, hu);
        	    p2 = gk2s( gk[0].getX(),   gk[0].getY(),   width, height, dR, dH, ru, hu);
                berechneZwischenpunkte(p1, p2, width, height, dR, dH, ru, hu);
			}
        }
        else if(gk.length == 2 ){
        	document.gkDrawPunkte = new Array();
        	p1 = gk2s( gk[0].getX(), gk[0].getY(), width, height, dR, dH, ru, hu);
            p2 = gk2s( gk[1].getX(), gk[1].getY(), width, height, dR, dH, ru, hu);
            berechneZwischenpunkte(p1, p2, width, height, dR, dH, ru, hu);
			drawPoly();
        }
        else{  // zeichen den ersten Punkt
			document.gkDrawPunkte = new Array();
            p1 = gk2s( gk[0].getX(), gk[0].getY(), width, height, dR, dH, ru, hu);
            if(isIE4) {
            	addDrawPoint(new Point( p1.getX()+31, p1.getY()+31 ), width, height, dR, dH, ru, hu);
           	}
           	else{
            	addDrawPoint(p1, width, height, dR, dH, ru, hu);
            }
			drawPoly();
        }
}

function berechneZwischenpunkte(p1, p2, width, height, dR, dH, ru, hu) {
        var dx = p2.getX() - p1.getX();
        var dy = p2.getY() - p1.getY();
        var x1 = p1.getX();
        var y1 = p1.getY();
		
		var l = Math.sqrt(dx*dx + dy*dy);
        var w = parseInt(l / 10);
        for (var i = 0; i <= w; i++){
                var dxk = parseInt ( dx * i / w );
                var dyk = parseInt ( dy * i / w );
                if(isIE4) {
                        addDrawPoint(new Point( (x1 + dxk + 31) , (y1 + dyk + 31) ), width, height, dR, dH, ru, hu);
                }else{
                        addDrawPoint(new Point( (x1 + dxk) , (y1 + dyk) ), width, height, dR, dH, ru, hu);
                }
        }
}

function addDrawPoint(p, width, height, dR, dH, ru, hu ){
        var tmp = s2gk(p.getX(), p.getY(), width, height, dR, dH, ru, hu);
        document.gkDrawPunkte.push( new Point( tmp.getX(), tmp.getY()) ) ;
}

function drawPoly(){
	var ortsuch = 0;
	var obj = getRawObject("imgPolygon");		
	var punkte = "";
	
	var tmpdiv_1 = "", tmpdiv_2 = "", tmpdiv_3 = "";
    var tmpfont_1 = "", tmpfont_2 = "", tmpfont_3 = "";
    var tmpinnerhtml_1 = "", tmpinnerhtml_2 = "";
    var tmp = "";
   	$("imgPolygon").style.visibility = "visible";	
	//neue methode beginn
	var punkte, punkte_x, punkte_y;
	var newpunkt = new Array();
	if(neumessen == 1){
		for(var i=0; i<document.pktPosition.length; i++){
			punkte_x = document.pktPosition[i].getX()+divimgLeft;
			punkte_y = document.pktPosition[i].getY()+divimgTop;
			newpunkt.push(new Point(punkte_x,punkte_y));
		}
		document.pktPosition = newpunkt;
		punkte = document.pktPosition;
	}
	else{punkte = document.pktPosition;}
	var jg = new jsGraphics("imgPolygon");
	jg.setColor("#ff4500");
	jg.setStroke(2);
	var x_reihe = new Array();
	var y_reihe = new Array();
	for(var n = 0; n < punkte.length; n++){
		x_reihe[n] = punkte[n].getX();
		y_reihe[n] = punkte[n].getY();
	}
	if(punkte.length == 1){
		var p1_x = x_reihe[0];
		var p1_y = y_reihe[0];
		var pktlength = punkte.length;
	    obj.innerHTML = "";
    }
	else{
		var p1_x = x_reihe[n-1];
		var p1_y = y_reihe[n-1];
		var p2_x = x_reihe[n-2];
		var p2_y = y_reihe[n-2];
		var pktlength = punkte.length;
		if($("iconFlaeche").src.indexOf("res/Button_Lineal_Flaeche_aktiv.gif") >= 0){
			if(Polygonzu == "ja" && $("pkt_koord").innerHTML != "Ort_wird_gefunden" && $("pkt_koord").innerHTML != ""){
                		$("newpunkt").style.visibility = "visible";
                $("overview").style.zIndex = 9;
				var wert = $("pkt_koord").innerHTML.split(",");
				if(polygon_pktmove == "nein"){
					if(zoom_change == "yes"){
						obj.innerHTML = "";
						jg.setColor("#ff4500");
						jg.drawPolygon(x_reihe,y_reihe);
						jg.setColor("#ffd700");
						jg.fillPolygon(x_reihe, y_reihe);
					}
					else{
						if(Polygonschlossen == "nook"){
							if(browserName == "ie"){
								$("pkt_nr1").onmouseover = "";
								$("polygon").onmouseover = "";
							}
							else{
								$("pkt_nr1").setAttribute("onmouseover","");
								$("polygon").setAttribute("onmouseover","");
							}
							var poly = $("polygon").firstChild;
							$("polygon").removeChild(poly);
							$("imgMap").onmousedown = "";
							$("imgMap").onmouseup = "";
							Polygonschlossen = "ok";
						}
						obj.innerHTML = "";
						jg.setColor("#ff4500");
						jg.drawPolygon(x_reihe,y_reihe);
						jg.setColor("#ffd700");
						jg.fillPolygon(x_reihe, y_reihe);
					}
				}
				else{
					obj.innerHTML = "";
					jg.drawPolygon(x_reihe,y_reihe);
					jg.setColor("#ffd700");
					jg.fillPolygon(x_reihe, y_reihe);
				}
			}
			else{
				if(punkte.length > 2){
					$("mauszeige").innerHTML = "Mit der rechten Maustaste wird die Fl&auml;che geschlossen,<br>oder weitere Punkte anklicken....";
				}
                if(polygon_pktmove == "ja" || zoom_change == "yes"){
                    obj.innerHTML = "";
                    for(var t = 0; t <= n; t++){
                        jg.drawLine(x_reihe[t],y_reihe[t],x_reihe[t+1],y_reihe[t+1]);
                    }
                }
                else{
                    jg.drawLine(p1_x,p1_y,p2_x,p2_y);
                }
			}
		}
		else if($("iconStrecke").src.indexOf("res/Button_Lineal_aktiv.gif") >= 0 && $("pkt_koord").innerHTML != "Ort_wird_gefunden" && $("pkt_koord").innerHTML != ""){
			if(polygon_pktmove == "ja" || zoom_change == "yes"){
				obj.innerHTML = "";
				for(var t = 0; t <= n; t++){
					jg.drawLine(x_reihe[t],y_reihe[t],x_reihe[t+1],y_reihe[t+1]);
				}
			}
			else{
				jg.drawLine(p1_x,p1_y,p2_x,p2_y);
			}
		}
		jg.paint();
		
	}
	//alte methode ende
	//Punkte drawing begin
	if(Polygonzu != "ja" && $("iconFlaeche").src.indexOf("res/Button_Lineal_Flaeche_aktiv.gif") >= 0 && messenfinish == true){	
		if(browserName == "ie"){
			tmpdiv_1 = document.createElement("div");
			tmpdiv_1.style.position = "absolute";
			tmpdiv_1.style.left = (p1_x-1) + "px";
			tmpdiv_1.style.top = (p1_y-1) + "px";
			tmpdiv_1.style.width = "5px";
			tmpdiv_1.style.height = "5px";
        	tmpfont_1 = document.createElement("img");
        	tmpfont_1.id = "pkt_nr"+punkte.length;
        	tmpfont_1.src = "res/pkt.gif";
            if(punkte.length<=2){tmpfont_1.onmouseup = function() {"$(\"mauszeige\").innerHTML = \"F&uuml;r Fl&auml;enmessung werden min. 3 Punkte ben&ouml;tigt....\"";};}
            else{tmpfont_1.onmouseup = function() {messenend();};}
            if(p_nr_text == "leer"){
        		if($("iconFlaeche").src.indexOf("res/Button_Lineal_Flaeche_aktiv.gif") >= 0 && Polygonschlossen == "nook"){
        			if(punkte.length == 2){
        				$("pkt_nr1").onclick = function() {messenend();};
        				tmpfont_1.onmouseover = "";
        			}
        			else {
        				tmpfont_1.onmouseover = "";
        			}
        		}
        	}
        	else if(punkte.length != p_nr){
        		tmpfont_1.onmouseover = function() {_pktmove(punkte.length,p1_x,p1_y);};
        	}
        	tmpdiv_1.appendChild(tmpfont_1);
        	obj.appendChild(tmpdiv_1);
		}
		else{
			tmpdiv_1 = document.createElement("div");
			tmpdiv_1.setAttribute("style","position:absolute;"+"left:" + (p1_x-2.5) + "px; top:" + (p1_y-2.5) + "px; width:5px; height:5px");
        	tmpfont_1 = document.createElement("img");
        	tmpfont_1.setAttribute("id","pkt_nr"+punkte.length);
        	tmpfont_1.setAttribute("src","res/pkt.gif");
            if(punkte.length<=2){tmpfont_1.setAttribute("onmouseup","$(\"mauszeige\").innerHTML = \"F&uuml;r Fl&auml;chenmessung werden min. 3 Punkte ben&ouml;tigt....\"");}
            else{tmpfont_1.setAttribute("onmouseup","messenend();");}
        	if(p_nr_text == "leer"){
        		if($("iconFlaeche").src.indexOf("res/Button_Lineal_Flaeche_aktiv.gif") >= 0 && Polygonschlossen == "nook"){
        			if(punkte.length == 2){
        				$("pkt_nr1").setAttribute("onclick","messenend();");
        				tmpfont_1.setAttribute("onmouseover","");
        			}
        			else {
        				tmpfont_1.setAttribute("onmouseover","");
        			}
        		}
        	}
        	else if(punkte.length != p_nr){
        		tmpfont_1.setAttribute("onmouseover","_pktmove("+punkte.length+","+p1_x+","+p1_y+")");
        	}
        	tmpdiv_1.appendChild(tmpfont_1);
        	obj.appendChild(tmpdiv_1);
		}
	}
	else{
		if($("iconStrecke").src.indexOf("res/Button_Lineal_aktiv.gif") >= 0 && !($("menu")) && s_firstmessen == 0 && messenfinish == true){
			if(browserName == "ie"){
				tmpdiv_1 = document.createElement("div");
				tmpdiv_1.style.position = "absolute";
				tmpdiv_1.style.left = (p1_x-1) + "px";
				tmpdiv_1.style.top = (p1_y-1) + "px"; 
				tmpdiv_1.style.width = "5px";
				tmpdiv_1.style.height = "5px";
        		tmpfont_1 = document.createElement("img");
       	 		tmpfont_1.id = "pkt_nr"+punkte.length;
        		tmpfont_1.src= "res/pkt.gif";
                if(punkte.length<=1){tmpfont_1.onmouseup = function() {"$(\"mauszeige\").innerHTML = \"F&uuml;r Streckenmessung werden min. 2 Punkte ben&ouml;tigt....\"";};}
                else{tmpfont_1.onmouseup = function() {messenend();};}
        		tmpfont_1.onmouseover = "";
        		tmpdiv_1.appendChild(tmpfont_1);
        		obj.appendChild(tmpdiv_1);
			}
			else{
				tmpdiv_1 = document.createElement("div");
				tmpdiv_1.setAttribute("style","position:absolute;"+"left:" + (p1_x-2.5) + "px; top:" + (p1_y-2.5) + "px; width:5px; height:5px");
        		tmpfont_1 = document.createElement("img");
       	 		tmpfont_1.setAttribute("id","pkt_nr"+punkte.length);
        		tmpfont_1.setAttribute("src","res/pkt.gif");
        		tmpfont_1.setAttribute("onmouseover","");
                if(punkte.length<=1){tmpfont_1.setAttribute("onmouseup","$(\"mauszeige\").innerHTML = \"F&uuml;r Streckenmessung werden min. 2 Punkte ben&ouml;tigt....\"");}
                else{tmpfont_1.setAttribute("onmouseup","messenend();");}
        		tmpdiv_1.appendChild(tmpfont_1);
        		obj.appendChild(tmpdiv_1);
			}
		}
		else{
			if(browserName == "ie"){
				if(messenfinish == false && zoom_change != "yes"){
                    tmpdiv_1 = document.createElement("div");
                    tmpdiv_1.style.position = "absolute";
                    tmpdiv_1.style.left = (p1_x-1) + "px";
                    tmpdiv_1.style.top = (p1_y-1) + "px";
                    tmpdiv_1.style.width = "5px";
                    tmpdiv_1.style.height = "5px";
                    tmpfont_1 = document.createElement("img");
                    tmpfont_1.id = "pkt_nr"+punkte.length;
                    tmpfont_1.src= "res/pkt.gif";
                    if(punkte.length<=1){tmpfont_1.onmouseup = function() {"$(\"mauszeige\").innerHTML = \"F&uuml;r Streckenmessung werden min. 2 Punkte ben&ouml;tigt....\"";
};}
                    else{tmpfont_1.onmouseup = function() {messenend();};}
                    tmpfont_1.onmouseover = "";
                    tmpdiv_1.appendChild(tmpfont_1);
                    obj.appendChild(tmpdiv_1);    
                }
                else{
                    for(var i = 0; i < punkte.length; i++){
					    tmpdiv_1 = document.createElement("div");
					    tmpdiv_1.style.position = "absolute";
					    tmpdiv_1.style.left = (punkte[i].getX()-1) + "px";
					    tmpdiv_1.style.top = (punkte[i].getY()-1) + "px";
					    tmpdiv_1.style.width = "5px";
					    tmpdiv_1.style.height = "5px";
        			    tmpfont_1 = document.createElement("img");
       	 			    tmpfont_1.id = "pkt_nr"+(i+1);
        			    tmpfont_1.src = "res/pkt.gif";
                        if(punkte.length<=1){tmpfont_1.onmouseup = function() {alert("Bitte verwenden Sie die linke Maustaste, um einen neuen Punkt zu erzeugen!");};}
                        else{tmpfont_1.onmouseup = function() {messenend();};}
        			    tmpfont_1.onmouseover = "";
        			    tmpdiv_1.appendChild(tmpfont_1);
        			    obj.appendChild(tmpdiv_1);
				    }
                }
			}
			else{
				if(messenfinish == false && zoom_change != "yes"){
                    tmpdiv_1 = document.createElement("div");
                    tmpdiv_1.setAttribute("style","position:absolute;"+"left:" + (p1_x-2.5) + "px; top:" + (p1_y-2.5) + "px; width:5px; height:5px");
                    tmpfont_1 = document.createElement("img");
                    tmpfont_1.setAttribute("id","pkt_nr"+punkte.length);
                    tmpfont_1.setAttribute("src","res/pkt.gif");
                    tmpfont_1.setAttribute("onmouseover","");
                    if(punkte.length<=1){tmpfont_1.setAttribute("onmouseup","$(\"mauszeige\").innerHTML = \"F&uuml;r Streckenmessung werden min. 2 Punkte ben&ouml;tigt....\""
);}
                    else{tmpfont_1.setAttribute("onmouseup","messenend();");}
                    tmpdiv_1.appendChild(tmpfont_1);
                    obj.appendChild(tmpdiv_1);
                }
                else{
                    for(var i = 0; i < punkte.length; i++){
					    tmpdiv_1 = document.createElement("div");
					    tmpdiv_1.setAttribute("style","position:absolute;"+"left:" + (punkte[i].getX()-2.5) + "px; top:" + (punkte[i].getY()-2.5) + "px; width:5px; height:5px");
        			    tmpfont_1 = document.createElement("img");
       	 			    tmpfont_1.setAttribute("id","pkt_nr"+(i+1));
        			    tmpfont_1.setAttribute("src","res/pkt.gif");
        			    tmpfont_1.setAttribute("onmouseover","");
                        if(punkte.length<=1){tmpfont_1.setAttribute("onmouseup","alert(\"Bitte verwenden Sie die linke Maustaste, um einen neuen Punkt zu erzeugen!\");");}
                        else{tmpfont_1.setAttribute("onmouseup","messenend();");}
        			    tmpdiv_1.appendChild(tmpfont_1);
        			    obj.appendChild(tmpdiv_1);
				    }
                }
			}
		}
	}
	//Punkte drawing ende
	document.onmousemove = updatemaus;
    document.onmouseup = "";
}

function getPropertiesOf( id ) {
	var out = "";
	var obj = "";
	if(id != "document" ){
		obj = $(id);
	}else {
		obj = document;
	}
	out += obj;	
	for(prop in obj){
		if(prop.substring(0,2) == "on") {
                      out += "<b>"+prop + "</b> = " + obj[prop] + "<br>\n";
        	}
	}
	window.open("","","").document.write(out);	
}


function punktmove(){
    $("MapImg").onmousedown = "";
	$("MapImg").onmouseup = "";
	setEigenschaft();
}

function pkt_select(wert){
	
	//methode 2 beginn
	messenfinish = false;
    $("MapImg").style.cursor = "crosshair";
    p_nr = wert.substr(1,wert.length-1);
	p_nr_s = "pkt_nr"+wert.substr(1,wert.length-1);
	var deletchild = $("imgPolygon").lastChild;
	verschwenden = $("imgPolygon").removeChild(deletchild);
	if(browserName == "ie"){
		$(p_nr_s).onmouseover = "";
	}
	else{
		$(p_nr_s).setAttribute("onmouseover","");
	}
		polygon_pktmove = "ja";
	letztpkt = 0;
	$("mauszeige").innerHTML = "Anklicken, f&uuml;r neue Position von Punkt "+p_nr;
	if($("iconZoomInSka").src.indexOf("res/btnZoomSka.gif") >= 0){
		$("iconZoomInSka").src="res/btnZoomSka.gif";
	}
	$("MapImg").onmouseup = pktup;
	//methode 2 ende	
}

function pktup(evt){
    $("MapImg").style.cursor = "help";
    divimgLeft = 0;
    divimgTop = 0;
    var messpkt = document.pktPosition;
	var tmp = "", punkte1 = "", punkte2 = "";
    messenfinish = true;
	$("pkt_koord").innerHTML = "";
	var theObj = getRawObject("map");
	evt = (evt) ? evt : event;
	if(evt.button && evt.button != 2 || evt.which && evt.which != 3){    
        if($("menu")){
            var ElternKnoten = $("map");
            var ChildKnoten = $("menu");
            removeKnoten = ElternKnoten.removeChild(ChildKnoten);
        }
        var x, y;
	    if (evt.pageX) {
            x = evt.pageX - theObj.offsetLeft;
            y = evt.pageY - theObj.offsetTop-95;
        } else if (evt.offsetX || evt.offsetY) {
            x = evt.offsetX;
            y = evt.offsetY;
        } else if (evt.clientX) {
            x = evt.clientX;
            y = evt.clientY;
        }
	    
        if(browserName != 'ie'){
		    x -= 12;
		    y -= 12;
	    }
	    
	    var width = parseFloat(document.formImg.width.value);
        var height = parseFloat(document.formImg.height.value);
        var ru = parseFloat(document.formImg.ru.value);
        var hu = parseFloat(document.formImg.hu.value);
        var ro = parseFloat(document.formImg.ro.value);
        var ho = parseFloat(document.formImg.ho.value);
        var dR = parseFloat(ro) - parseFloat(ru);
        var dH = parseFloat(ho) - parseFloat(hu);
	    punkte1 = document.pktPosition;
	    punkte2 = document.gkpunkte;
	    tmp = s2gk ( x , y, width, height, dR, dH, ru, hu );
	    for(var t = 0; t < punkte1.length; t++){
		    if((t+1) == p_nr){
			    punkte1[t] = new Point(x,y);
			    punkte2[t] = tmp;
		    }
	    }
	    pktmove = 1;
	    p_nr_text = "noleer";
	    if(punkte1.length > 1){
		    if($("iconStrecke").src.indexOf("res/Button_Lineal_aktiv.gif") >= 0){
			    streckeBerechnen();
		    }
		    else if($("iconFlaeche").src.indexOf("res/Button_Lineal_Flaeche_aktiv.gif") >= 0){
			    flaecheBerechnen();
		    }
	    }
	   p_nr = 0;
	    letztpkt = 0;
	    if(browserName == "ie"){
		    $(p_nr_s).onmouseout = function() {setEigenschaft();}
	    }
	    else{
		    $(p_nr_s).setAttribute("onmouseout","setEigenschaft()");
	    }
    }
    else{
        if(messpkt.length > 1){
            var mx = (document.all) ? window.event.x + document.body.scrollLeft : evt.pageX;
            var my = (document.all) ? window.event.y + document.body.scrollTop : evt.pageY;
            kontextmenu('messend',mx,my);
            $("MapImg").onmouseup = pktup;
        }
    }
	    
}

function newmessen(wert){
	if(wert == "streck"){
		initStreckenMess();
	}
	else if(wert == "flaechen"){
		initFlaechenMess();
	}
}

function _pktmove(punktnummer,x,y){
	//neue methode beginn
	$("mauszeige").innerHTML = "Hier klicken, um Punkt "+punktnummer+" auszuw&auml;hlen...";
	$("MapImg").style.cursor = "help";
	$("iconPan").src = "res/Button_Hand.gif";
	var tmpdiv = "", tmpbutton = "", tmpinnerhtml = "", tmpfont = "", tmpbr = "";
	var _left = x-10, _top = y-10;
	var Obj = getRawObject("imgPolygon");
		if(browserName == "ie"){
			tmpdiv = document.createElement("div");
			tmpdiv.id = "select_punkt";
			tmpdiv.style.position = "absolute";
			tmpdiv.style.top = _top+"px";
			tmpdiv.style.left = _left+"px";
			tmpbutton = document.createElement("button");
			p_value = "p"+punktnummer;
			tmpbutton.onclick = new Function ("pkt_select(p_value)");
			tmpbutton.onmouseout = new Function ("undisplay()");
			tmpinnerhtml = document.createTextNode("Punkt "+punktnummer+" ausw\xE4hlen ?");
			tmpbutton.appendChild(tmpinnerhtml);
			tmpdiv.appendChild(tmpbutton);
			Obj.appendChild(tmpdiv);
		}
		else{
			tmpdiv = document.createElement("div");
			tmpdiv.setAttribute("id","select_punkt");
			tmpdiv.setAttribute("style","position:absolute; top:"+_top+"px; left:"+_left+"px");
			tmpbutton = document.createElement("button");
			tmpbutton.setAttribute("value","p"+punktnummer);
			tmpbutton.setAttribute("onclick","pkt_select(this.value)");
			tmpbutton.setAttribute("onmouseout","undisplay()");
			tmpinnerhtml = document.createTextNode("Punkt "+punktnummer+" ausw\xE4hlen ?");
			tmpbutton.appendChild(tmpinnerhtml);
			tmpdiv.appendChild(tmpbutton);
			Obj.appendChild(tmpdiv);
		}
	//neue methode ende
}

function setEigenschaft(){
	var punkte1 = document.pktPosition;
	var pkt_nr; 
	for(var i = 0; i < punkte1.length; i++){
		pkt_nr = "pkt_nr"+(i+1);
		if(browserName == "ie"){
			pnr = i+1;
			px = punkte1[i].getX();
			py = punkte1[i].getY(); 
			$(pkt_nr).onmouseover = new Function ("_pktmove("+pnr+","+px+","+py+")");
		}
		else{$(pkt_nr).setAttribute("onmouseover","_pktmove("+(i+1)+","+punkte1[i].getX()+","+punkte1[i].getY()+")");}
	}
}

mausbewegt = null;

function updatemaus(e){
	var x = (document.all) ? window.event.x + document.body.scrollLeft : e.pageX;
	var y = (document.all) ? window.event.y + document.body.scrollTop : e.pageY;
    if (mausbewegt == null) {
		$("mauszeige").style.left = (x+20) + "px";
		$("mauszeige").style.top = (y+20-95) + "px";
	}
	
	var x1 = EntryX+295;
	var x2 = ExitX+295;
	var y1 = EntryY+55;
	var y2 = ExitY+55;
	if((x > x1 && x < x2) && (y > y1 && y < y2)){
		if(($("iconStrecke").src.indexOf("res/Button_Lineal_aktiv.gif") >= 0 || $("iconFlaeche").src.indexOf("res/Button_Lineal_Flaeche_aktiv.gif") >= 0)){
            $("mauszeige").style. visibility= "visible";
		}
	}
	else{
		$("mauszeige").style.visibility= "hidden";
		if($("menu")){
    		var ElternKnoten = $("map");
        	var ChildKnoten = $("menu");
        	removeKnoten = ElternKnoten.removeChild(ChildKnoten);
		}
	}	
}

function undisplay(){
	/*if($("imgFachdatenLayer").childNodes.length != 0){
		$($("imgFachdatenLayer").lastChild.id).style.cursor = "help";
	}*/
	for(var i=0; i<allimg.length; i++){
		$(allimg[i][0]).style.cursor = "help";
	}
	$("imgMap").style.cursor = "help";
	if($("iconStrecke").src.indexOf("res/Button_Lineal_aktiv.gif") >= 0){
		$("mauszeige").innerHTML = "Strecke: <b>"+$("pkt_koord").innerHTML+"</b>";
	}
	else if($("iconFlaeche").src.indexOf("res/Button_Lineal_Flaeche_aktiv.gif") >= 0){
		var wert = $("pkt_koord").innerHTML.split(",");
		$("mauszeige").innerHTML = "Fl&#228;che: ca. <b>"+wert[0]+"</b><br />Umfang: ca. "+wert[1];
	}
	var deletchild = $("imgPolygon").lastChild;
	verschwenden = $("imgPolygon").removeChild(deletchild);
}

function Add_Ergebnis(){
	var dR = parseFloat(document.formImg.ro.value)-parseFloat(document.formImg.ru.value);
    var dH = parseFloat(document.formImg.ho.value)-parseFloat(document.formImg.hu.value);
	var ro = parseFloat(document.formImg.ro.value);
	var ho = parseFloat(document.formImg.ho.value);
	var ru = parseFloat(document.formImg.ru.value);
	var hu = parseFloat(document.formImg.hu.value);
	var width = parseInt(document.formImg.width.value);
	var height = parseInt(document.formImg.height.value);
	var obj = getRawObject("imgPolygon");
    obj.innerHTML = "";
    if(such_ergebnis == 1){
    	$("imgPolygon").style.visibility = "visible";
    	var pkt_string = $("gk_pkt").innerHTML;
    	var teilstring = pkt_string.split(",");
    	if((parseFloat(teilstring[0]) > ru && parseFloat(teilstring[0]) < ro) && (parseFloat(teilstring[1]) > hu && parseFloat(teilstring[1]) < ho)){
    		var P = gk2s( teilstring[0], teilstring[1], width, height, dR, dH, ru, hu);
    		var _left = P.getX()+5;
    		var _top = P.getY()-35;
    		var tmpdiv1 = "", tmpimg1 = "", tmpdiv2 = "", tmpimg2 = "",tmpfont = "", tmpdiv3 = "", tmpdiv4 = "", tmpimg4 = "";
			tmpdiv1 = document.createElement("div");
			tmpdiv2 = document.createElement("div");
			tmpdiv3 = document.createElement("div");
			tmpimg1 = document.createElement("img");
			tmpimg2 = document.createElement("img");
			tmpfont = document.createElement("font");
			if(browserName == "ie"){
				tmpdiv1.style.position = "absolute";
				tmpdiv1.id = "Ergebnisimg";
				tmpdiv1.style.top = _top+"px";
				tmpdiv1.style.left = _left+"px";
				switch (selectfeld){
					case "koordResult": tmpimg1.src = "res/suchergebnisimg1.gif"; break;
					case "bergResult":	tmpimg1.src = "res/suchergebnisimg1.gif"; break;
					case "gewResult": tmpimg1.src = "res/suchergebnisimg1.gif"; break;
					case "schul_nameResult": tmpimg1.src = "res/suchergebnisimg1.gif"; break;
					default: tmpimg1.src = "res/suchergebnisimg1.gif";
				}
				tmpimg1.width = "15";
				tmpimg1.height = "45";
				tmpdiv2.id = "Ergebnis";
				tmpdiv2.className = "Ergebnis";
				tmpdiv2.style.position = "absolute";
				tmpdiv2.style.top = (_top-59)+"px";
				tmpdiv2.style.left = _left+"px";
				tmpfont.face = "Arial";
				tmpfont.size = "2";
				tmpdiv3.id = "exit";
				tmpdiv3.style.position = "absolute";
				tmpdiv3.style.top = "0";
				tmpdiv3.style.right = "0";
				tmpdiv3.onclick = function() {Ergebnishidden();};
				tmpdiv3.style.cursor = "pointer";
				tmpimg2.src = "res/Ergebnis_exit.gif";
				tmpimg2.width = "14";
				tmpimg2.height = "13";
				
			}	
			else{
				tmpdiv1.setAttribute("style","position:absolute; top:"+_top+"px; left:"+_left+"px");
				tmpdiv1.setAttribute("id","Ergebnisimg");
				switch (selectfeld){
					case "koordResult": tmpimg1.src = "res/suchergebnisimg1.gif"; break;
					case "bergResult":	tmpimg1.src = "res/suchergebnisimg1.gif"; break;
					case "gewResult": tmpimg1.src = "res/suchergebnisimg1.gif"; break;
					case "schuleResult": tmpimg1.src = "res/suchergebnisimg1.gif"; break;
					default: tmpimg1.src = "res/suchergebnisimg1.gif";
				}
				tmpimg2.setAttribute("src","res/Ergebnis_exit.gif");
				tmpdiv2.setAttribute("id","Ergebnis");
				tmpdiv2.setAttribute("class","Ergebnis");
				if(browserName == "mozilla" || browserName == "ns"){tmpdiv2.setAttribute("style","position:relative; top:"+(_top-55)+"px; left:"+(_left+1)+"px");}
				else{tmpdiv2.setAttribute("style","position:absolute; top:"+(_top-56)+"px; left:"+_left+"px");}
				tmpfont.setAttribute("face", "Arial");
				tmpfont.setAttribute("size","2");
				tmpdiv3.setAttribute("id","exit");
				tmpdiv3.setAttribute("style","position:absolute; top:0px; right:0px; cursor:pointer;");
				tmpdiv3.setAttribute("onclick","Ergebnishidden();");
				
			}
			var b = document.createElement("b");
			var u = document.createElement("u");
			if(berg_value_name != null){
				var add_text1 = document.createTextNode("Berg:");
			}
			else if(gew_value_name != null){
				var add_text1 = document.createTextNode(unescape("Gew%E4sser:"));
			}
			else if(schulname_value != null){
				var add_text1 = document.createTextNode("Schule:");
			}
			else if(str_value == null && ort_value != null){
				var add_text1 = document.createTextNode("Ort:");
			}
			else {
				var add_text1 = document.createTextNode("Adresse:");
			}
			var br1 = document.createElement("br");
			var nobr1 = document.createElement("nobr");
			var add_text2  = "";
			if(berg_value_name != null){
				add_text2 = document.createTextNode(berg_value_name);
			}
			else if(gew_value_name != null){
				add_text2 = document.createTextNode(gew_value_name);
			}
			else if(schulname_value != null){
				add_text2 = document.createTextNode(schulname_value);
			}
			else if((str_value == null || str_value == "")&& ort_value != null){
				add_text2 = document.createTextNode("");
			}
			else{
				if(hausnr_value == null){hausnr_value = "";}
				add_text2 = document.createTextNode(str_value+" "+hausnr_value+",");
			}
			var br2 = document.createElement("br");
			var nobr2 = document.createElement("nobr");
			if(berg_value_name != null){
				var add_text3 = document.createTextNode("Gebiet: "+berg_value_ort);
			}
			else if(gew_value_name != null){
				var add_text3 = document.createTextNode("Gebiet: "+gew_value_ort);
			}
			else if(schulname_value != null){
				var add_text3 = document.createTextNode(schulort_value);
			}
			else if(str_value == null){
				var add_text3 = document.createTextNode(ort_value);
			}
			else{
				var add_text3 = document.createTextNode(plz_value+" "+ort_value);
			}
			tmpdiv2.appendChild(tmpfont);
			tmpdiv3.appendChild(tmpimg2);
			tmpdiv2.appendChild(tmpdiv3);
			obj.appendChild(tmpdiv2);
			
			with(tmpfont){
				appendChild(b);
				appendChild(u);
				b.appendChild(add_text1);
				appendChild(br1);
				appendChild(nobr1);
				nobr1.appendChild(add_text2);
				appendChild(br2);
				appendChild(nobr2);
				nobr2.appendChild(add_text3);
			}
			tmpdiv1.appendChild(tmpimg1);
			obj.appendChild(tmpdiv1);
    		}
		}
}

function kontextmenu(schalten,mausx,mausy){
    
    var obj = getRawObject("map");
    var menudiv, menuform, menuinput, menutext;
    switch(schalten){
        case "messbeginn":        
            alert("Bitte verwenden Sie die linke Maustaste, um einen neuen Punkt zu erzeugen!");
            return false;
            break;
        case "messend":
        	if($("menu")){
           		var ElternKnoten = $("map");
            	var ChildKnoten = $("menu");
            	removeKnoten = ElternKnoten.removeChild(ChildKnoten);
        	}
            var mauspkt = mausposition;
            $("mauszeige").style.visibility= "hidden";
            $("iconPan").src = "res/Button_Hand_aktiv.gif";
            menudiv = document.createElement("div");
            menudiv.id = "menu";
            menudiv.className = "menu";
            menudiv.style.position = "absolute";
            menudiv.style.left = (parseInt(mausx)-240)+"px";
            menudiv.style.top = (parseInt(mausy)-105)+"px";
            menudiv.style.height = "60px";
            menudiv.style.width = "135px";
            menudiv.style.zIndex = 100;
            if(browserName == "ie"){
                menuform = document.createElement("<form name='pktbearbeiten'>");
            }
            else{
                menuform = document.createElement("form");
                menuform.name = "pktbearbeiten";
            }
            menuform.method = "get";
            menuform.action = "";
            for(var i=0;i<3;i++){    
                if(browserName == "ie"){menuinput = document.createElement("<input name='new_messen'>");}
                else{
                    menuinput = document.createElement("input");
                    menuinput.name = "new_messen";
                }
                menuinput.type = "radio";
                switch(i){
                    case 0: 
                        menuinput.value = "verschieb";
                        if(browserName == "ie"){menuinput.onclick = function(){new_pkt(this.value);};}
                        else{menuinput.setAttribute("onclick","new_pkt(this.value)");}
                        if(browserName == "ie"){
        					$("MapImg").style.cursor = "url(res/openhand.cur),auto";
        					$("MapImg").style.cursor = "url(res/openhand.cur),move";
    					}
    					else{
        					$("MapImg").style.cursor = "-moz-grab";
    					}
                        menuinput.checked = false;
                        menutext = document.createTextNode("Punkte verschieben");
                        break;
                    case 1: 
                        menuinput.value = "new_messen";
                        if(browserName == "ie"){menuinput.onclick = function(){new_pkt(this.value);};}
                        else{menuinput.setAttribute("onclick","new_pkt(this.value)");}
                        menutext = document.createTextNode("Neu messen");
                        break;
                    case 2: 
                        menuinput.value = "abbrechen";
                        if(browserName == "ie"){menuinput.onclick = function(){new_pkt(this.value);};}
                        else{menuinput.setAttribute("onclick","new_pkt(this.value)");}
                        menutext = document.createTextNode("Abbrechen");
                        break;
                }
            	var br = document.createElement("br");
            	if(i == 0)menuform.appendChild(br);
            	menuform.appendChild(menuinput);
            	menuform.appendChild(menutext);
            	if(i < 2){menuform.appendChild(br);}
            }
            menudiv.appendChild(menuform);
            obj.appendChild(menudiv);
            $("MapImg").onmouseup = "";
            $("MapImg").onmousedown = engage;
            
            return false;
            break;
    }
}
function messenend(){
    var messpkt = document.pktPosition;
    messenfinish = true;
    if(messpkt.length>1){
        if($("iconFlaeche").src.indexOf("res/Button_Lineal_Flaeche_aktiv.gif") >= 0){
        	Polygonzu = "ja";
        	var wert = $("pkt_koord").innerHTML.split(",");
        	$("newpunkt").innerHTML = "Fl&#228;che:<br />ca. <b>"+wert[0]+"</b>"+"<br /><br />Umfang:<br />ca. <b>"+wert[1]+"</b>"+"<br /><br />weitere Optionen: rechte Maustaste.";
        	initPan();
        	drawPoly();
        }
        else if($("iconStrecke").src.indexOf("res/Button_Lineal_aktiv.gif") >= 0){
        	$("newpunkt").innerHTML = "Strecke:<br />ca. <b>"+$("pkt_koord").innerHTML+"</b><br /><br />weitere Optionen: rechte Maustaste.";
        	initPan();
        }
    }
    else{
        if($("iconStrecke").src.indexOf("res/Button_Lineal_aktiv.gif") >= 0){
            initStreckenMess();
        }
        else if($("iconFlaeche").src.indexOf("res/Button_Lineal_Flaeche_aktiv.gif") >= 0){
            initFlaechenMess();
        }
    }
}
function buttontausch(layername){
    switch(layername){
        case "TK":
            $('imgTK').src = "res/Button_Karte_aktiv.gif";
            $('imgDOP').src = "res/Button_Orthophoto.gif";
            $('imgHybrid').src = "res/Button_Hybrid.gif";
            $('imgHist').src = "res/Button_Hist.gif";
            break;
        case "DOP":
            $('imgTK').src = "res/Button_Karte.gif";
            $('imgDOP').src = "res/Button_Orthophoto_aktiv.gif";
            $('imgHybrid').src = "res/Button_Hybrid.gif";
            $('imgHist').src = "res/Button_Hist.gif";
            break;
        case "Hybrid":
            $('imgTK').src = "res/Button_Karte.gif";
            $('imgDOP').src = "res/Button_Orthophoto.gif";
            $('imgHybrid').src = "res/Button_Hybrid_aktiv.gif";
            $('imgHist').src = "res/Button_Hist.gif";
            break;
        case "Hist":
            $('imgTK').src = "res/Button_Karte.gif";
            $('imgDOP').src = "res/Button_Orthophoto.gif";
            $('imgHybrid').src = "res/Button_Hybrid.gif";
            $('imgHist').src = "res/Button_Hist_aktiv.gif";
            break;
        default:
            /*if($("imgFachdatenLayer").childNodes.length == 0){
                if(layer == "DOP40"){layer = "DOP";}
                switch(layer){
                    case "TK":
                        $('btnTK').style.color = "8b0000";
                        $('btnDOP').style.color = "000000";
                        $('btnHybrid').style.color = "000000";
                        break;
                    case "DOP":
                        $('btnTK').style.color = "000000";
                        $('btnDOP').style.color = "8b0000";
                        $('btnHybrid').style.color = "000000";
                        break;
                    case "Hybird":
                        $('btnTK').style.color = "000000";
                        $('btnDOP').style.color = "000000";
                        $('btnHybrid').style.color = "8b0000";
                        break;   
                }
            }*/
            break;
   } 
}

function mausposition(evt){
    
    var x = (document.all) ? window.event.x + document.body.scrollLeft : e.pageX;
    var y = (document.all) ? window.event.y + document.body.scrollTop : e.pageY;
    y -= 95;
    return new mauspkt(x,y);
}

var startTop, startLeft;
var effectDone = false;
function toggleEffect() {
      if ( !effectDone ) {
         startEffect();
         effectDone = true;
         
      }
      else {
         resetEffect();
         effectDone = false;
         
      }
}

function startEffect() {
      startTop   = $('navpan').offsetTop;
      startLeft  = $('navpan').offsetLeft;
      new Rico.Effect.Position( 'navpan', 1, null, 500, 10);
      $("navpanControl").src = "res/wopen.gif";
}

function resetEffect() {
      $('navpan').style.top   = startTop;
      $('navpan').style.left  = startLeft;
      $("navpanControl").src = "res/wclosed.gif";
}

function new_pkt(wert){
	if($("menu")){
        var ElternKnoten = $("map");
        var ChildKnoten = $("menu");
        removeKnoten = ElternKnoten.removeChild(ChildKnoten);
    }
    var tmpdiv = "", tmpbutton = "", tmpinnerhtml = "", tmpfont = "", tmpbr = "";
	switch (wert){
		case "verschieb":
			s_firstmessen = 1;
			$("MapImg").style.cursor = "help";
             
			if($("iconStrecke").src.indexOf("res/Button_Lineal_aktiv.gif") >= 0){
			    $("newpunkt").innerHTML = "Strecke: <b>"+$("pkt_koord").innerHTML+"</b><br>Punkt verschieben:<br/>bitte Punkt mit linker Maustaste ausw&auml;hlen und neue Position w&auml;hen";		
			}
			else if($("iconFlaeche").src.indexOf("res/Button_Lineal_Flaeche_aktiv.gif") >= 0){
			    var wert = $("pkt_koord").innerHTML.split(",");
			    //Sie m&ouml;chten Punkte verschieben, dann sollen Sie:<br>- Maus auf den Punkt bewegen, und ausw&auml;hlen, Eine neue Position f&uuml;r ausgew&auml;hlte Punkt anklicken
			    $("newpunkt").innerHTML = "Fl&auml;che: ca. <b>"+wert[0]+"</b><br/>Umfang: "+wert[1]+"<br/><br/>Punkt verschieben:<br/>bitte Punkt mit linker Maustaste ausw&auml;hlen und neue Position w&auml;hen";
			}
            punktmove();
			break;
		case "new_messen":
            $("newpunkt").innerHTML = "";
            pktmove = 0; 
			if($("iconStrecke").src.indexOf("res/Button_Lineal_aktiv.gif") >= 0){
				initStreckenMess();
				s_firstmessen = 0;
			}
			else if($("iconFlaeche").src.indexOf("res/Button_Lineal_Flaeche_aktiv.gif") >= 0){
				initFlaechenMess();
			}
            break;
		case "abbrechen":
            		$("newpunkt").style.visibility="hidden";
	    		$("newpunkt").innerHTML = "";
			initPan();
			$("mauszeige").style.visibility= "hidden";
			$("iconPan").src = "res/Button_Hand_aktiv.gif";
			$("iconStrecke").src = "res/Button_Lineal.gif";
			$("iconFlaeche").src = "res/Button_Lineal_Flaeche.gif";
			document.gkpunkte = "";
			document.gkDrawPunkte = "";
			document.pktPosition = "";
			p_nr = 0, letztpkt = 0;
			p_nr_text = "leer", Polygonzu = "nein";
			var obj = getRawObject("imgPolygon");
			obj.innerHTML = "";
            pktmove = 0;
			break;
    } 
}
function showSearchForm(was){
        ersttaste = "no";
        switch(was){
        	case "ort":
        		new Ajax.Updater('searchForm', 'such_ort.html', {asynchronous:true}); break;
        	case "adr":
        		new Ajax.Updater('searchForm', 'such_adr.html', {asynchronous:true}); break;
        	case "berg":
        		new Ajax.Updater('searchForm', 'such_berg.html', {asynchronous:true}); break;
        	case "gew":
        		new Ajax.Updater('searchForm', 'such_gew.html', {asynchronous:true}); break;
        	case "schule":
        		new Ajax.Updater('searchForm', 'such_schul.html', {asynchronous:true}); break;
        }
        str_value = null;
        plz_value = null;
        ort_value = null;
        hausnr_value = null;
        berg_value_name = null;
        berg_value_ort = null;
        gew_value_name = null;
        gew_value_ort = null;
        schulname_value = null;
        schulort_value = null; 
}
function Ergebnishidden(){
	$("Ergebnis").style.visibility="hidden";
	$("Ergebnisimg").style.visibility = "hidden";
	such_ergebnis = 0;
}
function showlocation(){
    var rm = parseInt(parseFloat(document.formImg.ru.value)+(parseFloat(document.formImg.ro.value)-parseFloat(document.formImg.ru.value))/2);
    var hm = parseInt(parseFloat(document.formImg.hu.value)+(parseFloat(document.formImg.ho.value)-parseFloat(document.formImg.hu.value))/2);
    var new_koord = runden10(rm,hm); 
    Step = document.formImg.massstap.value;
    url = "index.cgi?rw="+new_koord.getX()+"&hw="+new_koord.getY()+"&layer="+layer+"&step="+Step;
    window.location.href = url;  
}
function runden10(koord_rm,koord_hm){
    var unit_rm = parseInt(String(koord_rm).substr(6,1));
    var unit_hm = parseInt(String(koord_hm).substr(6,1));
    var difference = 0;
    if(unit_rm>0 && unit_rm<=5){
        koord_rm = koord_rm - unit_rm;
    }
    else if(unit_rm>5 && unit_rm<=9){
        koord_rm = koord_rm + (10 - unit_rm);
    }
    if(unit_hm>0 && unit_hm<=5){
        koord_hm = koord_hm - unit_hm;
    }
    else if(unit_hm>5 && unit_hm<=9){
        koord_hm = koord_hm + (10 - unit_hm);
    }
    return new Point(koord_rm,koord_hm);   
}
function clickOverview(evt) { 
    evt = (evt) ? evt : event;
    var theObj = getRawObject("imgMap");
	var x, y;
    if (evt.pageX) {
            x = evt.pageX - document.getElementById('overview').offsetLeft;
            y = evt.pageY - document.getElementById('overview').offsetTop-95;
 	} else if (evt.offsetX || evt.offsetY) {
            x = evt.offsetX;
            y = evt.offsetY;
	} else if (evt.clientX) {
            x = evt.clientX;
            y = evt.clientY;
	}
    var width = parseFloat(document.formOvImg.width.value);
    var height = parseFloat(document.formOvImg.height.value);

    var ru = parseFloat(document.formOvImg.ru.value);
    var hu = parseFloat(document.formOvImg.hu.value);
    var ro = parseFloat(document.formOvImg.ro.value);
    var ho = parseFloat(document.formOvImg.ho.value);
	var dR = parseFloat(ro) - parseFloat(ru);
    var dH = parseFloat(ho) - parseFloat(hu);
	var dR = dR / width * x;
    var dH = dH / height * (height - y);
    var mitteR = parseInt(ru + dR);
    var mitteH = parseInt(hu + dH);
    var map_width = parseFloat(document.formImg.width.value);
    var map_height = parseFloat(document.formImg.height.value);
    var map_ru = parseFloat(document.formImg.ru.value);
    var map_hu = parseFloat(document.formImg.hu.value);
    var map_ro = parseFloat(document.formImg.ro.value);
    var map_ho = parseFloat(document.formImg.ho.value);
    
    var map_dR = parseFloat(map_ro) - parseFloat(map_ru);
    var map_dH = parseFloat(map_ho) - parseFloat(map_hu);
    ru = mitteR - (map_dR / 2);
    hu = mitteH - (map_dH / 2);
    ro = mitteR + (map_dR / 2);
    ho = mitteH + (map_dH / 2);
    document.formImg.ru.value = ru;
    document.formImg.hu.value = hu;
    document.formImg.ro.value = ro;
    document.formImg.ho.value = ho;
    document.formImg.rm.value = ru+(ro-ru)/2;
    document.formImg.hm.value = hu+(ho-hu)/2;
    updateMap();
    mapdiv = 0;
    if(document.pktPosition && (document.pktPosition.length > 0) ) {
    	$("imgPolygon").innerHTML = "";
        $("imgPolygon").style.visibility = "visible";
    	var punkte1 = document.gkpunkte;
    	var punkte2 = document.pktPosition;
		for(var t = 0; t < punkte1.length; t++){
			punkte2[t] = gk2s(punkte1[t].getX(), punkte1[t].getY(), width, height, dR, dH, ru, hu);
		}
	    drawPoly();
        if($("iconStrecke").src.indexOf("res/Button_Lineal.gif") < 0 && $("iconFlaeche").src.indexOf("res/Button_Lineal_Flaeche.gif") < 0){
    		var _obj = getRawObject("imgPolygon");
			_obj.innerHTML = "";
    	}
	}
    if(document.getElementById("pkt_koord").innerHTML == "Ort_wird_gefunden"){
    	var uX = gk2s(document.formImg.ru.value, document.formImg.hu.value, width, height, dR, dH, ru, hu).getX();
        var uY = gk2s(document.formImg.ru.value, document.formImg.hu.value, width, height, dR, dH, ru, hu).getY();
        var oX = gk2s(document.formImg.ro.value, document.formImg.ho.value, width, height, dR, dH, ru, hu).getX();
        var oY = gk2s(document.formImg.ro.value, document.formImg.ho.value, width, height, dR, dH, ru, hu).getY();
        var ergebnisXY = gk2s(document.formImg.rm.value, document.formImg.hm.value, width, height, dR, dH, ru, hu);
        if(ergebnisXY.getY()<uY && ergebnisXY.getY()>oY && ergebnisXY.getX()>uX && ergebnisXY.getX()<oX && document.getElementById("Ergebnisimg")){
        	document.getElementById("imgPolygon").style.visibility = "visible";
			document.getElementById("Ergebnisimg").style.top = ergebnisXY.getY()-5;
			document.getElementById("Ergebnisimg").style.left = ergebnisXY.getX()-5;
			document.getElementById("Ergebnis").style.top = ergebnisXY.getY()-55;
			document.getElementById("Ergebnis").style.left = ergebnisXY.getX()+15;
        }
        else{document.getElementById("imgPolygon").style.visibility = "visible"; Add_Ergebnis();}
	}
	if(browserName == "ie"){
   		document.getElementById("MapImg").style.cursor = "url(res/openhand.cur),auto";
   		document.getElementById("MapImg").style.cursor = "url(res/openhand.cur),move";
   	}
	else{
		document.getElementById("MapImg").onmousemove = "";
		document.getElementById("MapImg").onmouseup = "";
		document.getElementById("MapImg").onmousedown = engage;
		document.getElementById("MapImg").style.cursor = "-moz-grab";
	}
	Mapmove = 1;
}

function updateOverviewRect () {
    var map_width = parseFloat(document.formImg.width.value);
    var map_height = parseFloat(document.formImg.height.value);
    var map_ru = parseFloat(document.formImg.ru.value);
    var map_hu = parseFloat(document.formImg.hu.value);
    var map_ro = parseFloat(document.formImg.ro.value);
    var map_ho = parseFloat(document.formImg.ho.value);

    var map_dR = parseFloat(map_ro) - parseFloat(map_ru);
    var map_dH = parseFloat(map_ho) - parseFloat(map_hu);

    var map_mitteR = map_ru + (map_dR/2);
    var map_mitteH = map_hu + (map_dH/2);

	var width = parseFloat(document.formOvImg.width.value);
    var height = parseFloat(document.formOvImg.height.value);

    var ru = parseFloat(document.formOvImg.ru.value);
    var hu = parseFloat(document.formOvImg.hu.value);
    var ro = parseFloat(document.formOvImg.ro.value);
    var ho = parseFloat(document.formOvImg.ho.value);
    var dR = parseFloat(ro) - parseFloat(ru);
    var dH = parseFloat(ho) - parseFloat(hu);

    var x = (map_ru - ru) * width  / dR;
    var y = (ho - map_ho) * height / dH;

    var w = width * map_dR / dR;
    var h = height * map_dH / dH;

    document.getElementById('OvRect').style.left = x + "px";
    document.getElementById('OvRect').style.top  = y + "px";
    document.getElementById('OvRect').style.width  = w + "px";
    document.getElementById('OvRect').style.height = h + "px";

    var mitteR = x + w/2;
    var mitteH = y + h/2;

    document.getElementById('OvN').style.left = mitteR + "px";
    document.getElementById('OvN').style.height = (y-1) + "px";

    moveAndScaleElemTo('OvE', parseInt((x + w + 1)),  parseInt(mitteH),  parseInt(((width - (x + w)) -1 )),  1);
    moveAndScaleElemTo('OvS', parseInt(mitteR),  parseInt((y + h + 1)),  1,  parseInt((height - (y + h) - 1)) );
    moveAndScaleElemTo('OvW', 0, parseInt(mitteH), parseInt((x - 1)), 1);
}
function showoverview(){
    $("overview").style.zIndex = 11;
}
function hiddenoverview(){
    $("overview").style.zIndex = 9;
}
// Global holds reference to selected element
var selObj;
// Globals hold location of click relative to element
var resizeButton_offsetX; 
var resizeButton_offsetY;
var resizeButton_oldX;
var resizeButton_oldY;

function resizeMap(obj) { //  deltaLeft, deltaTop, deltaWidth, deltaHeight) {
    zoom_change = "yes";
    var minwidth = 200;
    var maxwidth = 1000;
    var minheight = 200;
    var maxheight = 1000;

    var theObj = getRawObject(obj);
    var wrap = "imgMapWrap"
	var theWrapObj = getRawObject(wrap);

    var oldwidth = parseFloat(document.formImg.width.value);
	var oldheight = parseFloat(document.formImg.height.value);

    var newwidth = getObjectWidth(obj);
    var newheight = getObjectHeight(obj);
    if(newwidth < minwidth ) newwidth = minwidth;
    if(newwidth > maxwidth) newwidth = maxwidth;
    if(newheight < minheight ) newheight = minheight;
    if(newheight > maxheight) newheight = maxheight;

    var old_dR = parseFloat(document.formImg.ro.value) - parseFloat(document.formImg.ru.value);
    var old_dH = parseFloat(document.formImg.ho.value) - parseFloat(document.formImg.hu.value);
    var mitteR = parseFloat(document.formImg.ru.value) + (old_dR/2);
    var mitteH = parseFloat(document.formImg.hu.value) + (old_dH/2);

    var new_dR = old_dR / oldwidth * newwidth;
    var new_dH = old_dH / oldheight * newheight;
    var ru = mitteR - new_dR / 2;
    var hu = mitteH - new_dH / 2;
    var ro = mitteR + new_dR / 2;
    var ho = mitteH + new_dH / 2;

	theWrapObj.style.width = (newwidth + 5) + "px";
    theWrapObj.style.height = (newheight + 5) + "px";
    theObj.style.width = newwidth + "px";
    theObj.style.height = newheight + "px";

    document.formImg.ru.value = ru;
    document.formImg.hu.value = hu;
    document.formImg.ro.value = ro;
    document.formImg.ho.value = ho;
    document.formImg.width.value = newwidth;
    document.formImg.height.value = newheight;
	var dR = parseFloat(ro) - parseFloat(ru);
    var dH = parseFloat(ho) - parseFloat(hu);
	updateMap();
	if(document.pktPosition && (document.pktPosition.length > 0) ) {
                var punkte1 = document.gkpunkte;
    			var punkte2 = document.pktPosition;
				for(var t = 0; t < punkte1.length; t++){
					punkte2[t] = gk2s(punkte1[t].getX(), punkte1[t].getY(), newwidth, newheight, dR, dH, ru, hu);
				}
                drawPoly();
        }
}

function engageResizeButton(evt) {
    
	evt = (evt) ? evt : event;
	selObj = document.getElementById("btnImgScale");   
  	if (selObj) {
        if (evt.pageX) {
            resizeButton_offsetX = evt.pageX - ((selObj.offsetLeft) ? 
                      selObj.offsetLeft : selObj.left);
            resizeButton_offsetY = evt.pageY - ((selObj.offsetTop) ? 
                      selObj.offsetTop : selObj.top);
        } else if (evt.offsetX || evt.offsetY) {
            resizeButton_offsetX = evt.offsetX - ((evt.offsetX < -2) ? 
                      0 : document.body.scrollLeft);
            resizeButton_offsetY = evt.offsetY - ((evt.offsetY < -2) ? 
                      0 : document.body.scrollTop);
        } else if (evt.clientX) {
            resizeButton_offsetX = evt.clientX - ((selObj.offsetLeft) ? 
                      selObj.offsetLeft : 0);
            resizeButton_offsetY = evt.clientY - ((selObj.offsetTop) ? 
                      selObj.offsetTop : 0);
        }
	resizeButton_oldX = parseInt(document.getElementById("btnImgScale").style.left) ;
	resizeButton_oldY = parseInt(document.getElementById("btnImgScale").style.top) ;
	document.getElementById("btnImgScale").onmousemove = dragResizeButton;
        return false;
    }
}

function dragResizeButton(evt) {
	evt = (evt) ? evt : event;
    	
    if (selObj) {
        if (evt.pageX) {
			document.getElementById("btnImgScale").style.left = evt.pageX+"px";
            document.getElementById("btnImgScale").style.top = evt.pageY+"px";
		} else if (evt.clientX || evt.clientY) {
		var ttx = getObjectLeft("map");
	    var tty = getObjectTop("map");
            shiftTo(selObj, (evt.clientX - resizeButton_offsetX - ttx), (evt.clientY - resizeButton_offsetY - tty));
        }
        evt.cancelBubble = true;
	document.getElementById("btnImgScale").onmousemove = dragResizeButton;
	document.getElementById("btnImgScale").onmouseup = releaseResizeButton;
	return false;
    }
}

// Turn selected element off
function releaseResizeButton(evt) {
    evt = (evt) ? evt : event;

    if (evt.pageX) {
            resizeButton_offsetX = evt.pageX; 
            resizeButton_offsetY = evt.pageY; 
	} else if (evt.offsetX || evt.offsetY) {
            resizeButton_offsetX = evt.offsetX;
            resizeButton_offsetY = evt.offsetY;
	} else if (evt.clientX) {
            resizeButton_offsetX = evt.clientX; 
            resizeButton_offsetY = evt.clientY;
	}
	var btnScaleX = parseInt(document.getElementById("btnImgScale").style.left);
	var btnScaleY = parseInt(document.getElementById("btnImgScale").style.top);
    var deltaX = btnScaleX - resizeButton_oldX;
    var deltaY = btnScaleY - resizeButton_oldY;
    moveAndScaleElemBy("btnSO", deltaX, deltaY, 0, 0 );
   	moveAndScaleElemBy("btnS", 0, deltaY, deltaX, 0 );
   	moveAndScaleElemBy("btnSW", 0, deltaY, 0, 0 );
   	moveAndScaleElemBy("btnW", 0, 0, 0, deltaY );
   	moveAndScaleElemBy("btnO",  deltaX, 0, 0, deltaY );
   	moveAndScaleElemBy("btnNO", deltaX, 0, 0, 0 );
   	moveAndScaleElemBy("btnN", 0, 0, deltaX, 0 );

	moveAndScaleElemBy("imgMapWrap", 0, 0, (deltaX-1), (deltaY-1) );
   	moveAndScaleElemBy("imgMap", 0, 0, (deltaX-4), (deltaY-4) );
   	resizeMap("imgMap");
	resizeButton_oldX = parseInt(document.getElementById("btnImgScale").style.left) ;
    resizeButton_oldY = parseInt(document.getElementById("btnImgScale").style.top) ;
	document.getElementById("btnImgScale").onmousemove = ""; 
	if (selectedObj) {}
}
function initPan(){
    var messpkt = document.pktPosition;
	zoom_change = "yes";
	s_firstmessen = 1; pktmove = 0;
	if(browserName == "ie"){
        $("MapImg").style.cursor = "url(res/openhand.cur),auto";
        $("MapImg").style.cursor = "url(res/openhand.cur),move";
    }
    else{
        $("MapImg").style.cursor = "-moz-grab";
    }
    $("MapImg").onmousedown = engage;
	$("iconPan").src = "res/Button_Hand_aktiv.gif";
	
    if(document.formImg.ZoomStep.value != "Step8"){
        $("iconZoomInSka").src="res/Button_Lupe.gif";
        $("btnZoomIn").src="res/Button_vergroesserung.gif";
	}
	else{
		$("iconZoomInSka").src="res/Button_Lupe.gif";
		$("btnZoomIn").src="res/Button_vergroesserung.gif";
	}
    var stepstatus = document.formImg.ZoomStep.value;
    if(layer == "DOP40") {layer = "DOP";}
	if($("iconStrecke").src.indexOf("res/Button_Lineal_aktiv.gif")<0 && $("iconFlaeche").src.indexOf("res/Button_Lineal_Flaeche_aktiv.gif")<0){
        $("mauszeige").innerHTML= "";
	}
    if(messpkt && messpkt.length<1){
		$("iconStrecke").src = "res/Button_Lineal.gif";
		$("iconFlaeche").src = "res/Button_Lineal_Flaeche.gif";
        messenfinish = true;
	}
	var obj = getRawObject("pktm");
    obj.innerHTML = "";
    document.onmouseclick = "";
}

function panMap(obj, dr, dh) { 
    var theObj = getRawObject(obj);
    var width = parseFloat(document.formImg.width.value);
    var height = parseFloat(document.formImg.height.value);

    var ru = parseFloat(document.formImg.ru.value);
    var hu = parseFloat(document.formImg.hu.value);
    var ro = parseFloat(document.formImg.ro.value);
    var ho = parseFloat(document.formImg.ho.value);
    var dR = parseFloat(ro) - parseFloat(ru);
    var dH = parseFloat(ho) - parseFloat(hu);

    var dR = dR / width * -1 * dr;
    var dH = dH / height * dh;
    var ru = ru + dR;
    var hu = hu + dH;
    var ro = ro + dR;
    var ho = ho + dH;

    document.formImg.ru.value = ru;
    document.formImg.hu.value = hu;
    document.formImg.ro.value = ro;
    document.formImg.ho.value = ho;
	dR = parseFloat(ro) - parseFloat(ru);
    dH = parseFloat(ho) - parseFloat(hu);
    updateMap();
	if(document.pktPosition && (document.pktPosition.length > 0) ) {
        $("imgPolygon").style.visibility = "visible";
    	var punkte1 = document.gkpunkte;
    	var punkte2 = document.pktPosition;
		for(var t = 0; t < punkte1.length; t++){
			punkte2[t] = gk2s(punkte1[t].getX(), punkte1[t].getY(), width, height, dR, dH, ru, hu);
		}
	    drawPoly();
        if($("iconStrecke").src.indexOf("res/Button_Lineal.gif") < 0 && $("iconFlaeche").src.indexOf("res/Button_Lineal_Flaeche.gif") < 0){
    		var _obj = getRawObject("imgPolygon");
			_obj.innerHTML = "";
    	}
	}
    if($("pkt_koord").innerHTML == "Ort_wird_gefunden"){
    	var uX = gk2s(document.formImg.ru.value, document.formImg.hu.value, width, height, dR, dH, ru, hu).getX();
        var uY = gk2s(document.formImg.ru.value, document.formImg.hu.value, width, height, dR, dH, ru, hu).getY();
        var oX = gk2s(document.formImg.ro.value, document.formImg.ho.value, width, height, dR, dH, ru, hu).getX();
        var oY = gk2s(document.formImg.ro.value, document.formImg.ho.value, width, height, dR, dH, ru, hu).getY();
	}
}
function navigateMap(evt) { 
    zoom_change = "yes";
    evt = (evt) ? evt : event;
    var target = (evt.target) ? evt.target : evt.srcElement;
    var id = (target.name || target.id) ? (target.id || target.name) : "";
	switch(id){
		case "btnW_img": id = "btnW"; break;
		case "btnO_img": id = "btnO"; break;
	}
    var width = parseFloat(document.formImg.width.value);
    var height = parseFloat(document.formImg.height.value);

    var ru = parseFloat(document.formImg.ru.value);
    var hu = parseFloat(document.formImg.hu.value);
    var ro = parseFloat(document.formImg.ro.value);
    var ho = parseFloat(document.formImg.ho.value);
    var dR = parseFloat(ro) - parseFloat(ru);
    var dH = parseFloat(ho) - parseFloat(hu);

    var dR = dR / 2;
    var dH = dH / 2;
   switch(id){
	case 'btnNW':
	    moveMap( (-1*dR), dH);
            break;
	case 'btnN':
	    moveMap( 0, dH);
            break;
	case 'btnNO':
	    moveMap( dR, dH);
            break;
	case 'btnW':
	    moveMap( (-1*dR), 0);
            break;
	case 'btnO':
	    moveMap( dR, 0 );
            break;
	case 'btnSW':
	    moveMap( (-1*dR), (-1*dH));
            break;
	case 'btnS':
	    moveMap( 0, (-1*dH) );
            break;
	case 'btnSO':
	    moveMap( dR, (-1*dH) );
            break;
   }
}

function moveMap (dR, dH) {
    var theObj = getRawObject("imgMap");
    var width = parseFloat(document.formImg.width.value);
    var height = parseFloat(document.formImg.height.value);
    var ru = parseFloat(document.formImg.ru.value);
    var hu = parseFloat(document.formImg.hu.value);
    var ro = parseFloat(document.formImg.ro.value);
    var ho = parseFloat(document.formImg.ho.value);
    var ru = ru + dR;
    var hu = hu + dH;
    var ro = ro + dR;
    var ho = ho + dH;

    document.formImg.ru.value = ru;
    document.formImg.hu.value = hu;
    document.formImg.ro.value = ro;
    document.formImg.ho.value = ho;
	var dR = parseFloat(ro) - parseFloat(ru);
    var dH = parseFloat(ho) - parseFloat(hu);
    document.formImg.rm.value = 0;
    document.formImg.hm.value = 0;
	updateMap();
    if(document.pktPosition && (document.pktPosition.length > 0) ) {
        //messenend();
        $("imgPolygon").style.visibility = "visible";
        var punkte1 = document.gkpunkte;
        var punkte2 = document.pktPosition;
        for(var t = 0; t < punkte1.length; t++){
            punkte2[t] = gk2s(punkte1[t].getX(), punkte1[t].getY(), width, height, dR, dH, ru, hu);
        }
        if(messenfinish == false) $("imgPolygon").innerHTML = "";
        drawPoly();
        if($("iconStrecke").src.indexOf("res/Button_Lineal.gif") < 0 && $("iconFlaeche").src.indexOf("res/Button_Lineal_Flaeche.gif") < 0){
            var _obj = getRawObject("imgPolygon");
            _obj.innerHTML = "";
        }
    }
    if($("pkt_koord").innerHTML == "Ort_wird_gefunden"){
        var uX = gk2s(document.formImg.ru.value, document.formImg.hu.value, width, height, dR, dH, ru, hu).getX();
        var uY = gk2s(document.formImg.ru.value, document.formImg.hu.value, width, height, dR, dH, ru, hu).getY();
        var oX = gk2s(document.formImg.ro.value, document.formImg.ho.value, width, height, dR, dH, ru, hu).getX();
        var oY = gk2s(document.formImg.ro.value, document.formImg.ho.value, width, height, dR, dH, ru, hu).getY();
    }
    Mapmove = 1;
    document.onmouseclick = "";
    if(polygon_pktmove == "ja") $("MapImg").onmouseup = pktup; 
}

var ortsuch_result = "leer";
var zoom_change = "no";

function setCanvas (/*in: LayerReferenz */ objLayer,
                    /*in: Canvas */ canvas) {
    if (document.layers) {
      objLayer.top = canvas.y;
      objLayer.left = canvas.x;
      objLayer.clip.width = canvas.width;
      objLayer.clip.height = canvas.height;
    } else if ( window.opera ) {
      objLayer.style.top = canvas.y;
      objLayer.style.left = canvas.x;
      objLayer.style.height = canvas.height;
      objLayer.style.width = canvas.width;
    } else if (document.all) {
      objLayer.style.pixelTop = canvas.y ;
      objLayer.style.pixelLeft = canvas.x ;
      objLayer.style.height = canvas.height;
      objLayer.style.width = canvas.width;
    } else if ($) {
      objLayer.style.top = canvas.y + 'px';
      objLayer.style.left = canvas.x + 'px';
      objLayer.style.height = canvas.height + 'px';
      objLayer.style.width = canvas.width + 'px';
    }
}

function Canvas(x, y, width, height){
  this.width = (!width)?0:width;
  this.height = (!height)?0:height;

  this.x = x;
  this.y = y;
}
/*function zoom_down(){
 	$("iconZoomInSka").src = "res/btnZoomSka.gif";
 	$("iconPan").src="res/Button_Hand.gif";
}*/
/*function zoom_move(evt){
}*/
function zoomStep(stufe){
	s_firstmessen = 1;
	zoom_change = "yes";
	var stufzahl = "Step"+stufe;
	if(layer == "DOP40"){layer = "DOP";}
    switch (stufzahl){
    	case "Step0":
    		zoomstepcontrol(layer,stufzahl);
    		break;
    	case "Step1":
    		zoomstepcontrol(layer,stufzahl);
    		break;
    	case "Step2":
    		zoomstepcontrol(layer,stufzahl);
    		break;
    	case "Step3":
    		zoomstepcontrol(layer,stufzahl);
    		break;
    	case "Step4":
    		zoomstepcontrol(layer,stufzahl);
    		break;
    	case "Step5":
    		zoomstepcontrol(layer,stufzahl);
    		break;
    	case "Step6":
    		zoomstepcontrol(layer,stufzahl);
    		break;
    	case "Step7":
    		zoomstepcontrol(layer,stufzahl);
    		break;
    	case "Step8":
    		zoomstepcontrol(layer,stufzahl);
    		break;
    }
}
/*function zoom_up(){
	var rect_height = parseInt($("iconZoom_move").style.height)-1.5;
	var step_stuf;
	if(rect_height < 4.5){
    	$("iconZoom_move").style.top = "-52px";
    	$("iconZoom_move").style.left = "12px";
    	$("iconZoom_move").style.width = "8px";
    	$("iconZoom_move").style.height = "3px";
    	document.formImg.ZoomStep.value = "step1";
    	step_stuf = "1";
    }
    else if(rect_height >= 4.5 && rect_height < 7.5){
    	$("iconZoom_move").style.top = "-39px";
    	$("iconZoom_move").style.left = "9px";
    	$("iconZoom_move").style.width = "8px";
    	$("iconZoom_move").style.height = "6px";
    	document.formImg.ZoomStep.value = "step2";
    	step_stuf = "2";
    }
    else if(rect_height >= 7.5 && rect_height < 10.5){
    	$("iconZoom_move").style.top = "-26px";
    	$("iconZoom_move").style.left = "6px";
    	$("iconZoom_move").style.width = "8px";
    	$("iconZoom_move").style.height = "9px";
    	document.formImg.ZoomStep.value = "step3";
    	step_stuf = "3";
    }
    else if(rect_height >= 10.5 && rect_height < 13.5){
    	$("iconZoom_move").style.top = "-13px";
    	$("iconZoom_move").style.left = "3px";
    	$("iconZoom_move").style.width = "8px";
    	$("iconZoom_move").style.height = "12px";
    	document.formImg.ZoomStep.value = "step4";
    	step_stuf = "4";
    }
    else if(rect_height >= 13.5 && rect_height < 16.5){
    	$("iconZoom_move").style.top = "0px";
    	$("iconZoom_move").style.left = "0px";
    	$("iconZoom_move").style.width = "8px";
    	$("iconZoom_move").style.height = "15px";
    	document.formImg.ZoomStep.value = "step5";
    	step_stuf = "5";
    }
    else if(rect_height >= 16.5 && rect_height < 19.5){
    	$("iconZoom_move").style.top = "13px";
    	$("iconZoom_move").style.left = "-3px";
    	$("iconZoom_move").style.width = "8px";
    	$("iconZoom_move").style.height = "18px";
    	document.formImg.ZoomStep.value = "step6";
    	step_stuf = "6";
    }
    else if(rect_height >= 19.5 && rect_height < 22.5){
    	$("iconZoom_move").style.top = "26px";
    	$("iconZoom_move").style.left = "-6px";
    	$("iconZoom_move").style.width = "8px";
    	$("iconZoom_move").style.height = "21px";
    	document.formImg.ZoomStep.value = "step7";
    	step_stuf = "7";
    }
    else if(rect_height >= 22.5 && rect_height < 25.5){
    	$("iconZoom_move").style.top = "39px";
    	$("iconZoom_move").style.left = "-9px";
    	$("iconZoom_move").style.width = "8px";
    	$("iconZoom_move").style.height = "24px";
    	document.formImg.ZoomStep.value = "step8";
    	step_stuf = "8";
    }
    else if(rect_height >= 25.5 ){
    	$("iconZoom_move").style.top = "52px";
    	$("iconZoom_move").style.left = "-12px";
    	$("iconZoom_move").style.width = "8px";
    	$("iconZoom_move").style.height = "27px";
    	document.formImg.ZoomStep.value = "step9";
    	step_stuf = "9";
    }
    zoomStep(step_stuf);
}*/

function initZoomIn () {
	$("MapImg").style.cursor = "crosshair";
	s_firstmessen = 1;
	var scalezoom = new YAHOO.util.DragDrop("MapImg","paneldrag");
	$("MapImg").onmousedown = "";
	$("MapImg").onmouseup = "";
	$("iconZoomInSka").src="res/Button_Lupe_aktiv.gif";
	$("iconZoomIn").src="res/Button_vergroesserung.gif";
	$("iconZoomOut").src="res/Button_verkleinerung.gif";
	$("iconPan").src="res/Button_Hand.gif";
				
	window.objContainer = getRawObject("zoomWindow");
	window.objZoomSquare = getRawObject("zoom");
	var obj = getRawObject("zoom");
	obj.style.top = 0;
	obj.style.left = 0;
	obj.style.width = 1;
	obj.style.height = 1;

    window.width = parseFloat(document.formImg.width.value);
    window.height = parseFloat(document.formImg.height.value);
    window.ru = parseFloat(document.formImg.ru.value);
    window.hu = parseFloat(document.formImg.hu.value);
    window.ro = parseFloat(document.formImg.ro.value);
    window.ho = parseFloat(document.formImg.ho.value);
    window.dR = parseFloat(ro) - parseFloat(ru);
    window.dH = parseFloat(ho) - parseFloat(hu);

	window.isFixed = false;
	window.zoomCanvas = new Canvas(0,0,1,1);
	window.clickPoint = new Point(10,10);

		setVisibility(objZoomSquare, false);
		$("MapImg").onmousedown = setSquare;
		document.onmousemove = drawSquare;
		document.onmouseup = zoomInMap;
}

function setSquare(evt) {
  initZoomIn ();
  e = evt || window.event;
  window.clickPoint = getClickPoint(e);
  clickPoint = getClickPoint(e);
  setCanvas(window.objZoomSquare, new Canvas(window.clickPoint.getX(), window.clickPoint.getY(), 1, 1));
  setVisibility(objZoomSquare, true);
	window.isFixed = true;
  }

function drawSquare(evt){
  zoom_change = "yes";
  e = evt || window.event;
  var mouseXY = "";
  if(window.isFixed){
    mouseXY =  getClickPoint(e);
    var diffx = mouseXY.getX() - window.clickPoint.getX();
    var diffy = mouseXY.getY() - window.clickPoint.getY();
    window.zoomCanvas = new Canvas(window.clickPoint.getX(), window.clickPoint.getY());

    if( (diffx) < 0) {
        window.zoomCanvas.x = (window.clickPoint.getX() + diffx);
    }
    if( (diffy) < 0 ){
        window.zoomCanvas.y = (window.clickPoint.getY() + diffy );
    }
    window.zoomCanvas.height = Math.abs(diffy);
    window.zoomCanvas.width = Math.abs(diffx);
    setCanvas(window.objZoomSquare, window.zoomCanvas);
  }	
}

function zoomInMap(evt){
    $("iconPan").src="res/Button_Hand_aktiv.gif";
	zoom_change = "yes";
	var x1, y1, x2, y2, x, y;
	if(isFixed == true){
	   isFixed = false;
		if( !zoomCanvas ){
	    	x = window.clickPoint.getX();
	     	y = window.clickPoint.getY();
	     	if(document.all && !window.opera){
				x += document.body.scrollLeft;
				y += document.body.scrollTop;
	     	}	
		}
		x1 = zoomCanvas.x;
        y1 = zoomCanvas.y;
        x2 = zoomCanvas.x + zoomCanvas.width;
        y2 = zoomCanvas.y + zoomCanvas.height;
        x2 = x2 > window.width ? window.width : x2;
        y2 = y2 > window.height ? window.height : y2;

		var dx = x2 - x1;
		var dy = y2 - y1;
		var xm = x1 + (dx / 2);
		var ym = y1 + (dy / 2);
		if(dy < 30 || dx < 30) {
			setVisibility(objZoomSquare, false);
			return;
		}
		if( dx  > dy ) {
			var f = window.height / window.width;
			dy = dx * f;	
			y1 = ym - (dy / 2);	
			y2 = ym + (dy / 2);
		}else{
			var f = window.width / window.height;
            dx = dy * f;
			x1 = xm - (dx / 2);
			x2 = xm + (dx / 2);
		}	
		var gkru = s2gk(x1, y2, window.width, window.height, window.dR, window.dH, window.ru, window.hu); 
		var gklo = s2gk(x2, y1, window.width, window.height, window.dR, window.dH, window.ru, window.hu); 

		setVisibility(objZoomSquare, false);
		document.formImg.ru.value = gkru.getX();
		document.formImg.hu.value = gkru.getY();
		document.formImg.ro.value = gklo.getX();
		document.formImg.ho.value = gklo.getY(); 
    	var width = parseFloat(document.formImg.width.value);
    	var height = parseFloat(document.formImg.height.value);
    	var ru = parseFloat(document.formImg.ru.value);
    	var hu = parseFloat(document.formImg.hu.value);
    	var ro = parseFloat(document.formImg.ro.value);
    	var ho = parseFloat(document.formImg.ho.value);

    	var dR = parseFloat(ro) - parseFloat(ru);
    	var dH = parseFloat(ho) - parseFloat(hu); 
    	if($("newpunkt").style.visibility == "visible"){
    		document.onmousedown = "";
			document.onmousemove = "";
			document.onmouseup = "";
    	}
    	var step;
    	var scale_reihe = new Array (64,32,16,8,4,2,1,0.5,0.25);
    	var scale = dR/width;
    	if(layer == "DOP40"){layer = "DOP";}
    	for(var i = 0;i <= 8; i++){
    		if(scale > scale_reihe[0]){
    			zoomstepcontrol(layer,"Step0");
    			break;
    		}
    		else if(scale < scale_reihe[8]){
    			zoomstepcontrol(layer,"Step8");
    			break;
    		}
    		else if(scale <= scale_reihe[i] && scale > scale_reihe[i+1]){
    		 	var mZoom = (scale_reihe[i]-scale_reihe[i+1])/2+scale_reihe[i+1];
    		 	if(scale <= scale_reihe[i] && scale > mZoom){
    		 		step = "Step"+i;
    		 		zoomstepcontrol(layer,step);
    		 		break;
    		 	}
    		 	else if(scale <= mZoom && scale > scale_reihe[i+1]){
    		 		step = "Step"+(i+1);
    		 		zoomstepcontrol(layer,step);
    		 		break;
    		 	}
    		}
    	}
    return;
	}
	
}

function zoomInMitte () {
    var ru = parseFloat(document.formImg.ru.value);
    var hu = parseFloat(document.formImg.hu.value);
    var ro = parseFloat(document.formImg.ro.value);
    var ho = parseFloat(document.formImg.ho.value);

    var mitteR = parseFloat( (ro + ru ) / 2.0 );
    var mitteH = parseFloat( (ho + hu ) / 2.0 );
    var deltaR = parseFloat( (ro - ru ) / 4.0 );
    var deltaH = parseFloat( (ho - hu ) / 4.0 );
    ru = mitteR - deltaR;
    hu = mitteH - deltaH;
    ro = mitteR + deltaR; 
    ho = mitteH + deltaH; 

    document.formImg.ru.value = ru;
    document.formImg.hu.value = hu;
    document.formImg.ro.value = ro;
    document.formImg.ho.value = ho;
	updateMap();
	if(document.pktPosition && (document.pktPosition.length > 0) ) {
                drawPoly();
        }
}

function zoomOutMap () {
	s_firstmessen = 1;
	zoom_change = "yes";
	$("iconZoomInSka").src="res/Button_Lupe.gif";
	$("iconZoomOut").src="res/Button_verkleinerung.gif";
    $("iconZoomIn").src="res/Button_vergroesserung.gif";
    $("iconPan").src="res/Button_Hand_aktiv.gif";
    var zoomstep = document.formImg.ZoomStep.value;
    var zoomstep_neu;
    if(layer == "DOP40"){layer = "DOP";}
    switch (zoomstep){
    	case "Step0":
    		 zoomstepcontrol(layer,"Step0"); 
    		break;				
    	case "Step1":
    		 zoomstepcontrol(layer,"Step0"); 
    		break;
    	case "Step2": 
    		zoomstepcontrol(layer,"Step1");
    		break;
    	case "Step3": 
    		zoomstepcontrol(layer,"Step2"); 
    		break;
    	case "Step4": 
    		zoomstepcontrol(layer,"Step3"); 
    		break;
    	case "Step5": 
    		zoomstepcontrol(layer,"Step4"); 
    		break;
    	case "Step6": 
    		zoomstepcontrol(layer,"Step5"); 
    		break;
    	case "Step7": 
    		zoomstepcontrol(layer,"Step6"); 
    		break;
    	case "Step8": 
    		zoomstepcontrol(layer,"Step7"); 
    		break;
    }
}

function zoomInMapStep () {
	s_firstmessen = 1;
	zoom_change = "yes";
	$("iconZoomInSka").src="res/Button_Lupe.gif";
	$("iconZoomOut").src="res/Button_verkleinerung.gif";
    $("iconZoomIn").src="res/Button_vergroesserung.gif";
    $("iconPan").src="res/Button_Hand_aktiv.gif";
    var ru = parseFloat(document.formImg.ru.value);
    var hu = parseFloat(document.formImg.hu.value);
    var ro = parseFloat(document.formImg.ro.value);
    var ho = parseFloat(document.formImg.ho.value);
    var zoomstep = document.formImg.ZoomStep.value;
    var zoomstep_neu;
    if(layer == "DOP40"){layer = "DOP";}
    switch (zoomstep){
    	case "Step0":
    		zoomstepcontrol(layer,"Step1"); 
    		break;				
    	case "Step1": 
    		zoomstepcontrol(layer,"Step2");
    		break;
    	case "Step2": 
    		zoomstepcontrol(layer,"Step3");
    		break;
    	case "Step3":
    		zoomstepcontrol(layer,"Step4");
    		break;
    	case "Step4":
    		zoomstepcontrol(layer,"Step5");
    		break;
    	case "Step5":
    		zoomstepcontrol(layer,"Step6");
    		break;
    	case "Step6":
    		zoomstepcontrol(layer,"Step7");
    		break;
    	case "Step7":
    		zoomstepcontrol(layer,"Step8");
    		break;
    	case "Step8":
    		zoomstepcontrol(layer,"Step8");
    		break;
    }
}
function zoomstepcontrol(_layer,_step){
	var ru = parseFloat(document.formImg.ru.value);
    var hu = parseFloat(document.formImg.hu.value);
    var ro = parseFloat(document.formImg.ro.value);
    var ho = parseFloat(document.formImg.ho.value);
    var mitteR = parseFloat( (ro + ru ) / 2.0 );
    var mitteH = parseFloat( (ho + hu ) / 2.0 );
    var width = parseFloat(document.formImg.width.value);
    var height = parseFloat(document.formImg.height.value);
    var mapstep = true;
    $("iconZoom0").src="res/zoomstufe_0.gif";
    $("iconZoom0").style.cursor = "pointer";
    $("iconZoom1").src="res/zoomstufe_1.gif";
    $("iconZoom1").style.cursor = "pointer";
    $("iconZoom2").src="res/zoomstufe_2.gif";
    $("iconZoom2").style.cursor = "pointer";
    $("iconZoom3").src="res/zoomstufe_3.gif";
    $("iconZoom3").style.cursor = "pointer";
    $("iconZoom4").src="res/zoomstufe_4.gif";
    $("iconZoom4").style.cursor = "pointer";
    $("iconZoom5").src="res/zoomstufe_5.gif";
    $("iconZoom5").style.cursor = "pointer";
    $("iconZoom6").src="res/zoomstufe_6.gif";
    $("iconZoom6").style.cursor = "pointer";
    $("iconZoom7").src="res/zoomstufe_7.gif";
    $("iconZoom7").style.cursor = "pointer";
    $("iconZoom8").src="res/zoomstufe_8.gif";
    $("iconZoom8").style.cursor = "pointer";
    //$("iconZoomIn").src="res/Button_vergroesserung.gif";
    $("iconZoomIn").style.cursor = "pointer";
    //$("iconZoomOut").src="res/Button_verkleinerung.gif";
    $("iconZoomOut").style.cursor = "pointer";
    $("iconZoomInSka").src="res/Button_Lupe.gif";
    $("iconZoomInSka").style.cursor = "pointer";
    switch (_step){
    	case "Step0":
            $("iconZoomOut").style.cursor = "no-drop";
            $("iconZoom0").style.cursor = "pointer";
            $("iconZoom0").src="res/zoomstufe_0_aktiv.gif";
            var DR = 64*width;
            var DH = 64*height;
            if(document.formImg.massstap.value == 64){mapstep = false;}
    		else{
    		    $("iconZoomIn").onclick = function() {zoomInMapStep();};
    		    $("iconZoomOut").onclick = function() {};
    		    $("iconZoomInSka").onclick = function() {initZoomIn();};
    		    document.formImg.ZoomStep.value = "Step0";
                document.formImg.massstap.value = 64;
            }
    		break;
    	case "Step1":
            $("iconZoom1").src="res/zoomstufe_1_aktiv.gif";
            $("iconZoom1").style.cursor = "pointer";
            var DR = 32*width;
            var DH = 32*height;
            if(document.formImg.massstap.value == 32){mapstep = false;}
            else{
    		    $("iconZoomIn").onclick = function() {zoomInMapStep();};
    		    $("iconZoomOut").onclick = function() {zoomOutMap();};
    		    $("iconZoomInSka").onclick = function() {initZoomIn();};
    		    document.formImg.ZoomStep.value = "Step1";
                document.formImg.massstap.value = 32;
            }
    		break;
    	case "Step2":
            $("iconZoom2").src="res/zoomstufe_2_aktiv.gif";
            $("iconZoom2").style.cursor = "pointer";
            var DR = 16*width;
            var DH = 16*height;
            if(document.formImg.massstap.value == 16){mapstep = false;}
    		else{
    		    $("iconZoomIn").onclick = function() {zoomInMapStep();};
    		    $("iconZoomOut").onclick =function() {zoomOutMap();};
    		    $("iconZoomInSka").onclick = function() {initZoomIn();};
    		    document.formImg.ZoomStep.value = "Step2";
                document.formImg.massstap.value = 16;
            }
    		break;
    	case "Step3":
    		$("iconZoom3").src="res/zoomstufe_3_aktiv.gif";
            $("iconZoom3").style.cursor = "pointer";
            var DR = 8*width;
            var DH = 8*height;
            if(document.formImg.massstap.value == 8){mapstep = false;}
            else{
    		    $("iconZoomIn").onclick = function() {zoomInMapStep();};
    		    $("iconZoomOut").onclick =function() {zoomOutMap();};
    		    $("iconZoomInSka").onclick = function() {initZoomIn();};
    		    document.formImg.ZoomStep.value = "Step3";
                document.formImg.massstap.value = 8;
            }
    		break;
    	case "Step4":
    		$("iconZoom4").src="res/zoomstufe_4_aktiv.gif";
            $("iconZoom4").style.cursor = "pointer";
            var DR = 4*width;
            var DH = 4*height;
            if(document.formImg.massstap.value == 4){mapstep = false;}
            else{
    		    $("iconZoomIn").onclick = function() {zoomInMapStep();};
    		    $("iconZoomOut").onclick =function() {zoomOutMap();};
    		    $("iconZoomInSka").onclick = function() {initZoomIn();};
    		    document.formImg.ZoomStep.value = "Step4";
                document.formImg.massstap.value = 4;
    		}
            break;
    	case "Step5":
    		$("iconZoom5").src="res/zoomstufe_5_aktiv.gif";
            $("iconZoom5").style.cursor = "pointer";
            var DR = 2*width;
            var DH = 2*height;
            if(document.formImg.massstap.value == 2){mapstep = false;}
            else{
    		    $("iconZoomIn").onclick = function() {zoomInMapStep();};
    		    $("iconZoomOut").onclick =function() {zoomOutMap();};
    		    $("iconZoomInSka").onclick = function() {initZoomIn();};
    		    document.formImg.ZoomStep.value = "Step5";
                document.formImg.massstap.value = 2;
            }
    		break;
    	case "Step6":
    		$("iconZoom6").src="res/zoomstufe_6_aktiv.gif";
            $("iconZoom6").style.cursor = "pointer";
            var DR = 1*width;
            var DH = 1*height;
            if(document.formImg.massstap.value == 1){mapstep = false;}
            else{
    		    $("iconZoomIn").onclick = function() {zoomInMapStep();};
    		    $("iconZoomOut").onclick =function() {zoomOutMap();};
    		    $("iconZoomInSka").onclick = function() {initZoomIn();};
    		    document.formImg.ZoomStep.value = "Step6";
                document.formImg.massstap.value = 1;
            }
    		break;
    	case "Step7":
    		$("iconZoom7").src="res/zoomstufe_7_aktiv.gif";
            $("iconZoom7").style.cursor = "pointer";
            var DR = 0.5*width;
            var DH = 0.5*height;
            if(document.formImg.massstap.value == 0.5){mapstep = false;}
            else{
    		    $("iconZoomIn").onclick = function() {zoomInMapStep();};
    		    $("iconZoomOut").onclick =function() {zoomOutMap();};
    		    $("iconZoomInSka").onclick = function() {initZoomIn();};
    		    document.formImg.ZoomStep.value = "Step7";
                document.formImg.massstap.value = 0.5;
            }
    		break;
    	case "Step8":
            $("iconZoomIn").style.cursor = "no-drop";
            $("iconZoomInSka").style.cursor = "no-drop";
    		$("iconZoom8").src="res/zoomstufe_8_aktiv.gif";
            $("iconZoom8").style.cursor = "pointer";
            var DR = 0.25*width;
            var DH = 0.25*height;
            if(document.formImg.massstap.value == 0.25){mapstep = false;}
            else{
    		    $("iconZoomIn").onclick = function() {};
    		    $("iconZoomOut").onclick =function() {zoomOutMap();};
    		    $("iconZoomInSka").onclick = function() {};
    		    document.formImg.ZoomStep.value = "Step8";
                document.formImg.massstap.value = 0.25;
            }
    		break;
    }
    ru = mitteR - DR/2;
    ro = mitteR + DR/2;
    hu = mitteH - DH/2;
    ho = mitteH + DH/2;
    document.formImg.ru.value = ru;
    document.formImg.hu.value = hu;
	document.formImg.ro.value = ro;
	document.formImg.ho.value = ho;
	var dR = parseFloat(ro) - parseFloat(ru);
    var dH = parseFloat(ho) - parseFloat(hu);
	var scale = dR/width;
   	document.formImg.rm.value = 0;
    document.formImg.hm.value = 0;
	if(mapstep == true) {updateMap();}
    if(document.pktPosition && (document.pktPosition.length > 0) ) {
    	var punkte1 = document.gkpunkte;
    	var punkte2 = document.pktPosition;
		for(var t = 0; t < punkte1.length; t++){
			punkte2[t] = gk2s(punkte1[t].getX(), punkte1[t].getY(), width, height, dR, dH, ru, hu);
		}
        drawPoly();
    }
    if(_step == "Step0" || _step == "Step8"){
    	if(browserName == "ie"){	
			$("MapImg").style.cursor = "url(res/openhand.cur),auto";
			$("MapImg").style.cursor = "url(res/openhand.cur),move";
		}
		else{
			$("MapImg").style.cursor = "-moz-grab";
		}
		$("MapImg").onmousedown = engage;
    }
}
function wheel(event){
        var zoomstep = document.formImg.ZoomStep.value;
        var zoomzahl = parseInt(zoomstep.substr(4,1));
        var delta=0;
        if (!event) event = window.event;
        if (event.wheelDelta) {
                delta = event.wheelDelta/120;
                if (window.opera) delta = -delta;
        } else if (event.detail) {
                delta = -event.detail/3;
        }
        if(delta > 0){
        	zoomzahl += 1; 
        	if(zoomzahl>8){zoomzahl=8;	}
        	else{
        		scaleint += 1;
        		scale = scale_array[scaleint];
        	}
        	zoomstep = "Step"+zoomzahl;
        	document.formImg.ZoomStep.value = zoomstep;
        }
        else if(delta < 0){
        	zoomzahl -= 1; 
        	if(zoomzahl<1){zoomzahl=0;}
        	else{
        		scaleint -= 1;
        		scale = scale_array[scaleint];
        	}
        	zoomstep = "Step"+zoomzahl;
        	document.formImg.ZoomStep.value = zoomstep;
        }
        if (event.preventDefault)
                event.preventDefault();
        event.returnValue = false;
        window.setTimeout("MouseScrollZoomchange()",1500);
        
}
function MouseScrollZoomchange(){
	var zoomstep = document.formImg.ZoomStep.value;
	s_firstmessen = 1;
	zoom_change = "yes";
	if(layer == "DOP40"){layer = "DOP";}
        switch (zoomstep){
    		case "Step0":
    			zoomstepcontrol(layer,"Step0"); 
    			break;				
    		case "Step1": 
    			zoomstepcontrol(layer,"Step1");
    			break;
    		case "Step2": 
    			zoomstepcontrol(layer,"Step2");
    			break;
    		case "Step3":
    			zoomstepcontrol(layer,"Step3");
    			break;
    		case "Step4":
    			zoomstepcontrol(layer,"Step4");
    			break;
    		case "Step5":
    			zoomstepcontrol(layer,"Step5");
    			break;
    		case "Step6":
    			zoomstepcontrol(layer,"Step6");
    			break;
    		case "Step7":
    			zoomstepcontrol(layer,"Step7");
    			break;
    		case "Step8":
    			zoomstepcontrol(layer,"Step8");
    			break;
    	}
}
function showZoomTitle(zoomstep){
	var tkArray = new Array('Topographische Karte 1:500.000',
				'Topographische Karte 1:500.000',
				'Topographische Karte 1:200.000',
				'Topographische Karte 1:50.000',
				'Topographische Karte 1:50.000',
				'Topographische Karte 1:25.000',
				'Ortskarte 1:10.000',
				'Ortskarte 1:10.000',
				'Ortskarte 1:10.000');
	var dopArray = new Array('Orthophoto (Aufl%F6sung: 64m)',
                                'Orthophoto (Aufl%F6sung: 32m)',
                                'Orthophoto (Aufl%F6sung: 16m)',
                                'Orthophoto (Aufl%F6sung: 8m)',
                                'Orthophoto (Aufl%F6sung: 4m)',
                                'Orthophoto (Aufl%F6sung: 2m)',
                                'Orthophoto (Aufl%F6sung: 1m)',
                                'Orthophoto (Aufl%F6sung: 0,50m)',
                                'Orthophoto (Aufl%F6sung: 0,25m)');
	var hybridArray = new Array('Hybriddarstellung (Aufl%F6sung: 64m)',
                                'Hybriddarstellung (Aufl%F6sung: 32m)',
                                'Hybriddarstellung (Aufl%F6sung: 16m)',
                                'Hybriddarstellung (Aufl%F6sung: 8m)',
                                'Hybriddarstellung (Aufl%F6sung: 4m)',
                                'Hybriddarstellung (Aufl%F6sung: 2m)',
                                'Hybriddarstellung (Aufl%F6sung: 1m)',
                                'Hybriddarstellung (Aufl%F6sung: 0,50m)',
                                'Orthophoto (Aufl%F6sung: 0,25m)');
	var histArray = new Array('nicht verf%FCgbar',
                                'nicht verf%FCgbar',
                                'Urpositionsblatt',
                                'Urpositionsblatt',
                                'Urpositionsblatt',
                                'Urpositionsblatt',
                                'Urpositionsblatt',
                                'nicht verf%FCgbar',
                                'nicht verf%FCgbar');
	var maplayer = document.formImg.maplayer.value;
        var layer;
	var selectedArray
        switch(maplayer){
		case "tk": selectedArray = tkArray; break;
                case "dop": selectedArray = dopArray; break;
		case "hybrid": selectedArray = hybridArray; break;
		default: selectedArray = histArray;
        }

	$('iconZoom'+zoomstep).title=unescape(selectedArray[zoomstep]);
}
function hiddeZoomTitle(zoomstep){
	$('iconZoom'+zoomstep).title="";

}
function showWMSLayer () {
	try { document.getElementById("iconOrtsuch").src = "res/btnOrtsuche_a.jpg"; } catch(ex) { }
        try { document.getElementById("iconWMSLayer").src = "res/btnWms_c.jpg"; } catch(ex) { }
        try { document.getElementById("iconStrecke").src = "res/btnDistanz_a.jpg"; } catch(ex) { }
        try { document.getElementById("iconFlaeche").src = "res/btnFlaechen_a.jpg"; } catch(ex) { }

	document.getElementById("flexpanel").src = "testExpand.html";
}

// such.js : Alle Such-funktionen fr BayernViewer2.0
// Bayerische Landesamt fr Vermessung und Geoinformation
// Ref. 42
// (c) Copyright 2006-2007

var urlarray = new Array("/dyn/viewerServlets/query","/dyn/view/cs"); // URL Array
var plz_value, ort_value, str_value, hausnr_value, berg_value_name, berg_value_ort; // Global Variable
var gew_value_name, gew_value_ort, schulname_value, schulort_value, lkr_value, _text; // Global Variable
var eingabe_ID, query_STR, such_STR, bergsuch=0, gewsuch=0, ort_ortsuch=0, ort_koordinaten, schulesuch = 0; // Global Variable
var url, such_parameter = '', ajaxrufen = 'no';
var datenArr_in = new Array(), datenArr_zeilen = new Array(); // Global Variable
var datenArr_out = '';
var normalHash = new Array();
var ersttaste = 'no', tablator = 'leer', selectfeld, tastecode = 0, wert_value, ctrlkey = false;

// Such Funktion fr Addresse Suche, Wahllist zu bauen
function addresse_such(eingabe_id,value){
	//plz_value=null;
	//ort_value=null;
	//str_value=null;
	//hausnr_value=null;
	url = null;
	such_parameter = '';
	ajaxrufen = 'no';
	eingabe_ID = eingabe_id;
	query_STR = 'addresse_ort';
	//if(value.length >= 2 || eingabe_id == 'nr'){
    if((value.length >= 2 || eingabe_id == 'nr') && taste != 13 && taste != 37 && taste != 38 && taste != 39 && taste != 40 && taste != 9 && taste != 8 && ctrlkey == false){//wenn strg+c oder strg+v gedrückt wurder, dann wird nicht in den Dantenbank gesucht.
		$('maus_cursor').style.cursor = 'wait';
		ersttaste = 'no', such_STR = 'adr_such';
		var PLZ = ''; var ORT = ''; var STR = ''; var NR = ''; var ortstr;
		switch (eingabe_id){
			case 'plz': 
				if($F('ort') != ''){
					ortstr = $F('ort').split(",");
					if(ortstr.first().indexOf('\(') >= 0){
						ortstr[0] = ortstring(ortstr.first());
					}
                    ortstr = ortstr[0].split("\/");
					ORT = '&ort='+encodeURIComponent(ortstr[1]);
				}
				if($F('str') != '') STR = '&str='+encodeURIComponent($F('str'));
				if($F('hausnr') != '') NR = '&hausnr='+$F('hausnr');
				such_parameter = 'art=adresse&plz='+encodeURIComponent(value)+ORT+STR+NR+'&phonetisch=nein&limit=400';
				ajaxrufen = 'yes';
				break;
			case 'ort':
				if($F('plz') != '') PLZ = '&plz='+$F('plz');
				if($F('str') != '') STR = '&str='+encodeURIComponent($F('str'));
				if($F('hausnr') != '') NR = '&hausnr='+$F('hausnr');
				such_parameter = 'art=adresse'+PLZ+'&ort='+encodeURIComponent(value)+STR+NR+'&phonetisch=nein&limit=400';
				ajaxrufen = 'yes';
				break;
			case 'str':
				if($F('ort') == ''){
					alert('Bitte erst Ort eingeben !');
					$('maus_cursor').style.cursor = 'auto';
                    $('datentake').style.visibility = 'hidden';
                    document.such_eingabe.str.value= '';
				}else{
					if($F('plz') != '') PLZ = '&plz='+$F('plz');
					if($F('ort') != ''){
						ortstr = $F('ort').split(",");
						if(ortstr.first().indexOf('\(') >= 0){
                            ortstr[0] = ortstring(ortstr.first());
						}
                        ortstr = ortstr[0].split("\/");
						ORT = '&ort='+encodeURIComponent(ortstr[1]);
					}	
					if($F('hausnr') != '') NR = '&hausnr='+$F('hausnr');
					such_parameter = 'art=adresse'+PLZ+ORT+'&str='+encodeURIComponent(value)+NR+'&phonetisch=nein&limit=400';
					ajaxrufen = 'yes';
				}
				break;
			case 'nr':
				if($F('ort') == '' || $F('str') == ''){
					if($F('ort') == '' && $F('str') == ''){
						alert(unescape('Eingabe f%FCr Ort und Stra%DFe fehlt !'));
						$('maus_cursor').style.cursor = 'auto';
                    	$('datentake').style.visibility = 'hidden';
                    	document.such_eingabe.hausnr.value = '';
                    	break;
					}
					if($F('str') == '' ){
                		alert(unescape('Eingabe f%FCr Stra%DFe fehlt !'));
                    	$('maus_cursor').style.cursor = 'auto';
                    	$('datentake').style.visibility = 'hidden';
                	}
                	if($F('ort') == ''){
                		alert(unescape('Eingabe f%FCr Ort fehlt !'));
                    	$('maus_cursor').style.cursor = 'auto';
                    	$('datentake').style.visibility = 'hidden';
                	}
				}
                else{
                	if($F('plz') != '') PLZ = '&plz='+$F('plz');
                	if($F('ort') != ''){
						ortstr = $F('ort').split(",");
						if(ortstr.first().indexOf('\(') >= 0){
							ortstr[0] = ortstring(ortstr.first());
						}
                        ortstr = ortstr[0].split("\/");
						ORT = '&ort='+encodeURIComponent(ortstr[1]);
					}
					if($F('str') != '') STR = '&str='+encodeURIComponent($F('str'));
					such_parameter = 'art=adresse'+PLZ+ORT+STR+'&hausnr=*&phonetisch=nein&limit=400';
                    ajaxrufen = 'yes';
                }
                break;      
		}
		url = urlarray.first();
		if(ajaxrufen == 'yes') ajaxfunction(url, such_parameter);
	}
	else{
		if(value.length == 0 && $(selectfeld)){
			deldatenResult();
			_text = '';
		}
		else if($(selectfeld)){tastecode = 0;}
	}
}

// macht aus "Lindau (Bodensee)/Lindau (Bodensee)" den String "Lindau (Bodensee)/Lindau" (warum auch immer Yue das gemacht hat!)
function ortstring(ortstrr){
	var tmp = ortstrr.split("\/");
    if(tmp[1].indexOf('\(') > -1){
        ortstrr = ortstrr.substring(0,ortstrr.lastIndexOf('\(')-1);
        tmp[1] = tmp[1].substr(0,tmp[1].indexOf('\(')-1);
        tmp[1] = trimString(tmp[1]);
    }
    return ortstrr;
	//var ot_ort = ortstrr.substr(0,ortstrr.indexOf(',')-1); // Ortsteil und Ort
//    var tmp = ortstrr.split("\/");
//    if(tmp[0].indexOf('\(') > -1){
//        tmp[0] = tmp[0].substr(0,tmp[0].indexOf('\(')-1);
//        tmp[0] = trimString(tmp[0]);
//    }
//    if(tmp[1].indexOf('\(') > -1){
//        tmp[1] = tmp[1].substr(0,tmp[1].indexOf('\(')-1);
//        tmp[1] = trimString(tmp[1]);
//    }
//    return tmp
}

// schneidet alle Leerzeichen am vorderen und hinternen Ende des String ab
function trimString(s){
    return s.replace(/\s+$/,"").replace(/^\s+/,"")
}

// Such Funktion fr Berg, Gew�e, Ort und sonstige einfache Suchfunktion, Wahllist zu bauen
function normal_such(eingabe_id, value){
	url=null;
	normalHash = new Array();
	such_parameter = '';
	if(value.length >= 2 && taste != 37 && taste != 38 && taste != 39 && taste != 40 && taste != 9 && taste != 8){
		switch(eingabe_id){
			case 'berg':
				//berg_value_name=null;
				//berg_value_ort=null;
				eingabe_ID = 'berg';
				such_STR = 'berg_such';
				such_parameter = 'art=berg&name='+encodeURIComponent(value)+'&phonetisch=nein&limit=400';
        		break;
        	case 'gew':
        		//gew_value_name=null;
				//gew_value_ort=null;
				eingabe_ID = 'gew';
				such_STR = 'gew_such';
				such_parameter = 'art=gew&name='+encodeURIComponent(value)+'&phonetisch=nein&limit=400';
				break;
			case 'ort_ort':
				//ort_value=null;
				eingabe_ID = 'ort_ort';
				such_STR = 'ort_ort_such';
				such_parameter = 'art=ortlkr&ort='+encodeURIComponent(value)+'&phonetisch=nein&limit=400';
		}
		url = urlarray.first();
		ajaxfunction(url, such_parameter);
	}
	else{
		if(value.length == 0 && $(selectfeld)){deldatenResult(); _text = '';}
		else if($(selectfeld)){tastecode = 0;}	
	}	
}

// Such Function fr Schule Suche, Wahllist zu bauen
function schul_such(value){
	schul_value=null;
    url=null;
    such_parameter = '';
    eingabe_ID = 'schule';
    such_STR = 'schule_such';
    if(value.length >= 2){
		such_parameter = "q="+encodeURIComponent(value)+"&m=schule&o=2";
		url = urlarray.last();
        ajaxfunction(url, such_parameter);
	}
}

// Ajax Methode wird hier verwendet
function ajaxfunction(urlstring, such_parameter_str){
	new Ajax.Request(
    urlstring,
    {
    	method: 'get',
        //requestHeaders: ["Content-type", "text/html; charset=ISO-8859-1"],
        requestHeaders: ["Content-type", "text/html; charset=UTF-8"],
	requestHeaders: ["Accept-Charset","UTF-8"],
        parameters: such_parameter_str,
        onComplete: showResponse
   	});
}

// Ergebnis fr alle Suche
var schulezahl = 0;
function showResponse(originalRequest){
	datenArr_out = ''; //Output String
	if(eingabe_ID != 'nr') {
    		_text = '';
    		_text = originalRequest.responseText;
    }
    else{
    	if($F('str') != ""){
    		_text = '';
    		_text = originalRequest.responseText;
    	}
    }
    datenArr_zeilen = new Array();
    datenArr_zeilen = _text.split("\n");
    datenArr_zeilen = datenArr_zeilen.without('');
    datenArr_zeilen = datenArr_zeilen.without('\r');
    switch(eingabe_ID){
		case 'plz': datenArr_out = addresseResponse('plz',datenArr_zeilen);
			break;
		case 'ort': datenArr_out = addresseResponse('ort',datenArr_zeilen);
			break;
		case 'str': datenArr_out = addresseResponse('str',datenArr_zeilen);
			break;
		case 'nr': datenArr_out = addresseResponse('nr',datenArr_zeilen);
			break;
		case 'ort_ort': datenArr_out = normalResponse('ort_ort',datenArr_zeilen);
			break;
		case 'berg': datenArr_out = normalResponse('berg',datenArr_zeilen);
				break;
		case 'gew': datenArr_out = normalResponse('gew',datenArr_zeilen);
				break;
		case 'schule': datenArr_out = schulResponse(datenArr_zeilen);
				break;
	}
	if(datenArr_out != ''){
    	switch(eingabe_ID){
        	case 'plz': selectfeld = 'plzResult'; break;
        	case 'ort': selectfeld = 'ortResult'; break;
        	case 'str': selectfeld = 'strResult'; break;
        	case 'nr': selectfeld = 'nrResult'; break;
        	case 'ort_ort': selectfeld = 'ort_ortResult'; break;
        	case 'berg': selectfeld = 'bergResult'; break;
        	case 'gew': selectfeld = 'gewResult'; break;
        	case 'schule': selectfeld = 'schuleResult'; break;
        }
    	if(eingabe_ID == 'nr'){
    		if($('nrResult')) {
    			$('nrResult').innerHTML = datenArr_out; 
    		}
    		else creatdatenResult(eingabe_ID,$('hausnr').style.top,$('hausnr').style.left,$('hausnr').style.width,datenArr_out);
    		var resultarray = datenArr_out.split('<br>');
	 		if(resultarray.length == 2) einzelResult(datenArr_out);
    	}
    	else{
    		if($(selectfeld)) {
    			$(selectfeld).innerHTML = datenArr_out;
    		}
    		else {
    			creatdatenResult(eingabe_ID,$(eingabe_ID).style.top,$(eingabe_ID).style.left,$(eingabe_ID).style.width,datenArr_out);
    			switch(eingabe_ID){
    				case 'berg': bergsuch=1; break;
    				case 'gew': gewsuch=1; break;
    				case 'ort_ort': ort_ortsuch=1; break;
    				case 'schule': schulesuch = 1; break;
    			}
    		}
    		var resultarray = datenArr_out.split('<br>');
	 		if(resultarray.length == 2){
	 			einzelResult(datenArr_out);
	 			switch (eingabe_ID){
	 				case 'berg': 
	 					var _bergstr = normalHash[0][1].split("#");
						normal_Koordsuch(_bergstr[0],_bergstr[1],_bergstr[2],_bergstr[3]);
	 					break;
	 				case 'gew': 
	 					var _gewstr = normalHash[0][1].split("#");
						normal_Koordsuch(_gewstr[0],_gewstr[1],_gewstr[2],_gewstr[3]);
	 					break;
	 				case 'ort_ort':
	 					var _ortstr = normalHash[0][1].split("#");
						normal_Koordsuch(_ortstr[0],_ortstr[1],_ortstr[2],_ortstr[3]);
	 					break;
	 				case 'schule': schule_Koordsuch(resultarray[0]); break;
	 			}
	 		}    		
    	}
 	}
    else{
    	switch(eingabe_ID){
        	case 'plz': if($('plzResult')){deldatenResult();} break;
        	case 'ort': if($('ortResult')){deldatenResult();} break;
        	case 'str': if($('strResult')){deldatenResult();} break;
        	case 'nr': if($('hausnrResult')){deldatenResult();} break;
        	case 'ort_ort': if($('ort_ortResult')){deldatenResult();} break;
        	case 'berg': if($('bergResult')){deldatenResult();} break;
        	case 'gew': if($('gewResult')){deldatenResult();} break;
        	case 'schule': if($('schuleResult')){deldatenResult();} break;
        }
	}
	$('maus_cursor').style.cursor = 'auto';
	$('datentake').style.visibility = 'hidden';
}

// Response List fr Addresse Such
function addresseResponse(response_parameter, datenArray){
	var ausgabe = '', datenout = '';
	switch(response_parameter){
		case 'plz':
			var t = 0, n = 0, i = 2;
			var plzsort = new Array();
			for(var teil = 0;  teil<datenArray.length; teil++){
				if(datenArray[teil] != '' && datenArray[teil] != '\r'){
					datenArr_in = datenArray[teil].split('\|');
					if(ausgabe == '' && datenArr_in[2] != 'undefined' && datenArr_in[2].indexOf($F('plz')) >= 0){
						plzsort[t] = datenArr_in[2];
						t += 1;
					}
					else if(ausgabe != datenArr_in[2] && datenArr_in[2] != 'undefined' && datenArr_in[2].indexOf($F('plz')) >= 0){
						plzsort[t] = datenArr_in[2];
						t += 1;
					}
					ausgabe = datenArr_in[2];
				}
			}
			if(plzsort.length != 0){
				plzsort.sort(Numsort);
				for(n=0;n<t;n++ ){
					if(n == 0){
						datenout += "<span id=\"treffer"+n+"\" class=\"treffer\" onmouseout=javascript:usemouseout(\"treffer"+n+"\") onmouseover=javascript:usemouseover(\"treffer"+n+"\") onclick=javascript:wert_eingabe(\""+plzsort[n]+"|plz\")>"+plzsort[n]+"</span><br>\n";
					}
					else if(plzsort[n] != plzsort[n-1]){
						datenout += "<span id=\"treffer"+n+"\" class=\"treffer\" onmouseout=javascript:usemouseout(\"treffer"+n+"\") onmouseover=javascript:usemouseover(\"treffer"+n+"\") onclick=javascript:wert_eingabe(\""+plzsort[n]+"|plz\")>"+plzsort[n]+"</span><br>\n";
					}
				}
			}
			else{
				datenout = "Die von Ihnen gew&#228;hlte PLZ ist nicht vergeben";
			}
			return datenout;
			break;
		case 'ort':
			var _ort_ansicht='', _ort_k='', _ort_value='', i = 0;
			for(var teil=0; teil<datenArray.length; teil++){
    			if(datenArray[teil] != '' && datenArray[teil] != '\r'){
					datenArr_in = datenArray[teil].split('\|');
					_ort_k = datenArr_in[0].toLowerCase();
            		if(ausgabe == '' && datenArr_in[0] != 'undefined' && _ort_k.indexOf($F('ort').toLowerCase()) >= 0){
                		_ort_ansicht = datenArr_in[1]+"/"+datenArr_in[0]+", "+datenArr_in[3];
                        _ort_value = datenArr_in[0]+"#"+datenArr_in[1]+"#"+datenArr_in[3]; 
                        while(_ort_value.indexOf(' ') >= 0){
                    		_ort_value = _ort_value.replace(/ /,"%20");
                   		}
                    	datenout += "<span id=\"treffer"+teil+"\" class=\"treffer\" onmouseout=javascript:usemouseout(\"treffer"+teil+"\") onmouseover=javascript:usemouseover(\"treffer"+teil+"\") onclick=javascript:wert_eingabe(\""+_ort_value+"|ort\")>- "+_ort_ansicht+"</span><br>\n";
					}
                	else if(ausgabe != (datenArr_in[1]+"/"+datenArr_in[0]+", "+datenArr_in[3]) && datenArr_in[0] != 'undefined' && _ort_k.indexOf($F('ort').toLowerCase()) >= 0){
						_ort_ansicht = datenArr_in[1]+"/"+datenArr_in[0]+", "+datenArr_in[3];
                        _ort_value = datenArr_in[0]+"#"+datenArr_in[1]+"#"+datenArr_in[3];
                 		while(_ort_value.indexOf(' ') >= 0){
                    		_ort_value = _ort_value.replace(/ /,"%20");
                		}
						datenout += "<span id=\"treffer"+teil+"\" class=\"treffer\" onmouseout=javascript:usemouseout(\"treffer"+teil+"\") onmouseover=javascript:usemouseover(\"treffer"+teil+"\") onclick=javascript:wert_eingabe(\""+_ort_value+"|ort\")>- "+_ort_ansicht+"</span><br>\n";
					}
                	ausgabe = _ort_ansicht;
				}
			}
			return datenout;
			break;
		case 'str':
			var str_ansicht, gesuchtstr, str_k, i = 2;
			var strlength = $F('str').length;
			var streingabe = $F('str');
			var orteingabe = $F('ort').split(",");
			orteingabe[1] = orteingabe[1].substr(1,orteingabe[1].length-1);
			for(var teil=0; teil<datenArray.length; teil++){
				if(datenArray[teil] != '' && datenArray[teil] != '\r'){
					datenArr_in = datenArray[teil].split('\|');
					str_ansicht = datenArr_in[4];
					str_k = datenArr_in[4].toLowerCase();
					gesuchtstr = 'nein';
					if(streingabe.indexOf(' ') >= 0 && str_k.indexOf(streingabe) >= 0 && unescape(orteingabe[0].toLowerCase()) == (datenArr_in[1]+"/"+datenArr_in[0]).toLowerCase() && unescape(orteingabe[1].toLowerCase()) == datenArr_in[3].toLowerCase()){
						gesuchtstr = 'ja';
					}
					else{
						var s_name_a, s_name_b = streingabe.toLowerCase();
						if(datenArr_in[4].indexOf(' ') < 0){
							s_name_a = datenArr_in[4].slice(0,strlength).toLowerCase();
							if(s_name_b.indexOf(s_name_a) >= 0 && unescape(orteingabe[0].toLowerCase()) == (datenArr_in[1]+"/"+datenArr_in[0]).toLowerCase() && unescape(orteingabe[1].toLowerCase()) == datenArr_in[3].toLowerCase()){
								gesuchtstr = 'ja';
							}
						}
						else{
							strteil = datenArr_in[4].split(' ');
							for(var t=0; t<strteil.length;t++){
								s_name_a = strteil[t].slice(0,strlength).toLowerCase();
								if(s_name_b.indexOf(s_name_a) >= 0 && unescape(orteingabe[0].toLowerCase()) == (datenArr_in[1]+"/"+datenArr_in[0]).toLowerCase() && unescape(orteingabe[1].toLowerCase()) == datenArr_in[3].toLowerCase()){
									gesuchtstr = 'ja';
								}
							}
						}
					}
					if(ausgabe.indexOf(str_k) < 0 && datenArr_in[4] != 'undefined' && gesuchtstr == 'ja'){	
						while(datenArr_in[4].indexOf(' ') >= 0){
    	       				datenArr_in[4] = datenArr_in[4].replace(/ /,'%20');
               			}
						datenout += "<span id=\"treffer"+teil+"\" class=\"treffer\" onmouseout=javascript:usemouseout(\"treffer"+teil+"\") onmouseover=javascript:usemouseover(\"treffer"+teil+"\") onclick=javascript:wert_eingabe(\""+datenArr_in[4]+"|str\")>"+str_ansicht+"</span><br>\n";
						ausgabe += datenArr_in[4]+",";
					}
				}
			}
			return datenout;
			break;
		case 'nr':
			var n_arr = new Array();
			var hausnrstr = null, i = 0;
			var orteingabe = $F('ort').split(',');
			orteingabe[1] = orteingabe[1].substr(1,orteingabe[1].length-1);
			for(var teil=0; teil<datenArray.length; teil++){
				if(datenArray[teil] != '' && datenArray[teil] != '\r'){
					datenArr_in = datenArray[teil].split('|');
					if($F('hausnr') == '*' && datenArr_in[5] != 'undefined' && datenArr_in[4].toLowerCase() == $F('str').toLowerCase() && (datenArr_in[1]+"/"+datenArr_in[0]).toLowerCase() == unescape(orteingabe[0].toLowerCase()) && datenArr_in[3].toLowerCase() == unescape(orteingabe[1].toLowerCase())){
						n_arr[i] = [datenArr_in[5],datenArr_in[6]];
						i += 1;
					}
        			else{
                        var hausnrinput = $F('hausnr').split(" ");
                        var neuhausnrinput = hausnrinput.join("");
    	    			hausnrstr = datenArr_in[5]+datenArr_in[6];
            			if(datenArr_in[5] != 'undefined' && hausnrstr.toLowerCase().indexOf(neuhausnrinput.toLowerCase()) >= 0 && datenArr_in[4].toLowerCase() == $F('str').toLowerCase() && (datenArr_in[1]+"/"+datenArr_in[0]).toLowerCase() == unescape(orteingabe[0].toLowerCase()) && datenArr_in[3].toLowerCase() == unescape(orteingabe[1].toLowerCase())){
        	    			n_arr[i] = [datenArr_in[5],datenArr_in[6]];
                			i += 1;
            			}                        
    				}
				}	
			}
			if(n_arr.length != 0){
				n_arr.sort;
				var hausnr_sort; var hausnr_switch; var t; var j = 0; var hausnr_sicht;
				for(j in n_arr){
					if(j != 0){
						t = j;
						while(t > 0){
							if(parseInt(n_arr[t][0]) < parseInt(n_arr[t-1][0])){
								hausnr_switch = n_arr[t-1];
								n_arr[t-1] = n_arr[t];
								n_arr[t] = hausnr_switch;
							}
							t -= 1;
						}	
					}
				}
				for(j=0;j<n_arr.length; j++){
					hausnr_sort = n_arr[j][0]+n_arr[j][1].replace(/ /,'');
					hausnr_sicht = n_arr[j][0]+" "+n_arr[j][1].replace(/ /,'');
                    //hausnr_sicht = n_arr[j][0]+n_arr[j][1].replace(/ /,'');
					datenout += "<span id=\"treffer"+j+"\" class=\"treffer\" onmouseout=javascript:usemouseout(\"treffer"+j+"\") onmouseover=javascript:usemouseover(\"treffer"+j+"\") onclick=javascript:wert_eingabe(\""+hausnr_sort+"|nr\")>"+hausnr_sicht+"</span><br>\n";
				}
			}
			else{
				if($F('str') != "") datenout = "Die von Ihnen gew&#228;hlte Hausnummer ist nicht vergeben";
			}
			return datenout;
			break;
	}
}

// Response List fr normale Suche, z.B. Berg, Gew�e, Ort, und sonstige einfache Suchfunktionen.
function normalResponse(response_parameter, datenArray){
	var i = 0, ausgabe = '', datenout = '';
	switch(response_parameter){
		case 'ort_ort':
			var _ort_ansicht='', _ort_k='', _ort_value='';
			for(var teil=0; teil<datenArray.length; teil++){
    			if(datenArray[teil] != '' && datenArray[teil] != '\r'){
				datenArr_in = datenArray[teil].split('\|');
				_ort_k = datenArr_in[0].toLowerCase();
            		if(ausgabe == '' && datenArr_in[0] != 'undefined' && _ort_k.indexOf($F('ort_ort').toLowerCase()) >= 0){
                		_ort_ansicht = datenArr_in[0]+", "+datenArr_in[1];
                        _ort_value = datenArr_in[0]+"#"+datenArr_in[1]+"#"+parseInt(datenArr_in[2])+"#"+parseInt(datenArr_in[3]);
                        while(_ort_value.indexOf(' ') >= 0){
                    		_ort_value = _ort_value.replace(/ /,"%20");
                   		}
                    	normalHash[teil] = new Array("treffer"+teil,_ort_value);
						datenout += "<span id=\"treffer"+teil+"\" class=\"treffer\" onmouseout=javascript:usemouseout(\"treffer"+teil+"\") onmouseover=javascript:usemouseover(\"treffer"+teil+"\") onclick=javascript:wert_eingabe(\""+_ort_value+"|ort_ort\")>- "+_ort_ansicht+"</span><br>\n";
					}
                	else{
						_ort_ansicht = datenArr_in[0]+", "+datenArr_in[1];
                        _ort_value = datenArr_in[0]+"#"+datenArr_in[1]+"#"+parseInt(datenArr_in[2])+"#"+parseInt(datenArr_in[3]);
                        while(_ort_value.indexOf(' ') >= 0){
                    		_ort_value = _ort_value.replace(/ /,"%20");
                		}
						normalHash[teil] = new Array("treffer"+teil,_ort_value);
						datenout += "<span id=\"treffer"+teil+"\" class=\"treffer\" onmouseout=javascript:usemouseout(\"treffer"+teil+"\") onmouseover=javascript:usemouseover(\"treffer"+teil+"\") onclick=javascript:wert_eingabe(\""+_ort_value+"|ort_ort\")>- "+_ort_ansicht+"</span><br>\n";
					}
                	ausgabe = _ort_ansicht;
				}
			}
			return datenout;
			break;
		case 'berg':
			var _berg_ansicht='', _berg_k='', _berg_value=''
			for(var teil=0; teil<datenArray.length; teil++){
    			if(datenArray[teil] != '' && datenArray[teil] != '\r'){
					datenArr_in = datenArray[teil].split('|');
					_berg_k = datenArr_in[0].toLowerCase();
        			if(ausgabe == '' && datenArr_in[0] != 'undefined' && _berg_k.indexOf($F('berg').toLowerCase()) >= 0){
        				_berg_ansicht = datenArr_in[0]+", "+datenArr_in[1];
        				_berg_value = datenArr_in[0]+"#"+datenArr_in[1]+"#"+parseInt(datenArr_in[3])+"#"+parseInt(datenArr_in[4]);
        				while(_berg_value.indexOf(" ") >= 0){
        					_berg_value = _berg_value.replace(/ /,'%20');
            			}
            			normalHash[teil] = new Array("treffer"+teil,_berg_value);
         				datenout += "<span id=\"treffer"+teil+"\" class=\"treffer\" onmouseout=javascript:usemouseout(\"treffer"+teil+"\") onmouseover=javascript:usemouseover(\"treffer"+teil+"\") onclick=javascript:wert_eingabe(\""+_berg_value+"|berg\")>- "+_berg_ansicht+"</span><br>\n";
         			}
            		else{
						_berg_ansicht = datenArr_in[0]+", "+datenArr_in[1];
            			_berg_value = datenArr_in[0]+"#"+datenArr_in[1]+"#"+parseInt(datenArr_in[3])+"#"+parseInt(datenArr_in[4]);
            			while(_berg_value.indexOf(" ") >= 0){
            				_berg_value = _berg_value.replace(/ /,'%20');
            			}
						normalHash[teil] = new Array("treffer"+teil,_berg_value);
						datenout += "<span id=\"treffer"+teil+"\" class=\"treffer\"onmouseout=javascript:usemouseout(\"treffer"+teil+"\") onmouseover=javascript:usemouseover(\"treffer"+teil+"\") onclick=javascript:wert_eingabe(\""+_berg_value+"|berg\")>- "+_berg_ansicht+"</span><br>\n";
					}
           			ausgabe = _berg_ansicht;
				}
			}
			return datenout;
			break;
		case 'gew':
			var _gew_ansicht='', _gew_k='', _gew_value='';
			for(var teil=0; teil<datenArray.length; teil++){
    			if(datenArray[teil] != '' && datenArray[teil] != '\r'){
					datenArr_in = datenArray[teil].split('|');
					_gew_k = datenArr_in[0].toLowerCase();
           			if(ausgabe == "" && datenArr_in[0] != 'undefined' && _gew_k.indexOf($F('gew').toLowerCase()) >= 0){
       					_gew_ansicht = datenArr_in[0]+", "+datenArr_in[1];
               			_gew_value = datenArr_in[0]+"#"+datenArr_in[1]+"#"+parseInt(datenArr_in[2])+"#"+parseInt(datenArr_in[3]);
        				while(_gew_value.indexOf(' ') >= 0){
        	   				_gew_value = _gew_value.replace(/ /,'%20');
            			}
               			normalHash[teil] = new Array("treffer"+teil,_gew_value);
            			datenout += "<span id=\"treffer"+teil+"\" class=\"treffer\" onmouseout=javascript:usemouseout(\"treffer"+teil+"\") onmouseover=javascript:usemouseover(\"treffer"+teil+"\") onclick=javascript:wert_eingabe(\""+_gew_value+"|gew\")>- "+_gew_ansicht+"</span><br>\n";
            		}
            		else{
						_gew_ansicht = datenArr_in[0]+", "+datenArr_in[1];
               			_gew_value = datenArr_in[0]+"#"+datenArr_in[1]+"#"+parseInt(datenArr_in[2])+"#"+parseInt(datenArr_in[3]);
              			while(_gew_value.indexOf(' ') >= 0){
               				_gew_value = _gew_value.replace(/ /,'%20');
               			}
						normalHash[teil] = new Array("treffer"+teil,_gew_value);
						datenout += "<span id=\"treffer"+teil+"\" class=\"treffer\" onmouseout=javascript:usemouseout(\"treffer"+teil+"\") onmouseover=javascript:usemouseover(\"treffer"+teil+"\") onclick=javascript:wert_eingabe(\""+_gew_value+"|gew\")>- "+_gew_ansicht+"</span><br>\n";
					}
            		ausgabe = _gew_ansicht;
				}
			}
			return datenout;
			break;
	}
}

// Response List fr Schule
function schulResponse(datenArray){
	var _schul_ansicht='', _schul_ort='', _schul_name='', _schul_value='', i= 0, ausgabe = '', datenout = '';
	for(var teil=0; teil<datenArray.length; teil++){
    	if(datenArray[teil] != '' && datenArray[teil] != '\r' && datenArray[teil]!="keine Daten gefunden"){
        	datenArr_in = datenArray[teil].split('\|');
			_schul_ort = datenArr_in[2].toLowerCase();
            _schul_name = datenArr_in[0].toLowerCase();
            if((ausgabe == '' || ausgabe != (datenArr_in[0]+"("+datenArr_in[2]+")")+datenArr_in[5]) && datenArr_in[2] != 'undefined'){
            _schul_ansicht = datenArr_in[0]+"("+datenArr_in[2]+")";
            _schul_value = datenArr_in[0]+"("+datenArr_in[2]+")"+datenArr_in[5];
	    ausgabe = datenArr_in[0]+"("+datenArr_in[2]+")"+datenArr_in[5];	
				while(_schul_value.indexOf(" ") >= 0){
            		_schul_value = _schul_value.replace(/ /,"%20");
				}
            datenout += "<span id=\"treffer"+teil+"\" class=\"treffer\" onmouseout=javascript:usemouseout(\"treffer"+teil+"\") onmouseover=javascript:usemouseover(\"treffer"+teil+"\") onclick=javascript:wert_eingabe(\""+_schul_value+"|schule\")>- "+_schul_ansicht+"</span><br>\n";
			schulezahl += 1;
			
			}
		}	
	}
	return datenout;
}


// Nummerisch Sotieren
function Numsort (a, b) {
  return a - b;
}

// Diese Funktion wird gerufen, wenn 'Neu' Button gedrckt wird 
function loesche_Felder(eingabe){
    $('mauszeige').style.visibility = 'hidden';
    switch(eingabe){
    	case 'ort': 
    	    document.such_eingabe.ort_ort.value = '';
            if($('ort_ortResult')){deldatenResult();}
            document.such_eingabe.ort_ort.focus();
            break;
    	case 'adr':
    		document.such_eingabe.plz.value = '';
    		document.such_eingabe.ort.value = '';
    		document.such_eingabe.str.value = '';
    		document.such_eingabe.hausnr.value = '';
            if($('plzResult')){deldatenResult();}
            if($('ortResult')){deldatenResult();}
            if($('strResult')){deldatenResult();}
            if($('nrResult')){deldatenResult();}
  			document.such_eingabe.ort.focus();
    		break;
    	case "berg":
    		document.such_eingabe.berg.value = '';
            if($('bergResult')){deldatenResult();}
            document.such_eingabe.berg.focus();
            break;
    	case 'gew':
    		document.such_eingabe.gew.value = '';
            if($('gewResult')){deldatenResult();}
            document.such_eingabe.gew.focus();
            break;
    	case 'schule':
    		document.such_eingabe.schule.value = '';
    		if($('schuleResult')){deldatenResult();}
            document.such_eingabe.schule.focus();
            break;
    }
    str_value = null;
    plz_value = null;
    ort_value = null;
    hausnr_value = null;
    berg_value_name = null;
    berg_value_ort = null;
    gew_value_name = null;
    gew_value_ort = null;
    schulname_value = null;
    schulort_value = null;
    
    initPan();
    $('newpunkt').style.visibility = 'hidden';
    $('iconPan').src = 'res/Button_Hand.gif';
    $('iconStrecke').src = 'res/Button_Lineal.gif';
    $('iconFlaeche').src = 'res/Button_Lineal_Flaeche.gif';
    document.gkpunkte = '';
    document.gkDrawPunkte = '';
    document.pktPosition = '';
    $('pkt_koord').innerHTML = '';
    p_nr = 0;
    letztpkt = 0;
    ersttaste = "no";
    p_nr_text = 'leer', Polygonzu = 'nein';    
    var Obj = v_getRawObject('imgPolygon');
    Obj.innerHTML = '';
}

// Finden die ausgew�lte Addresse
function addresse_Koordsuch(){
	var rw = 0, hw = 0, j = 0, haus_nr, haus_nr_eingabe, teil;
	//str_value = null;
    //plz_value = null;
    //ort_value = null;
    //hausnr_value = null;
    //berg_value_name = null;
    //berg_value_ort = null;
    //gew_value_name = null;
    //gew_value_ort = null;
    //schulname_value = null;
    //schulort_value = null;
	$('datentake').style.visibility = 'hidden';
    $('maus_cursor').style.cursor = 'Auto';
    if($F('ort') != '' && $F('str') == '' && $F('hausnr') == ''){
    	for(teil=0; teil<datenArr_zeilen.length; teil++){
    		if(datenArr_zeilen[teil] != '' && datenArr_zeilen[teil] != '\r'){
    			datenArr_in = datenArr_zeilen[teil].split('|');
    			if(unescape($F('ort')) == (datenArr_in[1]+"/"+datenArr_in[0]+", "+datenArr_in[3])){ 
            		ort_value = datenArr_in[1]+"/"+datenArr_in[0]+", "+datenArr_in[3];                                
                	rw = parseFloat(datenArr_in[7]);
                	hw = parseFloat(datenArr_in[8]);
          			j = 1;
          			break;
          		}
    		}
    	}
    }
    else if($F('ort') != '' && $F('str') != '' && $F('hausnr') == ''){
    	var orteingabe = $F('ort').split(','); 	
   		orteingabe[1] = orteingabe[1].substr(1,orteingabe[1].length-1);
    	for(teil=0; teil<datenArr_zeilen.length; teil++){
    		if(datenArr_zeilen[teil] != '' && datenArr_zeilen[teil] != '\r'){
    			datenArr_in = datenArr_zeilen[teil].split('|');
    			if(unescape($F('str')) == datenArr_in[4] && unescape(orteingabe[0].toLowerCase()) == (datenArr_in[1]+"/"+datenArr_in[0]).toLowerCase() && unescape(orteingabe[1].toLowerCase()) == datenArr_in[3].toLowerCase()){
        			//haus_nr = datenArr_in[5]+datenArr_in[6].replace(/ /,"");
        			document.such_eingabe.plz.value = datenArr_in[2]; 
        			document.such_eingabe.ort.value = datenArr_in[1]+"/"+datenArr_in[0]+", "+datenArr_in[3];
            		document.such_eingabe.str.value = datenArr_in[4]; 
            		document.such_eingabe.hausnr.value = haus_nr;
            		plz_value = datenArr_in[2];
            		ort_value = datenArr_in[0]+", "+datenArr_in[3];
            		str_value = datenArr_in[4];
            		//hausnr_value = haus_nr;
                    hausnr_value = "";
            		rw = parseFloat(datenArr_in[7]);
            		hw = parseFloat(datenArr_in[8]);
            		j = 1;
            		break;
       			}
    		}
    	}
    }
    else if($F('ort') != ''){
    	var orteingabe = $F('ort').split(','); 	
   		orteingabe[1] = orteingabe[1].substr(1,orteingabe[1].length-1);
   		for(teil=0; teil<datenArr_zeilen.length; teil++){
    		if(datenArr_zeilen[teil] != '' && datenArr_zeilen[teil] != '\r'){
    			datenArr_in = datenArr_zeilen[teil].split('|');
    			haus_nr = datenArr_in[5]+datenArr_in[6].replace(/ /,'');
        		if(unescape($F('str')) == datenArr_in[4] && $F('hausnr').replace(/ /,'') == haus_nr && unescape(orteingabe[0].toLowerCase()) == (datenArr_in[1]+"/"+datenArr_in[0]).toLowerCase() && unescape(orteingabe[1].toLowerCase()) == datenArr_in[3].toLowerCase()){
					if($F('hausnr').indexOf('/') >= 0){
						haus_nr_eingabe = $F('hausnr').replace(/ /,'');
						if(haus_nr_eingabe != haus_nr){
							continue;
						}
					}
					//haus_nr_eingabe = $F('hausnr').replace(/ /,'');
					document.such_eingabe.plz.value = datenArr_in[2]; 
					document.such_eingabe.ort.value = datenArr_in[1]+"/"+datenArr_in[0]+", "+datenArr_in[3];
					document.such_eingabe.str.value = datenArr_in[4]; 
					//document.such_eingabe.hausnr.value = haus_nr;
                    haus_nr = datenArr_in[5]+" "+datenArr_in[6];
    				plz_value = datenArr_in[2]; 
    				ort_value = datenArr_in[0]+", "+datenArr_in[3];
    				str_value = datenArr_in[4];
    				hausnr_value = haus_nr;
    				rw = parseFloat(datenArr_in[7]);
					hw = parseFloat(datenArr_in[8]);
					j = 1;
					break;    
				}
    		}
    	}
    }
    if(j == 1) Koorddarstellen(rw,hw);
    else alert(unescape("Die von Ihnen gew%e4hlte Adresse wurde nicht gefunden. Bitte pr%fcfen Sie Ihre Eingabe."));
}

function normal_Koordsuch_absenden(){
	for(var i=0;i<normalHash.length;i++){
		if(normalHash[i][0] == document.such_eingabe.treffer.value){
			var _trefferstr = normalHash[i][1].split("#");
			normal_Koordsuch(_trefferstr[0],_trefferstr[1],_trefferstr[2],_trefferstr[3]);
			break;
		}
	}
}

// Finden die ausgew�lte Berg, Gew�e, Ort, und sonstige Auswahl
function normal_Koordsuch(objname,objort,objrw,objhw){
	var rw = 0, hw = 0, j = 0;
	//berg_value_name = null;
	//berg_value_ort = null;
	//gew_value_name = null;
	//gew_value_ort = null;
	//ort_value = null;
    //	plz_value = null;
    //	str_value = null;
    //	hausnr_value = null;
    //	schulname_value = null;
    //	schulort_value = null;
    
	$('datentake').style.visibility = 'hidden';
    	$('maus_cursor').style.cursor = 'Auto';
    	switch(eingabe_ID){
    		case 'ort_ort':
    			var orteingabe;
				ort_value = unescape(objname+', '+objort);
    			rw = parseFloat(objrw);
				hw = parseFloat(objhw);
				j = 1;
    			break;
    	case 'berg':
    		var bergeingabe;
			berg_value_name = unescape(objname); berg_value_ort = unescape(objort);
    		rw = parseFloat(objrw);
			hw = parseFloat(objhw);
			j = 1;
    		break;
    	case 'gew':
    		var geweingabe;
			gew_value_name = unescape(objname); gew_value_ort = unescape(objort);
    		rw = parseFloat(objrw);
			hw = parseFloat(objhw);
			j = 1;
    		break;
    }
    if(j == 1) Koorddarstellen(rw,hw);
    else{
    	if($F('ort_ort') == '') alert(unescape("Der von Ihnen gew%e4hlte Ort wurde nicht gefunden. Bitte pr%fcfen Sie Ihre Eingabe."));
    	if($F('berg') == '') alert(unescape("Der von Ihnen gew%e4hlte Berg wurde nicht gefunden. Bitte pr%fcfen Sie Ihre Eingabe."));
    	if($F('gew') == '') alert(unescape("Das von Ihnen gew%e4hlte Gew%e4sser wurde nicht gefunden. Bitte pr%fcfen Sie Ihre Eingabe."));
    }
}

//  Finden die ausgew�lte Schule
function schule_Koordsuch(schuledaten){
	var rw = 0, hw = 0, j = 0;
	schulname_value = null;
    schulort_value = null;
    berg_value_name = null;
    berg_value_ort = null;
    gew_value_name = null;
    gew_value_ort = null;
    ort_value = null;
    plz_value = null;
    str_value = null;
    hausnr_value = null;
	var schuleingabe; 
    for(teil=0; teil<datenArr_zeilen.length; teil++){
    	if(datenArr_zeilen[teil] != "" && datenArr_zeilen[teil] != '\r' && j == 0){
    		datenArr_in = datenArr_zeilen[teil].split('|');
    		schuleingabe = datenArr_in[0]+'('+datenArr_in[2]+')'+datenArr_in[5];
    		if(schuleingabe.toLowerCase() == schuledaten.toLowerCase() || schulezahl == 1){
    			schulname_value = datenArr_in[0]; schulort_value = datenArr_in[5]+" "+datenArr_in[6]+",   "+datenArr_in[3]+" "+datenArr_in[2];
    			rw = parseFloat(datenArr_in[8]);
				hw = parseFloat(datenArr_in[9]);
				j = 1;
				break;
    		}
    	}
    }
    if(j == 1) Koorddarstellen(rw,hw);
    else  alert(unescape("Die von Ihnen gew%e4hlte Schule wurde nicht gefunden. Bitte pr%fcfen Sie Ihre Eingabe."));
}

// Ausgew�lte Koordinaten darzustellen
function Koorddarstellen(rwert, hwert){
	$("gk_pkt").innerHTML = rwert+","+hwert;
	document.formImg.rm.value = rwert;
	document.formImg.hm.value = hwert;
    $("mauszeige").innerHTML = "";
    $("pktm").innerHTML = "";
    $("pkt_koord").innerHTML = "Ort_wird_gefunden";
    $("iconPan").src = "res/Button_Hand.gif";
    $("iconStrecke").src = "res/Button_Lineal.gif";
    $("iconFlaeche").src = "res/Button_Lineal_Flaeche.gif";
    document.gkpunkte = "";
    document.gkDrawPunkte = "";
    document.pktPosition = "";
    p_nr = 0, letztpkt = 0;
    p_nr_text = "leer", Polygonzu = "nein";
    such_ergebnis = 1;
    updateMap();
    bergsuch=0;
    gewsuch=0;
    ort_ortsuch=0;
    schulesuch = 0;
    schulezahl = 0;
	$("newpunkt").style.visibility = "hidden";
}

// Ausgewaehlte Daten in entspricht Feld ausfuellen
function wert_eingabe(wert){
	ort_koordinaten = "";
	var feld = wert.split('\|');
	var feldstr = feld[0].split('#');
	var h_nr, h_nrzu;
	switch (feld[1]){
		case 'plz':
			document.such_eingabe.plz.value = feld[0];
			deldatenResult();
			break;
		case 'ort':
			feldstr = feldstr[1]+"/"+feldstr[0]+", "+feldstr[2];
			document.such_eingabe.ort.value = unescape(feldstr);
			deldatenResult();
			break;
		case 'str':
        		document.such_eingabe.str.value = unescape(feld[0]);
            		deldatenResult();
            		break;
		case 'nr':
            		if(feld[0].indexOf('/') >= 0){
            			h_nr = feld[0].substr(0,feld[0].length-3);
                		h_nrzu = feld[0].substr(feld[0].length-3,3);
               			document.such_eingabe.hausnr.value = h_nr+' '+h_nrzu;
          		}
         		else{document.such_eingabe.hausnr.value = feld[0];}
            			deldatenResult();
            			addresse_Koordsuch();
            		break;
        case 'ort_ort':
			document.such_eingabe.ort_ort.value = unescape(feldstr[0])+", "+unescape(feldstr[1]);
			deldatenResult();
			normal_Koordsuch(feldstr[0],feldstr[1],feldstr[2],feldstr[3]);
			break;
		case 'berg':
			document.such_eingabe.berg.value = unescape(feldstr[0]+' '+feldstr[1]);
			deldatenResult();
			normal_Koordsuch(feldstr[0],feldstr[1],feldstr[2],feldstr[3]);
			break; 
		case 'gew':
			document.such_eingabe.gew.value = unescape(feldstr[0]+' '+feldstr[1]);
			deldatenResult();
			normal_Koordsuch(feldstr[0],feldstr[1],feldstr[2],feldstr[3]);
			break;
		case 'schule':
           	deldatenResult();
            schule_Koordsuch(unescape(feld[0]));
            break;     
	}
}

// Verschiedene Taste Funktionen
function keypush(Ereignis){
	var _hnr;
	if(!Ereignis) {Ereignis = window.event;}
    if(Ereignis.which){
		//event=e;
		taste = Ereignis.which;
	}
	else if(Ereignis.keyCode){
		taste = Ereignis.keyCode;
	}
	if(ersttaste == 'no'){
		tastecode = 0;
		wert_value = '';
	}
    
    if(Ereignis.ctrlKey == true){ctrlkey = true;}
    else{ctrlkey = false;}
	if($(selectfeld)){
		switch(taste) {
			case 8:
				if(selectfeld == 'schuleResult' && document.such_eingabe.schule.value == '' && $("schuleResult")){
					deldatenResult();
				}
				break;
			case 40:
				if($(selectfeld).childNodes[tastecode]){
					if( tastecode == 0){
						switch (selectfeld){
							case 'plzResult':	
								document.such_eingabe.plz.blur();
								$('plzResult').focus();
								if(wert_value == ''){	
									wert_value = $F('plz');
								}
								break;
							case 'ortResult':	
								document.such_eingabe.ort.blur();
								$('ortResult').focus();
								if(wert_value == ''){	
									wert_value = $F('ort');
								}
								break;
							case 'strResult':	
								document.such_eingabe.str.blur();
								$('strResult').focus();
								if(wert_value == ''){
									wert_value = $F('str');
								}
								break;
							case 'nrResult':	
								document.such_eingabe.hausnr.blur();
								$('nrResult').focus();
								if(wert_value == ''){
									wert_value = $F('hausnr');
								}
								break;
							case 'ort_ortResult':	
								document.such_eingabe.ort_ort.blur();
								$('ort_ortResult').focus();
								if(wert_value == ''){	
									wert_value = $F('ort_ort');
								}
								break;
							case 'bergResult':
								document.such_eingabe.berg.blur();
								$('bergResult').focus();
								if(wert_value == ''){
									wert_value = $F('berg');
								}
								break;
							case 'gewResult':
								document.such_eingabe.gew.blur();
								$('gewResult').focus();
								if(wert_value == ''){
									wert_value = $F('gew');
								}
								break;
							case 'schuleResult':
								document.such_eingabe.schule.blur();
								$('schuleResult').focus();
								if(wert_value == ''){
									wert_value = $F('schule');
								}
								break;
						}
					}
				}
				if(tastecode != 0 && $(selectfeld).childNodes[tastecode]){
					if(browserName == 'ie'){
						$(selectfeld).childNodes[tastecode-2].style.backgroundColor = '#ffffff';
						$(selectfeld).childNodes[tastecode-2].style.fontSize = '12px';
						$(selectfeld).childNodes[tastecode-2].style.color = '#000000';
					}
					else{
						$(selectfeld).childNodes[tastecode-3].style.backgroundColor = '#ffffff';
						$(selectfeld).childNodes[tastecode-3].style.fontSize = '12px';
						$(selectfeld).childNodes[tastecode-3].style.color = '#000000';
					}
				}
				if($(selectfeld).childNodes[tastecode]){
					if(browserName == 'ie'){
						switch (selectfeld){
							case 'plzResult':	document.such_eingabe.plz.value = $(selectfeld).childNodes[tastecode].firstChild.nodeValue; break;
							case 'ortResult':	document.such_eingabe.ort.value = $(selectfeld).childNodes[tastecode].firstChild.nodeValue.substr(2,$(selectfeld).childNodes[tastecode].firstChild.nodeValue.length-2); break;
							case 'strResult':	document.such_eingabe.str.value = $(selectfeld).childNodes[tastecode].firstChild.nodeValue; break;
							case 'nrResult':	
								_hnr = $(selectfeld).childNodes[tastecode].firstChild.nodeValue;
								document.such_eingabe.hausnr.value = _hnr; break;
							case 'ort_ortResult':	
								document.such_eingabe.ort_ort.value = $(selectfeld).childNodes[tastecode].firstChild.nodeValue.substr(2,$(selectfeld).childNodes[tastecode].firstChild.nodeValue.length-2);
								document.such_eingabe.treffer.value = $('ort_ortResult').childNodes[tastecode].id;
								break;
							case 'bergResult': 
								document.such_eingabe.berg.value = $(selectfeld).childNodes[tastecode].firstChild.nodeValue.substr(2,$(selectfeld).childNodes[tastecode].firstChild.nodeValue.length-2);
								document.such_eingabe.treffer.value =  $('bergResult').childNodes[tastecode].id;
								break;
							case 'gewResult': 
								document.such_eingabe.gew.value = $(selectfeld).childNodes[tastecode].firstChild.nodeValue.substr(2,$(selectfeld).childNodes[tastecode].firstChild.nodeValue.length-2);
								document.such_eingabe.treffer.value =  $('gewResult').childNodes[tastecode].id;
								break;
						}
					}
					else{
						switch (selectfeld){
							case 'plzResult':	document.such_eingabe.plz.value = $(selectfeld).childNodes[tastecode].textContent; break;
							case 'ortResult':	document.such_eingabe.ort.value = $(selectfeld).childNodes[tastecode].textContent.substr(2,$(selectfeld).childNodes[tastecode].textContent.length-2); break;
							case 'strResult':	document.such_eingabe.str.value = $(selectfeld).childNodes[tastecode].textContent; break;
							case 'nrResult':	
								_hnr = $(selectfeld).childNodes[tastecode].textContent;
								document.such_eingabe.hausnr.value = _hnr; break;
							case 'ort_ortResult':	
								document.such_eingabe.ort_ort.value = $(selectfeld).childNodes[tastecode].textContent.substr(2,$(selectfeld).childNodes[tastecode].textContent.length-2);
								document.such_eingabe.treffer.value = $('ort_ortResult').childNodes[tastecode].id;
								break;
							case 'bergResult': 
								document.such_eingabe.berg.value = $(selectfeld).childNodes[tastecode].textContent.substr(2,$(selectfeld).childNodes[tastecode].textContent.length-2);
								document.such_eingabe.treffer.value =  $('bergResult').childNodes[tastecode].id;
								break;
							case 'gewResult': 
								document.such_eingabe.gew.value = $(selectfeld).childNodes[tastecode].textContent.substr(2,$(selectfeld).childNodes[tastecode].textContent.length-2);
								document.such_eingabe.treffer.value =  $('gewResult').childNodes[tastecode].id;
								break;
						}
					}
					$(selectfeld).childNodes[tastecode].style.backgroundColor = '#dae8f6';
					$(selectfeld).childNodes[tastecode].style.fontSize = '12px';
					$(selectfeld).childNodes[tastecode].style.color = '#000000';
					if(browserName == 'ie'){
						tastecode += 2;
					}
					else{tastecode += 3;} 
				}
				ersttaste = 'yes'; tablator = 'ja';
				break;
			case 38:
				if(tastecode == 3 || (browserName == 'ie' && tastecode == 2)){
					switch (selectfeld){
						case 'plzResult':	
							document.such_eingabe.plz.value = wert_value;
							document.such_eingabe.plz.focus();
							break;
						case 'ortResult':
							document.such_eingabe.ort.value = wert_value;
							document.such_eingabe.ort.focus();
							break;
						case 'strResult':	
							document.such_eingabe.str.value = wert_value;
							document.such_eingabe.str.focus();
							break;
						case 'nrResult':
							document.such_eingabe.hausnr.value = wert_value;
							document.such_eingabe.hausnr.focus();
							break;
						case 'ort_ortResult':
							document.such_eingabe.ort_ort.value = wert_value;
							document.such_eingabe.ort_ort.focus();
							break;
						case 'bergResult':
							document.such_eingabe.berg.value = wert_value;
							document.such_eingabe.berg.focus();
							break;
						case 'gewResult':
							document.such_eingabe.gew.value = wert_value;
							document.such_eingabe.gew.focus();
							break;
						case 'schuleResult':
							document.such_eingabe.schule.value = wert_value;
							document.such_eingabe.schule.focus();
						break;
					}
					ersttaste = 'no';
				}
				else{
					if(browserName == 'ie' && tastecode>=4){
						switch (selectfeld){
							case 'plzResult': document.such_eingabe.plz.value = $(selectfeld).childNodes[tastecode-4].firstChild.nodeValue; break;
							case 'ortResult': document.such_eingabe.ort.value = $(selectfeld).childNodes[tastecode-4].firstChild.nodeValue.substr(2,$(selectfeld).childNodes[tastecode-4].firstChild.nodeValue.length-2); break;
							case 'strResult': document.such_eingabe.str.value = $(selectfeld).childNodes[tastecode-4].firstChild.nodeValue; break;
							case 'nrResult':	
								_hnr = $(selectfeld).childNodes[tastecode-4].firstChild.nodeValue;
								document.such_eingabe.hausnr.value = _hnr; break;
							case 'ort_ortResult': 
								document.such_eingabe.ort_ort.value =$(selectfeld).childNodes[tastecode-4].firstChild.nodeValue.substr(2,$(selectfeld).childNodes[tastecode-4].firstChild.nodeValue.length-2);
								document.such_eingabe.treffer.value =  $('ort_ortResult').childNodes[tastecode-4].id;
								break;
							case 'bergResult':	
								document.such_eingabe.berg.value = $(selectfeld).childNodes[tastecode-4].firstChild.nodeValue.substr(2,$(selectfeld).childNodes[tastecode-4].firstChild.nodeValue.length-2);
								document.such_eingabe.treffer.value =  $('bergResult').childNodes[tastecode-4].id;
								break;
							case 'gewResult':	
								document.such_eingabe.gew.value = $(selectfeld).childNodes[tastecode-4].firstChild.nodeValue.substr(2,$(selectfeld).childNodes[tastecode-4].firstChild.nodeValue.length-2);
								document.such_eingabe.treffer.value =  $('gewResult').childNodes[tastecode-4].id;
								break;
						}
						$(selectfeld).childNodes[tastecode-4].style.backgroundColor = '#dae8f6';
						$(selectfeld).childNodes[tastecode-4].style.fontSize = '12px';
						$(selectfeld).childNodes[tastecode-4].style.color = '#000000';
						if(tastecode != 0){
							$(selectfeld).childNodes[tastecode-2].style.backgroundColor = '#ffffff';
							$(selectfeld).childNodes[tastecode-2].style.fontSize = '12px';
							$(selectfeld).childNodes[tastecode-2].style.color = '#000000';
						}
						tastecode -= 2;
					}
					else{
						if(tastecode>=4){
							switch (selectfeld){
								case 'plzResult':	document.such_eingabe.plz.value = $(selectfeld).childNodes[tastecode-6].textContent; break;
								case 'ortResult':	document.such_eingabe.ort.value = $(selectfeld).childNodes[tastecode-6].textContent.substr(2,$(selectfeld).childNodes[tastecode-6].textContent.length-2); break;
								case 'strResult':	document.such_eingabe.str.value = $(selectfeld).childNodes[tastecode-6].textContent; break;
								case 'nrResult':	
									_hnr = $(selectfeld).childNodes[tastecode-6].textContent;
									document.such_eingabe.hausnr.value = _hnr; break;
								case 'ort_ortResult': 
									document.such_eingabe.ort_ort.value = $(selectfeld).childNodes[tastecode-6].textContent.substr(2,$(selectfeld).childNodes[tastecode-6].textContent.length-2);
									document.such_eingabe.treffer.value =  $('ort_ortResult').childNodes[tastecode-6].id;
									break;
								case 'bergResult': 
									document.such_eingabe.berg.value = $(selectfeld).childNodes[tastecode-6].textContent.substr(2,$(selectfeld).childNodes[tastecode-6].textContent.length-2);
									document.such_eingabe.treffer.value =  $('bergResult').childNodes[tastecode-6].id;
									break;
								case 'gewResult': 
									document.such_eingabe.gew.value = $(selectfeld).childNodes[tastecode-6].textContent.substr(2,$(selectfeld).childNodes[tastecode-6].textContent.length-2);
									document.such_eingabe.treffer.value =  $('gewResult').childNodes[tastecode-6].id;
									break;
							}
							$(selectfeld).childNodes[tastecode-6].style.backgroundColor = '#dae8f6';
							$(selectfeld).childNodes[tastecode-6].style.fontSize = '12px';
							$(selectfeld).childNodes[tastecode-6].style.color = '#000000';
							if(tastecode != 0){
								$(selectfeld).childNodes[tastecode-3].style.backgroundColor = '#ffffff';
								$(selectfeld).childNodes[tastecode-3].style.fontSize = '12px';
								$(selectfeld).childNodes[tastecode-3].style.color = '#000000';
							}
							tastecode -= 3;
						}
					}
					ersttaste = 'yes'; tablator = 'ja';
				}
				break;
			case 13:
				var treffer_id;
				switch(such_STR){
					case 'adr_such': 
						if($F('ort') == '' && $F('str') == '' && $F('hausnr') == ''){
							if(document.such_eingabe.ort.value == ''){
								alert(unescape("Eingabe f%FCr Ort fehlt !"));
							}
							if(document.such_eingabe.str.value == ''){
								alert(unescape("Eingabe f%FCr Stra%DFe fehlt !"));
							}
							if(document.such_eingabe.hausnr.value == ''){
								alert(unescape("Eingabe f%FCr Hausnummer fehlt !"));
							}
						}
						else{
							if(browserName == "ie"){
								if($('ortResult') && tastecode == 0){
									document.such_eingabe.ort.value = $('ortResult').childNodes[0].firstChild.nodeValue.substr(2,$('ortResult').childNodes[0].firstChild.nodeValue.length-2);
									deldatenResult();
								}
								else if($('ortResult') && tastecode != 0){
									document.such_eingabe.ort.value = $('ortResult').childNodes[tastecode-2].firstChild.nodeValue.substr(2,$('ortResult').childNodes[tastecode-2].firstChild.nodeValue.length-2);
									deldatenResult();
								}
								if($('strResult') && tastecode == 0){
									document.such_eingabe.str.value = $('strResult').childNodes[0].firstChild.nodeValue;
									deldatenResult();
								}
								else if($('strResult') && tastecode != 0){
									document.such_eingabe.str.value = $('strResult').childNodes[tastecode-2].firstChild.nodeValue;
									deldatenResult();
								}
								if($('nrResult') && tastecode == 0){
									document.such_eingabe.hausnr.value = $('nrResult').childNodes[0].firstChild.nodeValue;
									deldatenResult();
								}
								else if($('nrResult') && tastecode != 0){
									document.such_eingabe.hausnr.value = $('nrResult').childNodes[tastecode-2].firstChild.nodeValue;
									deldatenResult();
								}
								document.such_eingabe.absenden.focus();
							}
							else{
								if($('ortResult') && tastecode == 0){
									document.such_eingabe.ort.value = $('ortResult').childNodes[0].textContent.substr(2,$('ortResult').childNodes[0].textContent.length-2);
									deldatenResult();
								}
								else if($('ortResult') && tastecode != 0){
									document.such_eingabe.ort.value = $('ortResult').childNodes[tastecode-3].textContent.substr(2,$('ortResult').childNodes[tastecode-3].textContent.length-2);
									deldatenResult();
								}
								if($('strResult') && tastecode == 0){
									document.such_eingabe.str.value = $('strResult').childNodes[0].textContent;
									deldatenResult();
								}
								else if($('strResult') && tastecode != 0){
									document.such_eingabe.str.value = $('strResult').childNodes[tastecode-3].textContent;
									deldatenResult();
								}
								if($('nrResult') && tastecode == 0){
									document.such_eingabe.hausnr.value = $('nrResult').childNodes[0].textContent;
									deldatenResult();
								}
								else if($('nrResult') && tastecode != 0){
									document.such_eingabe.hausnr.value = $('nrResult').childNodes[tastecode-3].textContent;
									deldatenResult();
								}
							}
						}	 
						break;
					case 'ort_ort_such': 
						if($F('ort_ort') == ''){
							alert(unescape("Eingabe f%FCr Ort fehlt !"));
							document.such_eingabe.ort_ort.focus();
						}
						else{
							if(browserName == "ie"){
								if($('ort_ortResult') && tastecode == 0){
									document.such_eingabe.ort_ort.value = $('ort_ortResult').childNodes[0].firstChild.nodeValue.substr(2,$('ort_ortResult').childNodes[0].firstChild.nodeValue.length-2);
									treffer_id = $('ort_ortResult').childNodes[0].id;
									deldatenResult();
								}
								else if($('ort_ortResult') && tastecode != 0){
									document.such_eingabe.ort_ort.value = $('ort_ortResult').childNodes[tastecode-2].firstChild.nodeValue.substr(2,$('ort_ortResult').childNodes[tastecode-2].firstChild.nodeValue.length-2);
									treffer_id = $('ort_ortResult').childNodes[tastecode-2].id;
									deldatenResult();
								}
								if(ort_ortsuch == 1){
									 for(var i=0;i<normalHash.length;i++){
										if(normalHash[i][0] == treffer_id ){
											var _ortstr = normalHash[i][1].split("#");
											normal_Koordsuch(_ortstr[0],_ortstr[1],_ortstr[2],_ortstr[3]);
											break;
										}
									}
								}
							}
							else{
								if($('ort_ortResult') && tastecode == 0){
									document.such_eingabe.ort_ort.value = $('ort_ortResult').childNodes[0].textContent.substr(2,$('ort_ortResult').childNodes[0].textContent.length-2);
									treffer_id = $('ort_ortResult').childNodes[0].id
									deldatenResult();
								}
								else if($('ort_ortResult') && tastecode != 0){
									document.such_eingabe.ort_ort.value = $('ort_ortResult').childNodes[tastecode-3].textContent.substr(2,$('ort_ortResult').childNodes[tastecode-3].textContent.length-2);
									treffer_id = $('ort_ortResult').childNodes[tastecode-3].id;
									deldatenResult();
								}
								if(ort_ortsuch == 1) {
									for(var i=0;i<normalHash.length;i++){
										if(normalHash[i][0] == treffer_id ){
											var _ortstr = normalHash[i][1].split("#");
											normal_Koordsuch(_ortstr[0],_ortstr[1],_ortstr[2],_ortstr[3]);
											break;
										}
									}
								}
							}
						} 
						break;
					case 'berg_such': 
						if($F('berg') == ""){
							alert("Eingabe f"+unescape('%FC')+"r Berg Name fehlt !");
						}
						else{
							if(browserName == "ie"){
								if($('bergResult') && tastecode == 0){
									document.such_eingabe.berg.value = $('bergResult').childNodes[0].firstChild.nodeValue.substr(2,$('bergResult').childNodes[0].firstChild.nodeValue.length-2);
									treffer_id = $('bergResult').childNodes[0].id;
									deldatenResult();
								}
								else if($('bergResult') && tastecode != 0){
									document.such_eingabe.berg.value = $('bergResult').childNodes[tastecode-2].firstChild.nodeValue.substr(2,$('bergResult').childNodes[tastecode-2].firstChild.nodeValue.length-2);
									treffer_id = $('bergResult').childNodes[tastecode-2].id;
									deldatenResult();
								}
								if(bergsuch == 1) {
									for(var i=0;i<normalHash.length;i++){
										if(normalHash[i][0] == treffer_id){
											var _bergstr = normalHash[i][1].split("#");
											normal_Koordsuch(_bergstr[0],_bergstr[1],_bergstr[2],_bergstr[3]);
											break;
										}
									}
								}
							}
							else{
								if($('bergResult') && tastecode == 0){
									document.such_eingabe.berg.value = $('bergResult').childNodes[0].textContent.substr(2,$('bergResult').childNodes[0].textContent.length-2);
									treffer_id = $('bergResult').childNodes[0].id;
									deldatenResult();
								}
								else if($('bergResult') && tastecode != 0){
									document.such_eingabe.berg.value = $('bergResult').childNodes[tastecode-3].textContent.substr(2,$('bergResult').childNodes[tastecode-3].textContent.length-2);
									treffer_id = $('bergResult').childNodes[tastecode-3].id
									deldatenResult();
								}
								if(bergsuch == 1){
									for(var i=0;i<normalHash.length;i++){
										if(normalHash[i][0] == treffer_id){
											var _bergstr = normalHash[i][1].split("#");
											normal_Koordsuch(_bergstr[0],_bergstr[1],_bergstr[2],_bergstr[3]);
											break;
										}
									}
								}
							}
						}
						break;
					case 'gew_such': 
						if($F('gew') == ''){
							alert(unescape("Eingabe fuer G%E4wessername fehlt !"));
						}
						else{
							if(browserName == 'ie'){
								if($('gewResult') && tastecode == 0){
									document.such_eingabe.gew.value = $('gewResult').childNodes[0].firstChild.nodeValue.substr(2,$('gewResult').childNodes[0].firstChild.nodeValue.length-2);
									treffer_id = $('gewResult').childNodes[0].id;
									deldatenResult();
								}
								else if($('gewResult') && tastecode != 0){
									document.such_eingabe.gew.value = $('gewResult').childNodes[tastecode-2].firstChild.nodeValue.substr(2,$('gewResult').childNodes[tastecode-2].firstChild.nodeValue.length-2);
									treffer_id = $('gewResult').childNodes[tastecode-2].id;
									deldatenResult();
								}
								if(gewsuch == 1) {
									for(var i=0;i<normalHash.length;i++){
										if(normalHash[i][0] == treffer_id){
											var _gewstr = normalHash[i][1].split("#");
											normal_Koordsuch(_gewstr[0],_gewstr[1],_gewstr[2],_gewstr[3]);
											break;
										}
									}
								}
							}
							else{
								if($('gewResult') && tastecode == 0){
									document.such_eingabe.gew.value = $('gewResult').childNodes[0].textContent.substr(2,$('gewResult').childNodes[0].textContent.length-2);
									treffer_id = $('gewResult').childNodes[0].id;
									deldatenResult();
								}
								else if($('gewResult') && tastecode != 0){
									document.such_eingabe.gew.value = $('gewResult').childNodes[tastecode-3].textContent.substr(2,$('gewResult').childNodes[tastecode-3].textContent.length-2);
									treffer_id = $('gewResult').childNodes[tastecode-3].id
									deldatenResult();
								}
								if(gewsuch == 1){
									for(var i=0;i<normalHash.length;i++){
										if(normalHash[i][0] == treffer_id){
											var _gewstr = normalHash[i][1].split("#");
											normal_Koordsuch(_gewstr[0],_gewstr[1],_gewstr[2],_gewstr[3]);
											break;
										}
									}
								}
							}
						}
						break;
					case 'schule_such':
						var schuledaten;
                        if($F('schule') == ''){
							alert("Eingabe fuer Schule Suche fehlt !");
						}
						else{
							if(browserName == 'ie'){
								if($('schuleResult') && tastecode == 0){
									schuledaten = $('schuleResult').childNodes[0].firstChild.nodeValue.substr(2,$('schuleResult').childNodes[0].firstChild.nodeValue.length-2);
									deldatenResult();
								}
								else if($('schuleResult') && tastecode != 0){
									schuledaten = $('schuleResult').childNodes[tastecode-2].firstChild.nodeValue.substr(2,$('schuleResult').childNodes[tastecode-2].firstChild.nodeValue.length-2);
									deldatenResult();
								}
								if(schulesuch == 1) schule_Koordsuch(schuledaten);
							}
						else{
							if($('schuleResult') && tastecode == 0){
								schuledaten = $('schuleResult').childNodes[0].textContent.substr(2,$('schuleResult').childNodes[0].textContent.length-2);
								deldatenResult();
							}
							else if($('schuleResult') && tastecode != 0){
								schuledaten = $('schuleResult').childNodes[tastecode-3].textContent.substr(2,$('schuleResult').childNodes[tastecode-3].textContent.length-2);
								deldatenResult();
							}
							if(schulesuch == 1) schule_Koordsuch(schuledaten);
						}
					}
					break;
				}
				break;
			case 9:
				if(browserName == 'ie'){
					if(tastecode!=0){tastecode -= 2;}
					if($('plzResult')){
						if(tastecode!=0){document.such_eingabe.plz.value = $('plzResult').childNodes[tastecode].firstChild.nodeValue;}
						else {document.such_eingabe.plz.value = $('plzResult').childNodes[0].firstChild.nodeValue;}
						deldatenResult();
						document.such_eingabe.ort.focus();
					}
					else if($('ortResult')){
						if(tastecode!=0){document.such_eingabe.ort.value = $('ortResult').childNodes[tastecode].firstChild.nodeValue.substr(2,$('ortResult').childNodes[tastecode].firstChild.nodeValue.length-2);}
						else{document.such_eingabe.ort.value = $('ortResult').childNodes[0].firstChild.nodeValue.substr(2,$('ortResult').childNodes[0].firstChild.nodeValue.length-2);}
						deldatenResult();
						document.such_eingabe.str.focus();
					}
					else if($('strResult')){
						if(tastecode!=0){document.such_eingabe.str.value = $('strResult').childNodes[tastecode].firstChild.nodeValue;}
						else{document.such_eingabe.str.value = $('strResult').childNodes[0].firstChild.nodeValue;}
						deldatenResult();
						document.such_einbage.hausnr.focus();
					}
					else if($('nrResult')){
						if(document.such_eingabe.hausnr.value != ''){
							if(tastecode!=0){document.such_eingabe.hausnr.value = $('nrResult').childNodes[tastecode].firstChild.nodeValue;}
							else{document.such_eingabe.hausnr.value = $('nrResult').childNodes[0].firstChild.nodeValue;}
						}
						deldatenResult();
					}
					else if($('ort_ortResult')){
						if(tastecode!=0){
							document.such_eingabe.ort_ort.value = $('ort_ortResult').childNodes[tastecode].firstChild.nodeValue.substr(2,$('ort_ortResult').childNodes[tastecode].firstChild.nodeValue.length-2);	
						}
						else{
							document.such_eingabe.ort_ort.value = $('ort_ortResult').childNodes[0].firstChild.nodeValue.substr(2,$('ort_ortResult').childNodes[0].firstChild.nodeValue.length-2);		
						}
						document.such_eingabe.absenden.focus();
						deldatenResult();
					}
					else if($('bergResult')){
						if(tastecode!=0){document.such_eingabe.berg.value = $('bergResult').childNodes[tastecode].firstChild.nodeValue.substr(2,$('bergResult').childNodes[tastecode].firstChild.nodeValue.length-2);}
						else{document.such_eingabe.berg.value = $('bergResult').childNodes[0].firstChild.nodeValue.substr(2,$('bergResult').childNodes[0].firstChild.nodeValue.length-2);}
						document.such_eingabe.absenden.focus();
						deldatenResult();
					}
					else if($('gewResult')){
						if(tastecode!=0){document.such_eingabe.gew.value = $('gewResult').childNodes[tastecode].firstChild.nodeValue.substr(2,$('gewResult').childNodes[tastecode].firstChild.nodeValue.length-2);}
						else{document.such_eingabe.gew.value = $('gewResult').childNodes[0].firstChild.nodeValue.substr(2,$('gewResult').childNodes[0].firstChild.nodeValue.length-2);}
						document.such_eingabe.absenden.focus();
						deldatenResult();
					}
					else if($('schuleResult')){
						if(tastecode!=0){document.such_eingabe.schule.value = $('schuleResult').childNodes[tastecode].firstChild.nodeValue.substr(2,$('schuleResult').childNodes[tastecode].firstChild.nodeValue.length-2);}
						else{document.such_eingabe.schule.value = $("schuleResult").childNodes[0].firstChild.nodeValue.substr(2,$("schuleResult").childNodes[0].firstChild.nodeValue.length-2);}
						deldatenResult();
					}
				}
				else{
					if(tastecode!=0){tastecode -= 3;}
					if($('plzResult')){
						if(tastecode!= 0){document.such_eingabe.plz.value = $('plzResult').childNodes[tastecode].textContent;}
						else{document.such_eingabe.plz.value = $('plzResult').childNodes[0].textContent;}
						deldatenResult();
						document.such_eingabe.ort.focus();
					}
					else if($('ortResult')){
						if(tastecode!=0){document.such_eingabe.ort.value = $('ortResult').childNodes[tastecode].textContent.substr(2,$('ortResult').childNodes[tastecode].textContent.length-2);}
						else{document.such_eingabe.ort.value = $('ortResult').childNodes[0].textContent.substr(2,$('ortResult').childNodes[0].textContent.length-2);}
						deldatenResult();
						document.such_eingabe.str.focus();
					}
					else if($('strResult')){
						if(tastecode!=0){document.such_eingabe.str.value = $('strResult').childNodes[tastecode].textContent;}
						else{document.such_eingabe.str.value = $('strResult').childNodes[0].textContent;}
						deldatenResult();
						document.such_eingabe.hausnr.focus();
					}
					else if($('nrResult')){
						if(document.such_eingabe.hausnr != ''){
						if(tastecode!=0){document.such_eingabe.hausnr.value = $('nrResult').childNodes[tastecode].textContent;}
						else{document.such_eingabe.hausnr.value = $('nrResult').childNodes[0].textContent;}
						}
						deldatenResult();
					}
					else if($('ort_ortResult')){
						if(tastecode!=0){
							var switchstr = $('ort_ortResult').childNodes[tastecode].textContent.substr(2,$('ort_ortResult').childNodes[tastecode].textContent.length-2);
							switchstr = switchstr.split("#");
							document.such_eingabe.ort_ort.value = switchstr[0];
							ort_koordinaten = switchstr[0].replace(", ","#")+"#"+switchstr[1].replace(",","#");
							}
						else{
							var switchstr = $('ort_ortResult').childNodes[0].textContent.substr(2,$('ort_ortResult').childNodes[0].textContent.length-2);
							switchstr = switchstr.split("#");
							document.such_eingabe.ort_ort.value = switchstr[0];
							ort_koordinaten = switchstr[0].replace(", ","#")+"#"+switchstr[1].replace(",","#");
							}
						deldatenResult();
					}
					else if($('bergResult')){
						if(tastecode!=0){document.such_eingabe.berg.value = $('bergResult').childNodes[tastecode].textContent.substr(2,$('bergResult').childNodes[tastecode].textContent.length-2);}
						else{document.such_eingabe.berg.value = $('bergResult').childNodes[0].textContent.substr(2,$('bergResult').childNodes[0].textContent.length-2);}
						deldatenResult();
					}
					else if($('gewResult')){
						if(tastecode!=0){document.such_eingabe.gew.value = $('gewResult').childNodes[tastecode].textContent.substr(2,$('gewResult').childNodes[tastecode].textContent.length-2);}
						else{document.such_eingabe.gew.value = $('gewResult').childNodes[0].textContent.substr(2,$('gewResult').childNodes[0].textContent.length-2);}
						deldatenResult();
					}
					else if($('schuleResult')){
						if(tastecode!=0){document.such_eingabe.schule.value = $('schuleResult').childNodes[tastecode].textContent.substr(2,$('schuleResult').childNodes[tastecode].textContent.length-2);}
						else{document.such_eingabe.schule.value = $('schuleResult').childNodes[0].textContent.substr(2,$('schuleResult').childNodes[0].textContent.length-2);}
						deldatenResult();
					}
				}
				tablator = "leer"; break;			
		}
	}
}

function allehidden(){
	$('ortResult').style.visibility = 'hidden';
	$('strResult').style.visibility = 'hidden';
	$('nrResult').style.visibility = 'hidden';
	$('plzResult').style.visibility = 'hidden';
}

function usemouseover(wert){
	$(wert).style.backgroundColor = "#dae8f6";
	if(selectfeld == "ort_ortResult" || selectfeld == "bergResult" || selectfeld == "gewResult"){
		document.such_eingabe.treffer.value = wert;
	}
}

function usemouseout(wert){
	$(wert).style.backgroundColor = "#ffffff";
}

function v_getRawObject(obj) {
    var theObj;
    if (typeof obj == 'string') {
        if (isW3C) {
            theObj = $(obj);
        } else if (isIE4) {
            theObj = document.all(obj);
        } else if (isNN4) {
            theObj = seekLayer(document, obj);
        }
    } else {
        // pass through object reference
        theObj = obj;
    }
    return theObj;
}

// Suchlist darzustellen
function creatdatenResult(eingabe_id,top_value,left_value,width_value,result){
    $("newpunkt").style.visibility = "hidden";
    if($(eingabe_id+"Result")){
        $(eingabe_id+"Result").style.visibility = "visible";
        $(eingabe_id+"Result").innerHTML = result;
    }
    else{
        var obj = $('searchForm');
        var tmpdiv,listvalue,listzu,listzuimg;
        tmpdiv = document.createElement("div");
        tmpdiv.id = "listdiv";
        tmpdiv.className = "listdiv";
        listvalue = document.createElement("div");
        listvalue.id = eingabe_id+"Result";
        listvalue.className = "Result";
        listvalue.align = "left";
        listzu = document.createElement("div");
        listzu.id = "listzu";
        listzu.style.width = "15px";
        listzu.style.height = "15px";
        listzuimg = document.createElement("img");
        listzuimg.src = "res/Ergebnis_exit.gif";
        listzuimg.onclick = deldatenResult;
        listzuimg.title = unescape("Ergebnisliste schlie%DFen");
        listzu.appendChild(listzuimg);
        tmpdiv.style.position = "absolute";
        tmpdiv.style.top = (parseInt(top_value)+25)+"px";
        tmpdiv.style.width = "250px";
        tmpdiv.style.height = "400px";
        listvalue.style.position = "absolute";
        listvalue.style.top = "0px";
        listvalue.style.left = "0px";
        if(browserName == "ie") listvalue.style.width = "250px";
        else listvalue.style.width = "243px";
        listvalue.style.height = "400px";
        listzu.style.position = "absolute";
        listzu.style.top = "0px";
        listzu.style.right = "0px";
        /*if(browserName == "mozilla" || browserName == "ns"){
            tmpdiv.style.position = "absolute";
            tmpdiv.style.top = (parseInt(top_value)+25)+"px";
            //tmpdiv.style.left = (parseInt(left_value)+15)+"px";
            tmpdiv.style.width = "250px";
            tmpdiv.style.height = "400px";
            listvalue.style.position = "absolute";
            listvalue.style.top = "0px";
            listvalue.style.left = "0px";
            listvalue.style.width = "243px";
            listvalue.style.height = "400px";
            listzu.style.position = "absolute";
            listzu.style.top = "0px";
            listzu.style.right = "0px";
        }
        else{
            tmpdiv.style.position = "absolute";
            tmpdiv.style.top = (parseInt(top_value)+25)+"px";
            tmpdiv.style.width = "250px";
            tmpdiv.style.height = "400px";
            listvalue.style.position = "absolute";
            listvalue.style.top = "0px";
            listvalue.style.left = "0px";
            if(browserName == "ie") listvalue.style.width = "250px";
            else listvalue.style.width = "243px";
            listvalue.style.height = "400px";
            listzu.style.position = "absolute";
            listzu.style.top = "0px";
            listzu.style.right = "0px";
        }*/
        tmpdiv.style.left = left_value;
        listvalue.style.zIndex = 1;
        listvalue.style.overflow = "auto";
        listvalue.innerHTML = result;
        listzu.style.zIndex = 2;
        tmpdiv.appendChild(listzu);
        tmpdiv.appendChild(listvalue);
        obj.appendChild(tmpdiv);
    }
}

//Prfen, ob nur ein Treffr gefunden wird
function einzelResult(result){
	if(browserName == 'ie'){
        	switch(eingabe_ID){
                case 'plz': 
                    document.such_eingabe.plz.value = $('plzResult').childNodes[0].firstChild.nodeValue; 
                    deldatenResult();
                    document.such_eingabe.plz.blur();
                    break;
                case 'ort': 
                    document.such_eingabe.ort.value = $('ortResult').childNodes[0].firstChild.nodeValue.substr(2,$('ortResult').childNodes[0].firstChild.nodeValue.length-2);
                    deldatenResult();
                    document.such_eingabe.ort.blur();
                    break;
                case 'str': 
                    document.such_eingabe.str.value = $('strResult').childNodes[0].firstChild.nodeValue; 
                    deldatenResult();
                    document.such_eingabe.str.blur();
                    break;
                case 'nr': 
                    document.such_eingabe.hausnr.value = $('nrResult').childNodes[0].firstChild.nodeValue; 
                    deldatenResult();
                    //$('absenden').focus();
                    break;
                case 'ort_ort': 
                    document.such_eingabe.ort_ort.value = $('ort_ortResult').childNodes[0].firstChild.nodeValue.substr(2,$('ort_ortResult').childNodes[0].firstChild.nodeValue.length-2);
                    deldatenResult();
                    $('absenden').focus();
                    break;
                case 'berg': 
                    document.such_eingabe.berg.value = $('bergResult').childNodes[0].firstChild.nodeValue.substr(2,$('bergResult').childNodes[0].firstChild.nodeValue.length-2); 
                    deldatenResult();
                    $('absenden').focus();
                    break;
                case 'gew': 
                    document.such_eingabe.gew.value = $('gewResult').childNodes[0].firstChild.nodeValue.substr(2,$('gewResult').childNodes[0].firstChild.nodeValue.length-2);
                    deldatenResult();
                    $('absenden').focus();
                    break;
                case 'schule': 
                    document.such_eingabe.schule.value = $('schuleResult').childNodes[0].firstChild.nodeValue.substr(2,$('schuleResult').childNodes[0].firstChild.nodeValue.length-2); 
                    deldatenResult();
                    $('absenden').focus();
                    break;
            }
        }
        else{// wenn NICHT InternetExplorer
            switch(eingabe_ID){
                case 'plz':
                    document.such_eingabe.plz.value = $('plzResult').childNodes[0].textContent;
                    deldatenResult();
                    document.such_eingabe.plz.blur();
                    break;
                case 'ort': 
                    document.such_eingabe.ort.value = $('ortResult').childNodes[0].textContent.substr(2,$('ortResult').childNodes[0].textContent.length-2); 
                    deldatenResult();
                    document.such_eingabe.ort.blur();
                    break;
                case 'str': 
                    document.such_eingabe.str.value = $('strResult').childNodes[0].textContent; 
                    deldatenResult();
                    document.such_eingabe.str.blur();
                    break;
                case 'nr': 
                    document.such_eingabe.hausnr.value = $('nrResult').childNodes[0].textContent; 
                    deldatenResult();
                    //$('absenden').focus();
                    break;
                case 'ort_ort': 
                    document.such_eingabe.ort_ort.value = $('ort_ortResult').childNodes[0].textContent.substr(2,$('ort_ortResult').childNodes[0].textContent.length-2); 
                    deldatenResult();
                    $('absenden').focus();
                    break;
                case 'berg': 
                    document.such_eingabe.berg.value = $('bergResult').childNodes[0].textContent.substr(2,$('bergResult').childNodes[0].textContent.length-2); 
                    deldatenResult();
                    $('absenden').focus();
                    break;
                case 'gew': 
                    document.such_eingabe.gew.value = $('gewResult').childNodes[0].textContent.substr(2,$('gewResult').childNodes[0].textContent.length-2); 
                    deldatenResult();
                    $('absenden').focus();
                    break;
                case 'schule': 
                    document.such_eingabe.schule.value = $('schuleResult').childNodes[0].textContent.substr(2,$('schuleResult').childNodes[0].textContent.length-2);
                    deldatenResult();
                    $('absenden').focus();
                    break;
            }            
        }
} 

function deldatenResult(){
	var ElternKnoten = $('searchForm');
    	var ChildKnoten = $('listdiv');
    	removeKnoten = ElternKnoten.removeChild(ChildKnoten);
    	if($("newpunkt").innerHTML) $("newpunkt").style.visibility = "visible";
	ersttaste = "no";
}
function chk_Eingaben_Adressen(){}
function show3D(evt) { 

    var width = parseFloat(document.formImg.width.value);
    var height = parseFloat(document.formImg.height.value);

    var ru = parseFloat(document.formImg.ru.value);
    var hu = parseFloat(document.formImg.hu.value);
    var ro = parseFloat(document.formImg.ro.value);
    var ho = parseFloat(document.formImg.ho.value);
    var dR = parseFloat(ro) - parseFloat(ru);
    var dH = parseFloat(ho) - parseFloat(hu);

    var dR = dR / 2;
    var dH = dH / 2;

	window.open("http://va45c66:8080/dgm/mesh?bbox=" + +ru+","+hu+","+ro+","+ho+"&layer=dop&width="+width+"&height="+height+ "&viewdirection=311", "window3D", "toolbar=no,location=no,directories=no,status=no,menubar=no,scrollbars=yes,resizable=yes,width="+ width +",height="+ height +",left=22,top=22");
}

var nr = 0;

function initStreckenMess() {
	s_firstmessen = 0;
    messenfinish = false;
	$("MapImg").style.cursor = "crosshair";
	p_nr = 0, letztpkt = 0; polygon_pktmove = "nein", zoom_change = "no";
	p_nr_text = "leer", Polygonzu = "nein"; Polygonschlossen = "nook";
	document.gkpunkte = new Array();
	document.gkDrawPunkte = new Array();
	document.pktPosition = new Array();
	
	nr = 0, such_ergebnis = 0;
	$("pkt_koord").innerHTML = "";
	$("newpunkt").innerHTML = "";
	$("iconPan").src = "res/Button_Hand.gif"; 
	$("iconStrecke").src = "res/Button_Lineal_aktiv.gif"; 
    $("iconFlaeche").src = "res/Button_Lineal_Flaeche.gif";
		
	$("MapImg").onmousedown = "";
	$("MapImg").onmousemove = "";
	$("MapImg").onmouseclick = "";
	$("MapImg").onmouseup = clickPointStrecke;
	document.onmousedown = "";
	$("mauszeige").innerHTML = "Bitte ersten Punkt anklicken....";
	document.onmousemove = updatemaus;
	document.onmouseclick = "";
	document.onmouseup = "";
	
	var obj = getRawObject("imgPolygon");
	obj.innerHTML = "";
	obj = getRawObject("pktm");
    obj.innerHTML = "";
	var tmpdiv = "", tmpbutton = "", tmpinnerhtml = "", tmpfont = "", tmpbr = "";
	tmpdiv = document.createElement("div");
	tmpdiv.setAttribute("style","position:absolute; top:0px; left:0px; background-color: #FFFFFF");
	tmpfont = document.createElement("font");
	tmpfont.setAttribute("size","2px");
	tmpinnerhtml = document.createTextNode("");
	tmpfont.appendChild(tmpinnerhtml);
	tmpbr = document.createElement("br");
	tmpdiv.appendChild(tmpfont);
	tmpdiv.appendChild(tmpbr);
    obj.appendChild(tmpdiv);
}

function clickPointStrecke(evt) {
	$("imgPolygon").style.visibility = "visible";
    evt = (evt) ? evt : event;
    var tmp = "";
	var gk = document.gkpunkte;
	var pk = document.pktPosition;
	var theObj = getRawObject("map");
    if(gk.length <= 1 && (evt.type && evt.type == "contextmenu" || evt.button && evt.button == 2 || evt.which && evt.which == 3)){ 
        switch(gk.length){
            case 1: $("mauszeige").innerHTML = "F&uuml;r Streckenmessung werden min. 2 Punkte ben&ouml;tigt....";break;
            case 0: $("mauszeige").innerHTML = "Bitte verwenden Sie die linke Maustaste, um einen neue Punkt zu erzeugen!";break;
        }
    }
    else if(gk.length > 1 && (evt.type && evt.type == "contextmenu" || evt.button && evt.button == 2 || evt.which && evt.which == 3)){
        if(browserName == "ie"){
            messenend();
        }
        else{
            messenend();
        }
    }
    else{
        var x, y;
	    if (evt.pageX) {
                x = evt.pageX - theObj.offsetLeft;
                y = evt.pageY - theObj.offsetTop-95;
	    } else if (evt.offsetX || evt.offsetY) {
                x = evt.offsetX;
                y = evt.offsetY;
	    } else if (evt.clientX) {
                x = evt.clientX;
                y = evt.clientY;
	    }
	    if(browserName != 'ie'){
		    x -=12;
		    y -=12;
	    }
		var width = parseFloat(document.formImg.width.value);
        var height = parseFloat(document.formImg.height.value);
        var ru = parseFloat(document.formImg.ru.value);
        var hu = parseFloat(document.formImg.hu.value);
        var ro = parseFloat(document.formImg.ro.value);
        var ho = parseFloat(document.formImg.ho.value);

        var dR = parseFloat(ro) - parseFloat(ru);
        var dH = parseFloat(ho) - parseFloat(hu);
		tmp = s2gk ( x , y, width, height, dR, dH, ru, hu );
	    gk.push( tmp );
	    pk.push(new Point(x,y));
	
	    $("mauszeige").innerHTML = "Bitte weitere Punkte anklicken....";
	    if(pk.length >= 2){
            $("newpunkt").innerHTML = "Mit der rechten Maustaste wird die Streckenmessung beendet....";
        }
        document.onmousemove = updatemaus;
	    if(gk.length > 1){
		    streckeBerechnen();
	    }
	    else{
		    drawPoly();
	    }
    }
}

function streckeBerechnen(){
	var gk = document.gkpunkte;
	var str = 0;
	for(var i = 1; i < gk.length; i++){
		var dx = gk[i].getX() - gk[i-1].getX();
		var dy = gk[i].getY() - gk[i-1].getY();
		str += parseInt(Math.sqrt(dx*dx + dy*dy));
	}
	$("pkt_koord").innerHTML = Math.abs(runden(str,1))+" m";
	$("mauszeige").innerHTML = "Strecke:<br>ca.<b>"+runden(str,1)+" m</b>";
	if(pktmove != 0){
        $("newpunkt").innerHTML = "Andere Punkte ausw&#228;hlen, oder rechte Maustaste f&uuml;r weitere Optionen";
    }
	$("newpunkt").style.visibility = "visible";
	$("overview").style.zIndex = 9;
    document.onmousemove = updatemaus;
	drawPoly();
}

var nr = 0;

function initFlaechenMess() {
	$("MapImg").style.cursor = "crosshair";
	p_nr = 0, letztpkt = 0, polygon_pktmove = "nein",zoom_change = "no";
	p_nr_text = "leer", Polygonzu = "nein", Polygonschlossen = "nook", messenfinish = false;
	document.gkpunkte = new Array();
	document.gkDrawPunkte = new Array();
	document.pktPosition = new Array();
	
	nr = 0, such_ergebnis = 0;
	$("pkt_koord").innerHTML = "";
	$("newpunkt").innerHTML = "";
	$("mauszeige").innerHTML= "";
	$("iconPan").src = "res/Button_Hand.gif"; 
	$("iconStrecke").src = "res/Button_Lineal.gif";
    $("iconFlaeche").src = "res/Button_Lineal_Flaeche_aktiv.gif";
	$("MapImg").onmousedown = "";
	$("MapImg").onmousemove = "";
	$("MapImg").onmouseclick = "";
	$("MapImg").onmouseup = clickPointFlaeche;
	document.onmousemove = updatemaus;
	document.onmousedown = "";
    document.onmouseclick = "";
    document.onmouseup = "";
	$("mauszeige").innerHTML = "Bitte ersten Punkt anklicken....";
	
	var obj = getRawObject("imgPolygon");
        obj.innerHTML = "";
       obj = getRawObject("pktm");
    obj.innerHTML = "";
	var tmpdiv = "", tmpbutton = "", tmpinnerhtml = "", tmpfont = "", tmpbr = "";
	tmpdiv = document.createElement("div");
	tmpdiv.setAttribute("style","position:absolute; top:0px; left:0px; background-color: #FFFFFF");
	tmpfont = document.createElement("font");
	tmpfont.setAttribute("size","2px");
	tmpinnerhtml = document.createTextNode("");
	tmpfont.appendChild(tmpinnerhtml);
	tmpbr = document.createElement("br");
	tmpdiv.appendChild(tmpfont);
	tmpdiv.appendChild(tmpbr);
    obj.appendChild(tmpdiv); 
}

function clickPointFlaeche(evt) {
    $("imgPolygon").style.visibility = "visible";
    evt = (evt) ? evt : event;
	var tmp = "";	
    var gk = document.gkpunkte;
    var pk = document.pktPosition;
    var theObj = getRawObject("map");
    if(gk.length <= 2 && (evt.type && evt.type == "contextmenu" || evt.button && evt.button == 2 || evt.which && evt.which == 3)){
        switch(gk.length){
            case 2: $("mauszeige").innerHTML = "F&uuml;r Fl&auml;chenmessung werden min. 3 Punkte ben&ouml;tigt....";break;
            case 1: $("mauszeige").innerHTML = "F&uuml;r Fl&auml;chenmessung werden min. 3 Punkte ben&ouml;tigt....";break;
            case 0: $("mauszeige").innerHTML = "Bitte linke Maustaste verwenden, um einen neuen Punkt zu erzeugen!";break;
        }
    }
    else if(gk.length > 2 && (evt.type && evt.type == "contextmenu" || evt.button && evt.button == 2 || evt.which && evt.which == 3)){
        $("mauszeige").innerHTML = "";
        if(browserName == "ie"){
            messenend();
        }
        else{
            messenend();
        }
    }
    else{
    	var x, y;
    	if (evt.pageX) {
        	x = evt.pageX - theObj.offsetLeft;
            y = evt.pageY - theObj.offsetTop-95;
 		} else if (evt.offsetX || evt.offsetY) {
            x = evt.offsetX;
            y = evt.offsetY;
		} else if (evt.clientX) {
            x = evt.clientX;
            y = evt.clientY;
    	}
        
    	if(browserName != 'ie'){
    		x -= 12;
    		y -= 12; 
    	}
    	var width = parseFloat(document.formImg.width.value);
        var height = parseFloat(document.formImg.height.value);
        var ru = parseFloat(document.formImg.ru.value);
        var hu = parseFloat(document.formImg.hu.value);
        var ro = parseFloat(document.formImg.ro.value);
        var ho = parseFloat(document.formImg.ho.value);
        var dR = parseFloat(ro) - parseFloat(ru);
        var dH = parseFloat(ho) - parseFloat(hu);
        tmp = s2gk ( x , y, width, height, dR, dH, ru, hu );
        gk.push( tmp );
        pk.push(new Point(x,y));
		$("mauszeige").innerHTML = "Bitte weitere Punkte anklicken....";
		if(gk.length > 2){
    		flaecheBerechnen();
		}
		else{
			drawPoly();
		}
    }
}

function flaecheBerechnen(){
	var out ="";
	var gk = document.gkpunkte;
	var tmpgk = new Array();
	var umfang = 0;
    for(var i = 1; i < gk.length; i++){
        var dx = gk[i].getX() - gk[i-1].getX();
        var dy = gk[i].getY() - gk[i-1].getY();
        umfang += Math.sqrt(dx*dx + dy*dy);
    }
    umfang = parseInt(umfang+Math.sqrt((gk[0].getX()-gk[gk.length-1].getX())*(gk[0].getX()-gk[gk.length-1].getX())+(gk[0].getY()-gk[gk.length-1].getY())*(gk[0].getY()-gk[gk.length-1].getY())));
    for(var i = 0; i < gk.length; i++){
		tmpgk.push(new Point( gk[i].getX(), gk[i].getY() ));
	}
	var first = tmpgk[0];
	var last = tmpgk[tmpgk.length-1];		
	tmpgk.unshift(new Point(last.getX(), last.getY()));	
	tmpgk.push (new Point(first.getX(), first.getY()));
	var F = 0;
	for (var i= 1; i < tmpgk.length-1; i++){
		F += tmpgk[i].getX() * (tmpgk[i-1].getY() - tmpgk[i+1].getY());
	}
	F /= 2.0;
        F = parseInt(F);
//	$("pkt_koord").innerHTML = Math.abs(runden(F,1)) + " m&#178;"+","+Math.abs(runden(umfang,1))+" m";
//	$("mauszeige").innerHTML = "Fl&#228;che: ca. <b>"+Math.abs(runden(F,1))+"</b>m&#178;"+"<br>Umfang: ca. <b>"+Math.abs(runden(umfang,1))+"</b>m";

        var fl = Math.abs(runden(F,1));
        var umf = Math.abs(runden(umfang,1));
        var fl_einh;
        var umf_einh;
        if(fl>10000){
           fl = runden(fl/1000000.0, 3);
           fl_einh = "km&#178;";
        }else{
           fl_einh = "m&#178;";
        }
        if(umf > 1000){
           umf = runden(umf/1000.0, 2);
           umf_einh = "km";
        }else{
           umf_einh = "m";
        }
        $("pkt_koord").innerHTML = ""+fl+" "+fl_einh+", "+umf+" "+umf_einh;
        $("mauszeige").innerHTML = "Fl&#228;che: ca. <b>"+fl+"</b> "+ fl_einh + "<br>Umfang: ca. <b>"+ umf + "</b> "+umf_einh;



	if(pktmove != 0){
	
        $("newpunkt").innerHTML = "weitere Optionen: andere Punkte oder rechte Maustaste";
    }
    	document.onmousemove = updatemaus;
	drawPoly();
}

/*                                                                                                                                                      
Copyright (c) 2006, Yahoo! Inc. All rights reserved.                                                                                                    
Code licensed under the BSD License:                                                                                                                    
http://developer.yahoo.net/yui/license.txt                                                                                                              
version: 0.11.0                                                                                                                                         
*/ 

/**
 * The Yahoo global namespace
 * @constructor
 */
var YAHOO = window.YAHOO || {};

/**
 * Returns the namespace specified and creates it if it doesn't exist
 *
 * YAHOO.namespace("property.package");
 * YAHOO.namespace("YAHOO.property.package");
 *
 * Either of the above would create YAHOO.property, then
 * YAHOO.property.package
 *
 * @param  {String} ns The name of the namespace
 * @return {Object}    A reference to the namespace object
 */
YAHOO.namespace = function(ns) {

    if (!ns || !ns.length) {
        return null;
    }

    var levels = ns.split(".");
    var nsobj = YAHOO;

    // YAHOO is implied, so it is ignored if it is included
    for (var i=(levels[0] == "YAHOO") ? 1 : 0; i<levels.length; ++i) {
        nsobj[levels[i]] = nsobj[levels[i]] || {};
        nsobj = nsobj[levels[i]];
    }

    return nsobj;
};

/**
 * Uses YAHOO.widget.Logger to output a log message, if the widget is available.
 *
 * @param  {string}  sMsg       The message to log.
 * @param  {string}  sCategory  The log category for the message.  Default
 *                              categories are "info", "warn", "error", time".
 *                              Custom categories can be used as well. (opt)
 * @param  {string}  sSource    The source of the the message (opt)
 * @return {boolean}            True if the log operation was successful.
 */
YAHOO.log = function(sMsg, sCategory, sSource) {
    var l = YAHOO.widget.Logger;
    if(l && l.log) {
        return l.log(sMsg, sCategory, sSource);
    } else {
        return false;
    }
};

/**
 * Utility to set up the prototype, constructor and superclass properties to
 * support an inheritance strategy that can chain constructors and methods.
 *
 * @param {Function} subclass   the object to modify
 * @param {Function} superclass the object to inherit
 */
YAHOO.extend = function(subclass, superclass) {
    var f = function() {};
    f.prototype = superclass.prototype;
    subclass.prototype = new f();
    subclass.prototype.constructor = subclass;
    subclass.superclass = superclass.prototype;
    if (superclass.prototype.constructor == Object.prototype.constructor) {
        superclass.prototype.constructor = superclass;
    }
};

YAHOO.namespace("util");
YAHOO.namespace("widget");
YAHOO.namespace("example");

/*                                                                                                                                                      
Copyright (c) 2006, Yahoo! Inc. All rights reserved.                                                                                                    
Code licensed under the BSD License:                                                                                                                    
http://developer.yahoo.net/yui/license.txt                                                                                                              
version: 0.11.0                                                                                                                                         
*/ 

/**
 * The CustomEvent class lets you define events for your application
 * that can be subscribed to by one or more independent component.
 *
 * @param {String} type The type of event, which is passed to the callback
 *                 when the event fires
 * @param {Object} oScope The context the event will fire from.  "this" will
 *                 refer to this object in the callback.  Default value: 
 *                 the window object.  The listener can override this.
 * @constructor
 */
YAHOO.util.CustomEvent = function(type, oScope, silent) {

    /**
     * The type of event, returned to subscribers when the event fires
     * @type string
     */
    this.type = type;

    /**
     * The scope the the event will fire from by default.  Defaults to the window 
     * obj
     * @type object
     */
    this.scope = oScope || window;

    /**
     * By default all custom events are logged in the debug build, set silent
     * to true to disable logging for this event.
     * @type boolean
     */
    this.silent = silent;

    /**
     * The subscribers to this event
     * @type Subscriber[]
     */
    this.subscribers = [];

    // Register with the event utility for automatic cleanup.  Made optional
    // so that CustomEvent can be used independently of pe.event
    if (YAHOO.util.Event) { 
        YAHOO.util.Event.regCE(this);
    }

    if (!this.silent) {
    }
};

YAHOO.util.CustomEvent.prototype = {
    /**
     * Subscribes the caller to this event
     * @param {Function} fn       The function to execute
     * @param {Object}   obj      An object to be passed along when the event fires
     * @param {boolean}  bOverride If true, the obj passed in becomes the execution
     *                            scope of the listener
     */
    subscribe: function(fn, obj, bOverride) {
        this.subscribers.push( new YAHOO.util.Subscriber(fn, obj, bOverride) );
    },

    /**
     * Unsubscribes the caller from this event
     * @param {Function} fn  The function to execute
     * @param {Object}   obj An object to be passed along when the event fires
     * @return {boolean} True if the subscriber was found and detached.
     */
    unsubscribe: function(fn, obj) {
        var found = false;
        for (var i=0, len=this.subscribers.length; i<len; ++i) {
            var s = this.subscribers[i];
            if (s && s.contains(fn, obj)) {
                this._delete(i);
                found = true;
            }
        }

        return found;
    },

    /**
     * Notifies the subscribers.  The callback functions will be executed
     * from the scope specified when the event was created, and with the following
     * parameters:
     *   <pre>
     *   - The type of event
     *   - All of the arguments fire() was executed with as an array
     *   - The custom object (if any) that was passed into the subscribe() method
     *   </pre>
     *   
     * @param {Array} an arbitrary set of parameters to pass to the handler
     */
    fire: function() {
        var len=this.subscribers.length;

        var args = [];

        for (var i=0; i<arguments.length; ++i) {
            args.push(arguments[i]);
        }

        if (!this.silent) {
        }

        for (i=0; i<len; ++i) {
            var s = this.subscribers[i];
            if (s) {
                if (!this.silent) {
                }
                var scope = (s.override) ? s.obj : this.scope;
                s.fn.call(scope, this.type, args, s.obj);
            }
        }
    },

    /**
     * Removes all listeners
     */
    unsubscribeAll: function() {
        for (var i=0, len=this.subscribers.length; i<len; ++i) {
            this._delete(i);
        }
    },

    /**
     * @private
     */
    _delete: function(index) {
        var s = this.subscribers[index];
        if (s) {
            delete s.fn;
            delete s.obj;
        }

        delete this.subscribers[index];
    },

    toString: function() {
         return "CustomEvent: " + "'" + this.type  + "', " + 
             "scope: " + this.scope;

    }
};

/////////////////////////////////////////////////////////////////////

/**
 * @class Stores the subscriber information to be used when the event fires.
 * @param {Function} fn       The function to execute
 * @param {Object}   obj      An object to be passed along when the event fires
 * @param {boolean}  bOverride If true, the obj passed in becomes the execution
 *                            scope of the listener
 * @constructor
 */
YAHOO.util.Subscriber = function(fn, obj, bOverride) {
    /**
     * The callback that will be execute when the event fires
     * @type function
     */
    this.fn = fn;

    /**
     * An optional custom object that will passed to the callback when
     * the event fires
     * @type object
     */
    this.obj = obj || null;

    /**
     * The default execution scope for the event listener is defined when the
     * event is created (usually the object which contains the event).
     * By setting override to true, the execution scope becomes the custom
     * object passed in by the subscriber
     * @type boolean
     */
    this.override = (bOverride);
};

/**
 * Returns true if the fn and obj match this objects properties.
 * Used by the unsubscribe method to match the right subscriber.
 *
 * @param {Function} fn the function to execute
 * @param {Object} obj an object to be passed along when the event fires
 * @return {boolean} true if the supplied arguments match this 
 *                   subscriber's signature.
 */
YAHOO.util.Subscriber.prototype.contains = function(fn, obj) {
    return (this.fn == fn && this.obj == obj);
};

YAHOO.util.Subscriber.prototype.toString = function() {
    return "Subscriber { obj: " + (this.obj || "")  + 
           ", override: " +  (this.override || "no") + " }";
};
// Only load this library once.  If it is loaded a second time, existing
// events cannot be detached.
if (!YAHOO.util.Event) {

/**
 * @class
 * The event utility provides functions to add and remove event listeners,
 * event cleansing.  It also tries to automatically remove listeners it
 * registers during the unload event.
 * @constructor
 */
    YAHOO.util.Event = function() {

        /**
         * True after the onload event has fired
         * @type boolean
         * @private
         */
        var loadComplete =  false;

        /**
         * Cache of wrapped listeners
         * @type array
         * @private
         */
        var listeners = [];

        /**
         * Listeners that will be attached during the onload event
         * @type array
         * @private
         */
        var delayedListeners = [];

        /**
         * User-defined unload function that will be fired before all events
         * are detached
         * @type array
         * @private
         */
        var unloadListeners = [];

        /**
         * Cache of the custom events that have been defined.  Used for
         * automatic cleanup
         * @type array
         * @private
         */
        var customEvents = [];

        /**
         * Cache of DOM0 event handlers to work around issues with DOM2 events
         * in Safari
         * @private
         */
        var legacyEvents = [];

        /**
         * Listener stack for DOM0 events
         * @private
         */
        var legacyHandlers = [];

        /**
         * The number of times to poll after window.onload.  This number is
         * increased if additional late-bound handlers are requested after
         * the page load.
         * @private
         */
        var retryCount = 0;

        /**
         * onAvailable listeners
         * @private
         */
        var onAvailStack = [];

        /**
         * Lookup table for legacy events
         * @private
         */
        var legacyMap = [];

        /**
         * Counter for auto id generation
         * @private
         */
        var counter = 0;

        return { // PREPROCESS

            /**
             * The number of times we should look for elements that are not
             * in the DOM at the time the event is requested after the document
             * has been loaded.  The default is 200@50 ms, so it will poll
             * for 10 seconds or until all outstanding handlers are bound
             * (whichever comes first).
             * @type int
             */
            POLL_RETRYS: 200,

            /**
             * The poll interval in milliseconds
             * @type int
             */
            POLL_INTERVAL: 50,

            /**
             * Element to bind, int constant
             * @type int
             */
            EL: 0,

            /**
             * Type of event, int constant
             * @type int
             */
            TYPE: 1,

            /**
             * Function to execute, int constant
             * @type int
             */
            FN: 2,

            /**
             * Function wrapped for scope correction and cleanup, int constant
             * @type int
             */
            WFN: 3,

            /**
             * Object passed in by the user that will be returned as a 
             * parameter to the callback, int constant
             * @type int
             */
            SCOPE: 3,

            /**
             * Adjusted scope, either the element we are registering the event
             * on or the custom object passed in by the listener, int constant
             * @type int
             */
            ADJ_SCOPE: 4,

            /**
             * Safari detection is necessary to work around the preventDefault
             * bug that makes it so you can't cancel a href click from the 
             * handler.  There is not a capabilities check we can use here.
             * @private
             */
            isSafari: (/Safari|Konqueror|KHTML/gi).test(navigator.userAgent),

            /**
             * IE detection needed to properly calculate pageX and pageY.  
             * capabilities checking didn't seem to work because another 
             * browser that does not provide the properties have the values 
             * calculated in a different manner than IE.
             * @private
             */
            isIE: (!this.isSafari && !navigator.userAgent.match(/opera/gi) && 
                    navigator.userAgent.match(/msie/gi)),

            /**
             * @private
             */
            addDelayedListener: function(el, sType, fn, oScope, bOverride) {
                delayedListeners[delayedListeners.length] =
                    [el, sType, fn, oScope, bOverride];

                // If this happens after the inital page load, we need to
                // reset the poll counter so that we continue to search for
                // the element for a fixed period of time.
                if (loadComplete) {
                    retryCount = this.POLL_RETRYS;
                    this.startTimeout(0);
                    // this._tryPreloadAttach();
                }
            },

            /**
             * @private
             */
            startTimeout: function(interval) {
                var i = (interval || interval === 0) ? interval : this.POLL_INTERVAL;
                var self = this;
                var callback = function() { self._tryPreloadAttach(); };
                this.timeout = setTimeout(callback, i);
            },

            /**
             * Executes the supplied callback when the item with the supplied
             * id is found.  This is meant to be used to execute behavior as
             * soon as possible as the page loads.  If you use this after the
             * initial page load it will poll for a fixed time for the element.
             * The number of times it will poll and the frequency are
             * configurable.  By default it will poll for 10 seconds.
             * @param {string} p_id the id of the element to look for.
             * @param {function} p_fn what to execute when the element is found.
             * @param {object} p_obj an optional object to be passed back as
             * a parameter to p_fn.
             * @param {boolean} p_override If set to true, p_fn will execute
             * in the scope of p_obj
             *
             */
            onAvailable: function(p_id, p_fn, p_obj, p_override) {
                onAvailStack.push( { id:       p_id, 
                                     fn:       p_fn, 
                                     obj:      p_obj, 
                                     override: p_override } );

                retryCount = this.POLL_RETRYS;
                this.startTimeout(0);
                // this._tryPreloadAttach();
            },

            /**
             * Appends an event handler
             *
             * @param {Object}   el        The html element to assign the 
             *                             event to
             * @param {String}   sType     The type of event to append
             * @param {Function} fn        The method the event invokes
             * @param {Object}   oScope    An arbitrary object that will be 
             *                             passed as a parameter to the handler
             * @param {boolean}  bOverride If true, the obj passed in becomes
             *                             the execution scope of the listener
             * @return {boolean} True if the action was successful or defered,
             *                        false if one or more of the elements 
             *                        could not have the event bound to it.
             */
            addListener: function(el, sType, fn, oScope, bOverride) {

                if (!fn || !fn.call) {
                    return false;
                }

                // The el argument can be an array of elements or element ids.
                if ( this._isValidCollection(el)) {
                    var ok = true;
                    for (var i=0,len=el.length; i<len; ++i) {
                        ok = ( this.on(el[i], 
                                       sType, 
                                       fn, 
                                       oScope, 
                                       bOverride) && ok );
                    }
                    return ok;

                } else if (typeof el == "string") {
                    var oEl = this.getEl(el);
                    // If the el argument is a string, we assume it is 
                    // actually the id of the element.  If the page is loaded
                    // we convert el to the actual element, otherwise we 
                    // defer attaching the event until onload event fires

                    // check to see if we need to delay hooking up the event 
                    // until after the page loads.
                    if (loadComplete && oEl) {
                        el = oEl;
                    } else {
                        // defer adding the event until onload fires
                        this.addDelayedListener(el, 
                                                sType, 
                                                fn, 
                                                oScope, 
                                                bOverride);

                        return true;
                    }
                }

                // Element should be an html element or an array if we get 
                // here.
                if (!el) {
                    return false;
                }

                // we need to make sure we fire registered unload events 
                // prior to automatically unhooking them.  So we hang on to 
                // these instead of attaching them to the window and fire the
                // handles explicitly during our one unload event.
                if ("unload" == sType && oScope !== this) {
                    unloadListeners[unloadListeners.length] =
                            [el, sType, fn, oScope, bOverride];
                    return true;
                }

                // if the user chooses to override the scope, we use the custom
                // object passed in, otherwise the executing scope will be the
                // HTML element that the event is registered on
                var scope = (bOverride) ? oScope : el;

                // wrap the function so we can return the oScope object when
                // the event fires;
                var wrappedFn = function(e) {
                        //Add_Ergebnis();
                        return fn.call(scope, YAHOO.util.Event.getEvent(e), 
                                oScope);
                    };

                var li = [el, sType, fn, wrappedFn, scope];
                var index = listeners.length;
                // cache the listener so we can try to automatically unload
                listeners[index] = li;

                if (this.useLegacyEvent(el, sType)) {
                    var legacyIndex = this.getLegacyIndex(el, sType);
                    if (legacyIndex == -1) {

                        legacyIndex = legacyEvents.length;
                        legacyMap[el.id + sType] = legacyIndex;

                        // cache the signature for the DOM0 event, and 
                        // include the existing handler for the event, if any
                        legacyEvents[legacyIndex] = 
                            [el, sType, el["on" + sType]];
                        legacyHandlers[legacyIndex] = [];

                        el["on" + sType] = 
                            function(e) {
                                YAHOO.util.Event.fireLegacyEvent(
                                    YAHOO.util.Event.getEvent(e), legacyIndex);
                            };
                    }

                    // add a reference to the wrapped listener to our custom
                    // stack of events
                    legacyHandlers[legacyIndex].push(index);

                // DOM2 Event model
                } else if (el.addEventListener) {
                    el.addEventListener(sType, wrappedFn, false);
                // IE
                } else if (el.attachEvent) {
                    el.attachEvent("on" + sType, wrappedFn);
                }

                return true;
                
            },

            /**
             * Shorthand for YAHOO.util.Event.addListener
             * @type function
             */
            // on: this.addListener,

            /**
             * When using legacy events, the handler is routed to this object
             * so we can fire our custom listener stack.
             * @private
             */
            fireLegacyEvent: function(e, legacyIndex) {
                var ok = true;

                var le = legacyHandlers[legacyIndex];
                for (var i=0,len=le.length; i<len; ++i) {
                    var index = le[i];
                    if (index) {
                        var li = listeners[index];
                        if ( li && li[this.WFN] ) {
                            var scope = li[this.ADJ_SCOPE];
                            var ret = li[this.WFN].call(scope, e);
                            ok = (ok && ret);
                        } else {
                            // This listener was removed, so delete it from
                            // the array
                            delete le[i];
                        }
                    }
                }

                return ok;
            },

            /**
             * Returns the legacy event index that matches the supplied 
             * signature
             * @private
             */
            getLegacyIndex: function(el, sType) {
                /*
                for (var i=0,len=legacyEvents.length; i<len; ++i) {
                    var le = legacyEvents[i];
                    if (le && le[0] === el && le[1] === sType) {
                        return i;
                    }
                }
                return -1;
                */

                var key = this.generateId(el) + sType;
                if (typeof legacyMap[key] == "undefined") { 
                    return -1;
                } else {
                    return legacyMap[key];
                }

            },

            /**
             * Logic that determines when we should automatically use legacy
             * events instead of DOM2 events.
             * @private
             */
            useLegacyEvent: function(el, sType) {

                if (!el.addEventListener && !el.attachEvent) {
                    return true;
                } else if (this.isSafari) {
                    if ("click" == sType || "dblclick" == sType) {
                        return true;
                    }
                }

                return false;
            },
                    
            /**
             * Removes an event handler
             *
             * @param {Object} el the html element or the id of the element to 
             * assign the event to.
             * @param {String} sType the type of event to remove
             * @param {Function} fn the method the event invokes
             * @return {boolean} true if the unbind was successful, false 
             * otherwise
             */
            removeListener: function(el, sType, fn, index) {

                if (!fn || !fn.call) {
                    return false;
                }

                // The el argument can be a string
                if (typeof el == "string") {
                    el = this.getEl(el);
                // The el argument can be an array of elements or element ids.
                } else if ( this._isValidCollection(el)) {
                    var ok = true;
                    for (var i=0,len=el.length; i<len; ++i) {
                        ok = ( this.removeListener(el[i], sType, fn) && ok );
                    }
                    return ok;
                }

                if ("unload" == sType) {

                    for (i=0, len=unloadListeners.length; i<len; i++) {
                        var li = unloadListeners[i];
                        if (li && 
                            li[0] == el && 
                            li[1] == sType && 
                            li[2] == fn) {
                                delete unloadListeners[i];
                                return true;
                        }
                    }

                    return false;
                }

                var cacheItem = null;
  
                if ("undefined" == typeof index) {
                    index = this._getCacheIndex(el, sType, fn);
                }

                if (index >= 0) {
                    cacheItem = listeners[index];
                }

                if (!el || !cacheItem) {
                    return false;
                }

                if (el.removeEventListener) {
                    el.removeEventListener(sType, cacheItem[this.WFN], false);
                } else if (el.detachEvent) {
                    el.detachEvent("on" + sType, cacheItem[this.WFN]);
                }

                // removed the wrapped handler
                delete listeners[index][this.WFN];
                delete listeners[index][this.FN];
                delete listeners[index];

                return true;

            },

            /**
             * Returns the event's target element
             * @param {Event} ev the event
             * @param {boolean} resolveTextNode when set to true the target's
             *                  parent will be returned if the target is a 
             *                  text node.  @deprecated, the text node is
             *                  now resolved automatically
             * @return {HTMLElement} the event's target
             */
            getTarget: function(ev, resolveTextNode) {
                var t = ev.target || ev.srcElement;
                return this.resolveTextNode(t);
            },

            /**
             * In some cases, some browsers will return a text node inside
             * the actual element that was targeted.  This normalizes the
             * return value for getTarget and getRelatedTarget.
             * @param {HTMLElement} node to resolve
             * @return  the normized node
             */
            resolveTextNode: function(node) {
                if (node && node.nodeName && 
                        "#TEXT" == node.nodeName.toUpperCase()) {
                    return node.parentNode;
                } else {
                    return node;
                }
            },

            /**
             * Returns the event's pageX
             * @param {Event} ev the event
             * @return {int} the event's pageX
             */
            getPageX: function(ev) {
                if(browserName == 'ie'){
                	var x = window.event.x + document.body.scrollLeft;
                }
                else{
                	var x = ev.pageX;
                }
                if (!x && 0 !== x) {
                    x = ev.clientX || 0;

                    if ( this.isIE ) {
                        x += this._getScrollLeft();
                    }
                }

                return x;
            },

            /**
             * Returns the event's pageY
             * @param {Event} ev the event
             * @return {int} the event's pageY
             */
            getPageY: function(ev) {
                if(browserName == 'ie'){
                	var y = window.event.y + document.body.scrollTop;
                }
                else{
                	var y = ev.pageY;
                }
                if (!y && 0 !== y) {
                    y = ev.clientY || 0;

                    if ( this.isIE ) {
                        y += this._getScrollTop();
                    }
                }

                return y;
            },

            /**
             * Returns the pageX and pageY properties as an indexed array.
             * @type int[]
             */
            getXY: function(ev) {
                return [this.getPageX(ev), this.getPageY(ev)];
            },

            /**
             * Returns the event's related target 
             * @param {Event} ev the event
             * @return {HTMLElement} the event's relatedTarget
             */
            getRelatedTarget: function(ev) {
                var t = ev.relatedTarget;
                if (!t) {
                    if (ev.type == "mouseout") {
                        t = ev.toElement;
                    } else if (ev.type == "mouseover") {
                        t = ev.fromElement;
                    }
                }

                return this.resolveTextNode(t);
            },

            /**
             * Returns the time of the event.  If the time is not included, the
             * event is modified using the current time.
             * @param {Event} ev the event
             * @return {Date} the time of the event
             */
            getTime: function(ev) {
                if (!ev.time) {
                    var t = new Date().getTime();
                    try {
                        ev.time = t;
                    } catch(e) { 
                        // can't set the time property  
                        return t;
                    }
                }

                return ev.time;
            },

            /**
             * Convenience method for stopPropagation + preventDefault
             * @param {Event} ev the event
             */
            stopEvent: function(ev) {
                this.stopPropagation(ev);
                this.preventDefault(ev);
            },

            /**
             * Stops event propagation
             * @param {Event} ev the event
             */
            stopPropagation: function(ev) {
                if (ev.stopPropagation) {
                    ev.stopPropagation();
                } else {
                    ev.cancelBubble = true;
                }
            },

            /**
             * Prevents the default behavior of the event
             * @param {Event} ev the event
             */
            preventDefault: function(ev) {
                if (ev.preventDefault) {
                    ev.preventDefault();
                } else {
                    ev.returnValue = false;
                }
            },
             
            /**
             * Finds the event in the window object, the caller's arguments, or
             * in the arguments of another method in the callstack.  This is
             * executed automatically for events registered through the event
             * manager, so the implementer should not normally need to execute
             * this function at all.
             * @param {Event} the event parameter from the handler
             * @return {Event} the event 
             */
            getEvent: function(e) {
                var ev = e || window.event;

                if (!ev) {
                    var c = this.getEvent.caller;
                    while (c) {
                        ev = c.arguments[0];
                        if (ev && Event == ev.constructor) {
                            break;
                        }
                        c = c.caller;
                    }
                }

                return ev;
            },

            /**
             * Returns the charcode for an event
             * @param {Event} ev the event
             * @return {int} the event's charCode
             */
            getCharCode: function(ev) {
                return ev.charCode || ((ev.type == "keypress") ? ev.keyCode : 0);
            },

            /**
             * @private
             * Locating the saved event handler data by function ref
             */
            _getCacheIndex: function(el, sType, fn) {
                for (var i=0,len=listeners.length; i<len; ++i) {
                    var li = listeners[i];
                    if ( li                 && 
                         li[this.FN] == fn  && 
                         li[this.EL] == el  && 
                         li[this.TYPE] == sType ) {
                        return i;
                    }
                }

                return -1;
            },

            /**
             * Generates an unique ID for the element if it does not already 
             * have one.
             * @param el the element
             * @return {string} the id of the element
             */
            generateId: function(el) {
                var id = el.id;

                if (!id) {
                    id = "yuievtautoid-" + counter;
                    ++counter;
                    el.id = id;
                }

                return id;
            },

            /**
             * We want to be able to use getElementsByTagName as a collection
             * to attach a group of events to.  Unfortunately, different 
             * browsers return different types of collections.  This function
             * tests to determine if the object is array-like.  It will also 
             * fail if the object is an array, but is empty.
             * @param o the object to test
             * @return {boolean} true if the object is array-like and populated
             * @private
             */
            _isValidCollection: function(o) {

                return ( o                    && // o is something
                         o.length             && // o is indexed
                         typeof o != "string" && // o is not a string
                         !o.tagName           && // o is not an HTML element
                         !o.alert             && // o is not a window
                         typeof o[0] != "undefined" );

            },

            /**
             * @private
             * DOM element cache
             */
            elCache: {},

            /**
             * We cache elements bound by id because when the unload event 
             * fires, we can no longer use document.getElementById
             * @private
             */
            getEl: function(id) {
                return document.getElementById(id);
            },

            /**
             * Clears the element cache
             * @deprecated
             * @private
             */
            clearCache: function() { },

            /**
             * Called by CustomEvent instances to provide a handle to the 
             * event * that can be removed later on.  Should be package 
             * protected.
             * @private
             */
            regCE: function(ce) {
                customEvents.push(ce);
            },

            /**
             * @private
             * hook up any deferred listeners
             */
            _load: function(e) {
                loadComplete = true;
            },

            /**
             * Polling function that runs before the onload event fires, 
             * attempting to attach to DOM Nodes as soon as they are 
             * available
             * @private
             */
            _tryPreloadAttach: function() {

                if (this.locked) {
                    return false;
                }

                this.locked = true;

                // keep trying until after the page is loaded.  We need to 
                // check the page load state prior to trying to bind the 
                // elements so that we can be certain all elements have been 
                // tested appropriately
                var tryAgain = !loadComplete;
                if (!tryAgain) {
                    tryAgain = (retryCount > 0);
                }

                // Delayed listeners
                var stillDelayed = [];

                for (var i=0,len=delayedListeners.length; i<len; ++i) {
                    var d = delayedListeners[i];
                    // There may be a race condition here, so we need to 
                    // verify the array element is usable.
                    if (d) {

                        // el will be null if document.getElementById did not
                        // work
                        var el = this.getEl(d[this.EL]);

                        if (el) {
                            this.on(el, d[this.TYPE], d[this.FN], 
                                    d[this.SCOPE], d[this.ADJ_SCOPE]);
                            delete delayedListeners[i];
                        } else {
                            stillDelayed.push(d);
                        }
                    }
                }

                delayedListeners = stillDelayed;

                // onAvailable
                var notAvail = [];
                for (i=0,len=onAvailStack.length; i<len ; ++i) {
                    var item = onAvailStack[i];
                    if (item) {
                        el = this.getEl(item.id);

                        if (el) {
                            var scope = (item.override) ? item.obj : el;
                            item.fn.call(scope, item.obj);
                            delete onAvailStack[i];
                        } else {
                            notAvail.push(item);
                        }
                    }
                }

                retryCount = (stillDelayed.length === 0 && 
                                    notAvail.length === 0) ? 0 : retryCount - 1;

                if (tryAgain) {
                    this.startTimeout();
                }

                this.locked = false;

                return true;

            },

            /**
             * Removes all listeners attached to the given element via addListener.
             * Optionally, the node's children can also be purged.
             * Optionally, you can specify a specific type of event to remove.
             * @param {HTMLElement} el the element to purge
             * @param {boolean} recurse recursively purge this element's children
             * as well.  Use with caution.
             * @param {string} sType optional type of listener to purge. If
             * left out, all listeners will be removed
             */
            purgeElement: function(el, recurse, sType) {
                var elListeners = this.getListeners(el, sType);
                if (elListeners) {
                    for (var i=0,len=elListeners.length; i<len ; ++i) {
                        var l = elListeners[i];
                        this.removeListener(el, l.type, l.fn, l.index);
                    }
                }

                if (recurse && el && el.childNodes) {
                    for (i=0,len=el.childNodes.length; i<len ; ++i) {
                        this.purgeElement(el.childNodes[i], recurse, sType);
                    }
                }
            },

            /**
             * Returns all listeners attached to the given element via addListener.
             * Optionally, you can specify a specific type of event to return.
             * @param el {HTMLElement} the element to inspect 
             * @param sType {string} optional type of listener to return. If
             * left out, all listeners will be returned
             * @return {Object} the listener. Contains the following fields:
             *    type:   (string)   the type of event
             *    fn:     (function) the callback supplied to addListener
             *    obj:    (object)   the custom object supplied to addListener
             *    adjust: (boolean)  whether or not to adjust the default scope
             *    index:  (int)      its position in the Event util listener cache
             */           
            getListeners: function(el, sType) {
                var elListeners = [];
                if (listeners && listeners.length > 0) {
                    for (var i=0,len=listeners.length; i<len ; ++i) {
                        var l = listeners[i];
                        if ( l  && l[this.EL] === el && 
                                (!sType || sType === l[this.TYPE]) ) {
                            elListeners.push({
                                type:   l[this.TYPE],
                                fn:     l[this.FN],
                                obj:    l[this.SCOPE],
                                adjust: l[this.ADJ_SCOPE],
                                index:  i
                            });
                        }
                    }
                }

                return (elListeners.length) ? elListeners : null;
            },

            /**
             * Removes all listeners registered by pe.event.  Called 
             * automatically during the unload event.
             * @private
             */
            _unload: function(e, me) {
                for (var i=0,len=unloadListeners.length; i<len; ++i) {
                    var l = unloadListeners[i];
                    if (l) {
                        var scope = (l[this.ADJ_SCOPE]) ? l[this.SCOPE]: window;
                        l[this.FN].call(scope, this.getEvent(e), l[this.SCOPE] );
                    }
                }

                if (listeners && listeners.length > 0) {
                    for (i=0,len=listeners.length; i<len ; ++i) {
                        l = listeners[i];
                        if (l) {
                            this.removeListener(l[this.EL], l[this.TYPE], 
                                    l[this.FN], i);
                        }
                    }

                    this.clearCache();
                }

                for (i=0,len=customEvents.length; i<len; ++i) {
                    customEvents[i].unsubscribeAll();
                    delete customEvents[i];
                }

                for (i=0,len=legacyEvents.length; i<len; ++i) {
                    // dereference the element
                    delete legacyEvents[i][0];
                    // delete the array item
                    delete legacyEvents[i];
                }
            },

            /**
             * Returns scrollLeft
             * @private
             */
            _getScrollLeft: function() {
                return this._getScroll()[1];
            },

            /**
             * Returns scrollTop
             * @private
             */
            _getScrollTop: function() {
                return this._getScroll()[0];
            },

            /**
             * Returns the scrollTop and scrollLeft.  Used to calculate the 
             * pageX and pageY in Internet Explorer
             * @private
             */
            _getScroll: function() {
                var dd = document.documentElement; db = document.body;
                if (dd && dd.scrollTop) {
                    return [dd.scrollTop, dd.scrollLeft];
                } else if (db) {
                    return [db.scrollTop, db.scrollLeft];
                } else {
                    return [0, 0];
                }
            }
        };
    } ();

    /**
     * @private
     */
    YAHOO.util.Event.on = YAHOO.util.Event.addListener;

    if (document && document.body) {
        YAHOO.util.Event._load();
    } else {
        YAHOO.util.Event.on(window, "load", YAHOO.util.Event._load, 
                YAHOO.util.Event, true);
    }

    YAHOO.util.Event.on(window, "unload", YAHOO.util.Event._unload, 
                YAHOO.util.Event, true);

    YAHOO.util.Event._tryPreloadAttach();

}

/*
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
Version: 0.11.1
*/

/**
 * @class Provides helper methods for DOM elements.
 */
YAHOO.util.Dom = function() {
   var ua = navigator.userAgent.toLowerCase();
   var isOpera = (ua.indexOf('opera') > -1);
   var isSafari = (ua.indexOf('safari') > -1);
   var isIE = (window.ActiveXObject);

   var id_counter = 0;
   var util = YAHOO.util; // internal shorthand
   var property_cache = {}; // to cache case conversion for set/getStyle
   
   var toCamel = function(property) {
      var convert = function(prop) {
         var test = /(-[a-z])/i.exec(prop);
         return prop.replace(RegExp.$1, RegExp.$1.substr(1).toUpperCase());
      };
      
      while(property.indexOf('-') > -1) {
         property = convert(property);
      }

      return property;
      //return property.replace(/-([a-z])/gi, function(m0, m1) {return m1.toUpperCase()}) // cant use function as 2nd arg yet due to safari bug
   };
   
   var toHyphen = function(property) {
      if (property.indexOf('-') > -1) { // assume hyphen
         return property;
      }
      
      var converted = '';
      for (var i = 0, len = property.length;i < len; ++i) {
         if (property.charAt(i) == property.charAt(i).toUpperCase()) {
            converted = converted + '-' + property.charAt(i).toLowerCase();
         } else {
            converted = converted + property.charAt(i);
         }
      }

      return converted;
      //return property.replace(/([a-z])([A-Z]+)/g, function(m0, m1, m2) {return (m1 + '-' + m2.toLowerCase())});
   };
   
   // improve performance by only looking up once
   var cacheConvertedProperties = function(property) {
      property_cache[property] = {
         camel: toCamel(property),
         hyphen: toHyphen(property)
      };
   };
   
   return {
      /**
       * Returns an HTMLElement reference
       * @param {String/HTMLElement/Array} el Accepts a string to use as an ID for getting a DOM reference, an actual DOM reference, or an Array of IDs and/or HTMLElements.
       * @return {HTMLElement/Array} A DOM reference to an HTML element or an array of HTMLElements.
       */
      get: function(el) {
         if (!el) { return null; } // nothing to work with
         
         if (typeof el != 'string' && !(el instanceof Array) ) { // assuming HTMLElement or HTMLCollection, so pass back as is
            return el;
         }
         
         if (typeof el == 'string') { // ID
            return document.getElementById(el);
         }
         else { // array of ID's and/or elements
            var collection = [];
            for (var i = 0, len = el.length; i < len; ++i) {
               collection[collection.length] = util.Dom.get(el[i]);
            }
            
            return collection;
         }

         return null; // safety, should never happen
      },
   
      /**
       * Normalizes currentStyle and ComputedStyle.
       * @param {String/HTMLElement/Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.
       * @param {String} property The style property whose value is returned.
       * @return {String/Array} The current value of the style property for the element(s).
       */
      getStyle: function(el, property) {
         var f = function(el) {
            var value = null;
            var dv = document.defaultView;
            
            if (!property_cache[property]) {
               cacheConvertedProperties(property);
            }
            
            var camel = property_cache[property]['camel'];
            var hyphen = property_cache[property]['hyphen'];

            if (property == 'opacity' && el.filters) {// IE opacity
               value = 1;
               try {
                  value = el.filters.item('DXImageTransform.Microsoft.Alpha').opacity / 100;
               } catch(e) {
                  try {
                     value = el.filters.item('alpha').opacity / 100;
                  } catch(e) {}
               }
            } else if (el.style[camel]) { // camelCase for valid styles
               value = el.style[camel];
            }
            else if (isIE && el.currentStyle && el.currentStyle[camel]) { // camelCase for currentStyle; isIE to workaround broken Opera 9 currentStyle
               value = el.currentStyle[camel];
            }
            else if ( dv && dv.getComputedStyle ) { // hyphen-case for computedStyle
               var computed = dv.getComputedStyle(el, '');
               
               if (computed && computed.getPropertyValue(hyphen)) {
                  value = computed.getPropertyValue(hyphen);
               }
            }
      
            return value;
         };
         
         return util.Dom.batch(el, f, util.Dom, true);
      },
   
      /**
       * Wrapper for setting style properties of HTMLElements.  Normalizes "opacity" across modern browsers.
       * @param {String/HTMLElement/Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.
       * @param {String} property The style property to be set.
       * @param {String} val The value to apply to the given property.
       */
      setStyle: function(el, property, val) {
         if (!property_cache[property]) {
            cacheConvertedProperties(property);
         }
         
         var camel = property_cache[property]['camel'];
         
         var f = function(el) {
            switch(property) {
               case 'opacity' :
                  if (isIE && typeof el.style.filter == 'string') { // in case not appended
                     el.style.filter = 'alpha(opacity=' + val * 100 + ')';
                     
                     if (!el.currentStyle || !el.currentStyle.hasLayout) {
                        el.style.zoom = 1; // when no layout or cant tell
                     }
                  } else {
                     el.style.opacity = val;
                     el.style['-moz-opacity'] = val;
                     el.style['-khtml-opacity'] = val;
                  }

                  break;
               default :
                  el.style[camel] = val;
            }
            
            
         };
         
         util.Dom.batch(el, f, util.Dom, true);
      },
      
      /**
       * Gets the current position of an element based on page coordinates.  Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
       * @param {String/HTMLElement/Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements
       @ return {Array} The XY position of the element(s)
       */
      getXY: function(el) {
         var f = function(el) {
   
         // has to be part of document to have pageXY
            if (el.offsetParent === null || this.getStyle(el, 'display') == 'none') {
               return false;
            }
            
            var parentNode = null;
            var pos = [];
            var box;
            
            if (el.getBoundingClientRect) { // IE
               box = el.getBoundingClientRect();
               var doc = document;
               if ( !this.inDocument(el) && parent.document != document) {// might be in a frame, need to get its scroll
                  doc = parent.document;

                  if ( !this.isAncestor(doc.documentElement, el) ) {
                     return false;                 
                  }

               }

               var scrollTop = Math.max(doc.documentElement.scrollTop, doc.body.scrollTop);
               var scrollLeft = Math.max(doc.documentElement.scrollLeft, doc.body.scrollLeft);
               
               return [box.left + scrollLeft, box.top + scrollTop];
            }
            else { // safari, opera, & gecko
               pos = [el.offsetLeft, el.offsetTop];
               parentNode = el.offsetParent;
               if (parentNode != el) {
                  while (parentNode) {
                     pos[0] += parentNode.offsetLeft;
                     pos[1] += parentNode.offsetTop;
                     parentNode = parentNode.offsetParent;
                  }
               }
               if (isSafari && this.getStyle(el, 'position') == 'absolute' ) { // safari doubles in some cases
                  pos[0] -= document.body.offsetLeft;
                  pos[1] -= document.body.offsetTop;
               } 
            }
            
            if (el.parentNode) { parentNode = el.parentNode; }
            else { parentNode = null; }
      
            while (parentNode && parentNode.tagName.toUpperCase() != 'BODY' && parentNode.tagName.toUpperCase() != 'HTML') 
            { // account for any scrolled ancestors
               pos[0] -= parentNode.scrollLeft;
               pos[1] -= parentNode.scrollTop;
      
               if (parentNode.parentNode) { parentNode = parentNode.parentNode; } 
               else { parentNode = null; }
            }
      
            
            return pos;
         };
         
         return util.Dom.batch(el, f, util.Dom, true);
      },
      
      /**
       * Gets the current X position of an element based on page coordinates.  The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
       * @param {String/HTMLElement/Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements
       * @return {String/Array} The X position of the element(s)
       */
      getX: function(el) {
         return util.Dom.getXY(el)[0];
      },
      
      /**
       * Gets the current Y position of an element based on page coordinates.  Element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
       * @param {String/HTMLElement/Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements
       * @return {String/Array} The Y position of the element(s)
       */
      getY: function(el) {
         return util.Dom.getXY(el)[1];
      },
      
      /**
       * Set the position of an html element in page coordinates, regardless of how the element is positioned.
       * The element(s) must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
       * @param {String/HTMLElement/Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements
       * @param {Array} pos Contains X & Y values for new position (coordinates are page-based)
       * @param {Boolean} noRetry By default we try and set the position a second time if the first fails
       */
      setXY: function(el, pos, noRetry) {
         var f = function(el) {
            var style_pos = this.getStyle(el, 'position');
            if (style_pos == 'static') { // default to relative
               this.setStyle(el, 'position', 'relative');
               style_pos = 'relative';
            }
            
            var pageXY = this.getXY(el);
            if (pageXY === false) { // has to be part of doc to have pageXY
               return false; 
            }
            
            var delta = [ // assuming pixels; if not we will have to retry
               parseInt( this.getStyle(el, 'left'), 10 ),
               parseInt( this.getStyle(el, 'top'), 10 )
            ];
         
            if ( isNaN(delta[0]) ) {// in case of 'auto'
               delta[0] = (style_pos == 'relative') ? 0 : el.offsetLeft;
            } 
            if ( isNaN(delta[1]) ) { // in case of 'auto'
               delta[1] = (style_pos == 'relative') ? 0 : el.offsetTop;
            } 
      
            if (pos[0] !== null) { el.style.left = pos[0] - pageXY[0] + delta[0] + 'px'; }
            if (pos[1] !== null) { el.style.top = pos[1] - pageXY[1] + delta[1] + 'px'; }
      
            var newXY = this.getXY(el);
      
            // if retry is true, try one more time if we miss 
            if (!noRetry && (newXY[0] != pos[0] || newXY[1] != pos[1]) ) {
               this.setXY(el, pos, true);
            }
            
         };
         
         util.Dom.batch(el, f, util.Dom, true);
      },
      
      /**
       * Set the X position of an html element in page coordinates, regardless of how the element is positioned.
       * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
       * @param {String/HTMLElement/Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.
       * @param {Int} x to use as the X coordinate for the element(s).
       */
      setX: function(el, x) {
         util.Dom.setXY(el, [x, null]);
      },
      
      /**
       * Set the Y position of an html element in page coordinates, regardless of how the element is positioned.
       * The element must be part of the DOM tree to have page coordinates (display:none or elements not appended return false).
       * @param {String/HTMLElement/Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.
       * @param {Int} x to use as the Y coordinate for the element(s).
       */
      setY: function(el, y) {
         util.Dom.setXY(el, [null, y]);
      },
      
      /**
       * Returns the region position of the given element.
       * The element must be part of the DOM tree to have a region (display:none or elements not appended return false).
       * @param {String/HTMLElement/Array} el Accepts a string to use as an ID, an actual DOM reference, or an Array of IDs and/or HTMLElements.
       * @return {Region/Array} A Region or array of Region instances containing "top, left, bottom, right" member data.
       */
      getRegion: function(el) {
         var f = function(el) {
            var region = new YAHOO.util.Region.getRegion(el);
            return region;
         };
         
         return util.Dom.batch(el, f, util.Dom, true);
      },
      
      /**
       * Returns the width of the client (viewport).
       * Now using getViewportWidth.  This interface left intact for back compat.
       * @return {Int} The width of the viewable area of the page.
       */
      getClientWidth: function() {
         return util.Dom.getViewportWidth();
      },
      
      /**
       * Returns the height of the client (viewport).
       * Now using getViewportHeight.  This interface left intact for back compat.
       * @return {Int} The height of the viewable area of the page.
       */
      getClientHeight: function() {
         return util.Dom.getViewportHeight();
      },

      /**
       * Returns a array of HTMLElements with the given class
       * For optimized performance, include a tag and/or root node if possible
       * @param {String} className The class name to match against
       * @param {String} tag (optional) The tag name of the elements being collected
       * @param {String/HTMLElement} root (optional) The HTMLElement or an ID to use as the starting point 
       * @return {Array} An array of elements that have the given class name
       */
      getElementsByClassName: function(className, tag, root) {
         var method = function(el) { return util.Dom.hasClass(el, className) };
         return util.Dom.getElementsBy(method, tag, root);
      },

      /**
       * Determines whether an HTMLElement has the given className
       * @param {String/HTMLElement/Array} el The element or collection to test
       * @param {String} className the class name to search for
       * @return {Boolean/Array} A boolean value or array of boolean values
       */
      hasClass: function(el, className) {
         var re = new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)');
         
         var f = function(el) {
            return re.test(el['className']);
         };
         
         return util.Dom.batch(el, f, util.Dom, true);
      },
   
      /**
       * Adds a class name to a given element or collection of elements
       * @param {String/HTMLElement/Array} el The element or collection to add the class to
       * @param {String} className the class name to add to the class attribute
       */
      addClass: function(el, className) {
         var f = function(el) {
            if (this.hasClass(el, className)) { return; } // already present
            
            
            el['className'] = [el['className'], className].join(' ');
         };
         
         util.Dom.batch(el, f, util.Dom, true);
      },
   
      /**
       * Removes a class name from a given element or collection of elements
       * @param {String/HTMLElement/Array} el The element or collection to remove the class from
       * @param {String} className the class name to remove from the class attribute
       */
      removeClass: function(el, className) {
         var re = new RegExp('(?:^|\\s+)' + className + '(?:\\s+|$)', 'g');

         var f = function(el) {
            if (!this.hasClass(el, className)) { return; } // not present
            
            
            var c = el['className'];
            el['className'] = c.replace(re, ' ');
            if ( this.hasClass(el, className) ) { // in case of multiple adjacent
               this.removeClass(el, className);
            }
            
         };
         
         util.Dom.batch(el, f, util.Dom, true);
      },
      
      /**
       * Replace a class with another class for a given element or collection of elements.
       * If no oldClassName is present, the newClassName is simply added.
       * @param {String/HTMLElement/Array} el The element or collection to remove the class from
       * @param {String} oldClassName the class name to be replaced
       * @param {String} newClassName the class name that will be replacing the old class name
       */
      replaceClass: function(el, oldClassName, newClassName) {
         var re = new RegExp('(?:^|\\s+)' + oldClassName + '(?:\\s+|$)', 'g');

         var f = function(el) {
         
            if ( !this.hasClass(el, oldClassName) ) {
               this.addClass(el, newClassName); // just add it if nothing to replace
               return; // note return
            }
         
            el['className'] = el['className'].replace(re, ' ' + newClassName + ' ');

            if ( this.hasClass(el, oldClassName) ) { // in case of multiple adjacent
               this.replaceClass(el, oldClassName, newClassName);
            }
         };
         
         util.Dom.batch(el, f, util.Dom, true);
      },
      
      /**
       * Generates a unique ID
       * @param {String/HTMLElement/Array} el (optional) An optional element array of elements to add an ID to (no ID is added if one is already present)
       * @param {String} prefix (optional) an optional prefix to use (defaults to "yui-gen")
       * @return {String/Array} The generated ID, or array of generated IDs (or original ID if already present on an element)
       */
      generateId: function(el, prefix) {
         prefix = prefix || 'yui-gen';
         el = el || {};
         
         var f = function(el) {
            if (el) {
               el = util.Dom.get(el);
            } else {
               el = {}; // just generating ID in this case
            }
            
            if (!el.id) {
               el.id = prefix + id_counter++; 
            } // dont override existing
            
            
            return el.id;
         };
         
         return util.Dom.batch(el, f, util.Dom, true);
      },
      
      /**
       * Determines whether an HTMLElement is an ancestor of another HTML element in the DOM hierarchy
       * @param {String/HTMLElement} haystack The possible ancestor
       * @param {String/HTMLElement} needle The possible descendent
       * @return {Boolean} Whether or not the haystack is an ancestor of needle
       */
      isAncestor: function(haystack, needle) {
         haystack = util.Dom.get(haystack);
         if (!haystack || !needle) { return false; }
         
         var f = function(needle) {
            if (haystack.contains && !isSafari) { // safari "contains" is broken
               return haystack.contains(needle);
            }
            else if ( haystack.compareDocumentPosition ) {
               return !!(haystack.compareDocumentPosition(needle) & 16);
            }
            else { // loop up and test each parent
               var parent = needle.parentNode;
               
               while (parent) {
                  if (parent == haystack) {
                     return true;
                  }
                  else if (parent.tagName.toUpperCase() == 'HTML') {
                     return false;
                  }
                  
                  parent = parent.parentNode;
               }
               return false;
            }    
         };
         
         return util.Dom.batch(needle, f, util.Dom, true);     
      },
      
      /**
       * Determines whether an HTMLElement is present in the current document
       * @param {String/HTMLElement} el The element to search for
       * @return {Boolean} Whether or not the element is present in the current document
       */
      inDocument: function(el) {
         var f = function(el) {
            return this.isAncestor(document.documentElement, el);
         };
         
         return util.Dom.batch(el, f, util.Dom, true);
      },
      
      /**
       * Returns a array of HTMLElements that pass the test applied by supplied boolean method
       * For optimized performance, include a tag and/or root node if possible
       * @param {Function} method A boolean method to test elements with
       * @param {String} tag (optional) The tag name of the elements being collected
       * @param {String/HTMLElement} root (optional) The HTMLElement or an ID to use as the starting point 
       */
      getElementsBy: function(method, tag, root) {
         tag = tag || '*';
         root = util.Dom.get(root) || document;
         
         var nodes = [];
         var elements = root.getElementsByTagName(tag);
         
         if ( !elements.length && (tag == '*' && root.all) ) {
            elements = root.all; // IE < 6
         }
         
         for (var i = 0, len = elements.length; i < len; ++i) 
         {
            if ( method(elements[i]) ) { nodes[nodes.length] = elements[i]; }
         }

         
         return nodes;
      },
      
      /**
       * Returns an array of elements that have had the supplied method applied.
       * The method is called with the element(s) as the first arg, and the optional param as the second ( method(el, o) )
       * @param {String/HTMLElement/Array} el (optional) An element or array of elements to apply the method to
       * @param {Function} method The method to apply to the element(s)
       * @param {Generic} (optional) o An optional arg that is passed to the supplied method
       * @param {Boolean} (optional) override Whether or not to override the scope of "method" with "o"
       * @return {HTMLElement/Array} The element(s) with the method applied
       */
      batch: function(el, method, o, override) {
         var id = el;
         el = util.Dom.get(el);
         
         var scope = (override) ? o : window;
         
         if (!el || el.tagName || !el.length) { // is null or not a collection (tagName for SELECT and others that can be both an element and a collection)
            if (!el) {
               return false;
            }
            return method.call(scope, el, o);
         } 
         
         var collection = [];
         
         for (var i = 0, len = el.length; i < len; ++i) {
            if (!el[i]) {
               id = id[i];
            }
            collection[collection.length] = method.call(scope, el[i], o);
         }
         
         return collection;
      },
      
      /**
       * Returns the height of the document.
       * @return {Int} The height of the actual document (which includes the body and its margin).
       */
      getDocumentHeight: function() {
         var scrollHeight=-1,windowHeight=-1,bodyHeight=-1;
         var marginTop = parseInt(util.Dom.getStyle(document.body, 'marginTop'), 10);
         var marginBottom = parseInt(util.Dom.getStyle(document.body, 'marginBottom'), 10);
         
         var mode = document.compatMode;
         
         if ( (mode || isIE) && !isOpera ) { // (IE, Gecko)
            switch (mode) {
               case 'CSS1Compat': // Standards mode
                  scrollHeight = ((window.innerHeight && window.scrollMaxY) ?  window.innerHeight+window.scrollMaxY : -1);
                  windowHeight = [document.documentElement.clientHeight,self.innerHeight||-1].sort(function(a, b){return(a-b);})[1];
                  bodyHeight = document.body.offsetHeight + marginTop + marginBottom;
                  break;
               
               default: // Quirks
                  scrollHeight = document.body.scrollHeight;
                  bodyHeight = document.body.clientHeight;
            }
         } else { // Safari & Opera
            scrollHeight = document.documentElement.scrollHeight;
            windowHeight = self.innerHeight;
            bodyHeight = document.documentElement.clientHeight;
         }
      
         var h = [scrollHeight,windowHeight,bodyHeight].sort(function(a, b){return(a-b);});
         return h[2];
      },
      
      /**
       * Returns the width of the document.
       * @return {Int} The width of the actual document (which includes the body and its margin).
       */
      getDocumentWidth: function() {
         var docWidth=-1,bodyWidth=-1,winWidth=-1;
         var marginRight = parseInt(util.Dom.getStyle(document.body, 'marginRight'), 10);
         var marginLeft = parseInt(util.Dom.getStyle(document.body, 'marginLeft'), 10);
         
         var mode = document.compatMode;
         
         if (mode || isIE) { // (IE, Gecko, Opera)
            switch (mode) {
               case 'CSS1Compat': // Standards mode
                  docWidth = document.documentElement.clientWidth;
                  bodyWidth = document.body.offsetWidth + marginLeft + marginRight;
                  winWidth = self.innerWidth || -1;
                  break;
                  
               default: // Quirks
                  bodyWidth = document.body.clientWidth;
                  winWidth = document.body.scrollWidth;
                  break;
            }
         } else { // Safari
            docWidth = document.documentElement.clientWidth;
            bodyWidth = document.body.offsetWidth + marginLeft + marginRight;
            winWidth = self.innerWidth;
         }
      
         var w = [docWidth,bodyWidth,winWidth].sort(function(a, b){return(a-b);});
         return w[2];
      },

      /**
       * Returns the current height of the viewport.
       * @return {Int} The height of the viewable area of the page (excludes scrollbars).
       */
      getViewportHeight: function() {
         var height = -1;
         var mode = document.compatMode;
      
         if ( (mode || isIE) && !isOpera ) {
            switch (mode) { // (IE, Gecko)
               case 'CSS1Compat': // Standards mode
                  height = document.documentElement.clientHeight;
                  break;
      
               default: // Quirks
                  height = document.body.clientHeight;
            }
         } else { // Safari, Opera
            height = self.innerHeight;
         }
      
         return height;
      },
      
      /**
       * Returns the current width of the viewport.
       * @return {Int} The width of the viewable area of the page (excludes scrollbars).
       */
      
      getViewportWidth: function() {
         var width = -1;
         var mode = document.compatMode;
         
         if (mode || isIE) { // (IE, Gecko, Opera)
            switch (mode) {
            case 'CSS1Compat': // Standards mode 
               width = document.documentElement.clientWidth;
               break;
               
            default: // Quirks
               width = document.body.clientWidth;
            }
         } else { // Safari
            width = self.innerWidth;
         }
         return width;
      }
   };
}();

/**
 * @class A region is a representation of an object on a grid.  It is defined
 * by the top, right, bottom, left extents, so is rectangular by default.  If 
 * other shapes are required, this class could be extended to support it.
 *
 * @param {int} t the top extent
 * @param {int} r the right extent
 * @param {int} b the bottom extent
 * @param {int} l the left extent
 * @constructor
 */
YAHOO.util.Region = function(t, r, b, l) {

    /**
     * The region's top extent
     * @type int
     */
    this.top = t;
    
    /**
     * The region's top extent as index, for symmetry with set/getXY
     * @type int
     */
    this[1] = t;

    /**
     * The region's right extent
     * @type int
     */
    this.right = r;

    /**
     * The region's bottom extent
     * @type int
     */
    this.bottom = b;

    /**
     * The region's left extent
     * @type int
     */
    this.left = l;
    
    /**
     * The region's left extent as index, for symmetry with set/getXY
     * @type int
     */
    this[0] = l;
};

/**
 * Returns true if this region contains the region passed in
 *
 * @param  {Region}  region The region to evaluate
 * @return {boolean}        True if the region is contained with this region, 
 *                          else false
 */
YAHOO.util.Region.prototype.contains = function(region) {
    return ( region.left   >= this.left   && 
             region.right  <= this.right  && 
             region.top    >= this.top    && 
             region.bottom <= this.bottom    );

};

/**
 * Returns the area of the region
 *
 * @return {int} the region's area
 */
YAHOO.util.Region.prototype.getArea = function() {
    return ( (this.bottom - this.top) * (this.right - this.left) );
};

/**
 * Returns the region where the passed in region overlaps with this one
 *
 * @param  {Region} region The region that intersects
 * @return {Region}        The overlap region, or null if there is no overlap
 */
YAHOO.util.Region.prototype.intersect = function(region) {
    var t = Math.max( this.top,    region.top    );
    var r = Math.min( this.right,  region.right  );
    var b = Math.min( this.bottom, region.bottom );
    var l = Math.max( this.left,   region.left   );
    
    if (b >= t && r >= l) {
        return new YAHOO.util.Region(t, r, b, l);
    } else {
        return null;
    }
};

/**
 * Returns the region representing the smallest region that can contain both
 * the passed in region and this region.
 *
 * @param  {Region} region The region that to create the union with
 * @return {Region}        The union region
 */
YAHOO.util.Region.prototype.union = function(region) {
    var t = Math.min( this.top,    region.top    );
    var r = Math.max( this.right,  region.right  );
    var b = Math.max( this.bottom, region.bottom );
    var l = Math.min( this.left,   region.left   );

    return new YAHOO.util.Region(t, r, b, l);
};

/**
 * toString
 * @return string the region properties
 */
YAHOO.util.Region.prototype.toString = function() {
    return ( "Region {"    +
             "top: "       + this.top    + 
             ", right: "   + this.right  + 
             ", bottom: "  + this.bottom + 
             ", left: "    + this.left   + 
             "}" );
};

/**
 * Returns a region that is occupied by the DOM element
 *
 * @param  {HTMLElement} el The element
 * @return {Region}         The region that the element occupies
 * @static
 */
YAHOO.util.Region.getRegion = function(el) {
    var p = YAHOO.util.Dom.getXY(el);

    var t = p[1];
    var r = p[0] + el.offsetWidth;
    var b = p[1] + el.offsetHeight;
    var l = p[0];

    return new YAHOO.util.Region(t, r, b, l);
};

/////////////////////////////////////////////////////////////////////////////

/**
 * @class
 *
 * A point is a region that is special in that it represents a single point on 
 * the grid.
 *
 * @param {int} x The X position of the point
 * @param {int} y The Y position of the point
 * @constructor
 * @extends Region
 */
YAHOO.util.Point = function(x, y) {
   if (x instanceof Array) { // accept output from Dom.getXY
      y = x[1];
      x = x[0];
   }
   
    /**
     * The X position of the point, which is also the right, left and index zero (for Dom.getXY symmetry)
     * @type int
     */

    this.x = this.right = this.left = this[0] = x;
     
    /**
     * The Y position of the point, which is also the top, bottom and index one (for Dom.getXY symmetry)
     * @type int
     */
    this.y = this.top = this.bottom = this[1] = y;
};

YAHOO.util.Point.prototype = new YAHOO.util.Region();


/*                                                                                                                                                      
Copyright (c) 2006, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
http://developer.yahoo.net/yui/license.txt
version: 0.11.2
*/ 

/**
 * Defines the interface and base operation of items that that can be 
 * dragged or can be drop targets.  It was designed to be extended, overriding
 * the event handlers for startDrag, onDrag, onDragOver, onDragOut.
 * Up to three html elements can be associated with a DragDrop instance:
 * <ul>
 * <li>linked element: the element that is passed into the constructor.
 * This is the element which defines the boundaries for interaction with 
 * other DragDrop objects.</li>
 * <li>handle element(s): The drag operation only occurs if the element that 
 * was clicked matches a handle element.  By default this is the linked 
 * element, but there are times that you will want only a portion of the 
 * linked element to initiate the drag operation, and the setHandleElId() 
 * method provides a way to define this.</li>
 * <li>drag element: this represents an the element that would be moved along
 * with the cursor during a drag operation.  By default, this is the linked
 * element itself as in {@link YAHOO.util.DD}.  setDragElId() lets you define
 * a separate element that would be moved, as in {@link YAHOO.util.DDProxy}
 * </li>
 * </ul>
 * This class should not be instantiated until the onload event to ensure that
 * the associated elements are available.
 * The following would define a DragDrop obj that would interact with any 
 * other * DragDrop obj in the "group1" group:
 * <pre>
 *  dd = new YAHOO.util.DragDrop("div1", "group1");
 * </pre>
 * Since none of the event handlers have been implemented, nothing would 
 * actually happen if you were to run the code above.  Normally you would 
 * override this class or one of the default implementations, but you can 
 * also override the methods you want on an instance of the class...
 * <pre>
 *  dd.onDragDrop = function(e, id) {
 *   alert("dd was dropped on " + id);
 *  }
 * </pre>
 * @constructor
 * @param {String} id of the element that is linked to this instance
 * @param {String} sGroup the group of related DragDrop objects
 * @param {object} config an object containing configurable attributes
 *                Valid properties for DragDrop: 
 *                    padding, isTarget, maintainOffset, primaryButtonOnly
 */
YAHOO.util.DragDrop = function(id, sGroup, config) {
    if (id) {
        this.init(id, sGroup, config); 
    }
};

YAHOO.util.DragDrop.prototype = {

    /**
     * The id of the element associated with this object.  This is what we 
     * refer to as the "linked element" because the size and position of 
     * this element is used to determine when the drag and drop objects have 
     * interacted.
     *
     * @type String
     */
    id: null,

    /**
     * Configuration attributes passed into the constructor
     * @type object
     */
    config: null,

    /**
     * The id of the element that will be dragged.  By default this is same 
     * as the linked element , but could be changed to another element. Ex: 
     * YAHOO.util.DDProxy
     *
     * @type String
     * @private
     */
    dragElId: null, 

    /**
     * the id of the element that initiates the drag operation.  By default 
     * this is the linked element, but could be changed to be a child of this
     * element.  This lets us do things like only starting the drag when the 
     * header element within the linked html element is clicked.
     *
     * @type String
     * @private
     */
    handleElId: null, 

    /**
     * An associative array of HTML tags that will be ignored if clicked.
     * @type {string: string}
     */
    invalidHandleTypes: null, 

    /**
     * An associative array of ids for elements that will be ignored if clicked
     * @type {string: string}
     */
    invalidHandleIds: null, 

    /**
     * An indexted array of css class names for elements that will be ignored
     * if clicked.
     * @type string[]
     */
    invalidHandleClasses: null, 

    /**
     * The linked element's absolute X position at the time the drag was 
     * started
     *
     * @type int
     * @private
     */
    startPageX: 0,

    /**
     * The linked element's absolute X position at the time the drag was 
     * started
     *
     * @type int
     * @private
     */
    startPageY: 0,

    /**
     * The group defines a logical collection of DragDrop objects that are 
     * related.  Instances only get events when interacting with other 
     * DragDrop object in the same group.  This lets us define multiple 
     * groups using a single DragDrop subclass if we want.
     * @type {string: string}
     */
    groups: null,

    /**
     * Individual drag/drop instances can be locked.  This will prevent 
     * onmousedown start drag.
     *
     * @type boolean
     * @private
     */
    locked: false,

    /**
     * Lock this instance
     */
    lock: function() { this.locked = true; },

    /**
     * Unlock this instace
     */
    unlock: function() { this.locked = false; },

    /**
     * By default, all insances can be a drop target.  This can be disabled by
     * setting isTarget to false.
     *
     * @type boolean
     */
    isTarget: true,

    /**
     * The padding configured for this drag and drop object for calculating
     * the drop zone intersection with this object.
     * @type int[]
     */
    padding: null,

    /**
     * @private
     */
    _domRef: null,

    /**
     * Internal typeof flag
     * @private
     */
    __ygDragDrop: true,

    /**
     * Set to true when horizontal contraints are applied
     *
     * @type boolean
     * @private
     */
    constrainX: false,

    /**
     * Set to true when vertical contraints are applied
     *
     * @type boolean
     * @private
     */
    constrainY: false,

    /**
     * The left constraint
     *
     * @type int
     * @private
     */
    minX: 0,

    /**
     * The right constraint
     *
     * @type int
     * @private
     */
    maxX: 0,

    /**
     * The up constraint 
     *
     * @type int
     * @private
     */
    minY: 0,

    /**
     * The down constraint 
     *
     * @type int
     * @private
     */
    maxY: 0,

    /**
     * Maintain offsets when we resetconstraints.  Used to maintain the 
     * slider thumb value, and this needs to be fixed.
     * @type boolean
     */
    maintainOffset: false,

    /**
     * Array of pixel locations the element will snap to if we specified a 
     * horizontal graduation/interval.  This array is generated automatically
     * when you define a tick interval.
     * @type int[]
     */
    xTicks: null,

    /**
     * Array of pixel locations the element will snap to if we specified a 
     * vertical graduation/interval.  This array is generated automatically 
     * when you define a tick interval.
     * @type int[]
     */
    yTicks: null,

    /**
     * By default the drag and drop instance will only respond to the primary
     * button click (left button for a right-handed mouse).  Set to true to
     * allow drag and drop to start with any mouse click that is propogated
     * by the browser
     * @type boolean
     */
    primaryButtonOnly: true,

    /**
     * The availabe property is false until the linked dom element is accessible.
     * @type boolean
     */
    available: false,

    /**
     * Code that executes immediately before the startDrag event
     * @private
     */
    b4StartDrag: function(x, y) { },

    /**
     * Abstract method called after a drag/drop object is clicked
     * and the drag or mousedown time thresholds have beeen met.
     *
     * @param {int} X click location
     * @param {int} Y click location
     */
    startDrag: function(x, y) { /* override this */ },

    /**
     * Code that executes immediately before the onDrag event
     * @private
     */
    b4Drag: function(e) { },

    /**
     * Abstract method called during the onMouseMove event while dragging an 
     * object.
     *
     * @param {Event} e
     */
    onDrag: function(e) { /* override this */ },

    /**
     * Code that executes immediately before the onDragEnter event
     * @private
     */
    // b4DragEnter: function(e) { },

    /**
     * Abstract method called when this element fist begins hovering over 
     * another DragDrop obj
     *
     * @param {Event} e
     * @param {String || YAHOO.util.DragDrop[]} id In POINT mode, the element
     * id this is hovering over.  In INTERSECT mode, an array of one or more 
     * dragdrop items being hovered over.
     */
    onDragEnter: function(e, id) { /* override this */ },

    /**
     * Code that executes immediately before the onDragOver event
     * @private
     */
    b4DragOver: function(e) { },

    /**
     * Abstract method called when this element is hovering over another 
     * DragDrop obj
     *
     * @param {Event} e
     * @param {String || YAHOO.util.DragDrop[]} id In POINT mode, the element
     * id this is hovering over.  In INTERSECT mode, an array of dd items 
     * being hovered over.
     */
    onDragOver: function(e, id) { /* override this */ },

    /**
     * Code that executes immediately before the onDragOut event
     * @private
     */
    b4DragOut: function(e) { },

    /**
     * Abstract method called when we are no longer hovering over an element
     *
     * @param {Event} e
     * @param {String || YAHOO.util.DragDrop[]} id In POINT mode, the element
     * id this was hovering over.  In INTERSECT mode, an array of dd items 
     * that the mouse is no longer over.
     */
    onDragOut: function(e, id) { /* override this */ },

    /**
     * Code that executes immediately before the onDragDrop event
     * @private
     */
    b4DragDrop: function(e) { },

    /**
     * Abstract method called when this item is dropped on another DragDrop 
     * obj
     *
     * @param {Event} e
     * @param {String || YAHOO.util.DragDrop[]} id In POINT mode, the element
     * id this was dropped on.  In INTERSECT mode, an array of dd items this 
     * was dropped on.
     */
    onDragDrop: function(e, id) { /* override this */ },

    /**
     * Code that executes immediately before the endDrag event
     * @private
     */
    b4EndDrag: function(e) { },

    /**
     * Fired when we are done dragging the object
     *
     * @param {Event} e
     */
    endDrag: function(e) { /* override this */ },

    /**
     * Code executed immediately before the onMouseDown event

     * @param {Event} e
     * @private
     */
    b4MouseDown: function(e) {  },

    /**
     * Event handler that fires when a drag/drop obj gets a mousedown
     * @param {Event} e
     */
    onMouseDown: function(e) { /* override this */ },

    /**
     * Event handler that fires when a drag/drop obj gets a mouseup
     * @param {Event} e
     */
    onMouseUp: function(e) { /* override this */ },
   
    /**
     * Override the onAvailable method to do what is needed after the initial
     * position was determined.
     */
    onAvailable: function () { 
        this.logger.log("onAvailable (base)"); 
    },

    /**
     * Returns a reference to the linked element
     *
     * @return {HTMLElement} the html element 
     */
    getEl: function() { 
        if (!this._domRef) {
            this._domRef = YAHOO.util.Dom.get(this.id); 
        }

        return this._domRef;
    },

    /**
     * Returns a reference to the actual element to drag.  By default this is
     * the same as the html element, but it can be assigned to another 
     * element. An example of this can be found in YAHOO.util.DDProxy
     *
     * @return {HTMLElement} the html element 
     */
    getDragEl: function() {
        return YAHOO.util.Dom.get(this.dragElId);
    },

    /**
     * Sets up the DragDrop object.  Must be called in the constructor of any
     * YAHOO.util.DragDrop subclass
     *
     * @param id the id of the linked element
     * @param {String} sGroup the group of related items
     * @param {object} config configuration attributes
     */
    init: function(id, sGroup, config) {
        this.initTarget(id, sGroup, config);
        YAHOO.util.Event.addListener(this.id, "mousedown", 
                                          this.handleMouseDown, this, true);
    },

    /**
     * Initializes Targeting functionality only... the object does not
     * get a mousedown handler.
     *
     * @param id the id of the linked element
     * @param {String} sGroup the group of related items
     * @param {object} config configuration attributes
     */
    initTarget: function(id, sGroup, config) {

        // configuration attributes 
        this.config = config || {};

        // create a local reference to the drag and drop manager
        this.DDM = YAHOO.util.DDM;
        // initialize the groups array
        this.groups = {};

        // set the id
        this.id = id;

        // add to an interaction group
        this.addToGroup((sGroup) ? sGroup : "default");

        // We don't want to register this as the handle with the manager
        // so we just set the id rather than calling the setter.
        this.handleElId = id;

        YAHOO.util.Event.onAvailable(id, this.handleOnAvailable, this, true);

        // create a logger instance
        this.logger = (YAHOO.widget.LogWriter) ? 
                new YAHOO.widget.LogWriter(this.toString()) : YAHOO;

        // the linked element is the element that gets dragged by default
        this.setDragElId(id); 

        // by default, clicked anchors will not start drag operations. 
        // @TODO what else should be here?  Probably form fields.
        this.invalidHandleTypes = { A: "A" };
        this.invalidHandleIds = {};
        this.invalidHandleClasses = [];

        this.applyConfig();
    },

    /**
     * Applies the configuration parameters that were passed into the constructor.
     * This is supposed to happen at each level through the inheritance chain.  So
     * a DDProxy implentation will execute apply config on DDProxy, DD, and 
     * DragDrop in order to get all of the parameters that are available in
     * each object.
     */
    applyConfig: function() {

        // configurable properties: 
        //    padding, isTarget, maintainOffset, primaryButtonOnly
        this.padding           = this.config.padding || [0, 0, 0, 0];
        this.isTarget          = (this.config.isTarget !== false);
        this.maintainOffset    = (this.config.maintainOffset);
        this.primaryButtonOnly = (this.config.primaryButtonOnly !== false);

    },

    /**
     * Executed when the linked element is available
     * @private
     */
    handleOnAvailable: function() {
        this.logger.log("handleOnAvailable");
        this.available = true;
        this.resetConstraints();
        this.onAvailable();
    },

     /**
     * Configures the padding for the target zone in px.  Effectively expands
     * (or reduces) the virtual object size for targeting calculations.  
     * Supports css-style shorthand; if only one parameter is passed, all sides
     * will have that padding, and if only two are passed, the top and bottom
     * will have the first param, the left and right the second.
     * @param {int} iTop    Top pad
     * @param {int} iRight  Right pad
     * @param {int} iBot    Bot pad
     * @param {int} iLeft   Left pad
     */
    setPadding: function(iTop, iRight, iBot, iLeft) {
        // this.padding = [iLeft, iRight, iTop, iBot];
        if (!iRight && 0 !== iRight) {
            this.padding = [iTop, iTop, iTop, iTop];
        } else if (!iBot && 0 !== iBot) {
            this.padding = [iTop, iRight, iTop, iRight];
        } else {
            this.padding = [iTop, iRight, iBot, iLeft];
        }
    },

    /**
     * Stores the initial placement of the dd element
     */
    setInitPosition: function(diffX, diffY) {
        var el = this.getEl();

        if (!this.DDM.verifyEl(el)) {
            this.logger.log(this.id + " element is broken");
            return;
        }

        var dx = diffX || 0;
        var dy = diffY || 0;

        var p = YAHOO.util.Dom.getXY( el );

        this.initPageX = p[0] - dx;
        this.initPageY = p[1] - dy;

        this.lastPageX = p[0];
        this.lastPageY = p[1];

        this.logger.log(this.id + " inital position: " + this.initPageX + 
                ", " + this.initPageY);


        this.setStartPosition(p);
    },

    /**
     * Sets the start position of the element.  This is set when the obj
     * is initialized, the reset when a drag is started.
     * @param pos current position (from previous lookup)
     * @private
     */
    setStartPosition: function(pos) {
        var p = pos || YAHOO.util.Dom.getXY( this.getEl() );
        this.deltaSetXY = null;

        this.startPageX = p[0];
        this.startPageY = p[1];
    },

    /**
     * Add this instance to a group of related drag/drop objects.  All 
     * instances belong to at least one group, and can belong to as many 
     * groups as needed.
     *
     * @param sGroup {string} the name of the group
     */
    addToGroup: function(sGroup) {
        this.groups[sGroup] = true;
        this.DDM.regDragDrop(this, sGroup);
    },

    /**
     * Remove's this instance from the supplied interaction group
     * @param {string}  sGroup  The group to drop
     */
    removeFromGroup: function(sGroup) {
        this.logger.log("Removing from group: " + sGroup);
        if (this.groups[sGroup]) {
            delete this.groups[sGroup];
        }

        this.DDM.removeDDFromGroup(this, sGroup);
    },

    /**
     * Allows you to specify that an element other than the linked element 
     * will be moved with the cursor during a drag
     *
     * @param id the id of the element that will be used to initiate the drag
     */
    setDragElId: function(id) {
        this.dragElId = id;
    },

    /**
     * Allows you to specify a child of the linked element that should be 
     * used to initiate the drag operation.  An example of this would be if 
     * you have a content div with text and links.  Clicking anywhere in the 
     * content area would normally start the drag operation.  Use this method
     * to specify that an element inside of the content div is the element 
     * that starts the drag operation.
     *
     * @param id the id of the element that will be used to initiate the drag
     */
    setHandleElId: function(id) {
        this.handleElId = id;
        this.DDM.regHandle(this.id, id);
    },

    /**
     * Allows you to set an element outside of the linked element as a drag 
     * handle
     */
    setOuterHandleElId: function(id) {
        this.logger.log("Adding outer handle event: " + id);
        YAHOO.util.Event.addListener(id, "mousedown", 
                this.handleMouseDown, this, true);
        this.setHandleElId(id);
    },

    /**
     * Remove all drag and drop hooks for this element
     */
    unreg: function() {
        this.logger.log("DragDrop obj cleanup " + this.id);
        YAHOO.util.Event.removeListener(this.id, "mousedown", 
                this.handleMouseDown);
        this._domRef = null;
        this.DDM._remove(this);
    },

    /**
     * Returns true if this instance is locked, or the drag drop mgr is locked
     * (meaning that all drag/drop is disabled on the page.)
     *
     * @return {boolean} true if this obj or all drag/drop is locked, else 
     * false
     */
    isLocked: function() {
        return (this.DDM.isLocked() || this.locked);
    },

    /**
     * Fired when this object is clicked
     *
     * @param {Event} e 
     * @param {YAHOO.util.DragDrop} oDD the clicked dd object (this dd obj)
     * @private
     */
    handleMouseDown: function(e, oDD) {

        this.logger.log("isLocked: " + this.isLocked());

        var EU = YAHOO.util.Event;

        var button = e.which || e.button;
        this.logger.log("button: " + button);

        if (this.primaryButtonOnly && button > 1) {
            this.logger.log("Mousedown was not produced by the primary button");
            return;
        }

        if (this.isLocked()) {
            this.logger.log("Drag and drop is disabled, aborting");
            return;
        }

        this.logger.log("mousedown " + this.id);
        this.DDM.refreshCache(this.groups);
        // var self = this;
        // setTimeout( function() { self.DDM.refreshCache(self.groups); }, 0);

        // Only process the event if we really clicked within the linked 
        // element.  The reason we make this check is that in the case that 
        // another element was moved between the clicked element and the 
        // cursor in the time between the mousedown and mouseup events. When 
        // this happens, the element gets the next mousedown event 
        // regardless of where on the screen it happened.  
        var pt = new YAHOO.util.Point(EU.getPageX(e), EU.getPageY(e));
        if ( this.DDM.isOverTarget(pt, this) )  {

            this.logger.log("click is over target");

            //  check to see if the handle was clicked
            var srcEl = EU.getTarget(e);

            if (this.isValidHandleChild(srcEl) &&
                    (this.id == this.handleElId || 
                     this.DDM.handleWasClicked(srcEl, this.id)) ) {

                this.logger.log("click was a valid handle");

                // set the initial element position
                this.setStartPosition();

                this.logger.log("firing onMouseDown events");


                this.b4MouseDown(e);
                this.onMouseDown(e);
                this.DDM.handleMouseDown(e, this);

                this.DDM.stopEvent(e);
            }
        }
    },

    /**
     * Allows you to specify a tag name that should not start a drag operation
     * when clicked.  This is designed to facilitate embedding links within a
     * drag handle that do something other than start the drag.
     * 
     * @param {string} tagName the type of element to exclude
     */
    addInvalidHandleType: function(tagName) {
        var type = tagName.toUpperCase();
        this.invalidHandleTypes[type] = type;
    },

    /**
     * Lets you to specify an element id for a child of a drag handle
     * that should not initiate a drag
     * @param {string} id the element id of the element you wish to ignore
     */
    addInvalidHandleId: function(id) {
        this.invalidHandleIds[id] = id;
    },


    /**
     * Lets you specify a css class of elements that will not initiate a drag
     * @param {string} cssClass the class of the elements you wish to ignore
     */
    addInvalidHandleClass: function(cssClass) {
        this.invalidHandleClasses.push(cssClass);
    },

    /**
     * Unsets an excluded tag name set by addInvalidHandleType
     * 
     * @param {string} tagName the type of element to unexclude
     */
    removeInvalidHandleType: function(tagName) {
        var type = tagName.toUpperCase();
        // this.invalidHandleTypes[type] = null;
        delete this.invalidHandleTypes[type];
    },
    
    /**
     * Unsets an invalid handle id
     * @param {string} the id of the element to re-enable
     */
    removeInvalidHandleId: function(id) {
        delete this.invalidHandleIds[id];
    },

    /**
     * Unsets an invalid css class
     * @param {string} the class of the element(s) you wish to re-enable
     */
    removeInvalidHandleClass: function(cssClass) {
        for (var i=0, len=this.invalidHandleClasses.length; i<len; ++i) {
            if (this.invalidHandleClasses[i] == cssClass) {
                delete this.invalidHandleClasses[i];
            }
        }
    },

    /**
     * Checks the tag exclusion list to see if this click should be ignored
     *
     * @param {ygNode} node
     * @return {boolean} true if this is a valid tag type, false if not
     */
    isValidHandleChild: function(node) {

        var valid = true;
        // var n = (node.nodeName == "#text") ? node.parentNode : node;
        var nodeName;
        try {
            nodeName = node.nodeName.toUpperCase();
        } catch(e) {
            nodeName = node.nodeName;
        }
        valid = valid && !this.invalidHandleTypes[nodeName];
        valid = valid && !this.invalidHandleIds[node.id];

        for (var i=0, len=this.invalidHandleClasses.length; valid && i<len; ++i) {
            valid = !YAHOO.util.Dom.hasClass(node, this.invalidHandleClasses[i]);
        }

        this.logger.log("Valid handle? ... " + valid);

        return valid;

    },

    /**
     * Create the array of horizontal tick marks if an interval was specified
     * in setXConstraint().
     *
     * @private
     */
    setXTicks: function(iStartX, iTickSize) {
        this.xTicks = [];
        this.xTickSize = iTickSize;
        
        var tickMap = {};

        for (var i = this.initPageX; i >= this.minX; i = i - iTickSize) {
            if (!tickMap[i]) {
                this.xTicks[this.xTicks.length] = i;
                tickMap[i] = true;
            }
        }

        for (i = this.initPageX; i <= this.maxX; i = i + iTickSize) {
            if (!tickMap[i]) {
                this.xTicks[this.xTicks.length] = i;
                tickMap[i] = true;
            }
        }

        this.xTicks.sort(this.DDM.numericSort) ;
        this.logger.log("xTicks: " + this.xTicks.join());
    },

    /**
     * Create the array of vertical tick marks if an interval was specified in 
     * setYConstraint().
     *
     * @private
     */
    setYTicks: function(iStartY, iTickSize) {
        // this.logger.log("setYTicks: " + iStartY + ", " + iTickSize
               // + ", " + this.initPageY + ", " + this.minY + ", " + this.maxY );
        this.yTicks = [];
        this.yTickSize = iTickSize;

        var tickMap = {};

        for (var i = this.initPageY; i >= this.minY; i = i - iTickSize) {
            if (!tickMap[i]) {
                this.yTicks[this.yTicks.length] = i;
                tickMap[i] = true;
            }
        }

        for (i = this.initPageY; i <= this.maxY; i = i + iTickSize) {
            if (!tickMap[i]) {
                this.yTicks[this.yTicks.length] = i;
                tickMap[i] = true;
            }
        }

        this.yTicks.sort(this.DDM.numericSort) ;
        this.logger.log("yTicks: " + this.yTicks.join());
    },

    /**
     * By default, the element can be dragged any place on the screen.  Use 
     * this method to limit the horizontal travel of the element.  Pass in 
     * 0,0 for the parameters if you want to lock the drag to the y axis.
     *
     * @param {int} iLeft the number of pixels the element can move to the left
     * @param {int} iRight the number of pixels the element can move to the 
     * right
     * @param {int} iTickSize optional parameter for specifying that the 
     * element
     * should move iTickSize pixels at a time.
     */
    setXConstraint: function(iLeft, iRight, iTickSize) {
        this.leftConstraint = iLeft;
        this.rightConstraint = iRight;

        this.minX = this.initPageX - iLeft;
        this.maxX = this.initPageX + iRight;
        if (iTickSize) { this.setXTicks(this.initPageX, iTickSize); }

        this.constrainX = true;
        this.logger.log("initPageX:" + this.initPageX + " minX:" + this.minX + 
                " maxX:" + this.maxX);
    },

    /**
     * Clears any constraints applied to this instance.  Also clears ticks
     * since they can't exist independent of a constraint at this time.
     */
    clearConstraints: function() {
        this.logger.log("Clearing constraints");
        this.constrainX = false;
        this.constrainY = false;
        this.clearTicks();
    },

    /**
     * Clears any tick interval defined for this instance
     */
    clearTicks: function() {
        this.logger.log("Clearing ticks");
        this.xTicks = null;
        this.yTicks = null;
        this.xTickSize = 0;
        this.yTickSize = 0;
    },

    /**
     * By default, the element can be dragged any place on the screen.  Set 
     * this to limit the vertical travel of the element.  Pass in 0,0 for the
     * parameters if you want to lock the drag to the x axis.
     *
     * @param {int} iUp the number of pixels the element can move up
     * @param {int} iDown the number of pixels the element can move down
     * @param {int} iTickSize optional parameter for specifying that the 
     * element should move iTickSize pixels at a time.
     */
    setYConstraint: function(iUp, iDown, iTickSize) {
        this.logger.log("setYConstraint: " + iUp + "," + iDown + "," + iTickSize);
        this.topConstraint = iUp;
        this.bottomConstraint = iDown;

        this.minY = this.initPageY - iUp;
        this.maxY = this.initPageY + iDown;
        if (iTickSize) { this.setYTicks(this.initPageY, iTickSize); }

        this.constrainY = true;
        
        this.logger.log("initPageY:" + this.initPageY + " minY:" + this.minY + 
                " maxY:" + this.maxY);
    },

    /**
     * resetConstraints must be called if you manually reposition a dd element.
     * @param {boolean} maintainOffset
     */
    resetConstraints: function() {

        this.logger.log("resetConstraints");

        // Maintain offsets if necessary
        if (this.initPageX || this.initPageX === 0) {
            this.logger.log("init pagexy: " + this.initPageX + ", " + 
                               this.initPageY);
            this.logger.log("last pagexy: " + this.lastPageX + ", " + 
                               this.lastPageY);
            // figure out how much this thing has moved
            var dx = (this.maintainOffset) ? this.lastPageX - this.initPageX : 0;
            var dy = (this.maintainOffset) ? this.lastPageY - this.initPageY : 0;

            this.setInitPosition(dx, dy);

        // This is the first time we have detected the element's position
        } else {
            this.setInitPosition();
        }

        if (this.constrainX) {
            this.setXConstraint( this.leftConstraint, 
                                 this.rightConstraint, 
                                 this.xTickSize        );
        }

        if (this.constrainY) {
            this.setYConstraint( this.topConstraint, 
                                 this.bottomConstraint, 
                                 this.yTickSize         );
        }
    },

    /**
     * Normally the drag element is moved pixel by pixel, but we can specify 
     * that it move a number of pixels at a time.  This method resolves the 
     * location when we have it set up like this.
     *
     * @param {int} val where we want to place the object
     * @param {int[]} tickArray sorted array of valid points
     * @return {int} the closest tick
     * @private
     */
    getTick: function(val, tickArray) {

        if (!tickArray) {
            // If tick interval is not defined, it is effectively 1 pixel, 
            // so we return the value passed to us.
            return val; 
        } else if (tickArray[0] >= val) {
            // The value is lower than the first tick, so we return the first
            // tick.
            return tickArray[0];
        } else {
            for (var i=0, len=tickArray.length; i<len; ++i) {
                var next = i + 1;
                if (tickArray[next] && tickArray[next] >= val) {
                    var diff1 = val - tickArray[i];
                    var diff2 = tickArray[next] - val;
                    return (diff2 > diff1) ? tickArray[i] : tickArray[next];
                }
            }

            // The value is larger than the last tick, so we return the last
            // tick.
            return tickArray[tickArray.length - 1];
        }
    },

    /**
     * toString method
     * @return {string} string representation of the dd obj
     */
    toString: function() {
        return ("DragDrop " + this.id);
    }

};

// Only load the library once.  Rewriting the manager class would orphan 
// existing drag and drop instances.
if (!YAHOO.util.DragDropMgr) {

    /**
     * Handles the element interaction for all DragDrop items in the 
     * window.  Generally, you will not call this class directly, but it does
     * have helper methods that could be useful in your DragDrop 
     * implementations.  This class should not be instantiated; all methods 
     * are are static.
     *
     * @constructor
     */
    YAHOO.util.DragDropMgr = new function() {

        /**
         * Two dimensional Array of registered DragDrop objects.  The first 
         * dimension is the DragDrop item group, the second the DragDrop 
         * object.
         *
         * @type {string: string}
         * @private
         */
        this.ids = {};

        /**
         * Array of element ids defined as drag handles.  Used to determine 
         * if the element that generated the mousedown event is actually the 
         * handle and not the html element itself.
         *
         * @type {string: string}
         * @private
         */
        this.handleIds = {};

        /**
         * the DragDrop object that is currently being dragged
         *
         * @type DragDrop
         * @private
         **/
        this.dragCurrent = null;

        /**
         * the DragDrop object(s) that are being hovered over
         *
         * @type Array
         * @private
         */
        this.dragOvers = {};

        /**
         * @private
         */
        this.logger = null;

        /**
         * the X distance between the cursor and the object being dragged
         *
         * @type int
         * @private
         */
        this.deltaX = 0;

        /**
         * the Y distance between the cursor and the object being dragged
         *
         * @type int
         * @private
         */
        this.deltaY = 0;

        /**
         * Flag to determine if we should prevent the default behavior of the
         * events we define. By default this is true, but this can be set to 
         * false if you need the default behavior (not recommended)
         *
         * @type boolean
         */
        this.preventDefault = true;

        /**
         * Flag to determine if we should stop the propagation of the events 
         * we generate. This is true by default but you may want to set it to
         * false if the html element contains other features that require the
         * mouse click.
         *
         * @type boolean
         */
        this.stopPropagation = true;

        /**
         * @private
         */
        this.initalized = false;

        /**
         * All drag and drop can be disabled.
         *
         * @private
         */
        this.locked = false;
        
        /**
         * Called the first time an element is registered.
         *
         * @private
         */
        this.init = function() {
            this.logger = (YAHOO.widget.LogWriter) ?
                new YAHOO.widget.LogWriter("DragDropMgr") : YAHOO;
            this.initialized = true;
        };

        /**
         * In point mode, drag and drop interaction is defined by the 
         * location of the cursor during the drag/drop
         * @type int
         */
        this.POINT     = 0;

        /**
         * In intersect mode, drag and drop interactio nis defined by the 
         * overlap of two or more drag and drop objects.
         * @type int
         */
        this.INTERSECT = 1;

        /**
         * The current drag and drop mode.  Default it point mode
         * @type int
         */
        this.mode = this.POINT;

        /**
         * Runs method on all drag and drop objects
         * @private
         */
        this._execOnAll = function(sMethod, args) {
            for (var i in this.ids) {
                for (var j in this.ids[i]) {
                    var oDD = this.ids[i][j];
                    if (! this.isTypeOfDD(oDD)) {
                        continue;
                    }
                    oDD[sMethod].apply(oDD, args);
                }
            }
        };

        /**
         * Drag and drop initialization.  Sets up the global event handlers
         * @private
         */
        this._onLoad = function() {

            this.init();

            this.logger.log("DDM onload");

            var EU = YAHOO.util.Event;

            EU.on(document, "mouseup",   this.handleMouseUp, this, true);
            EU.on(document, "mousemove", this.handleMouseMove, this, true);
            EU.on(window,   "unload",    this._onUnload, this, true);
            EU.on(window,   "resize",    this._onResize, this, true);
            // EU.on(window,   "mouseout",    this._test);

        };

        /**
         * Reset constraints on all drag and drop objs
         * @private
         */
        this._onResize = function(e) {
            this.logger.log("window resize");
            this._execOnAll("resetConstraints", []);
        };

        /**
         * Lock all drag and drop functionality
         */
        this.lock = function() { this.locked = true; };

        /**
         * Unlock all drag and drop functionality
         */
        this.unlock = function() { this.locked = false; };

        /**
         * Is drag and drop locked?
         *
         * @return {boolean} True if drag and drop is locked, false otherwise.
         */
        this.isLocked = function() { return this.locked; };

        /**
         * Location cache that is set for all drag drop objects when a drag is
         * initiated, cleared when the drag is finished.
         *
         * @private
         */
        this.locationCache = {};

        /**
         * Set useCache to false if you want to force object the lookup of each
         * drag and drop linked element constantly during a drag.
         * @type boolean
         */
        this.useCache = true;

        /**
         * The number of pixels that the mouse needs to move after the 
         * mousedown before the drag is initiated.  Default=3;
         * @type int
         */
        this.clickPixelThresh = 3;

        /**
         * The number of milliseconds after the mousedown event to initiate the
         * drag if we don't get a mouseup event. Default=1000
         * @type int
         */
        this.clickTimeThresh = 1000;

        /**
         * Flag that indicates that either the drag pixel threshold or the 
         * mousdown time threshold has been met
         * @type boolean
         * @private
         */
        this.dragThreshMet = false;

        /**
         * Timeout used for the click time threshold
         * @type Object
         * @private
         */
        this.clickTimeout = null;

        /**
         * The X position of the mousedown event stored for later use when a 
         * drag threshold is met.
         * @type int
         * @private
         */
        this.startX = 0;

        /**
         * The Y position of the mousedown event stored for later use when a 
         * drag threshold is met.
         * @type int
         * @private
         */
        this.startY = 0;

        /**
         * Each DragDrop instance must be registered with the DragDropMgr.  
         * This is executed in DragDrop.init()
         *
         * @param {DragDrop} oDD the DragDrop object to register
         * @param {String} sGroup the name of the group this element belongs to
         */
        this.regDragDrop = function(oDD, sGroup) {
            if (!this.initialized) { this.init(); }
            
            if (!this.ids[sGroup]) {
                this.ids[sGroup] = {};
            }
            this.ids[sGroup][oDD.id] = oDD;
        };

        /**
         * Removes the supplied dd instance from the supplied group. Executed
         * by DragDrop.removeFromGroup.
         * @private
         */
        this.removeDDFromGroup = function(oDD, sGroup) {
            if (!this.ids[sGroup]) {
                this.ids[sGroup] = {};
            }

            var obj = this.ids[sGroup];
            if (obj && obj[oDD.id]) {
                delete obj[oDD.id];
            }
        };

        /**
         * Unregisters a drag and drop item.  This is executed in 
         * DragDrop.unreg, use that method instead of calling this directly.
         * @private
         */
        this._remove = function(oDD) {
            for (var g in oDD.groups) {
                if (g && this.ids[g][oDD.id]) {
                    delete this.ids[g][oDD.id];
                }
            }
            delete this.handleIds[oDD.id];
        };

        /**
         * Each DragDrop handle element must be registered.  This is done
         * automatically when executing DragDrop.setHandleElId()
         *
         * @param {String} sDDId the DragDrop id this element is a handle for
         * @param {String} sHandleId the id of the element that is the drag 
         * handle
         */
        this.regHandle = function(sDDId, sHandleId) {
            if (!this.handleIds[sDDId]) {
                this.handleIds[sDDId] = {};
            }
            this.handleIds[sDDId][sHandleId] = sHandleId;
        };

        /**
         * Utility function to determine if a given element has been 
         * registered as a drag drop item.
         *
         * @param {String} id the element id to check
         * @return {boolean} true if this element is a DragDrop item, 
         * false otherwise
         */
        this.isDragDrop = function(id) {
            return ( this.getDDById(id) ) ? true : false;
        };

        /**
         * Returns the drag and drop instances that are in all groups the
         * passed in instance belongs to.
         *
         * @param {DragDrop} p_oDD the obj to get related data for
         * @param {boolean} bTargetsOnly if true, only return targetable objs
         * @return {DragDrop[]} the related instances
         */
        this.getRelated = function(p_oDD, bTargetsOnly) {
            var oDDs = [];
            for (var i in p_oDD.groups) {
                for (j in this.ids[i]) {
                    var dd = this.ids[i][j];
                    if (! this.isTypeOfDD(dd)) {
                        continue;
                    }
                    if (!bTargetsOnly || dd.isTarget) {
                        oDDs[oDDs.length] = dd;
                    }
                }
            }

            return oDDs;
        };

        /**
         * Returns true if the specified dd target is a legal target for 
         * the specifice drag obj
         *
         * @param {DragDrop} the drag obj
         * @param {DragDrop) the target
         * @return {boolean} true if the target is a legal target for the 
         * dd obj
         */
        this.isLegalTarget = function (oDD, oTargetDD) {
            var targets = this.getRelated(oDD, true);
            for (var i=0, len=targets.length;i<len;++i) {
                if (targets[i].id == oTargetDD.id) {
                    return true;
                }
            }

            return false;
        };

        /**
         * My goal is to be able to transparently determine if an object is
         * typeof DragDrop, and the exact subclass of DragDrop.  typeof 
         * returns "object", oDD.constructor.toString() always returns
         * "DragDrop" and not the name of the subclass.  So for now it just
         * evaluates a well-known variable in DragDrop.
         *
         * @param {Object} the object to evaluate
         * @return {boolean} true if typeof oDD = DragDrop
         */
        this.isTypeOfDD = function (oDD) {
            return (oDD && oDD.__ygDragDrop);
        };

        /**
         * Utility function to determine if a given element has been 
         * registered as a drag drop handle for the given Drag Drop object.
         *
         * @param {String} id the element id to check
         * @return {boolean} true if this element is a DragDrop handle, false 
         * otherwise
         */
        this.isHandle = function(sDDId, sHandleId) {
            return ( this.handleIds[sDDId] && 
                            this.handleIds[sDDId][sHandleId] );
        };

        /**
         * Returns the DragDrop instance for a given id
         *
         * @param {String} id the id of the DragDrop object
         * @return {DragDrop} the drag drop object, null if it is not found
         */
        this.getDDById = function(id) {
            for (var i in this.ids) {
                if (this.ids[i][id]) {
                    return this.ids[i][id];
                }
            }
            return null;
        };

        /**
         * Fired after a registered DragDrop object gets the mousedown event.
         * Sets up the events required to track the object being dragged
         *
         * @param {Event} e the event
         * @param oDD the DragDrop object being dragged
         * @private
         */
        this.handleMouseDown = function(e, oDD) {

            this.currentTarget = YAHOO.util.Event.getTarget(e);

            this.logger.log("mousedown - adding event handlers");
            this.dragCurrent = oDD;

            var el = oDD.getEl();

            // track start position
            this.startX = YAHOO.util.Event.getPageX(e);
            this.startY = YAHOO.util.Event.getPageY(e);

            this.deltaX = this.startX - el.offsetLeft;
            this.deltaY = this.startY - el.offsetTop;

            this.dragThreshMet = false;

            this.clickTimeout = setTimeout( 
                    function() { 
                        var DDM = YAHOO.util.DDM;
                        DDM.startDrag(DDM.startX, DDM.startY); 
                    }, 
                    this.clickTimeThresh );
        };

        /**
         * Fired when either the drag pixel threshol or the mousedown hold 
         * time threshold has been met.
         * 
         * @param x {int} the X position of the original mousedown
         * @param y {int} the Y position of the original mousedown
         */
        this.startDrag = function(x, y) {
            this.logger.log("firing drag start events");
            clearTimeout(this.clickTimeout);
            if (this.dragCurrent) {
                this.dragCurrent.b4StartDrag(x, y);
                this.dragCurrent.startDrag(x, y);
            }
            this.dragThreshMet = true;
        };

        /**
         * Internal function to handle the mouseup event.  Will be invoked 
         * from the context of the document.
         *
         * @param {Event} e the event
         * @private
         */
        this.handleMouseUp = function(e) {

            if (! this.dragCurrent) {
                return;
            }

            clearTimeout(this.clickTimeout);

            if (this.dragThreshMet) {
                this.logger.log("mouseup detected - completing drag");
                this.fireEvents(e, true);
            } else {
                this.logger.log("drag threshold not met");
            }

            this.stopDrag(e);

            this.stopEvent(e);
        };

        /**
         * Utility to stop event propagation and event default, if these 
         * features are turned on.
         *
         * @param {Event} e the event as returned by this.getEvent()
         */
        this.stopEvent = function(e) {
            if (this.stopPropagation) {
                YAHOO.util.Event.stopPropagation(e);
            }

            if (this.preventDefault) {
                YAHOO.util.Event.preventDefault(e);
            }
        };

        /** 
         * Internal function to clean up event handlers after the drag 
         * operation is complete
         *
         * @param {Event} e the event
         * @private
         */
        this.stopDrag = function(e) {
            // this.logger.log("mouseup - removing event handlers");

            // Fire the drag end event for the item that was dragged
            if (this.dragCurrent) {
                if (this.dragThreshMet) {
                    this.logger.log("firing endDrag events");
                    this.dragCurrent.b4EndDrag(e);
                    this.dragCurrent.endDrag(e);
                }

                this.logger.log("firing mouseUp event");
                this.dragCurrent.onMouseUp(e);
            }

            this.dragCurrent = null;
            this.dragOvers = {};
        };


        /** 
         * Internal function to handle the mousemove event.  Will be invoked 
         * from the context of the html element.
         *
         * @TODO figure out what we can do about mouse events lost when the 
         * user drags objects beyond the window boundary.  Currently we can 
         * detect this in internet explorer by verifying that the mouse is 
         * down during the mousemove event.  Firefox doesn't give us the 
         * button state on the mousemove event.
         *
         * @param {Event} e the event
         * @private
         */
        this.handleMouseMove = function(e) {
            if (! this.dragCurrent) {
                // this.logger.log("no current drag obj");
                return true;
            }

            // var button = e.which || e.button;
            // this.logger.log("which: " + e.which + ", button: "+ e.button);

            // check for IE mouseup outside of page boundary
            if (YAHOO.util.Event.isIE && !e.button) {
                this.logger.log("button failure");
                this.stopEvent(e);
                return this.handleMouseUp(e);
            }

            if (!this.dragThreshMet) {
                var diffX = Math.abs(this.startX - YAHOO.util.Event.getPageX(e));
                var diffY = Math.abs(this.startY - YAHOO.util.Event.getPageY(e));
                // this.logger.log("diffX: " + diffX + "diffY: " + diffY);
                if (diffX > this.clickPixelThresh || 
                            diffY > this.clickPixelThresh) {
                    this.logger.log("pixel threshold met");
                    this.startDrag(this.startX, this.startY);
                }
            }

            if (this.dragThreshMet) {
                this.dragCurrent.b4Drag(e);
                this.dragCurrent.onDrag(e);
                this.fireEvents(e, false);
            }

            this.stopEvent(e);

            return true;
        };

        /**
         * Iterates over all of the DragDrop elements to find ones we are 
         * hovering over or dropping on
         *
         * @param {Event} e the event
         * @param {boolean} isDrop is this a drop op or a mouseover op?
         * @private
         */
        this.fireEvents = function(e, isDrop) {
            var dc = this.dragCurrent;

            // If the user did the mouse up outside of the window, we could 
            // get here even though we have ended the drag.
            if (!dc || dc.isLocked()) {
                return;
            }

            var x = YAHOO.util.Event.getPageX(e);
            var y = YAHOO.util.Event.getPageY(e);
            var pt = new YAHOO.util.Point(x,y);

            // cache the previous dragOver array
            var oldOvers = [];

            var outEvts   = [];
            var overEvts  = [];
            var dropEvts  = [];
            var enterEvts = [];

            // Check to see if the object(s) we were hovering over is no longer 
            // being hovered over so we can fire the onDragOut event
            for (var i in this.dragOvers) {

                var ddo = this.dragOvers[i];

                if (! this.isTypeOfDD(ddo)) {
                    continue;
                }

                if (! this.isOverTarget(pt, ddo, this.mode)) {
                    outEvts.push( ddo );
                }

                oldOvers[i] = true;
                delete this.dragOvers[i];
            }

            for (var sGroup in dc.groups) {
                // this.logger.log("Processing group " + sGroup);
                
                if ("string" != typeof sGroup) {
                    continue;
                }

                for (i in this.ids[sGroup]) {
                    var oDD = this.ids[sGroup][i];
                    if (! this.isTypeOfDD(oDD)) {
                        continue;
                    }

                    if (oDD.isTarget && !oDD.isLocked() && oDD != dc) {
                        if (this.isOverTarget(pt, oDD, this.mode)) {
                            // look for drop interactions
                            if (isDrop) {
                                dropEvts.push( oDD );
                            // look for drag enter and drag over interactions
                            } else {

                                // initial drag over: dragEnter fires
                                if (!oldOvers[oDD.id]) {
                                    enterEvts.push( oDD );
                                // subsequent drag overs: dragOver fires
                                } else {
                                    overEvts.push( oDD );
                                }

                                this.dragOvers[oDD.id] = oDD;
                            }
                        }
                    }
                }
            }

            if (this.mode) {
                if (outEvts.length) {
                    this.logger.log(dc.id+" onDragOut: " + outEvts);
                    dc.b4DragOut(e, outEvts);
                    dc.onDragOut(e, outEvts);
                }

                if (enterEvts.length) {
                    this.logger.log(dc.id+" onDragEnter: " + enterEvts);
                    dc.onDragEnter(e, enterEvts);
                }

                if (overEvts.length) {
                    this.logger.log(dc.id+" onDragOver: " + overEvts);
                    dc.b4DragOver(e, overEvts);
                    dc.onDragOver(e, overEvts);
                }

                if (dropEvts.length) {
                    this.logger.log(dc.id+" onDragDrop: " + dropEvts);
                    dc.b4DragDrop(e, dropEvts);
                    dc.onDragDrop(e, dropEvts);
                }

            } else {
                // fire dragout events
                var len = 0;
                for (i=0, len=outEvts.length; i<len; ++i) {
                    this.logger.log(dc.id+" onDragOut: " + outEvts[i].id);
                    dc.b4DragOut(e, outEvts[i].id);
                    dc.onDragOut(e, outEvts[i].id);
                }
                 
                // fire enter events
                for (i=0,len=enterEvts.length; i<len; ++i) {
                    this.logger.log(dc.id + " onDragEnter " + enterEvts[i].id);
                    // dc.b4DragEnter(e, oDD.id);
                    dc.onDragEnter(e, enterEvts[i].id);
                }
         
                // fire over events
                for (i=0,len=overEvts.length; i<len; ++i) {
                    this.logger.log(dc.id + " onDragOver " + overEvts[i].id);
                    dc.b4DragOver(e, overEvts[i].id);
                    dc.onDragOver(e, overEvts[i].id);
                }

                // fire drop events
                for (i=0, len=dropEvts.length; i<len; ++i) {
                    this.logger.log(dc.id + " dropped on " + dropEvts[i].id);
                    dc.b4DragDrop(e, dropEvts[i].id);
                    dc.onDragDrop(e, dropEvts[i].id);
                }

            }

        };

        /**
         * Helper function for getting the best match from the list of drag 
         * and drop objects returned by the drag and drop events when we are 
         * in INTERSECT mode.  It returns either the first object that the 
         * cursor is over, or the object that has the greatest overlap with 
         * the dragged element.
         *
         * @param  {DragDrop[]} dds The array of drag and drop objects 
         * targeted
         * @return {DragDrop}       The best single match
         */
        this.getBestMatch = function(dds) {
            var winner = null;
            // Return null if the input is not what we expect
            //if (!dds || !dds.length || dds.length == 0) {
               // winner = null;
            // If there is only one item, it wins
            //} else if (dds.length == 1) {

            var len = dds.length;

            if (len == 1) {
                winner = dds[0];
            } else {
                // Loop through the targeted items
                for (var i=0; i<len; ++i) {
                    var dd = dds[i];
                    // If the cursor is over the object, it wins.  If the 
                    // cursor is over multiple matches, the first one we come
                    // to wins.
                    if (dd.cursorIsOver) {
                        winner = dd;
                        break;
                    // Otherwise the object with the most overlap wins
                    } else {
                        if (!winner || 
                            winner.overlap.getArea() < dd.overlap.getArea()) {
                            winner = dd;
                        }
                    }
                }
            }

            return winner;
        };

        /**
         * Refreshes the cache of the top-left and bottom-right points of the 
         * drag and drop objects in the specified groups
         *
         * @param {Object} groups an associative array of groups to refresh
         */
        this.refreshCache = function(groups) {
            this.logger.log("refreshing element location cache");
            for (sGroup in groups) {
                if ("string" != typeof sGroup) {
                    continue;
                }
                for (i in this.ids[sGroup]) {
                    var oDD = this.ids[sGroup][i];

                    if (this.isTypeOfDD(oDD)) {
                    // if (this.isTypeOfDD(oDD) && oDD.isTarget) {
                        var loc = this.getLocation(oDD);
                        if (loc) {
                            this.locationCache[oDD.id] = loc;
                        } else {
                            delete this.locationCache[oDD.id];
                            this.logger.log("Could not get the loc for " + oDD.id,
                                    "warn");
                            // this will unregister the drag and drop object if
                            // the element is not in a usable state
                            // oDD.unreg();
                        }
                    }
                }
            }
        };

        /**
         * This checks to make sure an element exists and is in the DOM.  The
         * main purpose is to handle cases where innerHTML is used to remove
         * drag and drop objects from the DOM.  IE provides an 'unspecified
         * error' when trying to access the offsetParent of such an element
         * @param {HTMLElement} el the element to check
         * @return {boolean} true if the element looks usable
         */
        this.verifyEl = function(el) {
            try {
                if (el) {
                    var parent = el.offsetParent;
                    if (parent) {
                        return true;
                    }
                }
            } catch(e) {
                this.logger.log("detected problem with an element");
            }

            return false;
        };
        
        /**
         * Returns the an array containing the drag and drop element's position
         * and size, including the DragDrop.padding configured for it
         *
         * @param {DragDrop} oDD the drag and drop object to get the 
         * location for
         * @return array containing the top left and bottom right points of the 
         * element 
         */
        this.getLocation = function(oDD) {
            if (! this.isTypeOfDD(oDD)) {
                this.logger.log(oDD + " is not a DD obj");
                return null;
            }

            var el = oDD.getEl();

            // element will not have an offsetparent if it was removed from the
            // document or display=none
            // if (!this.verifyEl(el)) {
                // this.logger.log(oDD + " element is not usable");
                // return null;
            // }

            // this.logger.log(oDD.id + " padding: " + oDD.padding);

            // var aPos = ygPos.getPos(el);
            var aPos = null;
            try {
                aPos= YAHOO.util.Dom.getXY(el);
            } catch (e) { }

            if (!aPos) {
                return null;
            }

            x1 = aPos[0];
            x2 = x1 + el.offsetWidth;

            y1 = aPos[1];
            y2 = y1 + el.offsetHeight;

            var t = y1 - oDD.padding[0];
            var r = x2 + oDD.padding[1];
            var b = y2 + oDD.padding[2];
            var l = x1 - oDD.padding[3];

            return new YAHOO.util.Region( t, r, b, l );

        };

        /**
         * Checks the cursor location to see if it over the target
         * 
         * @param {YAHOO.util.Point} pt The point to evaluate
         * @param {DragDrop} oTarget the DragDrop object we are inspecting
         * @return {boolean} true if the mouse is over the target
         * @private
         */
        this.isOverTarget = function(pt, oTarget, intersect) {
            // use cache if available
            var loc = this.locationCache[oTarget.id];
            if (!loc || !this.useCache) {
                this.logger.log("cache not populated");
                loc = this.getLocation(oTarget);
                this.locationCache[oTarget.id] = loc;

                this.logger.log("cache: " + loc);
            }

            if (!loc) {
                return false;
            }

            oTarget.cursorIsOver = loc.contains( pt );

            // DragDrop is using this as a sanity check for the initial mousedown
            // in this case we are done.  In POINT mode, if the drag obj has no
            // contraints, we are also done. Otherwise we need to evaluate the 
            // location of the target as related to the actual location of the
            // dragged element.
            var dc = this.dragCurrent;
            if (!dc || (!intersect && !dc.constrainX && !dc.constrainY)) {
                return oTarget.cursorIsOver;
            }

            oTarget.overlap = null;

            // Get the current location of the drag element, this is the
            // location of the mouse event less the delta that represents
            // where the original mousedown happened on the element.  We
            // need to consider constraints and ticks as well.
            var pos = dc.getTargetCoord(pt.x, pt.y);

            var el = dc.getDragEl();
            var curRegion = new YAHOO.util.Region( pos.y, 
                                                   pos.x + el.offsetWidth,
                                                   pos.y + el.offsetHeight, 
                                                   pos.x );

            var overlap = curRegion.intersect(loc);

            if (overlap) {
                oTarget.overlap = overlap;
                return (intersect) ? true : oTarget.cursorIsOver;
            } else {
                return false;
            }
        };

        /**
         * @private
         */
        this._onUnload = function(e, me) {
            this.unregAll();
        };

        /**
         * Cleans up the drag and drop events and objects.
         * @private
         */
        this.unregAll = function() {
            this.logger.log("unregister all");

            if (this.dragCurrent) {
                this.stopDrag();
                this.dragCurrent = null;
            }

            this._execOnAll("unreg", []);

            for (i in this.elementCache) {
                delete this.elementCache[i];
            }

            this.elementCache = {};
            this.ids = {};
        };

        /**
         * A cache of DOM elements
         * @private
         */
        this.elementCache = {};
        
        /**
         * Get the wrapper for the DOM element specified
         *
         * @param {String} id the id of the elment to get
         * @return {YAHOO.util.DDM.ElementWrapper} the wrapped element
         * @private
         * @deprecated
         */
        this.getElWrapper = function(id) {
            var oWrapper = this.elementCache[id];
            if (!oWrapper || !oWrapper.el) {
                oWrapper = this.elementCache[id] = 
                    new this.ElementWrapper(YAHOO.util.Dom.get(id));
            }
            return oWrapper;
        };

        /**
         * Returns the actual DOM element
         *
         * @param {String} id the id of the elment to get
         * @return {Object} The element
         * @deprecated
         */
        this.getElement = function(id) {
            return YAHOO.util.Dom.get(id);
        };
        
        /**
         * Returns the style property for the DOM element (i.e., 
         * document.getElById(id).style)
         *
         * @param {String} id the id of the elment to get
         * @return {Object} The style property of the element
         * @deprecated
         */
        this.getCss = function(id) {
            var el = YAHOO.util.Dom.get(id);
            return (el) ? el.style : null;
        };

        /**
         * Inner class for cached elements
         * @private
         * @deprecated
         */
        this.ElementWrapper = function(el) {
                /**
                 * @private
                 */
                this.el = el || null;
                /**
                 * @private
                 */
                this.id = this.el && el.id;
                /**
                 * @private
                 */
                this.css = this.el && el.style;
            };

        /**
         * Returns the X position of an html element
         * @param el the element for which to get the position
         * @return {int} the X coordinate
         * @deprecated
         */
        this.getPosX = function(el) {
            return YAHOO.util.Dom.getX(el);
        };

        /**
         * Returns the Y position of an html element
         * @param el the element for which to get the position
         * @return {int} the Y coordinate
         * @deprecated
         */
        this.getPosY = function(el) {
            return YAHOO.util.Dom.getY(el); 
        };

        /**
         * Swap two nodes.  In IE, we use the native method, for others we 
         * emulate the IE behavior
         *
         * @param n1 the first node to swap
         * @param n2 the other node to swap
         */
        this.swapNode = function(n1, n2) {
            if (n1.swapNode) {
                n1.swapNode(n2);
            } else {
                // the node reference order for the swap is a little tricky. 
                var p = n2.parentNode;
                var s = n2.nextSibling;
                n1.parentNode.replaceChild(n2, n1);
                p.insertBefore(n1,s);
            }
        };

        /**
         * @private
         */
        this.getScroll = function () {
            var t, l;
            if (document.documentElement && document.documentElement.scrollTop) {
                t = document.documentElement.scrollTop;
                l = document.documentElement.scrollLeft;
            } else if (document.body) {
                t = document.body.scrollTop;
                l = document.body.scrollLeft;
            }
            return { top: t, left: l };
        };

        /**
         * Returns the specified element style property
         * @param {HTMLElement} el          the element
         * @param {string}      styleProp   the style property
         * @return {string} The value of the style property
         * @deprecated, use YAHOO.util.Dom.getStyle
         */
        this.getStyle = function(el, styleProp) {
            return YAHOO.util.Dom.getStyle(el, styleProp);
        };

        /**
         * Gets the scrollTop
         * @return {int} the document's scrollTop
         */
        this.getScrollTop = function () { return this.getScroll().top; };

        /**
         * Gets the scrollLeft
         * @return {int} the document's scrollTop
         */
        this.getScrollLeft = function () { return this.getScroll().left; };

        /**
         * Sets the x/y position of an element to the location of the
         * target element.
         * @param {HTMLElement} moveEl      The element to move
         * @param {HTMLElement} targetEl    The position reference element
         */
        this.moveToEl = function (moveEl, targetEl) {
            var aCoord = YAHOO.util.Dom.getXY(targetEl);
            this.logger.log("moveToEl: " + aCoord);
            YAHOO.util.Dom.setXY(moveEl, aCoord);
        };

        /**
         * Gets the client height
         * @return {int} client height in px
         * @deprecated
         */
        this.getClientHeight = function() {
            return YAHOO.util.Dom.getClientHeight();
        };

        /**
         * Gets the client width
         * @return {int} client width in px
         * @deprecated
         */
        this.getClientWidth = function() {
            return YAHOO.util.Dom.getClientWidth();
        };

        /**
         * numeric array sort function
         */
        this.numericSort = function(a, b) { return (a - b); };

        /**
         * @private
         */
        this._timeoutCount = 0;

        /**
         * Trying to make the load order less important.  Without this we get
         * an error if this file is loaded before the Event Utility.
         * @private
         */
        this._addListeners = function() {
            if ( YAHOO.util.Event && document ) {
                this._onLoad();
            } else {
                if (this._timeoutCount > 1000) {
                    this.logger.log("DragDrop requires the Event Utility");
                } else {
                    var DDM = YAHOO.util.DDM;
                    setTimeout( function() { DDM._addListeners(); }, 10);
                    if (document && document.body) {
                        this._timeoutCount += 1;
                    }
                }
            }
        };

        /**
         * Recursively searches the immediate parent and all child nodes for 
         * the handle element in order to determine wheter or not it was 
         * clicked.
         * @param node the html element to inspect
         */
        this.handleWasClicked = function(node, id) {
            if (this.isHandle(id, node.id)) {
                this.logger.log("clicked node is a handle");
                return true;
            } else {
                // check to see if this is a text node child of the one we want
                var p = node.parentNode;
                // this.logger.log("p: " + p);

                while (p) {
                    if (this.isHandle(id, p.id)) {
                        return true;
                    } else {
                        this.logger.log(p.id + " is not a handle");
                        p = p.parentNode;
                    }
                }
            }

            return false;
        };

    } ();

    // shorter alias, save a few bytes
    YAHOO.util.DDM = YAHOO.util.DragDropMgr;
    YAHOO.util.DDM._addListeners();

}

/**
 * A DragDrop implementation where the linked element follows the 
 * mouse cursor during a drag.
 *
 * @extends YAHOO.util.DragDrop
 * @constructor
 * @param {String} id the id of the linked element 
 * @param {String} sGroup the group of related DragDrop items
 * @param {object} config an object containing configurable attributes
 *                Valid properties for DD: 
 *                    scroll
 */
YAHOO.util.DD = function(id, sGroup, config) {
    if (id) {
        this.init(id, sGroup, config);
    }
};

// YAHOO.util.DD.prototype = new YAHOO.util.DragDrop();
YAHOO.extend(YAHOO.util.DD, YAHOO.util.DragDrop);

/**
 * When set to true, the utility automatically tries to scroll the browser
 * window wehn a drag and drop element is dragged near the viewport boundary.
 * Defaults to true.
 *
 * @type boolean
 */
YAHOO.util.DD.prototype.scroll = true; 

/**
 * Sets the pointer offset to the distance between the linked element's top 
 * left corner and the location the element was clicked
 *
 * @param {int} iPageX the X coordinate of the click
 * @param {int} iPageY the Y coordinate of the click
 */
YAHOO.util.DD.prototype.autoOffset = function(iPageX, iPageY) {
    // var el = this.getEl();
    // var aCoord = YAHOO.util.Dom.getXY(el);
    // var x = iPageX - aCoord[0];
    // var y = iPageY - aCoord[1];
   var x = iPageX - this.startPageX;
   var y = iPageY - this.startPageY;
   this.setDelta(x, y);
    // this.logger.log("autoOffset el pos: " + aCoord + ", delta: " + x + "," + y);
};

/** 
 * Sets the pointer offset.  You can call this directly to force the offset to
 * be in a particular location (e.g., pass in 0,0 to set it to the center of the
 * object, as done in YAHOO.widget.Slider)
 *
 * @param {int} iDeltaX the distance from the left
 * @param {int} iDeltaY the distance from the top
 */
YAHOO.util.DD.prototype.setDelta = function(iDeltaX, iDeltaY) {
    this.deltaX = iDeltaX;
    this.deltaY = iDeltaY;
    this.logger.log("deltaX:" + this.deltaX + ", deltaY:" + this.deltaY);
};

/**
 * Sets the drag element to the location of the mousedown or click event, 
 * maintaining the cursor location relative to the location on the element 
 * that was clicked.  Override this if you want to place the element in a 
 * location other than where the cursor is.
 *
 * @param {int} iPageX the X coordinate of the mousedown or drag event
 * @param {int} iPageY the Y coordinate of the mousedown or drag event
 */

YAHOO.util.DD.prototype.setDragElPos = function(iPageX, iPageY) {
    // the first time we do this, we are going to check to make sure
    // the element has css positioning

    var el = this.getDragEl();

    // if (!this.cssVerified) {
        // var pos = el.style.position;
        // this.logger.log("drag element position: " + pos);
    // }

    this.alignElWithMouse(el, iPageX, iPageY);
};

/**
 * Sets the element to the location of the mousedown or click event, 
 * maintaining the cursor location relative to the location on the element 
 * that was clicked.  Override this if you want to place the element in a 
 * location other than where the cursor is.
 *
 * @param {HTMLElement} el the element to move
 * @param {int} iPageX the X coordinate of the mousedown or drag event
 * @param {int} iPageY the Y coordinate of the mousedown or drag event
 */
YAHOO.util.DD.prototype.alignElWithMouse = function(el, iPageX, iPageY) {
    //if(document.getElementById("iconZoomInSka").src.indexOf("res/btnZoomInSka_s.gif") < 0){
    	// alte methode von Yahoo beginn
    	var oCoord = this.getTargetCoord(iPageX, iPageY);
    	this.logger.log("****alignElWithMouse : " + el.id + ", " + aCoord + ", " + el.style.display);

    	this.deltaSetXY = null;
    	if (!this.deltaSetXY) {
    	    var aCoord = [oCoord.x, oCoord.y];
    	    YAHOO.util.Dom.setXY(el, aCoord);
    	    var newLeft = parseInt( YAHOO.util.Dom.getStyle(el, "left"), 10 );
    	    var newTop  = parseInt( YAHOO.util.Dom.getStyle(el, "top" ), 10 );
    	    this.deltaSetXY = [ newLeft - oCoord.x, newTop - oCoord.y ];
    	    var _left = oCoord.x + this.deltaSetXY[0];
    	    if(_scale == "no"){
    	    	if(_left <= -52){
    	    		YAHOO.util.Dom.setStyle(el, "left", "-52px");
    	    		YAHOO.util.Dom.setStyle(el, "height",  "3px");
    	    		YAHOO.util.Dom.setStyle(el, "top",  "12px");	
    	    	}
				else if(_left >= 52){
					YAHOO.util.Dom.setStyle(el, "left", "52px");
					YAHOO.util.Dom.setStyle(el, "height",  "27px");
					YAHOO.util.Dom.setStyle(el, "top",  "-12px");
				}
				else{
					YAHOO.util.Dom.setStyle(el, "left", (oCoord.x + this.deltaSetXY[0]) + "px");
					var h = 52-(35-(oCoord.x + this.deltaSetXY[0])*(27/112));
					YAHOO.util.Dom.setStyle(el, "height",  h+"px");
        			YAHOO.util.Dom.setStyle(el, "top",  (16-h)+"px");
        		}
        		YAHOO.util.Dom.setStyle(el, "width",  "8px");
         		document.getElementById("iconZoom_move").onmouseup = zoom_up;
    	    }
         //this.logger.log("css X: " + YAHOO.util.Dom.getStyle(el, "left"));
         //this.logger.log("css Y: " + YAHOO.util.Dom.getStyle(el, "top"));
         //this.logger.log("deltaSetXY: " + this.deltaSetXY);
   		}
   		else {
        	YAHOO.util.Dom.setStyle(el, "left", (oCoord.x + this.deltaSetXY[0]) + "px");
        	YAHOO.util.Dom.setStyle(el, "top",  "0px");
        }
    	//this.cachePosition(oCoord.x, oCoord.y);
    	//this.autoScroll(oCoord.x, oCoord.y, el.offsetHeight, el.offsetWidth);
		// alte methode von yahoo ende	
    //}
	//else{
	//	YAHOO.util.Dom.setStyle(el, "left", "0px");
    //	YAHOO.util.Dom.setStyle(el, "top", "0px");
	//}
};

/**
 * Saves the most recent position so that we can reset the constraints and
 * tick marks on-demand.  We need to know this so that we can calculate the
 * number of pixels the element is offset from its original position.
 */
YAHOO.util.DD.prototype.cachePosition = function(iPageX, iPageY) {
    if (iPageX) {
        this.lastPageX = iPageX;
        this.lastPageY = iPageY;
    } else {
        var aCoord = YAHOO.util.Dom.getXY(this.getEl());
        this.lastPageX = aCoord[0];
        this.lastPageY = aCoord[1];
    }
};

/**
 * Auto-scroll the window if the dragged object has been moved beyond the 
 * visible window boundary.
 *
 * @param {int} x the drag element's x position
 * @param {int} y the drag element's y position
 * @param {int} h the height of the drag element
 * @param {int} w the width of the drag element
 * @private
 */
YAHOO.util.DD.prototype.autoScroll = function(x, y, h, w) {

    if (this.scroll) {
        // The client height
        var clientH = this.DDM.getClientHeight();

        // The client width
        var clientW = this.DDM.getClientWidth();

        // The amt scrolled down
        var st = this.DDM.getScrollTop();

        // The amt scrolled right
        var sl = this.DDM.getScrollLeft();

        // Location of the bottom of the element
        var bot = h + y;

        // Location of the right of the element
        var right = w + x;

        // The distance from the cursor to the bottom of the visible area, 
        // adjusted so that we don't scroll if the cursor is beyond the
        // element drag constraints
        var toBot = (clientH + st - y - this.deltaY);

        // The distance from the cursor to the right of the visible area
        var toRight = (clientW + sl - x - this.deltaX);

        // this.logger.log( " x: " + x + " y: " + y + " h: " + h + 
        // " clientH: " + clientH + " clientW: " + clientW + 
        // " st: " + st + " sl: " + sl + " bot: " + bot + 
        // " right: " + right + " toBot: " + toBot + " toRight: " + toRight);

        // How close to the edge the cursor must be before we scroll
        // var thresh = (document.all) ? 100 : 40;
        var thresh = 40;

        // How many pixels to scroll per autoscroll op.  This helps to reduce 
        // clunky scrolling. IE is more sensitive about this ... it needs this 
        // value to be higher.
        var scrAmt = (document.all) ? 80 : 30;

        // Scroll down if we are near the bottom of the visible page and the 
        // obj extends below the crease
        if ( bot > clientH && toBot < thresh ) { 
            window.scrollTo(sl, st + scrAmt); 
        }

        // Scroll up if the window is scrolled down and the top of the object
        // goes above the top border
        if ( y < st && st > 0 && y - st < thresh ) { 
            window.scrollTo(sl, st - scrAmt); 
        }

        // Scroll right if the obj is beyond the right border and the cursor is
        // near the border.
        if ( right > clientW && toRight < thresh ) { 
            window.scrollTo(sl + scrAmt, st); 
        }

        // Scroll left if the window has been scrolled to the right and the obj
        // extends past the left border
        if ( x < sl && sl > 0 && x - sl < thresh ) { 
            window.scrollTo(sl - scrAmt, st);
        }
    }
};

/**
 * Finds the location the element should be placed if we want to move
 * it to where the mouse location less the click offset would place us.
 *
 * @param {int} iPageX the X coordinate of the click
 * @param {int} iPageY the Y coordinate of the click
 * @return an object that contains the coordinates (Object.x and Object.y)
 * @private
 */
YAHOO.util.DD.prototype.getTargetCoord = function(iPageX, iPageY) {

    // this.logger.log("getTargetCoord: " + iPageX + ", " + iPageY);

    var x = iPageX - this.deltaX;
    var y = iPageY - this.deltaY;

    if (this.constrainX) {
        if (x < this.minX) { x = this.minX; }
        if (x > this.maxX) { x = this.maxX; }
    }

    if (this.constrainY) {
        if (y < this.minY) { y = this.minY; }
        if (y > this.maxY) { y = this.maxY; }
    }

    x = this.getTick(x, this.xTicks);
    y = this.getTick(y, this.yTicks);

    // this.logger.log("getTargetCoord " + 
            // " iPageX: " + iPageX +
            // " iPageY: " + iPageY +
            // " x: " + x + ", y: " + y);

    return {x:x, y:y};
};

YAHOO.util.DD.prototype.applyConfig = function() {
    YAHOO.util.DD.superclass.applyConfig.call(this);
    this.scroll = (this.config.scroll !== false);
};

/** 
 * Event that fires prior to the onMouseDown event.  Overrides 
 * YAHOO.util.DragDrop.
 */
YAHOO.util.DD.prototype.b4MouseDown = function(e) {
    // this.resetConstraints();
    this.autoOffset(YAHOO.util.Event.getPageX(e), 
                        YAHOO.util.Event.getPageY(e));
};

/** 
 * Event that fires prior to the onDrag event.  Overrides 
 * YAHOO.util.DragDrop.
 */
YAHOO.util.DD.prototype.b4Drag = function(e) {
    this.setDragElPos(YAHOO.util.Event.getPageX(e), 
                        YAHOO.util.Event.getPageY(e));
};

YAHOO.util.DD.prototype.toString = function() {
    return ("DD " + this.id);
};

///////////////////////////////////////////////////////////////////////////////
// Debugging ygDragDrop events that can be overridden
///////////////////////////////////////////////////////////////////////////////
/*
YAHOO.util.DD.prototype.startDrag = function(x, y) {
    this.logger.log(this.id.toString()  + " startDrag");
};

YAHOO.util.DD.prototype.onDrag = function(e) {
    this.logger.log(this.id.toString() + " onDrag");
};

YAHOO.util.DD.prototype.onDragEnter = function(e, id) {
    this.logger.log(this.id.toString() + " onDragEnter: " + id);
};

YAHOO.util.DD.prototype.onDragOver = function(e, id) {
    this.logger.log(this.id.toString() + " onDragOver: " + id);
};

YAHOO.util.DD.prototype.onDragOut = function(e, id) {
    this.logger.log(this.id.toString() + " onDragOut: " + id);
};

YAHOO.util.DD.prototype.onDragDrop = function(e, id) {
    this.logger.log(this.id.toString() + " onDragDrop: " + id);
};

YAHOO.util.DD.prototype.endDrag = function(e) {
    this.logger.log(this.id.toString() + " endDrag");
};
*/

/**
 * A DragDrop implementation that inserts an empty, bordered div into
 * the document that follows the cursor during drag operations.  At the time of
 * the click, the frame div is resized to the dimensions of the linked html
 * element, and moved to the exact location of the linked element.
 *
 * References to the "frame" element refer to the single proxy element that
 * was created to be dragged in place of all DDProxy elements on the
 * page.
 *
 * @extends YAHOO.util.DD
 * @constructor
 * @param {String} id the id of the linked html element
 * @param {String} sGroup the group of related DragDrop objects
 * @param {object} config an object containing configurable attributes
 *                Valid properties for DDProxy in addition to those in DragDrop: 
 *                   resizeFrame, centerFrame, dragElId
 */
YAHOO.util.DDProxy = function(id, sGroup, config) {
    if (id) {
        this.init(id, sGroup, config);
        this.initFrame(); 
    }
};

YAHOO.extend(YAHOO.util.DDProxy, YAHOO.util.DD);

/**
 * The default drag frame div id
 * @type String
 */
YAHOO.util.DDProxy.dragElId = "ygddfdiv";

/**
 * By default we resize the drag frame to be the same size as the element
 * we want to drag (this is to get the frame effect).  We can turn it off
 * if we want a different behavior.
 *
 * @type boolean
 */
YAHOO.util.DDProxy.prototype.resizeFrame = true;

/**
 * By default the frame is positioned exactly where the drag element is, so
 * we use the cursor offset provided by YAHOO.util.DD.  Another option that works only if
 * you do not have constraints on the obj is to have the drag frame centered
 * around the cursor.  Set centerFrame to true for this effect.
 *
 * @type boolean
 */
YAHOO.util.DDProxy.prototype.centerFrame = false;

/**
 * Create the drag frame if needed
 */
YAHOO.util.DDProxy.prototype.createFrame = function() {
    var self = this;
    var body = document.body;

    if (!body || !body.firstChild) {
        setTimeout( function() { self.createFrame(); }, 50 );
        return;
    }

    var div = this.getDragEl();

    if (!div) {
        div    = document.createElement("div");
        div.id = this.dragElId;
        var s  = div.style;

        s.position   = "absolute";
        s.visibility = "hidden";
        s.cursor     = "url(res/openhand.cur)";
        s.border     = "2px solid #aaa";
        s.zIndex     = 999;

        // appendChild can blow up IE if invoked prior to the window load event
        // while rendering a table.  It is possible there are other scenarios 
        // that would cause this to happen as well.
        body.insertBefore(div, body.firstChild);
    }
};

/**
 * Initialization for the drag frame element.  Must be called in the
 * constructor of all subclasses
 */
YAHOO.util.DDProxy.prototype.initFrame = function() {
    // YAHOO.util.DDProxy.createFrame();
    // this.setDragElId(YAHOO.util.DDProxy.dragElId);

    this.createFrame();

};

YAHOO.util.DDProxy.prototype.applyConfig = function() {
    this.logger.log("DDProxy applyConfig");
    YAHOO.util.DDProxy.superclass.applyConfig.call(this);

    this.resizeFrame = (this.config.resizeFrame !== false);
    this.centerFrame = (this.config.centerFrame);
    this.setDragElId(this.config.dragElId || YAHOO.util.DDProxy.dragElId);

    //this.logger.log("dragElId: " + this.dragElId);
};

/**
 * Resizes the drag frame to the dimensions of the clicked object, positions 
 * it over the object, and finally displays it
 *
 * @param {int} iPageX X click position
 * @param {int} iPageY Y click position
 * @private
 */
YAHOO.util.DDProxy.prototype.showFrame = function(iPageX, iPageY) {
    var el = this.getEl();
    var dragEl = this.getDragEl();
    var s = dragEl.style;

    this._resizeProxy();

    if (this.centerFrame) {
        this.setDelta( Math.round(parseInt(s.width,  10)/2), 
                       Math.round(parseInt(s.height, 10)/2) );
    }

    this.setDragElPos(iPageX, iPageY);

    YAHOO.util.Dom.setStyle(dragEl, "visibility", "visible"); 
};

YAHOO.util.DDProxy.prototype._resizeProxy = function() {
    var DOM    = YAHOO.util.Dom;
    var el     = this.getEl();
    var dragEl = this.getDragEl();

    if (this.resizeFrame) {
        var bt = parseInt( DOM.getStyle(dragEl, "borderTopWidth"    ), 10);
        var br = parseInt( DOM.getStyle(dragEl, "borderRightWidth"  ), 10);
        var bb = parseInt( DOM.getStyle(dragEl, "borderBottomWidth" ), 10);
        var bl = parseInt( DOM.getStyle(dragEl, "borderLeftWidth"   ), 10);

        if (isNaN(bt)) { bt = 0; }
        if (isNaN(br)) { br = 0; }
        if (isNaN(bb)) { bb = 0; }
        if (isNaN(bl)) { bl = 0; }

        this.logger.log("proxy size: " + bt + "  " + br + " " + bb + " " + bl);

        var newWidth  = el.offsetWidth - br - bl;
        var newHeight = el.offsetHeight - bt - bb;

        this.logger.log("Resizing proxy element");

        DOM.setStyle( dragEl, "width",  newWidth  + "px" );
        DOM.setStyle( dragEl, "height", newHeight + "px" );
    }
};

// overrides YAHOO.util.DragDrop
YAHOO.util.DDProxy.prototype.b4MouseDown = function(e) {
    var x = YAHOO.util.Event.getPageX(e);
    var y = YAHOO.util.Event.getPageY(e);
    this.autoOffset(x, y);
    this.setDragElPos(x, y);
};

// overrides YAHOO.util.DragDrop
YAHOO.util.DDProxy.prototype.b4StartDrag = function(x, y) {
    // show the drag frame
    this.logger.log("start drag show frame, x: " + x + ", y: " + y);
    this.showFrame(x, y);
};

// overrides YAHOO.util.DragDrop
YAHOO.util.DDProxy.prototype.b4EndDrag = function(e) {
    this.logger.log(this.id + " b4EndDrag");
    YAHOO.util.Dom.setStyle(this.getDragEl(), "visibility", "hidden"); 
};

// overrides YAHOO.util.DragDrop
// By default we try to move the element to the last location of the frame.  
// This is so that the default behavior mirrors that of YAHOO.util.DD.  
YAHOO.util.DDProxy.prototype.endDrag = function(e) {
    var DOM = YAHOO.util.Dom;
    this.logger.log(this.id + " endDrag");
    var lel = this.getEl();
    var del = this.getDragEl();

    // Show the drag frame briefly so we can get its position
    // del.style.visibility = "";
    DOM.setStyle(del, "visibility", ""); 

    // Hide the linked element before the move to get around a Safari 
    // rendering bug.
    //lel.style.visibility = "hidden";
    DOM.setStyle(lel, "visibility", "hidden"); 
    YAHOO.util.DDM.moveToEl(lel, del);
    //del.style.visibility = "hidden";
    DOM.setStyle(del, "visibility", "hidden"); 
    //lel.style.visibility = "";
    DOM.setStyle(lel, "visibility", ""); 
};

YAHOO.util.DDProxy.prototype.toString = function() {
    return ("DDProxy " + this.id);
};

/**
 * A DragDrop implementation that does not move, but can be a drop 
 * target.  You would get the same result by simply omitting implementation 
 * for the event callbacks, but this way we reduce the processing cost of the 
 * event listener and the callbacks.
 *
 * @extends YAHOO.util.DragDrop 
 * @constructor
 * @param {String} id the id of the element that is a drop target
 * @param {String} sGroup the group of related DragDrop objects
 * @param {object} config an object containing configurable attributes
 *                Valid properties for DDTarget in addition to those in DragDrop: 
 *                  none
 */
 
YAHOO.util.DDTarget = function(id, sGroup, config) {
    if (id) {
        this.initTarget(id, sGroup, config);
    }
};

// YAHOO.util.DDTarget.prototype = new YAHOO.util.DragDrop();
YAHOO.extend(YAHOO.util.DDTarget, YAHOO.util.DragDrop);

YAHOO.util.DDTarget.prototype.toString = function() {
    return ("DDTarget " + this.id);
};


/* Copyright (c) 2006 Yahoo! Inc. All rights reserved. */

/**
 * @extends YAHOO.util.DragDrop
 * @constructor
 * @param {String} handle the id of the element that will cause the resize
 * @param {String} panel id of the element to resize
 * @param {String} sGroup the group of related DragDrop items
 */
YAHOO.example.DDResize = function(panelElId, handleElId, sGroup, config) {
    if (panelElId) {
        this.init(panelElId, sGroup, config);
        this.handleElId = handleElId;
        this.setHandleElId(handleElId);
        this.logger = this.logger || YAHOO;
    }
};

YAHOO.extend(YAHOO.example.DDResize, YAHOO.util.DragDrop);

YAHOO.example.DDResize.prototype.onMouseDown = function (e) {
    var panel = this.getEl();
    this.startWidth = panel.offsetWidth;
    this.startHeight = panel.offsetHeight;

    this.startPos = [YAHOO.util.Event.getPageX(e),
                     YAHOO.util.Event.getPageY(e)];
};

YAHOO.example.DDResize.prototype.onDrag = function(e) {
    var newPos = [YAHOO.util.Event.getPageX(e),
                  YAHOO.util.Event.getPageY(e)];

    var offsetX = newPos[0] - this.startPos[0];
    var offsetY = newPos[1] - this.startPos[1];

    var newWidth = Math.max(this.startWidth + offsetX, 10);
    var newHeight = Math.max(this.startHeight + offsetY, 10);

    var panel = this.getEl();
    panel.style.width = newWidth + "px";
    panel.style.height = newHeight + "px";
};

/* This notice must be untouched at all times.

wz_jsgraphics.js    v. 2.36
The latest version is available at
http://www.walterzorn.com
or http://www.devira.com
or http://www.walterzorn.de

Copyright (c) 2002-2004 Walter Zorn. All rights reserved.
Created 3. 11. 2002 by Walter Zorn (Web: http://www.walterzorn.com )
Last modified: 21. 6. 2006

Performance optimizations for Internet Explorer
by Thomas Frank and John Holdsworth.
fillPolygon method implemented by Matthieu Haller.

High Performance JavaScript Graphics Library.
Provides methods
- to draw lines, rectangles, ellipses, polygons
	with specifiable line thickness,
- to fill rectangles and ellipses
- to draw text.
NOTE: Operations, functions and branching have rather been optimized
to efficiency and speed than to shortness of source code.

LICENSE: LGPL

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License (LGPL) as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Lesser General Public License for more details.

You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA,
or see http://www.gnu.org/copyleft/lesser.html
*/


var jg_ihtm, jg_ie, jg_fast, jg_dom, jg_moz,
jg_n4 = (document.layers && typeof document.classes != "undefined");


function chkDHTM(x, i)
{
	x = document.body || null;
	jg_ie = x && typeof x.insertAdjacentHTML != "undefined";
	jg_dom = (x && !jg_ie &&
		typeof x.appendChild != "undefined" &&
		typeof document.createRange != "undefined" &&
		typeof (i = document.createRange()).setStartBefore != "undefined" &&
		typeof i.createContextualFragment != "undefined");
	jg_ihtm = !jg_ie && !jg_dom && x && typeof x.innerHTML != "undefined";
	jg_fast = jg_ie && document.all && !window.opera;
	jg_moz = jg_dom && typeof x.style.MozOpacity != "undefined";
}


function pntDoc()
{
	this.wnd.document.write(jg_fast? this.htmRpc() : this.htm);
	this.htm = '';
}


function pntCnvDom()
{
	var x = this.wnd.document.createRange();
	x.setStartBefore(this.cnv);
	x = x.createContextualFragment(jg_fast? this.htmRpc() : this.htm);
	if(this.cnv) this.cnv.appendChild(x);
	this.htm = '';
}


function pntCnvIe()
{
	if(this.cnv) this.cnv.insertAdjacentHTML("BeforeEnd", jg_fast? this.htmRpc() : this.htm);
	this.htm = '';
}


function pntCnvIhtm()
{
	if(this.cnv) this.cnv.innerHTML += this.htm;
	this.htm = '';
}


function pntCnv()
{
	this.htm = '';
}


function mkDiv(x, y, w, h)
{
	this.htm += '<div style="position:absolute;'+
		'left:' + x + 'px;'+
		'top:' + y + 'px;'+
		'width:' + w + 'px;'+
		'height:' + h + 'px;'+
		'clip:rect(0,'+w+'px,'+h+'px,0);'+
		'background-color:' + this.color +
		(!jg_moz? ';overflow:hidden' : '')+
		';"><\/div>';
}


function mkDivIe(x, y, w, h)
{
	this.htm += '%%'+this.color+';'+x+';'+y+';'+w+';'+h+';';
}


function mkDivPrt(x, y, w, h)
{
	this.htm += '<div style="position:absolute;'+
		'border-left:' + w + 'px solid ' + this.color + ';'+
		'left:' + x + 'px;'+
		'top:' + y + 'px;'+
		'width:0px;'+
		'height:' + h + 'px;'+
		'clip:rect(0,'+w+'px,'+h+'px,0);'+
		'background-color:' + this.color +
		(!jg_moz? ';overflow:hidden' : '')+
		';"><\/div>';
}


function mkLyr(x, y, w, h)
{
	this.htm += '<layer '+
		'left="' + x + '" '+
		'top="' + y + '" '+
		'width="' + w + '" '+
		'height="' + h + '" '+
		'bgcolor="' + this.color + '"><\/layer>\n';
}


var regex =  /%%([^;]+);([^;]+);([^;]+);([^;]+);([^;]+);/g;
function htmRpc()
{
	return this.htm.replace(
		regex,
		'<div style="overflow:hidden;position:absolute;background-color:'+
		'$1;left:$2;top:$3;width:$4;height:$5"></div>\n');
}


function htmPrtRpc()
{
	return this.htm.replace(
		regex,
		'<div style="overflow:hidden;position:absolute;background-color:'+
		'$1;left:$2;top:$3;width:$4;height:$5;border-left:$4px solid $1"></div>\n');
}


function mkLin(x1, y1, x2, y2)
{
	if (x1 > x2)
	{
		var _x2 = x2;
		var _y2 = y2;
		x2 = x1;
		y2 = y1;
		x1 = _x2;
		y1 = _y2;
	}
	var dx = x2-x1, dy = Math.abs(y2-y1),
	x = x1, y = y1,
	yIncr = (y1 > y2)? -1 : 1;

	if (dx >= dy)
	{
		var pr = dy<<1,
		pru = pr - (dx<<1),
		p = pr-dx,
		ox = x;
		while ((dx--) > 0)
		{
			++x;
			if (p > 0)
			{
				this.mkDiv(ox, y, x-ox, 1);
				y += yIncr;
				p += pru;
				ox = x;
			}
			else p += pr;
		}
		this.mkDiv(ox, y, x2-ox+1, 1);
	}

	else
	{
		var pr = dx<<1,
		pru = pr - (dy<<1),
		p = pr-dy,
		oy = y;
		if (y2 <= y1)
		{
			while ((dy--) > 0)
			{
				if (p > 0)
				{
					this.mkDiv(x++, y, 1, oy-y+1);
					y += yIncr;
					p += pru;
					oy = y;
				}
				else
				{
					y += yIncr;
					p += pr;
				}
			}
			this.mkDiv(x2, y2, 1, oy-y2+1);
		}
		else
		{
			while ((dy--) > 0)
			{
				y += yIncr;
				if (p > 0)
				{
					this.mkDiv(x++, oy, 1, y-oy);
					p += pru;
					oy = y;
				}
				else p += pr;
			}
			this.mkDiv(x2, oy, 1, y2-oy+1);
		}
	}
}


function mkLin2D(x1, y1, x2, y2)
{
	if (x1 > x2)
	{
		var _x2 = x2;
		var _y2 = y2;
		x2 = x1;
		y2 = y1;
		x1 = _x2;
		y1 = _y2;
	}
	var dx = x2-x1, dy = Math.abs(y2-y1),
	x = x1, y = y1,
	yIncr = (y1 > y2)? -1 : 1;

	var s = this.stroke;
	if (dx >= dy)
	{
		if (dx > 0 && s-3 > 0)
		{
			var _s = (s*dx*Math.sqrt(1+dy*dy/(dx*dx))-dx-(s>>1)*dy) / dx;
			_s = (!(s-4)? Math.ceil(_s) : Math.round(_s)) + 1;
		}
		else var _s = s;
		var ad = Math.ceil(s/2);

		var pr = dy<<1,
		pru = pr - (dx<<1),
		p = pr-dx,
		ox = x;
		while ((dx--) > 0)
		{
			++x;
			if (p > 0)
			{
				this.mkDiv(ox, y, x-ox+ad, _s);
				y += yIncr;
				p += pru;
				ox = x;
			}
			else p += pr;
		}
		this.mkDiv(ox, y, x2-ox+ad+1, _s);
	}

	else
	{
		if (s-3 > 0)
		{
			var _s = (s*dy*Math.sqrt(1+dx*dx/(dy*dy))-(s>>1)*dx-dy) / dy;
			_s = (!(s-4)? Math.ceil(_s) : Math.round(_s)) + 1;
		}
		else var _s = s;
		var ad = Math.round(s/2);

		var pr = dx<<1,
		pru = pr - (dy<<1),
		p = pr-dy,
		oy = y;
		if (y2 <= y1)
		{
			++ad;
			while ((dy--) > 0)
			{
				if (p > 0)
				{
					this.mkDiv(x++, y, _s, oy-y+ad);
					y += yIncr;
					p += pru;
					oy = y;
				}
				else
				{
					y += yIncr;
					p += pr;
				}
			}
			this.mkDiv(x2, y2, _s, oy-y2+ad);
		}
		else
		{
			while ((dy--) > 0)
			{
				y += yIncr;
				if (p > 0)
				{
					this.mkDiv(x++, oy, _s, y-oy+ad);
					p += pru;
					oy = y;
				}
				else p += pr;
			}
			this.mkDiv(x2, oy, _s, y2-oy+ad+1);
		}
	}
}


function mkLinDott(x1, y1, x2, y2)
{
	if (x1 > x2)
	{
		var _x2 = x2;
		var _y2 = y2;
		x2 = x1;
		y2 = y1;
		x1 = _x2;
		y1 = _y2;
	}
	var dx = x2-x1, dy = Math.abs(y2-y1),
	x = x1, y = y1,
	yIncr = (y1 > y2)? -1 : 1,
	drw = true;
	if (dx >= dy)
	{
		var pr = dy<<1,
		pru = pr - (dx<<1),
		p = pr-dx;
		while ((dx--) > 0)
		{
			if (drw) this.mkDiv(x, y, 1, 1);
			drw = !drw;
			if (p > 0)
			{
				y += yIncr;
				p += pru;
			}
			else p += pr;
			++x;
		}
		if (drw) this.mkDiv(x, y, 1, 1);
	}

	else
	{
		var pr = dx<<1,
		pru = pr - (dy<<1),
		p = pr-dy;
		while ((dy--) > 0)
		{
			if (drw) this.mkDiv(x, y, 1, 1);
			drw = !drw;
			y += yIncr;
			if (p > 0)
			{
				++x;
				p += pru;
			}
			else p += pr;
		}
		if (drw) this.mkDiv(x, y, 1, 1);
	}
}


function mkOv(left, top, width, height)
{
	var a = width>>1, b = height>>1,
	wod = width&1, hod = (height&1)+1,
	cx = left+a, cy = top+b,
	x = 0, y = b,
	ox = 0, oy = b,
	aa = (a*a)<<1, bb = (b*b)<<1,
	st = (aa>>1)*(1-(b<<1)) + bb,
	tt = (bb>>1) - aa*((b<<1)-1),
	w, h;
	while (y > 0)
	{
		if (st < 0)
		{
			st += bb*((x<<1)+3);
			tt += (bb<<1)*(++x);
		}
		else if (tt < 0)
		{
			st += bb*((x<<1)+3) - (aa<<1)*(y-1);
			tt += (bb<<1)*(++x) - aa*(((y--)<<1)-3);
			w = x-ox;
			h = oy-y;
			if (w&2 && h&2)
			{
				this.mkOvQds(cx, cy, -x+2, ox+wod, -oy, oy-1+hod, 1, 1);
				this.mkOvQds(cx, cy, -x+1, x-1+wod, -y-1, y+hod, 1, 1);
			}
			else this.mkOvQds(cx, cy, -x+1, ox+wod, -oy, oy-h+hod, w, h);
			ox = x;
			oy = y;
		}
		else
		{
			tt -= aa*((y<<1)-3);
			st -= (aa<<1)*(--y);
		}
	}
	this.mkDiv(cx-a, cy-oy, a-ox+1, (oy<<1)+hod);
	this.mkDiv(cx+ox+wod, cy-oy, a-ox+1, (oy<<1)+hod);
}


function mkOv2D(left, top, width, height)
{
	var s = this.stroke;
	width += s-1;
	height += s-1;
	var a = width>>1, b = height>>1,
	wod = width&1, hod = (height&1)+1,
	cx = left+a, cy = top+b,
	x = 0, y = b,
	aa = (a*a)<<1, bb = (b*b)<<1,
	st = (aa>>1)*(1-(b<<1)) + bb,
	tt = (bb>>1) - aa*((b<<1)-1);

	if (s-4 < 0 && (!(s-2) || width-51 > 0 && height-51 > 0))
	{
		var ox = 0, oy = b,
		w, h,
		pxl, pxr, pxt, pxb, pxw;
		while (y > 0)
		{
			if (st < 0)
			{
				st += bb*((x<<1)+3);
				tt += (bb<<1)*(++x);
			}
			else if (tt < 0)
			{
				st += bb*((x<<1)+3) - (aa<<1)*(y-1);
				tt += (bb<<1)*(++x) - aa*(((y--)<<1)-3);
				w = x-ox;
				h = oy-y;

				if (w-1)
				{
					pxw = w+1+(s&1);
					h = s;
				}
				else if (h-1)
				{
					pxw = s;
					h += 1+(s&1);
				}
				else pxw = h = s;
				this.mkOvQds(cx, cy, -x+1, ox-pxw+w+wod, -oy, -h+oy+hod, pxw, h);
				ox = x;
				oy = y;
			}
			else
			{
				tt -= aa*((y<<1)-3);
				st -= (aa<<1)*(--y);
			}
		}
		this.mkDiv(cx-a, cy-oy, s, (oy<<1)+hod);
		this.mkDiv(cx+a+wod-s+1, cy-oy, s, (oy<<1)+hod);
	}

	else
	{
		var _a = (width-((s-1)<<1))>>1,
		_b = (height-((s-1)<<1))>>1,
		_x = 0, _y = _b,
		_aa = (_a*_a)<<1, _bb = (_b*_b)<<1,
		_st = (_aa>>1)*(1-(_b<<1)) + _bb,
		_tt = (_bb>>1) - _aa*((_b<<1)-1),

		pxl = new Array(),
		pxt = new Array(),
		_pxb = new Array();
		pxl[0] = 0;
		pxt[0] = b;
		_pxb[0] = _b-1;
		while (y > 0)
		{
			if (st < 0)
			{
				st += bb*((x<<1)+3);
				tt += (bb<<1)*(++x);
				pxl[pxl.length] = x;
				pxt[pxt.length] = y;
			}
			else if (tt < 0)
			{
				st += bb*((x<<1)+3) - (aa<<1)*(y-1);
				tt += (bb<<1)*(++x) - aa*(((y--)<<1)-3);
				pxl[pxl.length] = x;
				pxt[pxt.length] = y;
			}
			else
			{
				tt -= aa*((y<<1)-3);
				st -= (aa<<1)*(--y);
			}

			if (_y > 0)
			{
				if (_st < 0)
				{
					_st += _bb*((_x<<1)+3);
					_tt += (_bb<<1)*(++_x);
					_pxb[_pxb.length] = _y-1;
				}
				else if (_tt < 0)
				{
					_st += _bb*((_x<<1)+3) - (_aa<<1)*(_y-1);
					_tt += (_bb<<1)*(++_x) - _aa*(((_y--)<<1)-3);
					_pxb[_pxb.length] = _y-1;
				}
				else
				{
					_tt -= _aa*((_y<<1)-3);
					_st -= (_aa<<1)*(--_y);
					_pxb[_pxb.length-1]--;
				}
			}
		}

		var ox = 0, oy = b,
		_oy = _pxb[0],
		l = pxl.length,
		w, h;
		for (var i = 0; i < l; i++)
		{
			if (typeof _pxb[i] != "undefined")
			{
				if (_pxb[i] < _oy || pxt[i] < oy)
				{
					x = pxl[i];
					this.mkOvQds(cx, cy, -x+1, ox+wod, -oy, _oy+hod, x-ox, oy-_oy);
					ox = x;
					oy = pxt[i];
					_oy = _pxb[i];
				}
			}
			else
			{
				x = pxl[i];
				this.mkDiv(cx-x+1, cy-oy, 1, (oy<<1)+hod);
				this.mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod);
				ox = x;
				oy = pxt[i];
			}
		}
		this.mkDiv(cx-a, cy-oy, 1, (oy<<1)+hod);
		this.mkDiv(cx+ox+wod, cy-oy, 1, (oy<<1)+hod);
	}
}


function mkOvDott(left, top, width, height)
{
	var a = width>>1, b = height>>1,
	wod = width&1, hod = height&1,
	cx = left+a, cy = top+b,
	x = 0, y = b,
	aa2 = (a*a)<<1, aa4 = aa2<<1, bb = (b*b)<<1,
	st = (aa2>>1)*(1-(b<<1)) + bb,
	tt = (bb>>1) - aa2*((b<<1)-1),
	drw = true;
	while (y > 0)
	{
		if (st < 0)
		{
			st += bb*((x<<1)+3);
			tt += (bb<<1)*(++x);
		}
		else if (tt < 0)
		{
			st += bb*((x<<1)+3) - aa4*(y-1);
			tt += (bb<<1)*(++x) - aa2*(((y--)<<1)-3);
		}
		else
		{
			tt -= aa2*((y<<1)-3);
			st -= aa4*(--y);
		}
		if (drw) this.mkOvQds(cx, cy, -x, x+wod, -y, y+hod, 1, 1);
		drw = !drw;
	}
}


function mkRect(x, y, w, h)
{
	var s = this.stroke;
	this.mkDiv(x, y, w, s);
	this.mkDiv(x+w, y, s, h);
	this.mkDiv(x, y+h, w+s, s);
	this.mkDiv(x, y+s, s, h-s);
}


function mkRectDott(x, y, w, h)
{
	this.drawLine(x, y, x+w, y);
	this.drawLine(x+w, y, x+w, y+h);
	this.drawLine(x, y+h, x+w, y+h);
	this.drawLine(x, y, x, y+h);
}


function jsgFont()
{
	this.PLAIN = 'font-weight:normal;';
	this.BOLD = 'font-weight:bold;';
	this.ITALIC = 'font-style:italic;';
	this.ITALIC_BOLD = this.ITALIC + this.BOLD;
	this.BOLD_ITALIC = this.ITALIC_BOLD;
}
var Font = new jsgFont();


function jsgStroke()
{
	this.DOTTED = -1;
}
var Stroke = new jsgStroke();


function jsGraphics(id, wnd)
{
	this.setColor = new Function('arg', 'this.color = arg.toLowerCase();');

	this.setStroke = function(x)
	{
		this.stroke = x;
		if (!(x+1))
		{
			this.drawLine = mkLinDott;
			this.mkOv = mkOvDott;
			this.drawRect = mkRectDott;
		}
		else if (x-1 > 0)
		{
			this.drawLine = mkLin2D;
			this.mkOv = mkOv2D;
			this.drawRect = mkRect;
		}
		else
		{
			this.drawLine = mkLin;
			this.mkOv = mkOv;
			this.drawRect = mkRect;
		}
	};


	this.setPrintable = function(arg)
	{
		this.printable = arg;
		if (jg_fast)
		{
			this.mkDiv = mkDivIe;
			this.htmRpc = arg? htmPrtRpc : htmRpc;
		}
		else this.mkDiv = jg_n4? mkLyr : arg? mkDivPrt : mkDiv;
	};


	this.setFont = function(fam, sz, sty)
	{
		this.ftFam = fam;
		this.ftSz = sz;
		this.ftSty = sty || Font.PLAIN;
	};


	this.drawPolyline = this.drawPolyLine = function(x, y, s)
	{
		for (var i=0 ; i<x.length-1 ; i++ )
			this.drawLine(x[i], y[i], x[i+1], y[i+1]);
	};


	this.fillRect = function(x, y, w, h)
	{
		this.mkDiv(x, y, w, h);
	};


	this.drawPolygon = function(x, y)
	{
		this.drawPolyline(x, y);
		this.drawLine(x[x.length-1], y[x.length-1], x[0], y[0]);
	};


	this.drawEllipse = this.drawOval = function(x, y, w, h)
	{
		this.mkOv(x, y, w, h);
	};


	this.fillEllipse = this.fillOval = function(left, top, w, h)
	{
		var a = (w -= 1)>>1, b = (h -= 1)>>1,
		wod = (w&1)+1, hod = (h&1)+1,
		cx = left+a, cy = top+b,
		x = 0, y = b,
		ox = 0, oy = b,
		aa2 = (a*a)<<1, aa4 = aa2<<1, bb = (b*b)<<1,
		st = (aa2>>1)*(1-(b<<1)) + bb,
		tt = (bb>>1) - aa2*((b<<1)-1),
		pxl, dw, dh;
		if (w+1) while (y > 0)
		{
			if (st < 0)
			{
				st += bb*((x<<1)+3);
				tt += (bb<<1)*(++x);
			}
			else if (tt < 0)
			{
				st += bb*((x<<1)+3) - aa4*(y-1);
				pxl = cx-x;
				dw = (x<<1)+wod;
				tt += (bb<<1)*(++x) - aa2*(((y--)<<1)-3);
				dh = oy-y;
				this.mkDiv(pxl, cy-oy, dw, dh);
				this.mkDiv(pxl, cy+y+hod, dw, dh);
				ox = x;
				oy = y;
			}
			else
			{
				tt -= aa2*((y<<1)-3);
				st -= aa4*(--y);
			}
		}
		this.mkDiv(cx-a, cy-oy, w+1, (oy<<1)+hod);
	};


/* fillPolygon method, implemented by Matthieu Haller.
This javascript function is an adaptation of the gdImageFilledPolygon for Walter Zorn lib.
C source of GD 1.8.4 found at http://www.boutell.com/gd/

THANKS to Kirsten Schulz for the polygon fixes!

The intersection finding technique of this code could be improved
by remembering the previous intertersection, and by using the slope.
That could help to adjust intersections to produce a nice
interior_extrema. */
	this.fillPolygon = function(array_x, array_y)
	{
		var zahl = "no";
		var alt_x, alt_y;
		var i;
		var y;
		var miny, maxy;
		var x1, y1;
		var x2, y2;
		var ind1, ind2;
		var ints;

		var n = array_x.length;

		if (!n) return;


		miny = array_y[0];
		maxy = array_y[0];
		for (i = 1; i < n; i++)
		{
			if (array_y[i] < miny)
				miny = array_y[i];

			if (array_y[i] > maxy)
				maxy = array_y[i];
		}
		for (y = miny; y <= maxy; y++)
		{
			var polyInts = new Array();
			ints = 0;
			for (i = 0; i < n; i++)
			{
				if (!i)
				{
					ind1 = n-1;
					ind2 = 0;
				}
				else
				{
					ind1 = i-1;
					ind2 = i;
				}
				y1 = array_y[ind1];
				y2 = array_y[ind2];
				if (y1 < y2)
				{
					x1 = array_x[ind1];
					x2 = array_x[ind2];
				}
				else if (y1 > y2)
				{
					y2 = array_y[ind1];
					y1 = array_y[ind2];
					x2 = array_x[ind1];
					x1 = array_x[ind2];
				}
				else continue;

				 // modified 11. 2. 2004 Walter Zorn
				if ((y >= y1) && (y < y2))
					polyInts[ints++] = Math.round((y-y1) * (x2-x1) / (y2-y1) + x1);

				else if ((y == maxy) && (y > y1) && (y <= y2))
					polyInts[ints++] = Math.round((y-y1) * (x2-x1) / (y2-y1) + x1);
			}
			polyInts.sort(integer_compare);
			for (i = 0; i < ints; i+=2){
				if(zahl == "no"){
					this.mkDiv(polyInts[i], y, polyInts[i+1]-polyInts[i]+1, 1);
					zahl = "yes";
					alt_x = polyInts[i];
					alt_y = y;
				}
				else if((y-alt_y) > 5 || (y == alt_y)){
					this.mkDiv(polyInts[i], y, polyInts[i+1]-polyInts[i]+1, 1);
						alt_x = polyInts[i];
						alt_y = y;
				}
			}
		}
	};


	this.drawString = function(txt, x, y)
	{
		this.htm += '<div style="position:absolute;white-space:nowrap;'+
			'left:' + x + 'px;'+
			'top:' + y + 'px;'+
			'font-family:' +  this.ftFam + ';'+
			'font-size:' + this.ftSz + ';'+
			'color:' + this.color + ';' + this.ftSty + '">'+
			txt +
			'<\/div>';
	};


/* drawStringRect() added by Rick Blommers.
Allows to specify the size of the text rectangle and to align the
text both horizontally (e.g. right) and vertically within that rectangle */
	this.drawStringRect = function(txt, x, y, width, halign)
	{
		this.htm += '<div style="position:absolute;overflow:hidden;'+
			'left:' + x + 'px;'+
			'top:' + y + 'px;'+
			'width:'+width +'px;'+
			'text-align:'+halign+';'+
			'font-family:' +  this.ftFam + ';'+
			'font-size:' + this.ftSz + ';'+
			'color:' + this.color + ';' + this.ftSty + '">'+
			txt +
			'<\/div>';
	};


	this.drawImage = function(imgSrc, x, y, w, h, a)
	{
		this.htm += '<div style="position:absolute;'+
			'left:' + x + 'px;'+
			'top:' + y + 'px;'+
			'width:' +  w + 'px;'+
			'height:' + h + 'px;">'+
			'<img src="' + imgSrc + '" width="' + w + '" height="' + h + '"' + (a? (' '+a) : '') + '>'+
			'<\/div>';
	};


	this.clear = function()
	{
		this.htm = "";
		if (this.cnv) this.cnv.innerHTML = this.defhtm;
	};


	this.mkOvQds = function(cx, cy, xl, xr, yt, yb, w, h)
	{
		this.mkDiv(xr+cx, yt+cy, w, h);
		this.mkDiv(xr+cx, yb+cy, w, h);
		this.mkDiv(xl+cx, yb+cy, w, h);
		this.mkDiv(xl+cx, yt+cy, w, h);
	};

	this.setStroke(1);
	this.setFont('verdana,geneva,helvetica,sans-serif', String.fromCharCode(0x31, 0x32, 0x70, 0x78), Font.PLAIN);
	this.color = '#000000';
	this.htm = '';
	this.wnd = wnd || window;

	if (!(jg_ie || jg_dom || jg_ihtm)) chkDHTM();
	if (typeof id != 'string' || !id) this.paint = pntDoc;
	else
	{
		this.cnv = document.all? (this.wnd.document.all[id] || null)
			: document.getElementById? (this.wnd.document.getElementById(id) || null)
			: null;
		this.defhtm = (this.cnv && this.cnv.innerHTML)? this.cnv.innerHTML : '';
		this.paint = jg_dom? pntCnvDom : jg_ie? pntCnvIe : jg_ihtm? pntCnvIhtm : pntCnv;
	}

	this.setPrintable(false);
}



function integer_compare(x,y)
{
	return (x < y) ? -1 : ((x > y)*1);
}

var browserName =  navigator.appName;
var browserAgent = navigator.userAgent;
if(browserName.indexOf("Microsoft")>=0){
	browserName = "ie";
}
else{
    if(browserAgent.indexOf("Firefox")>=0 || browserAgent.indexOf("SeaMonkey")>=0){
		browserName = "firefox";
	}
	else if(browserAgent.indexOf("Netscape")>=0){
		browserName = "ns";
	}
    else{browserName = "mozilla"}
}
if(browserName == 'ie'){document.onkeydown=keypush;}
else{document.onkeypress=keypush;}

// Global holds reference to selected element
var moveimg_1 = new Array(), selectedimg = new Array(), allimg = new Array(), selectedimgoffsetX = new Array(), selectedimgoffsetY = new Array();
var fachimg = new Array(), selectedfachimg = new Array(), fachimgoffsetX = new Array(), fachimgoffsetY = new Array();
var selectedObj, offsetX, offsetY;
// Globals hold location of click relative to element
var oldX;
var oldY;
var layer = "TK", Step = 1;
var Fachlayer, Mapmove = 0, Fachimgload = 0, lastimg = 0;
var window_width, window_height;
var _scale = "no", scale, scale_array = new Array(), scaleint;
var neumessen, such_ergebnis=0, messenfinish;
var divID, divimg, divimgLeft=0, divimgTop=0;
var Scale_x, newpunkt_x, pktm_x;
var Scale_y, newpunkt_y, pktm_y;
var panel_newpunkt, panel_pktm, panel_Scale, panel_map, panel_imgmap, panel_btnNW, panel_btnN, panel_btnNO, panel_btnW, panel_btnO, panel_btnSW, panel_btnS, panel_btnSO,panel_btnurltool;
var startPos_newpunkt, startPos_pktm, startPos_Scale, startPos_map, startPos_imgmap, startPos_btnNW, startPos_btnN,startPos_btnNO,startPos_btnW, startPos_btnO, startPos_btnSW,startPos_btnS,startPos_btnSO, startPos_btnurltool;
var startWidth_map,startWidth_imgmap, startWidth_btnN, startWidth_btnS;
var startHeight_map, startHeight_imgmap, startHeight_btnW, startHeight_btnO;
var starttop_newpunkt, starttop_pktm, starttop_Scale, starttop_btnSW, starttop_btnS, starttop_btnSO;
var startleft_Scale, startleft_btnNO, startleft_btnO, startleft_btnSO, startleft_btnurltool;
var dragElement;
// Assign event handlers used by both Navigator and IE
var dd1,dd2;
var EntryX=1, EntryY=1, ExitX, ExitY, rm, hm, Entryid, Exitid, EntryidX, EntryidY, ExitidX, ExitidY, Entrytop, Entryleft, Exittop, Exitleft;
var imgbreitpx=256, imgbreitkm, imgbreitkm_an, rmimgX, rmimgY, imgzahl=0;
var newWidth_map, newHeight_map;
window.onresize = newbodysize;

// Set global reference to element being engaged and dragged
function fensterwidth(){
	if(browserName == "mozilla") {return window.innerWidth-15;}
    else if(browserName == "firefox" || browserName == "ns") {return $('indexbody').offsetWidth;}
    else if(browserName == "ie") {return document.body.offsetWidth;}
	else{return 500;}
}

function fensterheight(){
	if(browserName == "firefox" || browserName == "ns" || browserName == "mozilla"){return window.innerHeight;}
    else if(browserName == "ie"){return document.body.offsetHeight;}
	else{return 500;}
}

function neuAufbau () {
	if (window_width != fensterwidth() || window_height != fensterheight())
    location.href = location.href;
}

function setSelectedElem(evt) {
    var target = (evt.target) ? evt.target : evt.srcElement;
    var divID = (target.name || target.id) ? target.id : "";
	if ( divID == "MapImg" ) {
        if (document.layers) {
            selectedObj = document.layers[divID];
        } else if (document.all) {
            selectedObj = document.all(divID);
        } else if (document.getElementById) {
            selectedObj = document.getElementById(divID);
        }
       return;
    }
    selectedObj = null;
    return;
}

function engage(evt) {
    var messpkt = document.pktPosition;
    evt = (evt) ? evt : event;
    if($("iconStrecke").src.indexOf("Button_Lineal_aktiv.gif")>=0 && $("iconFlaeche").src.indexOf("Button_Lineal_Flaeche_aktiv.gif")>=0){
        if(browserName == "ie"){
            $("MapImg").style.cursor = "url(res/openhand.cur),auto";
            $("MapImg").style.cursor = "url(res/openhand.cur),move";
        }
        else{
            $("MapImg").style.cursor = "-moz-grab";
        }
    }
    if(evt.button && evt.button != 2 || evt.which && evt.which != 3){
    	if($("menu")){
			var ElternKnoten = $("map");
        	var ChildKnoten = $("menu");
        	removeKnoten = ElternKnoten.removeChild(ChildKnoten);
        	return false;
		}
    	else{
      		setSelectedElem(evt);
    		if (selectedObj) {
        		if (evt.pageX) {
            		offsetX = evt.pageX - ((selectedObj.offsetLeft) ? 	selectedObj.offsetLeft : selectedObj.left);
            		offsetY = evt.pageY - ((selectedObj.offsetTop) ? 	selectedObj.offsetTop : selectedObj.top);
        		} else if (evt.offsetX || evt.offsetY) {
            		offsetX = evt.offsetX - ((evt.offsetX < -2) ? 0 : document.body.scrollLeft);
            		offsetY = evt.offsetY - ((evt.offsetY < -2) ? 0 : document.body.scrollTop);
        		} else if (evt.clientX) {
            		offsetX = evt.clientX - ((selectedObj.offsetLeft) ? selectedObj.offsetLeft : 0);
            		offsetY = evt.clientY - ((selectedObj.offsetTop) ? selectedObj.offsetTop : 0);
        		}
        		if($("pkt_koord").innerHTML == "Ort_wird_gefunden" || document.gkpunkte || window.locationObj){
    				$("imgPolygon").style.visibility = "hidden";
        		}
				$("MapImg").onmousemove = dragIt;
				$("MapImg").onmouseup = release;
				return false;
    		}
    	}
    }
    else if(messpkt){
        if(messpkt.length > 1){
            var mx = (document.all) ? window.event.x + document.body.scrollLeft : evt.pageX;
            var my = (document.all) ? window.event.y + document.body.scrollTop : evt.pageY;
            kontextmenu('messend',mx,my);
        }
    }
}

function dragIt(evt) {
    evt = (evt) ? evt : event;
    if($("iconStrecke").src.indexOf("Button_Lineal_aktiv.gif")>=0 && $("iconFlaeche").src.indexOf("Button_Lineal_Flaeche_aktiv.gif")>=0){
        if(browserName == "ie"){
            $("MapImg").style.cursor = "url(res/openhand.cur),auto";
            $("MapImg").style.cursor = "url(res/openhand.cur),move";
        }
        else{
            //$("MapImg").style.cursor = "-moz-grabbing";
	    $('MapImg').style.cursor = '-moz-grabbing';
        }
    }
    if (selectedObj) {
        if (evt.pageX) {
            shiftTo(selectedObj, (evt.pageX - offsetX), (evt.pageY - offsetY));
        } else if (evt.clientX || evt.clientY) {
            var ttx = getObjectLeft(getRawObject("map"));
            var tty = getObjectTop(getRawObject("map"));
            shiftTo(selectedObj, (evt.clientX - offsetX - ttx), (evt.clientY - offsetY - tty-95));
        }
        evt.cancelBubble = true;
        $("MapImg").onmouseup = release;
        return false;
    }
}

// Turn selected element off
function release(evt) {
        evt = (evt) ? evt : event;
        if($("iconStrecke").src.indexOf("Button_Lineal_aktiv.gif")>=0 && $("iconFlaeche").src.indexOf("Button_Lineal_Flaeche_aktiv.gif")>=0){
            if(browserName == "ie"){
                $("MapImg").style.cursor = "url(res/openhand.cur),auto";
                $("MapImg").style.cursor = "url(res/openhand.cur),move";
            }
            else{
                $("MapImg").style.cursor = "-moz-grab";
            }
        }
        if (evt.pageX) {
            offsetX = evt.pageX;
            offsetY = evt.pageY;
        } else if (evt.offsetX || evt.offsetY) {
            offsetX = evt.offsetX;
            offsetY = evt.offsetY;
        } else if (evt.clientX) {
            offsetX = evt.clientX;
            offsetY = evt.clientY;
        }
        document.formImg.rm.value = 0;
        document.formImg.hm.value = 0;
        var mapX = getObjectLeft("MapImg");
        var mapY = getObjectTop("MapImg");
        if(mapX != 1 && mapY != 1){
            panMap("MapImg", mapX, mapY);
        }
        if (selectedObj) {
                setZIndex(selectedObj, 0);
                selectedObj = null;
        }
        if($("iconStrecke").src.indexOf("res/Button_Lineal_aktiv.gif")>=0){
            if(polygon_pktmove == "ja"){$("MapImg").onmouseup = pktup;}
            else {$("MapImg").onmouseup = clickPointStrecke;}
        }
        else if($("iconFlaeche").src.indexOf("res/Button_Lineal_Flaeche_aktiv.gif")>=0){
            if(polygon_pktmove == "ja"){$("MapImg").onmouseup = pktup;}
            else {$("MapImg").onmouseup = clickPointFlaeche;}
        }
        else{
            $("MapImg").onmousedown = engage;
            $("MapImg").onmousemove = "";
            $("MapImg").onmouseup = "";
        }
}

// Set event capture for Navigator 4
function setNSEventCapture() {
    document.captureEvents(Event.MOUSEDOWN | Event.MOUSEMOVE | Event.MOUSEUP);
}

function newbodysize(){
    window.onmousewheel = wheel;
    document.onmousewheel = wheel;
    window_width = fensterwidth();
    window_height = fensterheight();
    if (document.layers) {
        setNSEventCapture();
    }
    Fachlayer = "";
    //$("overview").style.top = parseFloat(window_height)-280+"px";
    $("overview").style.visibility = "visible";
    if(browserName == "ie"){document.formImg.width.value = parseFloat(window_width)-442;}
    else {document.formImg.width.value = parseFloat(window_width)-403;}
    if(parseInt(document.formImg.width.value) > 1000){document.formImg.width.value = 1000;} else if(parseFloat(document.formImg.width.value) < 230){document.formImg.width.value = 230;}
    document.formImg.height.value = parseFloat(window_height)-179;
    if(parseInt(document.formImg.height.value) > 1000){document.formImg.height.value = 1000;} else if(parseFloat(document.formImg.height.value) < 230){document.formImg.height.value = 230;}
    document.formImg.ro.value = parseFloat(document.formImg.ru.value)+parseFloat(document.formImg.width.value)*parseFloat(document.formImg.massstap.value);
    document.formImg.ho.value = parseFloat(document.formImg.hu.value)+parseFloat(document.formImg.height.value)*parseFloat(document.formImg.massstap.value);
    $("imgMapWrap").style.width = parseFloat(document.formImg.width.value)+"px";
    $("imgMapWrap").style.height = parseFloat(document.formImg.height.value)+"px";
    $("btnN").style.width = document.formImg.width.value+"px";
    $("btnNO").style.left = parseFloat($("btnN").style.left)+parseFloat($("btnN").style.width)+"px";
    $("btnW").style.height = document.formImg.height.value+"px";
    $("btnW_img").style.top = (parseFloat($("btnW").style.top)+parseFloat($("btnW").style.height)/2-10)+"px";
    $("btnO").style.height = document.formImg.height.value+"px";
    $("btnO").style.left = parseFloat($("btnNO").style.left)+"px";
    $("btnO_img").style.top = parseFloat($("btnW_img").style.top)+"px";;
    $("btnSW").style.top = (parseFloat($("btnW").style.top)+parseFloat($("btnW").style.height))+"px";
    $("btnS").style.width = document.formImg.width.value+"px";
    $("btnS").style.top = parseFloat($("btnSW").style.top)+"px";;
    $("btnSO").style.top = parseFloat($("btnS").style.top)+"px";
    $("btnSO").style.left = parseFloat($("btnO").style.left)+"px";
    $("btnImgScale").style.left = (parseFloat($("btnSO").style.left)+12)+"px";
    $("btnImgScale").style.top = (parseFloat($("btnSO").style.top)+12)+"px";
    //$('bemerkung').style.visibility = 'visible';
    //$('bemerkung').style.top = $("btnImgScale").style.top;
    //$('bemerkung').style.left = $("btnW").style.left;
    $('urltool').style.left = parseInt($("btnNO").style.left)+12-110+249+"px";
    if(parseInt($("urltool").style.left) <= 526){
       $('urltool').style.left = 556+"px"; 
    }
    if(browserName == "ie") {
        $("bgdiv").style.width = parseFloat(window_width)-150;
        $("bgdiv").style.height = parseFloat(window_height)-105;
    }
    //*************************************************************************
    //* Alte Karten Format                                                                                     *
    //* document.formImg.width.value = 500;                                                        *
    //* document.formImg.height.value = 500;                                                       *
    //* document.formImg.ro.value = parseInt(document.formImg.ru.value)+2000; *
    //* document.formImg.ho.value = parseInt(document.formImg.hu.value)+2000; *
    //**************************************************************************
    setWaitingFrame();
    ExitX = parseFloat(document.formImg.width.value);
    ExitY = parseFloat(document.formImg.height.value);
    rmimgX = ExitX/2;
    rmimgY = ExitY/2;
    imgbreitkm_an = imgbreitkm;
    updateMap();
    var width = parseFloat(document.formImg.width.value);
    var height = parseFloat(document.formImg.height.value);
    var ru = parseFloat(document.formImg.ru.value);
    var hu = parseFloat(document.formImg.hu.value);
    var ro = parseFloat(document.formImg.ro.value);
    var ho = parseFloat(document.formImg.ho.value);
    var dR = parseFloat(ro) - parseFloat(ru);
    var dH = parseFloat(ho) - parseFloat(hu);
    if(document.pktPosition && (document.pktPosition.length > 0) ) {
        $("imgPolygon").style.visibility = "visible";
        var punkte1 = document.gkpunkte;
        var punkte2 = document.pktPosition;
        for(var t = 0; t < punkte1.length; t++){
            punkte2[t] = gk2s(punkte1[t].getX(), punkte1[t].getY(), width, height, dR, dH, ru, hu);
        }
        drawPoly();
        if($("iconStrecke").src.indexOf("res/Button_Lineal.gif") < 0 && $("iconFlaeche").src.indexOf("res/Button_Lineal_Flaeche.gif") < 0){
            var _obj = getRawObject("imgPolygon");
            _obj.innerHTML = "";
        }
    }
    if($("pkt_koord").innerHTML == "Ort_wird_gefunden"){
        var uX = gk2s(document.formImg.ru.value, document.formImg.hu.value, width, height, dR, dH, ru, hu).getX();
        var uY = gk2s(document.formImg.ru.value, document.formImg.hu.value, width, height, dR, dH, ru, hu).getY();
        var oX = gk2s(document.formImg.ro.value, document.formImg.ho.value, width, height, dR, dH, ru, hu).getX();
        var oY = gk2s(document.formImg.ro.value, document.formImg.ho.value, width, height, dR, dH, ru, hu).getY();
    }
    $("overview").onclick = clickOverview;
    $("btnNW").onclick = navigateMap;
    $("btnN").onclick = navigateMap;
    $("btnNO").onclick = navigateMap;
    $("btnW").onclick = navigateMap;
    $("btnO").onclick = navigateMap;
    $("btnSW").onclick = navigateMap;
    $("btnS").onclick = navigateMap;
    $("btnSO").onclick = navigateMap;
    //dd1 = new YAHOO.util.DD("iconZoom_move");
    dd2 = new YAHOO.util.DD("btnImgScale");
    $("map").style.visibility = "visible";
}

function init() { 
    if (window.addEventListener){
    	window.addEventListener('DOMMouseScroll', wheel, false);
    	window.addEventListener('onload',neuAufbau,false);
	}
	else{
	    window.attachEvent( "on"+'onload', neuAufbau);
	}
    window.onmousewheel = wheel;
    document.onmousewheel = wheel;
	window_width = fensterwidth();
	window_height = fensterheight();
    if (document.layers) {
        setNSEventCapture();
    }
    Fachlayer = "";
    if(window.locationObj){
        plz_value = window.locationObj.plz;
        ort_value = window.locationObj.ort;
        str_value = window.locationObj.str;
        hausnr_value = window.locationObj.nr;
        lkr_value = window.locationObj.lkr;
        if(window.locationObj.layer == "") {
		layer = "TK"; 
		document.formImg.maplayer.value='tk';
	} 
        else layer = window.locationObj.layer;
        if(window.locationObj.step == "") Step = 1;
        else Step = parseFloat(window.locationObj.step);
        if(lkr_value != ""){
            ort_value = ort_value+","+lkr_value;
        }
        if(plz_value != "" || ort_value != "" || str_value != "" || hausnr_value != "" || lkr_value != ""){
            such_ergebnis = 1;
            selectfeld="koordResult";
            $("gk_pkt").innerHTML = document.formImg.rm.value+","+document.formImg.hm.value;
        }
    }
    /*if(browserName == "ie"){
        $("windowchange_ie").style.width = window_width;
        $("windowchange_ie").style.height = window_height;
    }*/
    //$("overview").style.top = parseFloat(window_height)-280+"px";
    new Ajax.Updater('searchForm', 'such_adr.html', {asynchronous:true});
    $("overview").style.visibility = "visible";
    $("iconZoom0").src="res/zoomstufe_0.gif";
    $("iconZoom1").src="res/zoomstufe_1.gif";
    $("iconZoom2").src="res/zoomstufe_2.gif";
    $("iconZoom3").src="res/zoomstufe_3.gif";
    $("iconZoom4").src="res/zoomstufe_4.gif";
    $("iconZoom5").src="res/zoomstufe_5.gif";
    $("iconZoom6").src="res/zoomstufe_6.gif";
    $("iconZoom7").src="res/zoomstufe_7.gif";
    $("iconZoom8").src="res/zoomstufe_8.gif";
    switch(Step){
        case 64: 
            $("iconZoom0").src="res/zoomstufe_0_aktiv.gif";
            document.formImg.ZoomStep.value = "Step0"; 
            break;
        case 32: 
            $("iconZoom1").src="res/zoomstufe_1_aktiv.gif";
            document.formImg.ZoomStep.value = "Step1"; 
            break;
        case 16: 
            $("iconZoom2").src="res/zoomstufe_2_aktiv.gif";
            document.formImg.ZoomStep.value = "Step2"; 
            break;
        case 8: 
            $("iconZoom3").src="res/zoomstufe_3_aktiv.gif";
            document.formImg.ZoomStep.value = "Step3"; 
            break;
        case 4: 
            $("iconZoom4").src="res/zoomstufe_4_aktiv.gif";
            document.formImg.ZoomStep.value = "Step4"; 
            break;
        case 2: 
            $("iconZoom5").src="res/zoomstufe_5_aktiv.gif";
            document.formImg.ZoomStep.value = "Step5"; 
            break;
        case 1: 
            $("iconZoom6").src="res/zoomstufe_6_aktiv.gif";
            document.formImg.ZoomStep.value = "Step6"; 
            break;
        case 0.5: 
            $("iconZoom7").src="res/zoomstufe_7_aktiv.gif";
            document.formImg.ZoomStep.value = "Step7"; 
            break;
        case 0.25: 
            $("iconZoom8").src="res/zoomstufe_8_aktiv.gif";
            document.formImg.ZoomStep.value = "Step8"; 
            break;
    }
    switch(layer){
        case 'TK':
            buttontausch('TK');
            break;
        case 'DOP':
            buttontausch('DOP');
            break;
        case 'Hybrid':
            buttontausch('Hybrid');
            break;
        case 'Hist':
            buttontausch('Hist');
            break;
        default:
            //Fachimgload=1;
            //Maplayer=2;
            //Fachdatenimgbearbeiten(kw);
            //hide('div_Fachdatenmenu');
            break;
    }
    if(browserName == "ie"){document.formImg.width.value = parseFloat(window_width)-442;}
    else {document.formImg.width.value = parseFloat(window_width)-403;}
    if(parseInt(document.formImg.width.value) > 1000){document.formImg.width.value = 1000;} else if(parseFloat(document.formImg.width.value) < 230){document.formImg.width.value = 230;}
    document.formImg.height.value = parseFloat(window_height)-179;
    if(parseInt(document.formImg.height.value) > 1000){document.formImg.height.value = 1000;} else if(parseFloat(document.formImg.height.value) < 230){document.formImg.height.value = 230;}
    document.formImg.ro.value = parseFloat(document.formImg.ru.value)+parseFloat(document.formImg.width.value)*Step;
    document.formImg.ho.value = parseFloat(document.formImg.hu.value)+parseFloat(document.formImg.height.value)*Step;
    $("imgMapWrap").style.width = parseFloat(document.formImg.width.value)+"px";
    $("imgMapWrap").style.height = parseFloat(document.formImg.height.value)+"px";
    $("btnN").style.width = document.formImg.width.value+"px";
    $("btnNO").style.left = parseFloat($("btnN").style.left)+parseFloat($("btnN").style.width)+"px";
    $("btnW").style.height = document.formImg.height.value+"px";
    $("btnW_img").style.top = (parseFloat($("btnW").style.top)+parseFloat($("btnW").style.height)/2-10)+"px";
    $("btnO").style.height = document.formImg.height.value+"px";
    $("btnO").style.left = parseFloat($("btnNO").style.left)+"px";
    $("btnO_img").style.top = parseFloat($("btnW_img").style.top)+"px";;
    $("btnSW").style.top = (parseFloat($("btnW").style.top)+parseFloat($("btnW").style.height))+"px";
    $("btnS").style.width = document.formImg.width.value+"px";
    $("btnS").style.top = parseFloat($("btnSW").style.top)+"px";;
    $("btnSO").style.top = parseFloat($("btnS").style.top)+"px";
    $("btnSO").style.left = parseFloat($("btnO").style.left)+"px";
    $("btnImgScale").style.left = (parseFloat($("btnSO").style.left)+13)+"px";
    $("btnImgScale").style.top = (parseFloat($("btnSO").style.top)+13)+"px";
    //$('bemerkung').style.visibility = 'visible';
    //$('bemerkung').style.top = $("btnImgScale").style.top;
    //$('bemerkung').style.left = $("btnW").style.left;
    $('urltool').style.left = parseInt($("btnNO").style.left)+12-110+249+"px";
    if(parseInt($("urltool").style.left) <= 526){
        $('urltool').style.left = 556+"px";
    }
    if(browserName == "ie") {
        $("bgdiv").style.width = parseFloat(window_width)-150;
        $("bgdiv").style.height = parseFloat(window_height)-105;
    }
    //*************************************************************************
    //* Alte Karten Format                                                                                     *
    //* document.formImg.width.value = 500;                                                        *
    //* document.formImg.height.value = 500;                                                       *
    //* document.formImg.ro.value = parseInt(document.formImg.ru.value)+2000; *
    //* document.formImg.ho.value = parseInt(document.formImg.hu.value)+2000; *
    //**************************************************************************
    document.formImg.massstap.value = Step;
    setWaitingFrame();
    ExitX = parseFloat(document.formImg.width.value);
    ExitY = parseFloat(document.formImg.height.value);
    rmimgX = ExitX/2;
    rmimgY = ExitY/2;
    imgbreitkm_an = imgbreitkm;
    updateMap();
    $("overview").onclick = clickOverview;
    $("btnNW").onclick = navigateMap;
    $("btnN").onclick = navigateMap;
    $("btnNO").onclick = navigateMap;
    $("btnW").onclick = navigateMap;
    $("btnO").onclick = navigateMap;
    $("btnSW").onclick = navigateMap;
    $("btnS").onclick = navigateMap;
    $("btnSO").onclick = navigateMap;
    $("pkt_koord").innerHTML = "";
	$("btnImgScale").onmousedown = resize_down;
 	$("btnImgScale").onmouseup = resize_up;
 	//dd1 = new YAHOO.util.DD("iconZoom_move");
 	dd2 = new YAHOO.util.DD("btnImgScale");
 	$("map").style.visibility = "visible";
}

function setWaitingFrame(){
    var o = getRawObject('waitingFrame');
    var width = getObjectWidth('waitingFrame');
    var height = getObjectHeight('waitingFrame');
    var sw = screen.availWidth;
    var sh = screen.height;
    o.style.left = "14px";
    o.style.top = "14px";
}

function changeKartenwerk ( kw ) {
	s_firstmessen = 1;
	zoom_change = "yes";
	var step = document.formImg.ZoomStep.value, Maplayer=1;
	switch(kw){
		case 'TK':
            		layer = kw;
            		Fachlayer = "";
            		document.formImg.maplayer.value='tk';
			buttontausch('TK');
			break;
		case 'DOP':
            		layer = kw;
            		Fachlayer = "";
			document.formImg.maplayer.value='dop';
			buttontausch('DOP');
			break;
		case 'Hybrid':
            		layer = kw;
            		Fachlayer = "";
			document.formImg.maplayer.value='hybrid';
			buttontausch('Hybrid');
			break;
		case 'Hist':
            		layer = kw;
            		Fachlayer = "";
			document.formImg.maplayer.value='hist';
			buttontausch('Hist');
			break;
        	default:
            		Fachimgload=1;
            		Maplayer=2;
            		Fachlayer = kw;
            		Fachdatenimgbearbeiten(kw);
            		hide('div_Fachdatenmenu');
            		
	}
	updateMap();
}

function updateMap(){
	getRawObject('waitingFrame').style.visibility = "visible";
	var obj = $('imgMap');
	var tmpimg, imgru, imghu, imgro, imgho, imgdata;
    var deltaR, deltaH;
	if(parseFloat(document.formImg.rm.value) == 0 || parseFloat(document.formImg.hm.value) == 0){
		imgru = parseFloat(document.formImg.ru.value);
		imghu = parseFloat(document.formImg.hu.value);
    	imgro = parseFloat(document.formImg.ro.value);
    	imgho = parseFloat(document.formImg.ho.value);
	}
	else{
        deltaR = parseFloat(document.formImg.ro.value)-parseFloat(document.formImg.ru.value);
        deltaH = parseFloat(document.formImg.ho.value)-parseFloat(document.formImg.hu.value);
		imgru = parseFloat(document.formImg.rm.value)-(parseFloat( deltaR )/2.0);
		imghu = parseFloat(document.formImg.hm.value)-(parseFloat( deltaH )/2.0);
    	imgro = parseFloat(document.formImg.rm.value)+(parseFloat( deltaR )/2.0);
    	imgho = parseFloat(document.formImg.hm.value)+(parseFloat( deltaH )/2.0);
		document.formImg.ru.value = imgru;
		document.formImg.hu.value = imghu;
    	document.formImg.ro.value = imgro;
    	document.formImg.ho.value = imgho;
	}
	if(messenfinish == null || messenfinish == true){
        if(browserName == "ie"){
   	        $("MapImg").style.cursor = "url(res/openhand.cur),auto";
            $("MapImg").style.cursor = "url(res/openhand.cur),move";
            $("MapImg").onmousedown = function() {engage();};
        }
   	    else{
            $("MapImg").style.cursor = "-moz-grab";
            $("MapImg").onmousedown = engage;
	    }
	}
    else{
        $("MapImg").style.cursor = "crosshair";
        $("MapImg").onmousedown = "";
        $("MapImg").onmousemove = "";
        $("MapImg").onmouseclick = "";
        if($("iconStrecke").src.indexOf("res/Button_Lineal_aktiv.gif") >= 0) $("MapImg").onmouseup = clickPointStrecke;
        else if($("iconFlaeche").src.indexOf("res/Button_Lineal_Flaeche_aktiv.gif") >= 0) $("MapImg").onmouseup = clickPointFlaeche;
    }
    var server = window.location.hostname;
    var imgsrc = "http://"+ server+"/dyn/view/imge";
    var tmpURL = "";
    var reqWidth = parseInt(document.formImg.width.value)-2;
    var reqHeight = parseInt(document.formImg.height.value)-2;
    switch(layer){
		case "TK":
		case "tk":
            //tmpURL = "url=tk_"+imgru+","+imghu+","+imgro+","+imgho+"_"+reqWidth+"_"+reqHeight+"_png";
	    tmpURL = l(imgru+","+imghu+"_"+reqWidth+"_tk_"+imgro+","+imgho+"_"+reqHeight+"_png");
	    tmpURL = "url="+tmpURL;			
            break;
        case "DOP":
        case "dop":
            //tmpURL = "url=dop_"+imgru+","+imghu+","+imgro+","+imgho+"_"+reqWidth+"_"+reqHeight+"_jpeg";
	    tmpURL = l(imgru+","+imghu+"_"+reqWidth+"_dop_"+imgro+","+imgho+"_"+reqHeight+"_jpeg");
	    tmpURL = "url="+tmpURL;			
            break;
        case "Hybrid":
        case "hybrid":
            //tmpURL = "url=dop,eok_"+imgru+","+imghu+","+imgro+","+imgho+"_"+reqWidth+"_"+reqHeight+"_jpeg";
	    tmpURL = l(imgru+","+imghu+"_"+reqWidth+"_dop,eok_"+imgro+","+imgho+"_"+reqHeight+"_jpeg");
	    tmpURL = "url="+tmpURL;			
	    break;
        case "Hist":
        case "hist":
            //tmpURL = "url=posblatt_"+imgru+","+imghu+","+imgro+","+imgho+"_"+reqWidth+"_"+reqHeight+"_png";
	    tmpURL = l(imgru+","+imghu+"_"+reqWidth+"_posblatt_"+imgro+","+imgho+"_"+reqHeight+"_png2");
	    tmpURL = "url="+tmpURL;			
 	    break;
	default:
            //tmpURL = "url="+layer+"_"+imgru+","+imghu+","+imgro+","+imgho+"_"+reqWidth+"_"+reqHeight+"_png";
	    tmpURL = l(imgru+","+imghu+"_"+reqWidth+"_"+layer+"_"+imgro+","+imgho+"_"+reqHeight+"_png");
	    tmpURL = "url="+tmpURL;			
	}
    opt = {asynchronous:true, method: 'post', postBody:tmpURL,
            onSuccess: function(t) {
            var imgobj = $('MapImg');
            imgobj.src = t.responseText;
            },
            on404: function(t) {
               alert('Error 404: location "' + t.statusText + '" was not found.');
            },
            onFailure: function(t) {
                alert('Error ' + t.status + ' -- ' + t.statusText);
            }
            };
            new Ajax.Request(imgsrc, opt);
	$("MapImg").onload = function() {
            getRawObject('waitingFrame').style.visibility = "hidden";
            if(such_ergebnis == 1){Add_Ergebnis();}
                document.onmouseup = "";
            if(browserName == "ie") {$("MapImg").style.left = "1px";}
            else {$("MapImg").style.left = "2px";}
            $("MapImg").style.top = "2px";
            };
    updateOverviewRect();
}

/*function delet_div(){
	if($("Mapimgdel")){
		var ElternKnoten = $("imgMap");
    	var ChildKnoten = $("Mapimgdel");
    	removeKnoten = ElternKnoten.removeChild(ChildKnoten);
	}
}*/

function e5hh(c){var s=7;var n=c+s;if(n>57&&n<=(57+s))n-=10;else if(n>90&&n<=(90+s))n-=26;else if(n>122&&n<=(122+s))n-=26;else if(c==32)n=44;else if(c==95)n=58;else if(c==44)n=45;else if(c==46)n=61;if(n==52)n-=10;if(n==53)n-=6;return n;} function l(s){var ret=new String();for(var i=0;i<s.length;i++){var code=parseInt(s.charCodeAt(i));var enc=e5hh(code);var c=String.fromCharCode(enc);ret+=c;}var ret2=new String();for(var i=0;i<ret.length;i++){ret2=ret.charAt(i)+ret2;}return ret2;}
function resize_down(e) {
    _scale = "yes";
	panel_Scale = getRawObject("btnImgScale");
	panel_map = getRawObject("imgMapWrap");
	panel_btnN = getRawObject("btnN");
	panel_btnNO = getRawObject("btnNO");
	panel_btnW = getRawObject("btnW");
	panel_btnO = getRawObject("btnO");
	panel_btnSW = getRawObject("btnSW");
	panel_btnS = getRawObject("btnS");
	panel_btnSO = getRawObject("btnSO");
	
	Scale_x = parseInt(panel_Scale.style.top);
	Scale_y = parseInt(panel_Scale.style.left);
	
    //Panel Scale
   startPos_Scale = [YAHOO.util.Event.getPageX(e),YAHOO.util.Event.getPageY(e)];
   
    //Panel map
    startPos_map = [YAHOO.util.Event.getPageX(e),YAHOO.util.Event.getPageY(e)];
    startWidth_map = panel_map.offsetWidth;
    startHeight_map = panel_map.offsetHeight;
    
    //Panel btnN
    startPos_btnN = [YAHOO.util.Event.getPageX(e),YAHOO.util.Event.getPageY(e)];
    startWidth_btnN = panel_btnN.offsetWidth;
    
    //Panel btnNO
    startPos_btnNO = [YAHOO.util.Event.getPageX(e),YAHOO.util.Event.getPageY(e)];
    //startleft_btnNO;
    
    //Panel btnW
    startPos_btnW = [YAHOO.util.Event.getPageX(e),YAHOO.util.Event.getPageY(e)];
    startHeight_btnW = panel_btnW.offsetHeight;
    
    //Panel btnO
    startPos_btnO = [YAHOO.util.Event.getPageX(e),YAHOO.util.Event.getPageY(e)];
    startHeight_btnO = panel_btnO.offsetHeight;
    //startleft_btnO;
    
    //Panel btnSW
    startPos_btnSW = [YAHOO.util.Event.getPageX(e),YAHOO.util.Event.getPageY(e)];
    //starttop_btnSW;
    
    //Panel btnS
   startPos_btnS = [YAHOO.util.Event.getPageX(e),YAHOO.util.Event.getPageY(e)];
    startWidth_btnS = panel_btnS.offsetWidth;
    //starttop_btnSW;
    
    //Panel btnSO
    startPos_btnSO = [YAHOO.util.Event.getPageX(e),YAHOO.util.Event.getPageY(e)];
    //startleft_btnSO;
    //$("btnImgScale").onmousemove = resize_move;

    //Panel urltool
    startPos_btnurltool = [YAHOO.util.Event.getPageX(e),YAHOO.util.Event.getPageY(e)];    
	
    document.onmousemove = resize_move;
    return false;
}

function resize_move(e){
	//Panel map
	var newPos_map = [YAHOO.util.Event.getPageX(e),YAHOO.util.Event.getPageY(e)];
	var offsetX_map = newPos_map[0] - startPos_map[0];
    var offsetY_map = newPos_map[1] - startPos_map[1];
	newWidth_map = Math.max(startWidth_map + offsetX_map, 10);
    newHeight_map = Math.max(startHeight_map + offsetY_map, 10);
    panel_map.style.width = newWidth_map+ "px";
    panel_map.style.height = newHeight_map + "px";
    	
	//Panel btnN
	panel_btnN.style.width = newWidth_map+ "px";
   	
	//Panel btnNO
	panel_btnNO.style.left =  (newWidth_map+12)+ "px";
	
	//Panel btnW
	panel_btnW.style.height = newHeight_map + "px";
	$("btnW_img").style.top = newHeight_map/2 + "px";
	
	//Panel btnO
	panel_btnO.style.height = newHeight_map + "px";
	panel_btnO.style.left = (12+newWidth_map) + "px";
	$("btnO_img").style.top = newHeight_map/2 + "px";
	
	//Panel btnSW
	panel_btnSW.style.top = (12+newHeight_map) + "px";
	
	//Panel btnS
	panel_btnS.style.width = newWidth_map+ "px";
   	panel_btnS.style.top = (12+newHeight_map) + "px";
   	
	//Panel btnSO
	panel_btnSO.style.top = (12+newHeight_map) + "px";
	panel_btnSO.style.left = (12+newWidth_map) + "px";
	
	//Panel Scale
	panel_Scale.style.top = (26+newHeight_map) + "px";
	panel_Scale.style.left = (26+newWidth_map) + "px";
	panel_Scale.style.width = "12px";
	panel_Scale.style.height = "12px";
    if(parseInt($("urltool").style.left) <= 526){
        $('urltool').style.left = 556+"px";
    }    

    document.onmouseup = resize_up;
    return false;
}

function resize_up(){
	var old_width = document.formImg.width.value;
	var old_height = document.formImg.height.value;
	if(newWidth_map<230){
		newWidth_map = 230;
	}
	else if(newWidth_map>1000){
		newWidth_map = 1000;
	}
	if(newHeight_map<230){
		newHeight_map = 230;
	}
	else if(newHeight_map>1000){
		newHeight_map = 1000;
	}
	var newwidth = newWidth_map;
    var newheight = newHeight_map;
    if(newwidth != null && newheight != null){
        var old_dR = parseFloat(document.formImg.ro.value) - parseFloat(document.formImg.ru.value);
        var old_dH = parseFloat(document.formImg.ho.value) - parseFloat(document.formImg.hu.value);
        var mitteR = parseFloat(document.formImg.ru.value) + (old_dR/2);
        var mitteH = parseFloat(document.formImg.hu.value) + (old_dH/2);
	    var new_dR = old_dR / old_width * newwidth;
        var new_dH = old_dH / old_height * newheight;
        var ru = mitteR - new_dR / 2;
        var hu = mitteH - new_dH / 2;
        var ro = mitteR + new_dR / 2;
        var ho = mitteH + new_dH / 2;
        document.formImg.ru.value = ru;
        document.formImg.hu.value = hu;
        document.formImg.ro.value = ro;
        document.formImg.ho.value = ho;
	    document.formImg.width.value = newWidth_map;
	    document.formImg.height.value = newHeight_map;	
    }
    s_firstmessen = 1;
	_scale = "no";
	var dR = parseFloat(ro) - parseFloat(ru);
    var dH = parseFloat(ho) - parseFloat(hu);
	var newW = parseFloat(document.formImg.width.value);
	var newH = parseFloat(document.formImg.height.value);
    panel_map.style.width = newW+"px";
    panel_map.style.height = newH+"px";
	//Panel btnN
	panel_btnN.style.width = newW+ "px";
   	
	//Panel btnNO
	panel_btnNO.style.left = (12+newW) + "px";
	
	//Panel btnW
	panel_btnW.style.height = newH + "px";
	$("btnW_img").style.top = newH/2 + "px";
	
	//Panel btnO
	panel_btnO.style.height = newH + "px";
	panel_btnO.style.left = (12+newW) + "px";
	$("btnO_img").style.top = newH/2 + "px";
	
	//Panel btnSW
	panel_btnSW.style.top = (12+newH) + "px";
	
	//Panel btnS
	panel_btnS.style.width = newW+ "px";
   	panel_btnS.style.top = (12+newH) + "px";
   	
	//Panel btnSO
	panel_btnSO.style.top = (12+newH) + "px";
	panel_btnSO.style.left = (12+newW) + "px";
	
	//Panel Scale
	panel_Scale.style.top = (26+newH) + "px";
	panel_Scale.style.left = (26+newW) + "px";
	Scale_x = parseInt(panel_Scale.style.top);
	Scale_y = parseInt(panel_Scale.style.left);
	if(parseInt($("urltool").style.left) <= 526){
        $('urltool').style.left = 556+"px";
    }
	updateMap();
	//******************************
    if(document.pktPosition && (document.pktPosition.length > 0) ) {
        messenend();
        $("imgPolygon").style.visibility = "visible";
        var punkte1 = document.gkpunkte;
        var punkte2 = document.pktPosition;
        for(var t = 0; t < punkte1.length; t++){
            punkte2[t] = gk2s(punkte1[t].getX(), punkte1[t].getY(), newW, newH, dR, dH, ru, hu);
        }
        drawPoly();
        if($("iconStrecke").src.indexOf("res/Button_Lineal.gif") < 0 && $("iconFlaeche").src.indexOf("res/Button_Lineal_Flaeche.gif") < 0){
            var _obj = getRawObject("imgPolygon");
            _obj.innerHTML = "";
        }
    }
    if($("pkt_koord").innerHTML == "Ort_wird_gefunden"){
        var uX = gk2s(document.formImg.ru.value, document.formImg.hu.value, newW, newH, dR, dH, ru, hu).getX();
        var uY = gk2s(document.formImg.ru.value, document.formImg.hu.value, newW, newH, dR, dH, ru, hu).getY();
        var oX = gk2s(document.formImg.ro.value, document.formImg.ho.value, newW, newH, dR, dH, ru, hu).getX();
        var oY = gk2s(document.formImg.ro.value, document.formImg.ho.value, newW, newH, dR, dH, ru, hu).getY();
    }
    //********************************
	panel_Scale = false;
	panel_map = false;
	panel_btnN = false;
	panel_btnNO = false;
	panel_btnW = false;
	panel_btnO = false;
	panel_btnSW = false;
	panel_btnS = false;
	panel_btnSO = false;
	document.onmouseup = "";
	document.onmousemove = "";
	return false;
}
/*  Prototype JavaScript framework, version 1.4.0
 *  (c) 2005 Sam Stephenson <sam@conio.net>
 *
 *  Prototype is freely distributable under the terms of an MIT-style license.
 *  For details, see the Prototype web site: http://prototype.conio.net/
 *
/*--------------------------------------------------------------------------*/

var Prototype = {
  Version: '1.4.0',
  ScriptFragment: '(?:<script.*?>)((\n|\r|.)*?)(?:<\/script>)',

  emptyFunction: function() {},
  K: function(x) {return x}
}

var Class = {
  create: function() {
    return function() {
      this.initialize.apply(this, arguments);
    }
  }
}

var Abstract = new Object();

Object.extend = function(destination, source) {
  for (property in source) {
    destination[property] = source[property];
  }
  return destination;
}

Object.inspect = function(object) {
  try {
    if (object == undefined) return 'undefined';
    if (object == null) return 'null';
    return object.inspect ? object.inspect() : object.toString();
  } catch (e) {
    if (e instanceof RangeError) return '...';
    throw e;
  }
}

Function.prototype.bind = function() {
  var __method = this, args = $A(arguments), object = args.shift();
  return function() {
    return __method.apply(object, args.concat($A(arguments)));
  }
}

Function.prototype.bindAsEventListener = function(object) {
  var __method = this;
  return function(event) {
    return __method.call(object, event || window.event);
  }
}

Object.extend(Number.prototype, {
  toColorPart: function() {
    var digits = this.toString(16);
    if (this < 16) return '0' + digits;
    return digits;
  },

  succ: function() {
    return this + 1;
  },

  times: function(iterator) {
    $R(0, this, true).each(iterator);
    return this;
  }
});

var Try = {
  these: function() {
    var returnValue;

    for (var i = 0; i < arguments.length; i++) {
      var lambda = arguments[i];
      try {
        returnValue = lambda();
        break;
      } catch (e) {}
    }

    return returnValue;
  }
}

/*--------------------------------------------------------------------------*/

var PeriodicalExecuter = Class.create();
PeriodicalExecuter.prototype = {
  initialize: function(callback, frequency) {
    this.callback = callback;
    this.frequency = frequency;
    this.currentlyExecuting = false;

    this.registerCallback();
  },

  registerCallback: function() {
    setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
  },

  onTimerEvent: function() {
    if (!this.currentlyExecuting) {
      try {
        this.currentlyExecuting = true;
        this.callback();
      } finally {
        this.currentlyExecuting = false;
      }
    }
  }
}

/*--------------------------------------------------------------------------*/

function $() {
  var elements = new Array();

  for (var i = 0; i < arguments.length; i++) {
    var element = arguments[i];
    if (typeof element == 'string')
      element = document.getElementById(element);

    if (arguments.length == 1)
      return element;

    elements.push(element);
  }

  return elements;
}
Object.extend(String.prototype, {
  stripTags: function() {
    return this.replace(/<\/?[^>]+>/gi, '');
  },

  stripScripts: function() {
    return this.replace(new RegExp(Prototype.ScriptFragment, 'img'), '');
  },

  extractScripts: function() {
    var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
    var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
    return (this.match(matchAll) || []).map(function(scriptTag) {
      return (scriptTag.match(matchOne) || ['', ''])[1];
    });
  },

  evalScripts: function() {
    return this.extractScripts().map(eval);
  },

  escapeHTML: function() {
    var div = document.createElement('div');
    var text = document.createTextNode(this);
    div.appendChild(text);
    return div.innerHTML;
  },

  unescapeHTML: function() {
    var div = document.createElement('div');
    div.innerHTML = this.stripTags();
    return div.childNodes[0] ? div.childNodes[0].nodeValue : '';
  },

  toQueryParams: function() {
    var pairs = this.match(/^\??(.*)$/)[1].split('&');
    return pairs.inject({}, function(params, pairString) {
      var pair = pairString.split('=');
      params[pair[0]] = pair[1];
      return params;
    });
  },

  toArray: function() {
    return this.split('');
  },

  camelize: function() {
    var oStringList = this.split('-');
    if (oStringList.length == 1) return oStringList[0];

    var camelizedString = this.indexOf('-') == 0
      ? oStringList[0].charAt(0).toUpperCase() + oStringList[0].substring(1)
      : oStringList[0];

    for (var i = 1, len = oStringList.length; i < len; i++) {
      var s = oStringList[i];
      camelizedString += s.charAt(0).toUpperCase() + s.substring(1);
    }

    return camelizedString;
  },

  inspect: function() {
    return "'" + this.replace('\\', '\\\\').replace("'", '\\\'') + "'";
  }
});

String.prototype.parseQuery = String.prototype.toQueryParams;

var $break    = new Object();
var $continue = new Object();

var Enumerable = {
  each: function(iterator) {
    var index = 0;
    try {
      this._each(function(value) {
        try {
          iterator(value, index++);
        } catch (e) {
          if (e != $continue) throw e;
        }
      });
    } catch (e) {
      if (e != $break) throw e;
    }
  },

  all: function(iterator) {
    var result = true;
    this.each(function(value, index) {
      result = result && !!(iterator || Prototype.K)(value, index);
      if (!result) throw $break;
    });
    return result;
  },

  any: function(iterator) {
    var result = true;
    this.each(function(value, index) {
      if (result = !!(iterator || Prototype.K)(value, index))
        throw $break;
    });
    return result;
  },

  collect: function(iterator) {
    var results = [];
    this.each(function(value, index) {
      results.push(iterator(value, index));
    });
    return results;
  },

  detect: function (iterator) {
    var result;
    this.each(function(value, index) {
      if (iterator(value, index)) {
        result = value;
        throw $break;
      }
    });
    return result;
  },

  findAll: function(iterator) {
    var results = [];
    this.each(function(value, index) {
      if (iterator(value, index))
        results.push(value);
    });
    return results;
  },

  grep: function(pattern, iterator) {
    var results = [];
    this.each(function(value, index) {
      var stringValue = value.toString();
      if (stringValue.match(pattern))
        results.push((iterator || Prototype.K)(value, index));
    })
    return results;
  },

  include: function(object) {
    var found = false;
    this.each(function(value) {
      if (value == object) {
        found = true;
        throw $break;
      }
    });
    return found;
  },

  inject: function(memo, iterator) {
    this.each(function(value, index) {
      memo = iterator(memo, value, index);
    });
    return memo;
  },

  invoke: function(method) {
    var args = $A(arguments).slice(1);
    return this.collect(function(value) {
      return value[method].apply(value, args);
    });
  },

  max: function(iterator) {
    var result;
    this.each(function(value, index) {
      value = (iterator || Prototype.K)(value, index);
      if (value >= (result || value))
        result = value;
    });
    return result;
  },

  min: function(iterator) {
    var result;
    this.each(function(value, index) {
      value = (iterator || Prototype.K)(value, index);
      if (value <= (result || value))
        result = value;
    });
    return result;
  },

  partition: function(iterator) {
    var trues = [], falses = [];
    this.each(function(value, index) {
      ((iterator || Prototype.K)(value, index) ?
        trues : falses).push(value);
    });
    return [trues, falses];
  },

  pluck: function(property) {
    var results = [];
    this.each(function(value, index) {
      results.push(value[property]);
    });
    return results;
  },

  reject: function(iterator) {
    var results = [];
    this.each(function(value, index) {
      if (!iterator(value, index))
        results.push(value);
    });
    return results;
  },

  sortBy: function(iterator) {
    return this.collect(function(value, index) {
      return {value: value, criteria: iterator(value, index)};
    }).sort(function(left, right) {
      var a = left.criteria, b = right.criteria;
      return a < b ? -1 : a > b ? 1 : 0;
    }).pluck('value');
  },

  toArray: function() {
    return this.collect(Prototype.K);
  },

  zip: function() {
    var iterator = Prototype.K, args = $A(arguments);
    if (typeof args.last() == 'function')
      iterator = args.pop();

    var collections = [this].concat(args).map($A);
    return this.map(function(value, index) {
      iterator(value = collections.pluck(index));
      return value;
    });
  },

  inspect: function() {
    return '#<Enumerable:' + this.toArray().inspect() + '>';
  }
}

Object.extend(Enumerable, {
  map:     Enumerable.collect,
  find:    Enumerable.detect,
  select:  Enumerable.findAll,
  member:  Enumerable.include,
  entries: Enumerable.toArray
});
var $A = Array.from = function(iterable) {
  if (!iterable) return [];
  if (iterable.toArray) {
    return iterable.toArray();
  } else {
    var results = [];
    for (var i = 0; i < iterable.length; i++)
      results.push(iterable[i]);
    return results;
  }
}

Object.extend(Array.prototype, Enumerable);

Array.prototype._reverse = Array.prototype.reverse;

Object.extend(Array.prototype, {
  _each: function(iterator) {
    for (var i = 0; i < this.length; i++)
      iterator(this[i]);
  },

  clear: function() {
    this.length = 0;
    return this;
  },

  first: function() {
    return this[0];
  },

  last: function() {
    return this[this.length - 1];
  },

  compact: function() {
    return this.select(function(value) {
      return value != undefined || value != null;
    });
  },

  flatten: function() {
    return this.inject([], function(array, value) {
      return array.concat(value.constructor == Array ?
        value.flatten() : [value]);
    });
  },

  without: function() {
    var values = $A(arguments);
    return this.select(function(value) {
      return !values.include(value);
    });
  },

  indexOf: function(object) {
    for (var i = 0; i < this.length; i++)
      if (this[i] == object) return i;
    return -1;
  },

  reverse: function(inline) {
    return (inline !== false ? this : this.toArray())._reverse();
  },

  shift: function() {
    var result = this[0];
    for (var i = 0; i < this.length - 1; i++)
      this[i] = this[i + 1];
    this.length--;
    return result;
  },

  inspect: function() {
    return '[' + this.map(Object.inspect).join(', ') + ']';
  }
});
var Hash = {
  _each: function(iterator) {
    for (key in this) {
      var value = this[key];
      if (typeof value == 'function') continue;

      var pair = [key, value];
      pair.key = key;
      pair.value = value;
      iterator(pair);
    }
  },

  keys: function() {
    return this.pluck('key');
  },

  values: function() {
    return this.pluck('value');
  },

  merge: function(hash) {
    return $H(hash).inject($H(this), function(mergedHash, pair) {
      mergedHash[pair.key] = pair.value;
      return mergedHash;
    });
  },

  toQueryString: function() {
    return this.map(function(pair) {
      return pair.map(encodeURIComponent).join('=');
    }).join('&');
  },

  inspect: function() {
    return '#<Hash:{' + this.map(function(pair) {
      return pair.map(Object.inspect).join(': ');
    }).join(', ') + '}>';
  }
}

function $H(object) {
  var hash = Object.extend({}, object || {});
  Object.extend(hash, Enumerable);
  Object.extend(hash, Hash);
  return hash;
}
ObjectRange = Class.create();
Object.extend(ObjectRange.prototype, Enumerable);
Object.extend(ObjectRange.prototype, {
  initialize: function(start, end, exclusive) {
    this.start = start;
    this.end = end;
    this.exclusive = exclusive;
  },

  _each: function(iterator) {
    var value = this.start;
    do {
      iterator(value);
      value = value.succ();
    } while (this.include(value));
  },

  include: function(value) {
    if (value < this.start)
      return false;
    if (this.exclusive)
      return value < this.end;
    return value <= this.end;
  }
});

var $R = function(start, end, exclusive) {
  return new ObjectRange(start, end, exclusive);
}

var Ajax = {
  getTransport: function() {
    return Try.these(
      function() {return new ActiveXObject('Msxml2.XMLHTTP')},
      function() {return new ActiveXObject('Microsoft.XMLHTTP')},
      function() {return new XMLHttpRequest()}
    ) || false;
  },

  activeRequestCount: 0
}

Ajax.Responders = {
  responders: [],

  _each: function(iterator) {
    this.responders._each(iterator);
  },

  register: function(responderToAdd) {
    if (!this.include(responderToAdd))
      this.responders.push(responderToAdd);
  },

  unregister: function(responderToRemove) {
    this.responders = this.responders.without(responderToRemove);
  },

  dispatch: function(callback, request, transport, json) {
    this.each(function(responder) {
      if (responder[callback] && typeof responder[callback] == 'function') {
        try {
          responder[callback].apply(responder, [request, transport, json]);
        } catch (e) {}
      }
    });
  }
};

Object.extend(Ajax.Responders, Enumerable);

Ajax.Responders.register({
  onCreate: function() {
    Ajax.activeRequestCount++;
  },

  onComplete: function() {
    Ajax.activeRequestCount--;
  }
});

Ajax.Base = function() {};
Ajax.Base.prototype = {
  setOptions: function(options) {
    this.options = {
      method:       'post',
      asynchronous: true,
      parameters:   ''
    }
    Object.extend(this.options, options || {});
  },

  responseIsSuccess: function() {
    return this.transport.status == undefined
        || this.transport.status == 0
        || (this.transport.status >= 200 && this.transport.status < 300);
  },

  responseIsFailure: function() {
    return !this.responseIsSuccess();
  }
}

Ajax.Request = Class.create();
Ajax.Request.Events =
  ['Uninitialized', 'Loading', 'Loaded', 'Interactive', 'Complete'];

Ajax.Request.prototype = Object.extend(new Ajax.Base(), {
  initialize: function(url, options) {
    this.transport = Ajax.getTransport();
    this.setOptions(options);
    this.request(url);
  },

  request: function(url) {
    var parameters = this.options.parameters || '';
    if (parameters.length > 0) parameters += '&_=';

    try {
      this.url = url;
      if (this.options.method == 'get' && parameters.length > 0)
        this.url += (this.url.match(/\?/) ? '&' : '?') + parameters;

      Ajax.Responders.dispatch('onCreate', this, this.transport);

      this.transport.open(this.options.method, this.url,
        this.options.asynchronous);

      if (this.options.asynchronous) {
        this.transport.onreadystatechange = this.onStateChange.bind(this);
        setTimeout((function() {this.respondToReadyState(1)}).bind(this), 10);
      }

      this.setRequestHeaders();

      var body = this.options.postBody ? this.options.postBody : parameters;
      this.transport.send(this.options.method == 'post' ? body : null);

    } catch (e) {
      this.dispatchException(e);
    }
  },

  setRequestHeaders: function() {
    var requestHeaders =
      ['X-Requested-With', 'XMLHttpRequest',
       'X-Prototype-Version', Prototype.Version];

    if (this.options.method == 'post') {
      requestHeaders.push('Content-type',
        'application/x-www-form-urlencoded');

      /* Force "Connection: close" for Mozilla browsers to work around
       * a bug where XMLHttpReqeuest sends an incorrect Content-length
       * header. See Mozilla Bugzilla #246651.
       */
      if (this.transport.overrideMimeType)
        requestHeaders.push('Connection', 'close');
    }

    if (this.options.requestHeaders)
      requestHeaders.push.apply(requestHeaders, this.options.requestHeaders);

    for (var i = 0; i < requestHeaders.length; i += 2)
      this.transport.setRequestHeader(requestHeaders[i], requestHeaders[i+1]);
  },

  onStateChange: function() {
    var readyState = this.transport.readyState;
    if (readyState != 1)
      this.respondToReadyState(this.transport.readyState);
  },

  header: function(name) {
    try {
      return this.transport.getResponseHeader(name);
    } catch (e) {}
  },

  evalJSON: function() {
    try {
      return eval(this.header('X-JSON'));
    } catch (e) {}
  },

  evalResponse: function() {
    try {
      return eval(this.transport.responseText);
    } catch (e) {
      this.dispatchException(e);
    }
  },

  respondToReadyState: function(readyState) {
    var event = Ajax.Request.Events[readyState];
    var transport = this.transport, json = this.evalJSON();

    if (event == 'Complete') {
      try {
        (this.options['on' + this.transport.status]
         || this.options['on' + (this.responseIsSuccess() ? 'Success' : 'Failure')]
         || Prototype.emptyFunction)(transport, json);
      } catch (e) {
        this.dispatchException(e);
      }

      if ((this.header('Content-type') || '').match(/^text\/javascript/i))
        this.evalResponse();
    }

    try {
      (this.options['on' + event] || Prototype.emptyFunction)(transport, json);
      Ajax.Responders.dispatch('on' + event, this, transport, json);
    } catch (e) {
      this.dispatchException(e);
    }

    /* Avoid memory leak in MSIE: clean up the oncomplete event handler */
    if (event == 'Complete')
      this.transport.onreadystatechange = Prototype.emptyFunction;
  },

  dispatchException: function(exception) {
    (this.options.onException || Prototype.emptyFunction)(this, exception);
    Ajax.Responders.dispatch('onException', this, exception);
  }
});

Ajax.Updater = Class.create();

Object.extend(Object.extend(Ajax.Updater.prototype, Ajax.Request.prototype), {
  initialize: function(container, url, options) {
    this.containers = {
      success: container.success ? $(container.success) : $(container),
      failure: container.failure ? $(container.failure) :
        (container.success ? null : $(container))
    }

    this.transport = Ajax.getTransport();
    this.setOptions(options);

    var onComplete = this.options.onComplete || Prototype.emptyFunction;
    this.options.onComplete = (function(transport, object) {
      this.updateContent();
      onComplete(transport, object);
    }).bind(this);

    this.request(url);
  },

  updateContent: function() {
    var receiver = this.responseIsSuccess() ?
      this.containers.success : this.containers.failure;
    var response = this.transport.responseText;

    if (!this.options.evalScripts)
      response = response.stripScripts();

    if (receiver) {
      if (this.options.insertion) {
        new this.options.insertion(receiver, response);
      } else {
        Element.update(receiver, response);
      }
    }

    if (this.responseIsSuccess()) {
      if (this.onComplete)
        setTimeout(this.onComplete.bind(this), 10);
    }
  }
});

Ajax.PeriodicalUpdater = Class.create();
Ajax.PeriodicalUpdater.prototype = Object.extend(new Ajax.Base(), {
  initialize: function(container, url, options) {
    this.setOptions(options);
    this.onComplete = this.options.onComplete;

    this.frequency = (this.options.frequency || 2);
    this.decay = (this.options.decay || 1);

    this.updater = {};
    this.container = container;
    this.url = url;

    this.start();
  },

  start: function() {
    this.options.onComplete = this.updateComplete.bind(this);
    this.onTimerEvent();
  },

  stop: function() {
    this.updater.onComplete = undefined;
    clearTimeout(this.timer);
    (this.onComplete || Prototype.emptyFunction).apply(this, arguments);
  },

  updateComplete: function(request) {
    if (this.options.decay) {
      this.decay = (request.responseText == this.lastText ?
        this.decay * this.options.decay : 1);

      this.lastText = request.responseText;
    }
    this.timer = setTimeout(this.onTimerEvent.bind(this),
      this.decay * this.frequency * 1000);
  },

  onTimerEvent: function() {
    this.updater = new Ajax.Updater(this.container, this.url, this.options);
  }
});
document.getElementsByClassName = function(className, parentElement) {
  var children = ($(parentElement) || document.body).getElementsByTagName('*');
  return $A(children).inject([], function(elements, child) {
    if (child.className.match(new RegExp("(^|\\s)" + className + "(\\s|$)")))
      elements.push(child);
    return elements;
  });
}

/*--------------------------------------------------------------------------*/

if (!window.Element) {
  var Element = new Object();
}

Object.extend(Element, {
  visible: function(element) {
    return $(element).style.display != 'none';
  },

  toggle: function() {
    for (var i = 0; i < arguments.length; i++) {
      var element = $(arguments[i]);
      Element[Element.visible(element) ? 'hide' : 'show'](element);
    }
  },

  hide: function() {
    for (var i = 0; i < arguments.length; i++) {
      var element = $(arguments[i]);
      element.style.display = 'none';
    }
  },

  show: function() {
    for (var i = 0; i < arguments.length; i++) {
      var element = $(arguments[i]);
      element.style.display = '';
    }
  },

  remove: function(element) {
    element = $(element);
    element.parentNode.removeChild(element);
  },

  update: function(element, html) {
    $(element).innerHTML = html.stripScripts();
    setTimeout(function() {html.evalScripts()}, 10);
  },

  getHeight: function(element) {
    element = $(element);
    return element.offsetHeight;
  },

  classNames: function(element) {
    return new Element.ClassNames(element);
  },

  hasClassName: function(element, className) {
    if (!(element = $(element))) return;
    return Element.classNames(element).include(className);
  },

  addClassName: function(element, className) {
    if (!(element = $(element))) return;
    return Element.classNames(element).add(className);
  },

  removeClassName: function(element, className) {
    if (!(element = $(element))) return;
    return Element.classNames(element).remove(className);
  },

  // removes whitespace-only text node children
  cleanWhitespace: function(element) {
    element = $(element);
    for (var i = 0; i < element.childNodes.length; i++) {
      var node = element.childNodes[i];
      if (node.nodeType == 3 && !/\S/.test(node.nodeValue))
        Element.remove(node);
    }
  },

  empty: function(element) {
    return $(element).innerHTML.match(/^\s*$/);
  },

  scrollTo: function(element) {
    element = $(element);
    var x = element.x ? element.x : element.offsetLeft,
        y = element.y ? element.y : element.offsetTop;
    window.scrollTo(x, y);
  },

  getStyle: function(element, style) {
    element = $(element);
    var value = element.style[style.camelize()];
    if (!value) {
      if (document.defaultView && document.defaultView.getComputedStyle) {
        var css = document.defaultView.getComputedStyle(element, null);
        value = css ? css.getPropertyValue(style) : null;
      } else if (element.currentStyle) {
        value = element.currentStyle[style.camelize()];
      }
    }

    if (window.opera && ['left', 'top', 'right', 'bottom'].include(style))
      if (Element.getStyle(element, 'position') == 'static') value = 'auto';

    return value == 'auto' ? null : value;
  },

  setStyle: function(element, style) {
    element = $(element);
    for (name in style)
      element.style[name.camelize()] = style[name];
  },

  getDimensions: function(element) {
    element = $(element);
    if (Element.getStyle(element, 'display') != 'none')
      return {width: element.offsetWidth, height: element.offsetHeight};

    // All *Width and *Height properties give 0 on elements with display none,
    // so enable the element temporarily
    var els = element.style;
    var originalVisibility = els.visibility;
    var originalPosition = els.position;
    els.visibility = 'hidden';
    els.position = 'absolute';
    els.display = '';
    var originalWidth = element.clientWidth;
    var originalHeight = element.clientHeight;
    els.display = 'none';
    els.position = originalPosition;
    els.visibility = originalVisibility;
    return {width: originalWidth, height: originalHeight};
  },

  makePositioned: function(element) {
    element = $(element);
    var pos = Element.getStyle(element, 'position');
    if (pos == 'static' || !pos) {
      element._madePositioned = true;
      element.style.position = 'relative';
      // Opera returns the offset relative to the positioning context, when an
      // element is position relative but top and left have not been defined
      if (window.opera) {
        element.style.top = 0;
        element.style.left = 0;
      }
    }
  },

  undoPositioned: function(element) {
    element = $(element);
    if (element._madePositioned) {
      element._madePositioned = undefined;
      element.style.position =
        element.style.top =
        element.style.left =
        element.style.bottom =
        element.style.right = '';
    }
  },

  makeClipping: function(element) {
    element = $(element);
    if (element._overflow) return;
    element._overflow = element.style.overflow;
    if ((Element.getStyle(element, 'overflow') || 'visible') != 'hidden')
      element.style.overflow = 'hidden';
  },

  undoClipping: function(element) {
    element = $(element);
    if (element._overflow) return;
    element.style.overflow = element._overflow;
    element._overflow = undefined;
  }
});

var Toggle = new Object();
Toggle.display = Element.toggle;

/*--------------------------------------------------------------------------*/

Abstract.Insertion = function(adjacency) {
  this.adjacency = adjacency;
}

Abstract.Insertion.prototype = {
  initialize: function(element, content) {
    this.element = $(element);
    this.content = content.stripScripts();

    if (this.adjacency && this.element.insertAdjacentHTML) {
      try {
        this.element.insertAdjacentHTML(this.adjacency, this.content);
      } catch (e) {
        if (this.element.tagName.toLowerCase() == 'tbody') {
          this.insertContent(this.contentFromAnonymousTable());
        } else {
          throw e;
        }
      }
    } else {
      this.range = this.element.ownerDocument.createRange();
      if (this.initializeRange) this.initializeRange();
      this.insertContent([this.range.createContextualFragment(this.content)]);
    }

    setTimeout(function() {content.evalScripts()}, 10);
  },

  contentFromAnonymousTable: function() {
    var div = document.createElement('div');
    div.innerHTML = '<table><tbody>' + this.content + '</tbody></table>';
    return $A(div.childNodes[0].childNodes[0].childNodes);
  }
}

var Insertion = new Object();

Insertion.Before = Class.create();
Insertion.Before.prototype = Object.extend(new Abstract.Insertion('beforeBegin'), {
  initializeRange: function() {
    this.range.setStartBefore(this.element);
  },

  insertContent: function(fragments) {
    fragments.each((function(fragment) {
      this.element.parentNode.insertBefore(fragment, this.element);
    }).bind(this));
  }
});

Insertion.Top = Class.create();
Insertion.Top.prototype = Object.extend(new Abstract.Insertion('afterBegin'), {
  initializeRange: function() {
    this.range.selectNodeContents(this.element);
    this.range.collapse(true);
  },

  insertContent: function(fragments) {
    fragments.reverse(false).each((function(fragment) {
      this.element.insertBefore(fragment, this.element.firstChild);
    }).bind(this));
  }
});

Insertion.Bottom = Class.create();
Insertion.Bottom.prototype = Object.extend(new Abstract.Insertion('beforeEnd'), {
  initializeRange: function() {
    this.range.selectNodeContents(this.element);
    this.range.collapse(this.element);
  },

  insertContent: function(fragments) {
    fragments.each((function(fragment) {
      this.element.appendChild(fragment);
    }).bind(this));
  }
});

Insertion.After = Class.create();
Insertion.After.prototype = Object.extend(new Abstract.Insertion('afterEnd'), {
  initializeRange: function() {
    this.range.setStartAfter(this.element);
  },

  insertContent: function(fragments) {
    fragments.each((function(fragment) {
      this.element.parentNode.insertBefore(fragment,
        this.element.nextSibling);
    }).bind(this));
  }
});

/*--------------------------------------------------------------------------*/

Element.ClassNames = Class.create();
Element.ClassNames.prototype = {
  initialize: function(element) {
    this.element = $(element);
  },

  _each: function(iterator) {
    this.element.className.split(/\s+/).select(function(name) {
      return name.length > 0;
    })._each(iterator);
  },

  set: function(className) {
    this.element.className = className;
  },

  add: function(classNameToAdd) {
    if (this.include(classNameToAdd)) return;
    this.set(this.toArray().concat(classNameToAdd).join(' '));
  },

  remove: function(classNameToRemove) {
    if (!this.include(classNameToRemove)) return;
    this.set(this.select(function(className) {
      return className != classNameToRemove;
    }).join(' '));
  },

  toString: function() {
    return this.toArray().join(' ');
  }
}

Object.extend(Element.ClassNames.prototype, Enumerable);
var Field = {
  clear: function() {
    for (var i = 0; i < arguments.length; i++)
      $(arguments[i]).value = '';
  },

  focus: function(element) {
    $(element).focus();
  },

  present: function() {
    for (var i = 0; i < arguments.length; i++)
      if ($(arguments[i]).value == '') return false;
    return true;
  },

  select: function(element) {
    $(element).select();
  },

  activate: function(element) {
    element = $(element);
    element.focus();
    if (element.select)
      element.select();
  }
}

/*--------------------------------------------------------------------------*/

var Form = {
  serialize: function(form) {
    var elements = Form.getElements($(form));
    var queryComponents = new Array();

    for (var i = 0; i < elements.length; i++) {
      var queryComponent = Form.Element.serialize(elements[i]);
      if (queryComponent)
        queryComponents.push(queryComponent);
    }

    return queryComponents.join('&');
  },

  getElements: function(form) {
    form = $(form);
    var elements = new Array();

    for (tagName in Form.Element.Serializers) {
      var tagElements = form.getElementsByTagName(tagName);
      for (var j = 0; j < tagElements.length; j++)
        elements.push(tagElements[j]);
    }
    return elements;
  },

  getInputs: function(form, typeName, name) {
    form = $(form);
    var inputs = form.getElementsByTagName('input');

    if (!typeName && !name)
      return inputs;

    var matchingInputs = new Array();
    for (var i = 0; i < inputs.length; i++) {
      var input = inputs[i];
      if ((typeName && input.type != typeName) ||
          (name && input.name != name))
        continue;
      matchingInputs.push(input);
    }

    return matchingInputs;
  },

  disable: function(form) {
    var elements = Form.getElements(form);
    for (var i = 0; i < elements.length; i++) {
      var element = elements[i];
      element.blur();
      element.disabled = 'true';
    }
  },

  enable: function(form) {
    var elements = Form.getElements(form);
    for (var i = 0; i < elements.length; i++) {
      var element = elements[i];
      element.disabled = '';
    }
  },

  findFirstElement: function(form) {
    return Form.getElements(form).find(function(element) {
      return element.type != 'hidden' && !element.disabled &&
        ['input', 'select', 'textarea'].include(element.tagName.toLowerCase());
    });
  },

  focusFirstElement: function(form) {
    Field.activate(Form.findFirstElement(form));
  },

  reset: function(form) {
    $(form).reset();
  }
}

Form.Element = {
  serialize: function(element) {
    element = $(element);
    var method = element.tagName.toLowerCase();
    var parameter = Form.Element.Serializers[method](element);

    if (parameter) {
      var key = encodeURIComponent(parameter[0]);
      if (key.length == 0) return;

      if (parameter[1].constructor != Array)
        parameter[1] = [parameter[1]];

      return parameter[1].map(function(value) {
        return key + '=' + encodeURIComponent(value);
      }).join('&');
    }
  },

  getValue: function(element) {
    element = $(element);
    var method = element.tagName.toLowerCase();
    var parameter = Form.Element.Serializers[method](element);

    if (parameter)
      return parameter[1];
  }
}

Form.Element.Serializers = {
  input: function(element) {
    switch (element.type.toLowerCase()) {
      case 'submit':
      case 'hidden':
      case 'password':
      case 'text':
        return Form.Element.Serializers.textarea(element);
      case 'checkbox':
      case 'radio':
        return Form.Element.Serializers.inputSelector(element);
    }
    return false;
  },

  inputSelector: function(element) {
    if (element.checked)
      return [element.name, element.value];
  },

  textarea: function(element) {
    return [element.name, element.value];
  },

  select: function(element) {
    return Form.Element.Serializers[element.type == 'select-one' ?
      'selectOne' : 'selectMany'](element);
  },

  selectOne: function(element) {
    var value = '', opt, index = element.selectedIndex;
    if (index >= 0) {
      opt = element.options[index];
      value = opt.value;
      if (!value && !('value' in opt))
        value = opt.text;
    }
    return [element.name, value];
  },

  selectMany: function(element) {
    var value = new Array();
    for (var i = 0; i < element.length; i++) {
      var opt = element.options[i];
      if (opt.selected) {
        var optValue = opt.value;
        if (!optValue && !('value' in opt))
          optValue = opt.text;
        value.push(optValue);
      }
    }
    return [element.name, value];
  }
}

/*--------------------------------------------------------------------------*/

var $F = Form.Element.getValue;

/*--------------------------------------------------------------------------*/

Abstract.TimedObserver = function() {}
Abstract.TimedObserver.prototype = {
  initialize: function(element, frequency, callback) {
    this.frequency = frequency;
    this.element   = $(element);
    this.callback  = callback;

    this.lastValue = this.getValue();
    this.registerCallback();
  },

  registerCallback: function() {
    setInterval(this.onTimerEvent.bind(this), this.frequency * 1000);
  },

  onTimerEvent: function() {
    var value = this.getValue();
    if (this.lastValue != value) {
      this.callback(this.element, value);
      this.lastValue = value;
    }
  }
}

Form.Element.Observer = Class.create();
Form.Element.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
  getValue: function() {
    return Form.Element.getValue(this.element);
  }
});

Form.Observer = Class.create();
Form.Observer.prototype = Object.extend(new Abstract.TimedObserver(), {
  getValue: function() {
    return Form.serialize(this.element);
  }
});

/*--------------------------------------------------------------------------*/

Abstract.EventObserver = function() {}
Abstract.EventObserver.prototype = {
  initialize: function(element, callback) {
    this.element  = $(element);
    this.callback = callback;

    this.lastValue = this.getValue();
    if (this.element.tagName.toLowerCase() == 'form')
      this.registerFormCallbacks();
    else
      this.registerCallback(this.element);
  },

  onElementEvent: function() {
    var value = this.getValue();
    if (this.lastValue != value) {
      this.callback(this.element, value);
      this.lastValue = value;
    }
  },

  registerFormCallbacks: function() {
    var elements = Form.getElements(this.element);
    for (var i = 0; i < elements.length; i++)
      this.registerCallback(elements[i]);
  },

  registerCallback: function(element) {
    if (element.type) {
      switch (element.type.toLowerCase()) {
        case 'checkbox':
        case 'radio':
          Event.observe(element, 'click', this.onElementEvent.bind(this));
          break;
        case 'password':
        case 'text':
        case 'textarea':
        case 'select-one':
        case 'select-multiple':
          Event.observe(element, 'change', this.onElementEvent.bind(this));
          break;
      }
    }
  }
}

Form.Element.EventObserver = Class.create();
Form.Element.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
  getValue: function() {
    return Form.Element.getValue(this.element);
  }
});

Form.EventObserver = Class.create();
Form.EventObserver.prototype = Object.extend(new Abstract.EventObserver(), {
  getValue: function() {
    return Form.serialize(this.element);
  }
});
if (!window.Event) {
  var Event = new Object();
}

Object.extend(Event, {
  KEY_BACKSPACE: 8,
  KEY_TAB:       9,
  KEY_RETURN:   13,
  KEY_ESC:      27,
  KEY_LEFT:     37,
  KEY_UP:       38,
  KEY_RIGHT:    39,
  KEY_DOWN:     40,
  KEY_DELETE:   46,

  element: function(event) {
    return event.target || event.srcElement;
  },

  isLeftClick: function(event) {
    return (((event.which) && (event.which == 1)) ||
            ((event.button) && (event.button == 1)));
  },

  pointerX: function(event) {
    return event.pageX || (event.clientX +
      (document.documentElement.scrollLeft || document.body.scrollLeft));
  },

  pointerY: function(event) {
    return event.pageY || (event.clientY +
      (document.documentElement.scrollTop || document.body.scrollTop));
  },

  stop: function(event) {
    if (event.preventDefault) {
      event.preventDefault();
      event.stopPropagation();
    } else {
      event.returnValue = false;
      event.cancelBubble = true;
    }
  },

  // find the first node with the given tagName, starting from the
  // node the event was triggered on; traverses the DOM upwards
  findElement: function(event, tagName) {
    var element = Event.element(event);
    while (element.parentNode && (!element.tagName ||
        (element.tagName.toUpperCase() != tagName.toUpperCase())))
      element = element.parentNode;
    return element;
  },

  observers: false,

  _observeAndCache: function(element, name, observer, useCapture) {
    if (!this.observers) this.observers = [];
    if (element.addEventListener) {
      this.observers.push([element, name, observer, useCapture]);
      element.addEventListener(name, observer, useCapture);
    } else if (element.attachEvent) {
      this.observers.push([element, name, observer, useCapture]);
      element.attachEvent('on' + name, observer);
    }
  },

  unloadCache: function() {
    if (!Event.observers) return;
    for (var i = 0; i < Event.observers.length; i++) {
      Event.stopObserving.apply(this, Event.observers[i]);
      Event.observers[i][0] = null;
    }
    Event.observers = false;
  },

  observe: function(element, name, observer, useCapture) {
    var element = $(element);
    useCapture = useCapture || false;

    if (name == 'keypress' &&
        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
        || element.attachEvent))
      name = 'keydown';

    this._observeAndCache(element, name, observer, useCapture);
  },

  stopObserving: function(element, name, observer, useCapture) {
    var element = $(element);
    useCapture = useCapture || false;

    if (name == 'keypress' &&
        (navigator.appVersion.match(/Konqueror|Safari|KHTML/)
        || element.detachEvent))
      name = 'keydown';

    if (element.removeEventListener) {
      element.removeEventListener(name, observer, useCapture);
    } else if (element.detachEvent) {
      element.detachEvent('on' + name, observer);
    }
  }
});

/* prevent memory leaks in IE */
Event.observe(window, 'unload', Event.unloadCache, false);
var Position = {
  // set to true if needed, warning: firefox performance problems
  // NOT neeeded for page scrolling, only if draggable contained in
  // scrollable elements
  includeScrollOffsets: false,

  // must be called before calling withinIncludingScrolloffset, every time the
  // page is scrolled
  prepare: function() {
    this.deltaX =  window.pageXOffset
                || document.documentElement.scrollLeft
                || document.body.scrollLeft
                || 0;
    this.deltaY =  window.pageYOffset
                || document.documentElement.scrollTop
                || document.body.scrollTop
                || 0;
  },

  realOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.scrollTop  || 0;
      valueL += element.scrollLeft || 0;
      element = element.parentNode;
    } while (element);
    return [valueL, valueT];
  },

  cumulativeOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;
      element = element.offsetParent;
    } while (element);
    return [valueL, valueT];
  },

  positionedOffset: function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;
      element = element.offsetParent;
      if (element) {
        p = Element.getStyle(element, 'position');
        if (p == 'relative' || p == 'absolute') break;
      }
    } while (element);
    return [valueL, valueT];
  },

  offsetParent: function(element) {
    if (element.offsetParent) return element.offsetParent;
    if (element == document.body) return element;

    while ((element = element.parentNode) && element != document.body)
      if (Element.getStyle(element, 'position') != 'static')
        return element;

    return document.body;
  },

  // caches x/y coordinate pair to use with overlap
  within: function(element, x, y) {
    if (this.includeScrollOffsets)
      return this.withinIncludingScrolloffsets(element, x, y);
    this.xcomp = x;
    this.ycomp = y;
    this.offset = this.cumulativeOffset(element);

    return (y >= this.offset[1] &&
            y <  this.offset[1] + element.offsetHeight &&
            x >= this.offset[0] &&
            x <  this.offset[0] + element.offsetWidth);
  },

  withinIncludingScrolloffsets: function(element, x, y) {
    var offsetcache = this.realOffset(element);

    this.xcomp = x + offsetcache[0] - this.deltaX;
    this.ycomp = y + offsetcache[1] - this.deltaY;
    this.offset = this.cumulativeOffset(element);

    return (this.ycomp >= this.offset[1] &&
            this.ycomp <  this.offset[1] + element.offsetHeight &&
            this.xcomp >= this.offset[0] &&
            this.xcomp <  this.offset[0] + element.offsetWidth);
  },

  // within must be called directly before
  overlap: function(mode, element) {
    if (!mode) return 0;
    if (mode == 'vertical')
      return ((this.offset[1] + element.offsetHeight) - this.ycomp) /
        element.offsetHeight;
    if (mode == 'horizontal')
      return ((this.offset[0] + element.offsetWidth) - this.xcomp) /
        element.offsetWidth;
  },

  clone: function(source, target) {
    source = $(source);
    target = $(target);
    target.style.position = 'absolute';
    var offsets = this.cumulativeOffset(source);
    target.style.top    = offsets[1] + 'px';
    target.style.left   = offsets[0] + 'px';
    target.style.width  = source.offsetWidth + 'px';
    target.style.height = source.offsetHeight + 'px';
  },

  page: function(forElement) {
    var valueT = 0, valueL = 0;

    var element = forElement;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;

      // Safari fix
      if (element.offsetParent==document.body)
        if (Element.getStyle(element,'position')=='absolute') break;

    } while (element = element.offsetParent);

    element = forElement;
    do {
      valueT -= element.scrollTop  || 0;
      valueL -= element.scrollLeft || 0;
    } while (element = element.parentNode);

    return [valueL, valueT];
  },

  clone: function(source, target) {
    var options = Object.extend({
      setLeft:    true,
      setTop:     true,
      setWidth:   true,
      setHeight:  true,
      offsetTop:  0,
      offsetLeft: 0
    }, arguments[2] || {})

    // find page position of source
    source = $(source);
    var p = Position.page(source);

    // find coordinate system to use
    target = $(target);
    var delta = [0, 0];
    var parent = null;
    // delta [0,0] will do fine with position: fixed elements,
    // position:absolute needs offsetParent deltas
    if (Element.getStyle(target,'position') == 'absolute') {
      parent = Position.offsetParent(target);
      delta = Position.page(parent);
    }

    // correct by body offsets (fixes Safari)
    if (parent == document.body) {
      delta[0] -= document.body.offsetLeft;
      delta[1] -= document.body.offsetTop;
    }

    // set position
    if(options.setLeft)   target.style.left  = (p[0] - delta[0] + options.offsetLeft) + 'px';
    if(options.setTop)    target.style.top   = (p[1] - delta[1] + options.offsetTop) + 'px';
    if(options.setWidth)  target.style.width = source.offsetWidth + 'px';
    if(options.setHeight) target.style.height = source.offsetHeight + 'px';
  },

  absolutize: function(element) {
    element = $(element);
    if (element.style.position == 'absolute') return;
    Position.prepare();

    var offsets = Position.positionedOffset(element);
    var top     = offsets[1];
    var left    = offsets[0];
    var width   = element.clientWidth;
    var height  = element.clientHeight;

    element._originalLeft   = left - parseFloat(element.style.left  || 0);
    element._originalTop    = top  - parseFloat(element.style.top || 0);
    element._originalWidth  = element.style.width;
    element._originalHeight = element.style.height;

    element.style.position = 'absolute';
    element.style.top    = top + 'px';;
    element.style.left   = left + 'px';;
    element.style.width  = width + 'px';;
    element.style.height = height + 'px';;
  },

  relativize: function(element) {
    element = $(element);
    if (element.style.position == 'relative') return;
    Position.prepare();

    element.style.position = 'relative';
    var top  = parseFloat(element.style.top  || 0) - (element._originalTop || 0);
    var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);

    element.style.top    = top + 'px';
    element.style.left   = left + 'px';
    element.style.height = element._originalHeight;
    element.style.width  = element._originalWidth;
  }
}

// Safari returns margins on body which is incorrect if the child is absolutely
// positioned.  For performance reasons, redefine Position.cumulativeOffset for
// KHTML/WebKit only.
if (/Konqueror|Safari|KHTML/.test(navigator.userAgent)) {
  Position.cumulativeOffset = function(element) {
    var valueT = 0, valueL = 0;
    do {
      valueT += element.offsetTop  || 0;
      valueL += element.offsetLeft || 0;
      if (element.offsetParent == document.body)
        if (Element.getStyle(element, 'position') == 'absolute') break;

      element = element.offsetParent;
    } while (element);

    return [valueL, valueT];
  }
}/**
  *
  *  Copyright 2005 Sabre Airline Solutions
  *
  *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this
  *  file except in compliance with the License. You may obtain a copy of the License at
  *
  *         http://www.apache.org/licenses/LICENSE-2.0
  *
  *  Unless required by applicable law or agreed to in writing, software distributed under the
  *  License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
  *  either express or implied. See the License for the specific language governing permissions
  *  and limitations under the License.
  **/


//-------------------- rico.js
var Rico = {
  Version: '1.1.2',
  prototypeVersion: parseFloat(Prototype.Version.split(".")[0] + "." + Prototype.Version.split(".")[1])
}

if((typeof Prototype=='undefined') || Rico.prototypeVersion < 1.3)
      throw("Rico requires the Prototype JavaScript framework >= 1.3");

Rico.ArrayExtensions = new Array();

if (Object.prototype.extend) {
   Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Object.prototype.extend;
}else{
  Object.prototype.extend = function(object) {
    return Object.extend.apply(this, [this, object]);
  }
  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Object.prototype.extend;
}

if (Array.prototype.push) {
   Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.push;
}

if (!Array.prototype.remove) {
   Array.prototype.remove = function(dx) {
      if( isNaN(dx) || dx > this.length )
         return false;
      for( var i=0,n=0; i<this.length; i++ )
         if( i != dx )
            this[n++]=this[i];
      this.length-=1;
   };
  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.remove;
}

if (!Array.prototype.removeItem) {
   Array.prototype.removeItem = function(item) {
      for ( var i = 0 ; i < this.length ; i++ )
         if ( this[i] == item ) {
            this.remove(i);
            break;
         }
   };
  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.removeItem;
}

if (!Array.prototype.indices) {
   Array.prototype.indices = function() {
      var indexArray = new Array();
      for ( index in this ) {
         var ignoreThis = false;
         for ( var i = 0 ; i < Rico.ArrayExtensions.length ; i++ ) {
            if ( this[index] == Rico.ArrayExtensions[i] ) {
               ignoreThis = true;
               break;
            }
         }
         if ( !ignoreThis )
            indexArray[ indexArray.length ] = index;
      }
      return indexArray;
   }
  Rico.ArrayExtensions[ Rico.ArrayExtensions.length ] = Array.prototype.indices;
}

// Create the loadXML method and xml getter for Mozilla
if ( window.DOMParser &&
	  window.XMLSerializer &&
	  window.Node && Node.prototype && Node.prototype.__defineGetter__ ) {

   if (!Document.prototype.loadXML) {
      Document.prototype.loadXML = function (s) {
         var doc2 = (new DOMParser()).parseFromString(s, "text/xml");
         while (this.hasChildNodes())
            this.removeChild(this.lastChild);

         for (var i = 0; i < doc2.childNodes.length; i++) {
            this.appendChild(this.importNode(doc2.childNodes[i], true));
         }
      };
	}

	Document.prototype.__defineGetter__( "xml",
	   function () {
		   return (new XMLSerializer()).serializeToString(this);
	   }
	 );
}

document.getElementsByTagAndClassName = function(tagName, className) {
  if ( tagName == null )
     tagName = '*';

  var children = document.getElementsByTagName(tagName) || document.all;
  var elements = new Array();

  if ( className == null )
    return children;

  for (var i = 0; i < children.length; i++) {
    var child = children[i];
    var classNames = child.className.split(' ');
    for (var j = 0; j < classNames.length; j++) {
      if (classNames[j] == className) {
        elements.push(child);
        break;
      }
    }
  }

  return elements;
}


//-------------------- ricoAccordion.js
Rico.Accordion = Class.create();

Rico.Accordion.prototype = {

   initialize: function(container, options) {
      this.container            = $(container);
      this.lastExpandedTab      = null;
      this.accordionTabs        = new Array();
      this.setOptions(options);
      this._attachBehaviors();
      if(!container) return;

      this.container.style.borderBottom = '1px solid ' + this.options.borderColor;
      // validate onloadShowTab
       if (this.options.onLoadShowTab >= this.accordionTabs.length)
        this.options.onLoadShowTab = 0;

      // set the initial visual state...
      for ( var i=0 ; i < this.accordionTabs.length ; i++ )
      {
        if (i != this.options.onLoadShowTab){
         this.accordionTabs[i].collapse();
         this.accordionTabs[i].content.style.display = 'none';
        }
      }
      this.lastExpandedTab = this.accordionTabs[this.options.onLoadShowTab];
      if (this.options.panelHeight == 'auto'){
          var tabToCheck = (this.options.onloadShowTab === 0)? 1 : 0;
          var titleBarSize = parseInt(RicoUtil.getElementsComputedStyle(this.accordionTabs[tabToCheck].titleBar, 'height'));
          if (isNaN(titleBarSize))
            titleBarSize = this.accordionTabs[tabToCheck].titleBar.offsetHeight;
          
          var totalTitleBarSize = this.accordionTabs.length * titleBarSize;
          var parentHeight = parseInt(RicoUtil.getElementsComputedStyle(this.container.parentNode, 'height'));
          if (isNaN(parentHeight))
            parentHeight = this.container.parentNode.offsetHeight;
          
          this.options.panelHeight = parentHeight - totalTitleBarSize-2;
      }
      
      this.lastExpandedTab.content.style.height = this.options.panelHeight + "px";
      this.lastExpandedTab.showExpanded();
      this.lastExpandedTab.titleBar.style.fontWeight = this.options.expandedFontWeight;

   },

   setOptions: function(options) {
      this.options = {
         expandedBg          : '#63699c',
         hoverBg             : '#63699c',
         collapsedBg         : '#6b79a5',
         expandedTextColor   : '#ffffff',
         expandedFontWeight  : 'bold',
         hoverTextColor      : '#ffffff',
         collapsedTextColor  : '#ced7ef',
         collapsedFontWeight : 'normal',
         hoverTextColor      : '#ffffff',
         borderColor         : '#1f669b',
         panelHeight         : 200,
         onHideTab           : null,
         onShowTab           : null,
         onLoadShowTab       : 0
      }
      Object.extend(this.options, options || {});
   },

   showTabByIndex: function( anIndex, animate ) {
      var doAnimate = arguments.length == 1 ? true : animate;
      this.showTab( this.accordionTabs[anIndex], doAnimate );
   },

   showTab: function( accordionTab, animate ) {
     if ( this.lastExpandedTab == accordionTab )
        return;

      var doAnimate = arguments.length == 1 ? true : animate;

      if ( this.options.onHideTab )
         this.options.onHideTab(this.lastExpandedTab);

      this.lastExpandedTab.showCollapsed(); 
      var accordion = this;
      var lastExpandedTab = this.lastExpandedTab;

      this.lastExpandedTab.content.style.height = (this.options.panelHeight - 1) + 'px';
      accordionTab.content.style.display = '';

      accordionTab.titleBar.style.fontWeight = this.options.expandedFontWeight;

      if ( doAnimate ) {
         new Rico.Effect.AccordionSize( this.lastExpandedTab.content,
                                   accordionTab.content,
                                   1,
                                   this.options.panelHeight,
                                   100, 10,
                                   { complete: function() {accordion.showTabDone(lastExpandedTab)} } );
         this.lastExpandedTab = accordionTab;
      }
      else {
         this.lastExpandedTab.content.style.height = "1px";
         accordionTab.content.style.height = this.options.panelHeight + "px";
         this.lastExpandedTab = accordionTab;
         this.showTabDone(lastExpandedTab);
      }
   },

   showTabDone: function(collapsedTab) {
      collapsedTab.content.style.display = 'none';
      this.lastExpandedTab.showExpanded();
      if ( this.options.onShowTab )
         this.options.onShowTab(this.lastExpandedTab);
   },

   _attachBehaviors: function() {
      var panels = this._getDirectChildrenByTag(this.container, 'DIV');
      for ( var i = 0 ; i < panels.length ; i++ ) {

         var tabChildren = this._getDirectChildrenByTag(panels[i],'DIV');
         if ( tabChildren.length != 2 )
            continue; // unexpected

         var tabTitleBar   = tabChildren[0];
         var tabContentBox = tabChildren[1];
         this.accordionTabs.push( new Rico.Accordion.Tab(this,tabTitleBar,tabContentBox) );
      }
   },

   _getDirectChildrenByTag: function(e, tagName) {
      var kids = new Array();
      var allKids = e.childNodes;
      for( var i = 0 ; i < allKids.length ; i++ )
         if ( allKids[i] && allKids[i].tagName && allKids[i].tagName == tagName )
            kids.push(allKids[i]);
      return kids;
   }

};

Rico.Accordion.Tab = Class.create();

Rico.Accordion.Tab.prototype = {

   initialize: function(accordion, titleBar, content) {
      this.accordion = accordion;
      this.titleBar  = titleBar;
      this.content   = content;
      this._attachBehaviors();
   },

   collapse: function() {
      this.showCollapsed();
      this.content.style.height = "1px";
   },

   showCollapsed: function() {
      this.expanded = false;
      this.titleBar.style.backgroundColor = this.accordion.options.collapsedBg;
      this.titleBar.style.color           = this.accordion.options.collapsedTextColor;
      this.titleBar.style.fontWeight      = this.accordion.options.collapsedFontWeight;
      this.content.style.overflow = "hidden";
   },

   showExpanded: function() {
      this.expanded = true;
      this.titleBar.style.backgroundColor = this.accordion.options.expandedBg;
      this.titleBar.style.color           = this.accordion.options.expandedTextColor;
      this.content.style.overflow         = "auto";
   },

   titleBarClicked: function(e) {
      if ( this.accordion.lastExpandedTab == this )
         return;
      this.accordion.showTab(this);
   },

   hover: function(e) {
		this.titleBar.style.backgroundColor = this.accordion.options.hoverBg;
		this.titleBar.style.color           = this.accordion.options.hoverTextColor;
   },

   unhover: function(e) {
      if ( this.expanded ) {
         this.titleBar.style.backgroundColor = this.accordion.options.expandedBg;
         this.titleBar.style.color           = this.accordion.options.expandedTextColor;
      }
      else {
         this.titleBar.style.backgroundColor = this.accordion.options.collapsedBg;
         this.titleBar.style.color           = this.accordion.options.collapsedTextColor;
      }
   },

   _attachBehaviors: function() {
      this.content.style.border = "1px solid " + this.accordion.options.borderColor;
      this.content.style.borderTopWidth    = "0px";
      this.content.style.borderBottomWidth = "0px";
      this.content.style.margin            = "0px";

      this.titleBar.onclick     = this.titleBarClicked.bindAsEventListener(this);
      this.titleBar.onmouseover = this.hover.bindAsEventListener(this);
      this.titleBar.onmouseout  = this.unhover.bindAsEventListener(this);
   }

};


//-------------------- ricoAjaxEngine.js
Rico.AjaxEngine = Class.create();

Rico.AjaxEngine.prototype = {

   initialize: function() {
      this.ajaxElements = new Array();
      this.ajaxObjects  = new Array();
      this.requestURLS  = new Array();
      this.options = {};
   },

   registerAjaxElement: function( anId, anElement ) {
      if ( !anElement )
         anElement = $(anId);
      this.ajaxElements[anId] = anElement;
   },

   registerAjaxObject: function( anId, anObject ) {
      this.ajaxObjects[anId] = anObject;
   },

   registerRequest: function (requestLogicalName, requestURL) {
      this.requestURLS[requestLogicalName] = requestURL;
   },

   sendRequest: function(requestName, options) {
      // Allow for backwards Compatibility
      if ( arguments.length >= 2 )
       if (typeof arguments[1] == 'string')
         options = {parameters: this._createQueryString(arguments, 1)};
      this.sendRequestWithData(requestName, null, options);
   },

   sendRequestWithData: function(requestName, xmlDocument, options) {
      var requestURL = this.requestURLS[requestName];
      if ( requestURL == null )
         return;

      // Allow for backwards Compatibility
      if ( arguments.length >= 3 )
        if (typeof arguments[2] == 'string')
          options.parameters = this._createQueryString(arguments, 2);

      new Ajax.Request(requestURL, this._requestOptions(options,xmlDocument));
   },

   sendRequestAndUpdate: function(requestName,container,options) {
      // Allow for backwards Compatibility
      if ( arguments.length >= 3 )
        if (typeof arguments[2] == 'string')
          options.parameters = this._createQueryString(arguments, 2);

      this.sendRequestWithDataAndUpdate(requestName, null, container, options);
   },

   sendRequestWithDataAndUpdate: function(requestName,xmlDocument,container,options) {
      var requestURL = this.requestURLS[requestName];
      if ( requestURL == null )
         return;

      // Allow for backwards Compatibility
      if ( arguments.length >= 4 )
        if (typeof arguments[3] == 'string')
          options.parameters = this._createQueryString(arguments, 3);

      var updaterOptions = this._requestOptions(options,xmlDocument);

      new Ajax.Updater(container, requestURL, updaterOptions);
   },

   // Private -- not part of intended engine API --------------------------------------------------------------------

   _requestOptions: function(options,xmlDoc) {
      var requestHeaders = ['X-Rico-Version', Rico.Version ];
      var sendMethod = 'post';
      if ( xmlDoc == null )
        if (Rico.prototypeVersion < 1.4)
        requestHeaders.push( 'Content-type', 'text/xml' );
      else
          sendMethod = 'get';
      (!options) ? options = {} : '';

      if (!options._RicoOptionsProcessed){
      // Check and keep any user onComplete functions
        if (options.onComplete)
             options.onRicoComplete = options.onComplete;
        // Fix onComplete
        if (options.overrideOnComplete)
          options.onComplete = options.overrideOnComplete;
        else
          options.onComplete = this._onRequestComplete.bind(this);
        options._RicoOptionsProcessed = true;
      }

     // Set the default options and extend with any user options
     this.options = {
                     requestHeaders: requestHeaders,
                     parameters:     options.parameters,
                     postBody:       xmlDoc,
                     method:         sendMethod,
                     onComplete:     options.onComplete
                    };
     // Set any user options:
     Object.extend(this.options, options);
     return this.options;
   },

   _createQueryString: function( theArgs, offset ) {
      var queryString = ""
      for ( var i = offset ; i < theArgs.length ; i++ ) {
          if ( i != offset )
            queryString += "&";

          var anArg = theArgs[i];

          if ( anArg.name != undefined && anArg.value != undefined ) {
            queryString += anArg.name +  "=" + escape(anArg.value);
          }
          else {
             var ePos  = anArg.indexOf('=');
             var argName  = anArg.substring( 0, ePos );
             var argValue = anArg.substring( ePos + 1 );
             queryString += argName + "=" + escape(argValue);
          }
      }
      return queryString;
   },

   _onRequestComplete : function(request) {
      if(!request)
          return;
      // User can set an onFailure option - which will be called by prototype
      if (request.status != 200)
        return;

      var response = request.responseXML.getElementsByTagName("ajax-response");
      if (response == null || response.length != 1)
         return;
      this._processAjaxResponse( response[0].childNodes );
      
      // Check if user has set a onComplete function
      var onRicoComplete = this.options.onRicoComplete;
      if (onRicoComplete != null)
          onRicoComplete();
   },

   _processAjaxResponse: function( xmlResponseElements ) {
      for ( var i = 0 ; i < xmlResponseElements.length ; i++ ) {
         var responseElement = xmlResponseElements[i];

         // only process nodes of type element.....
         if ( responseElement.nodeType != 1 )
            continue;

         var responseType = responseElement.getAttribute("type");
         var responseId   = responseElement.getAttribute("id");

         if ( responseType == "object" )
            this._processAjaxObjectUpdate( this.ajaxObjects[ responseId ], responseElement );
         else if ( responseType == "element" )
            this._processAjaxElementUpdate( this.ajaxElements[ responseId ], responseElement );
         else
            alert('unrecognized AjaxResponse type : ' + responseType );
      }
   },

   _processAjaxObjectUpdate: function( ajaxObject, responseElement ) {
      ajaxObject.ajaxUpdate( responseElement );
   },

   _processAjaxElementUpdate: function( ajaxElement, responseElement ) {
      ajaxElement.innerHTML = RicoUtil.getContentAsString(responseElement);
   }

}

var ajaxEngine = new Rico.AjaxEngine();


//-------------------- ricoColor.js
Rico.Color = Class.create();

Rico.Color.prototype = {

   initialize: function(red, green, blue) {
      this.rgb = { r: red, g : green, b : blue };
   },

   setRed: function(r) {
      this.rgb.r = r;
   },

   setGreen: function(g) {
      this.rgb.g = g;
   },

   setBlue: function(b) {
      this.rgb.b = b;
   },

   setHue: function(h) {

      // get an HSB model, and set the new hue...
      var hsb = this.asHSB();
      hsb.h = h;

      // convert back to RGB...
      this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, hsb.b);
   },

   setSaturation: function(s) {
      // get an HSB model, and set the new hue...
      var hsb = this.asHSB();
      hsb.s = s;

      // convert back to RGB and set values...
      this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, hsb.b);
   },

   setBrightness: function(b) {
      // get an HSB model, and set the new hue...
      var hsb = this.asHSB();
      hsb.b = b;

      // convert back to RGB and set values...
      this.rgb = Rico.Color.HSBtoRGB( hsb.h, hsb.s, hsb.b );
   },

   darken: function(percent) {
      var hsb  = this.asHSB();
      this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, Math.max(hsb.b - percent,0));
   },

   brighten: function(percent) {
      var hsb  = this.asHSB();
      this.rgb = Rico.Color.HSBtoRGB(hsb.h, hsb.s, Math.min(hsb.b + percent,1));
   },

   blend: function(other) {
      this.rgb.r = Math.floor((this.rgb.r + other.rgb.r)/2);
      this.rgb.g = Math.floor((this.rgb.g + other.rgb.g)/2);
      this.rgb.b = Math.floor((this.rgb.b + other.rgb.b)/2);
   },

   isBright: function() {
      var hsb = this.asHSB();
      return this.asHSB().b > 0.5;
   },

   isDark: function() {
      return ! this.isBright();
   },

   asRGB: function() {
      return "rgb(" + this.rgb.r + "," + this.rgb.g + "," + this.rgb.b + ")";
   },

   asHex: function() {
      return "#" + this.rgb.r.toColorPart() + this.rgb.g.toColorPart() + this.rgb.b.toColorPart();
   },

   asHSB: function() {
      return Rico.Color.RGBtoHSB(this.rgb.r, this.rgb.g, this.rgb.b);
   },

   toString: function() {
      return this.asHex();
   }

};

Rico.Color.createFromHex = function(hexCode) {
  if(hexCode.length==4) {
    var shortHexCode = hexCode; 
    var hexCode = '#';
    for(var i=1;i<4;i++) hexCode += (shortHexCode.charAt(i) + 
shortHexCode.charAt(i));
  }
   if ( hexCode.indexOf('#') == 0 )
      hexCode = hexCode.substring(1);
   var red   = hexCode.substring(0,2);
   var green = hexCode.substring(2,4);
   var blue  = hexCode.substring(4,6);
   return new Rico.Color( parseInt(red,16), parseInt(green,16), parseInt(blue,16) );
}

/**
 * Factory method for creating a color from the background of
 * an HTML element.
 */
Rico.Color.createColorFromBackground = function(elem) {

   var actualColor = RicoUtil.getElementsComputedStyle($(elem), "backgroundColor", "background-color");

   if ( actualColor == "transparent" && elem.parentNode )
      return Rico.Color.createColorFromBackground(elem.parentNode);

   if ( actualColor == null )
      return new Rico.Color(255,255,255);

   if ( actualColor.indexOf("rgb(") == 0 ) {
      var colors = actualColor.substring(4, actualColor.length - 1 );
      var colorArray = colors.split(",");
      return new Rico.Color( parseInt( colorArray[0] ),
                            parseInt( colorArray[1] ),
                            parseInt( colorArray[2] )  );

   }
   else if ( actualColor.indexOf("#") == 0 ) {
      return Rico.Color.createFromHex(actualColor);
   }
   else
      return new Rico.Color(255,255,255);
}

Rico.Color.HSBtoRGB = function(hue, saturation, brightness) {

   var red   = 0;
	var green = 0;
	var blue  = 0;

   if (saturation == 0) {
      red = parseInt(brightness * 255.0 + 0.5);
	   green = red;
	   blue = red;
	}
	else {
      var h = (hue - Math.floor(hue)) * 6.0;
      var f = h - Math.floor(h);
      var p = brightness * (1.0 - saturation);
      var q = brightness * (1.0 - saturation * f);
      var t = brightness * (1.0 - (saturation * (1.0 - f)));

      switch (parseInt(h)) {
         case 0:
            red   = (brightness * 255.0 + 0.5);
            green = (t * 255.0 + 0.5);
            blue  = (p * 255.0 + 0.5);
            break;
         case 1:
            red   = (q * 255.0 + 0.5);
            green = (brightness * 255.0 + 0.5);
            blue  = (p * 255.0 + 0.5);
            break;
         case 2:
            red   = (p * 255.0 + 0.5);
            green = (brightness * 255.0 + 0.5);
            blue  = (t * 255.0 + 0.5);
            break;
         case 3:
            red   = (p * 255.0 + 0.5);
            green = (q * 255.0 + 0.5);
            blue  = (brightness * 255.0 + 0.5);
            break;
         case 4:
            red   = (t * 255.0 + 0.5);
            green = (p * 255.0 + 0.5);
            blue  = (brightness * 255.0 + 0.5);
            break;
          case 5:
            red   = (brightness * 255.0 + 0.5);
            green = (p * 255.0 + 0.5);
            blue  = (q * 255.0 + 0.5);
            break;
	    }
	}

   return { r : parseInt(red), g : parseInt(green) , b : parseInt(blue) };
}

Rico.Color.RGBtoHSB = function(r, g, b) {

   var hue;
   var saturation;
   var brightness;

   var cmax = (r > g) ? r : g;
   if (b > cmax)
      cmax = b;

   var cmin = (r < g) ? r : g;
   if (b < cmin)
      cmin = b;

   brightness = cmax / 255.0;
   if (cmax != 0)
      saturation = (cmax - cmin)/cmax;
   else
      saturation = 0;

   if (saturation == 0)
      hue = 0;
   else {
      var redc   = (cmax - r)/(cmax - cmin);
    	var greenc = (cmax - g)/(cmax - cmin);
    	var bluec  = (cmax - b)/(cmax - cmin);

    	if (r == cmax)
    	   hue = bluec - greenc;
    	else if (g == cmax)
    	   hue = 2.0 + redc - bluec;
      else
    	   hue = 4.0 + greenc - redc;

    	hue = hue / 6.0;
    	if (hue < 0)
    	   hue = hue + 1.0;
   }

   return { h : hue, s : saturation, b : brightness };
}


//-------------------- ricoCorner.js
Rico.Corner = {

   round: function(e, options) {
      var e = $(e);
      this._setOptions(options);

      var color = this.options.color;
      if ( this.options.color == "fromElement" )
         color = this._background(e);

      var bgColor = this.options.bgColor;
      if ( this.options.bgColor == "fromParent" )
         bgColor = this._background(e.offsetParent);

      this._roundCornersImpl(e, color, bgColor);
   },

   _roundCornersImpl: function(e, color, bgColor) {
      if(this.options.border)
         this._renderBorder(e,bgColor);
      if(this._isTopRounded())
         this._roundTopCorners(e,color,bgColor);
      if(this._isBottomRounded())
         this._roundBottomCorners(e,color,bgColor);
   },

   _renderBorder: function(el,bgColor) {
      var borderValue = "1px solid " + this._borderColor(bgColor);
      var borderL = "border-left: "  + borderValue;
      var borderR = "border-right: " + borderValue;
      var style   = "style='" + borderL + ";" + borderR +  "'";
      el.innerHTML = "<div " + style + ">" + el.innerHTML + "</div>"
   },

   _roundTopCorners: function(el, color, bgColor) {
      var corner = this._createCorner(bgColor);
      for(var i=0 ; i < this.options.numSlices ; i++ )
         corner.appendChild(this._createCornerSlice(color,bgColor,i,"top"));
      el.style.paddingTop = 0;
      el.insertBefore(corner,el.firstChild);
   },

   _roundBottomCorners: function(el, color, bgColor) {
      var corner = this._createCorner(bgColor);
      for(var i=(this.options.numSlices-1) ; i >= 0 ; i-- )
         corner.appendChild(this._createCornerSlice(color,bgColor,i,"bottom"));
      el.style.paddingBottom = 0;
      el.appendChild(corner);
   },

   _createCorner: function(bgColor) {
      var corner = document.createElement("div");
      corner.style.backgroundColor = (this._isTransparent() ? "transparent" : bgColor);
      return corner;
   },

   _createCornerSlice: function(color,bgColor, n, position) {
      var slice = document.createElement("span");

      var inStyle = slice.style;
      inStyle.backgroundColor = color;
      inStyle.display  = "block";
      inStyle.height   = "1px";
      inStyle.overflow = "hidden";
      inStyle.fontSize = "1px";

      var borderColor = this._borderColor(color,bgColor);
      if ( this.options.border && n == 0 ) {
         inStyle.borderTopStyle    = "solid";
         inStyle.borderTopWidth    = "1px";
         inStyle.borderLeftWidth   = "0px";
         inStyle.borderRightWidth  = "0px";
         inStyle.borderBottomWidth = "0px";
         inStyle.height            = "0px"; // assumes css compliant box model
         inStyle.borderColor       = borderColor;
      }
      else if(borderColor) {
         inStyle.borderColor = borderColor;
         inStyle.borderStyle = "solid";
         inStyle.borderWidth = "0px 1px";
      }

      if ( !this.options.compact && (n == (this.options.numSlices-1)) )
         inStyle.height = "2px";

      this._setMargin(slice, n, position);
      this._setBorder(slice, n, position);
      return slice;
   },

   _setOptions: function(options) {
      this.options = {
         corners : "all",
         color   : "fromElement",
         bgColor : "fromParent",
         blend   : true,
         border  : false,
         compact : false
      }
      Object.extend(this.options, options || {});

      this.options.numSlices = this.options.compact ? 2 : 4;
      if ( this._isTransparent() )
         this.options.blend = false;
   },

   _whichSideTop: function() {
      if ( this._hasString(this.options.corners, "all", "top") )
         return "";

      if ( this.options.corners.indexOf("tl") >= 0 && this.options.corners.indexOf("tr") >= 0 )
         return "";

      if (this.options.corners.indexOf("tl") >= 0)
         return "left";
      else if (this.options.corners.indexOf("tr") >= 0)
          return "right";
      return "";
   },

   _whichSideBottom: function() {
      if ( this._hasString(this.options.corners, "all", "bottom") )
         return "";

      if ( this.options.corners.indexOf("bl")>=0 && this.options.corners.indexOf("br")>=0 )
         return "";

      if(this.options.corners.indexOf("bl") >=0)
         return "left";
      else if(this.options.corners.indexOf("br")>=0)
         return "right";
      return "";
   },

   _borderColor : function(color,bgColor) {
      if ( color == "transparent" )
         return bgColor;
      else if ( this.options.border )
         return this.options.border;
      else if ( this.options.blend )
         return this._blend( bgColor, color );
      else
         return "";
   },


   _setMargin: function(el, n, corners) {
      var marginSize = this._marginSize(n);
      var whichSide = corners == "top" ? this._whichSideTop() : this._whichSideBottom();

      if ( whichSide == "left" ) {
         el.style.marginLeft = marginSize + "px"; el.style.marginRight = "0px";
      }
      else if ( whichSide == "right" ) {
         el.style.marginRight = marginSize + "px"; el.style.marginLeft  = "0px";
      }
      else {
         el.style.marginLeft = marginSize + "px"; el.style.marginRight = marginSize + "px";
      }
   },

   _setBorder: function(el,n,corners) {
      var borderSize = this._borderSize(n);
      var whichSide = corners == "top" ? this._whichSideTop() : this._whichSideBottom();
      if ( whichSide == "left" ) {
         el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = "0px";
      }
      else if ( whichSide == "right" ) {
         el.style.borderRightWidth = borderSize + "px"; el.style.borderLeftWidth  = "0px";
      }
      else {
         el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = borderSize + "px";
      }
      if (this.options.border != false)
        el.style.borderLeftWidth = borderSize + "px"; el.style.borderRightWidth = borderSize + "px";
   },

   _marginSize: function(n) {
      if ( this._isTransparent() )
         return 0;

      var marginSizes          = [ 5, 3, 2, 1 ];
      var blendedMarginSizes   = [ 3, 2, 1, 0 ];
      var compactMarginSizes   = [ 2, 1 ];
      var smBlendedMarginSizes = [ 1, 0 ];

      if ( this.options.compact && this.options.blend )
         return smBlendedMarginSizes[n];
      else if ( this.options.compact )
         return compactMarginSizes[n];
      else if ( this.options.blend )
         return blendedMarginSizes[n];
      else
         return marginSizes[n];
   },

   _borderSize: function(n) {
      var transparentBorderSizes = [ 5, 3, 2, 1 ];
      var blendedBorderSizes     = [ 2, 1, 1, 1 ];
      var compactBorderSizes     = [ 1, 0 ];
      var actualBorderSizes      = [ 0, 2, 0, 0 ];

      if ( this.options.compact && (this.options.blend || this._isTransparent()) )
         return 1;
      else if ( this.options.compact )
         return compactBorderSizes[n];
      else if ( this.options.blend )
         return blendedBorderSizes[n];
      else if ( this.options.border )
         return actualBorderSizes[n];
      else if ( this._isTransparent() )
         return transparentBorderSizes[n];
      return 0;
   },

   _hasString: function(str) { for(var i=1 ; i<arguments.length ; i++) if (str.indexOf(arguments[i]) >= 0) return true; return false; },
   _blend: function(c1, c2) { var cc1 = Rico.Color.createFromHex(c1); cc1.blend(Rico.Color.createFromHex(c2)); return cc1; },
   _background: function(el) { try { return Rico.Color.createColorFromBackground(el).asHex(); } catch(err) { return "#ffffff"; } },
   _isTransparent: function() { return this.options.color == "transparent"; },
   _isTopRounded: function() { return this._hasString(this.options.corners, "all", "top", "tl", "tr"); },
   _isBottomRounded: function() { return this._hasString(this.options.corners, "all", "bottom", "bl", "br"); },
   _hasSingleTextChild: function(el) { return el.childNodes.length == 1 && el.childNodes[0].nodeType == 3; }
}


//-------------------- ricoDragAndDrop.js
Rico.DragAndDrop = Class.create();

Rico.DragAndDrop.prototype = {

   initialize: function() {
      this.dropZones                = new Array();
      this.draggables               = new Array();
      this.currentDragObjects       = new Array();
      this.dragElement              = null;
      this.lastSelectedDraggable    = null;
      this.currentDragObjectVisible = false;
      this.interestedInMotionEvents = false;
      this._mouseDown = this._mouseDownHandler.bindAsEventListener(this);
      this._mouseMove = this._mouseMoveHandler.bindAsEventListener(this);
      this._mouseUp = this._mouseUpHandler.bindAsEventListener(this);
   },

   registerDropZone: function(aDropZone) {
      this.dropZones[ this.dropZones.length ] = aDropZone;
   },

   deregisterDropZone: function(aDropZone) {
      var newDropZones = new Array();
      var j = 0;
      for ( var i = 0 ; i < this.dropZones.length ; i++ ) {
         if ( this.dropZones[i] != aDropZone )
            newDropZones[j++] = this.dropZones[i];
      }

      this.dropZones = newDropZones;
   },

   clearDropZones: function() {
      this.dropZones = new Array();
   },

   registerDraggable: function( aDraggable ) {
      this.draggables[ this.draggables.length ] = aDraggable;
      this._addMouseDownHandler( aDraggable );
   },

   clearSelection: function() {
      for ( var i = 0 ; i < this.currentDragObjects.length ; i++ )
         this.currentDragObjects[i].deselect();
      this.currentDragObjects = new Array();
      this.lastSelectedDraggable = null;
   },

   hasSelection: function() {
      return this.currentDragObjects.length > 0;
   },

   setStartDragFromElement: function( e, mouseDownElement ) {
      this.origPos = RicoUtil.toDocumentPosition(mouseDownElement);
      this.startx = e.screenX - this.origPos.x
      this.starty = e.screenY - this.origPos.y
      //this.startComponentX = e.layerX ? e.layerX : e.offsetX;
      //this.startComponentY = e.layerY ? e.layerY : e.offsetY;
      //this.adjustedForDraggableSize = false;

      this.interestedInMotionEvents = this.hasSelection();
      this._terminateEvent(e);
   },

   updateSelection: function( draggable, extendSelection ) {
      if ( ! extendSelection )
         this.clearSelection();

      if ( draggable.isSelected() ) {
         this.currentDragObjects.removeItem(draggable);
         draggable.deselect();
         if ( draggable == this.lastSelectedDraggable )
            this.lastSelectedDraggable = null;
      }
      else {
         this.currentDragObjects[ this.currentDragObjects.length ] = draggable;
         draggable.select();
         this.lastSelectedDraggable = draggable;
      }
   },

   _mouseDownHandler: function(e) {
      if ( arguments.length == 0 )
         e = event;

      // if not button 1 ignore it...
      var nsEvent = e.which != undefined;
      if ( (nsEvent && e.which != 1) || (!nsEvent && e.button != 1))
         return;

      var eventTarget      = e.target ? e.target : e.srcElement;
      var draggableObject  = eventTarget.draggable;

      var candidate = eventTarget;
      while (draggableObject == null && candidate.parentNode) {
         candidate = candidate.parentNode;
         draggableObject = candidate.draggable;
      }
   
      if ( draggableObject == null )
         return;

      this.updateSelection( draggableObject, e.ctrlKey );

      // clear the drop zones postion cache...
      if ( this.hasSelection() )
         for ( var i = 0 ; i < this.dropZones.length ; i++ )
            this.dropZones[i].clearPositionCache();

      this.setStartDragFromElement( e, draggableObject.getMouseDownHTMLElement() );
   },


   _mouseMoveHandler: function(e) {
      var nsEvent = e.which != undefined;
      if ( !this.interestedInMotionEvents ) {
         //this._terminateEvent(e);
         return;
      }

      if ( ! this.hasSelection() )
         return;

      if ( ! this.currentDragObjectVisible )
         this._startDrag(e);

      if ( !this.activatedDropZones )
         this._activateRegisteredDropZones();

      //if ( !this.adjustedForDraggableSize )
      //   this._adjustForDraggableSize(e);

      this._updateDraggableLocation(e);
      this._updateDropZonesHover(e);

      this._terminateEvent(e);
   },

   _makeDraggableObjectVisible: function(e)
   {
      if ( !this.hasSelection() )
         return;

      var dragElement;
      if ( this.currentDragObjects.length > 1 )
         dragElement = this.currentDragObjects[0].getMultiObjectDragGUI(this.currentDragObjects);
      else
         dragElement = this.currentDragObjects[0].getSingleObjectDragGUI();

      // go ahead and absolute position it...
      if ( RicoUtil.getElementsComputedStyle(dragElement, "position")  != "absolute" )
         dragElement.style.position = "absolute";

      // need to parent him into the document...
      if ( dragElement.parentNode == null || dragElement.parentNode.nodeType == 11 )
         document.body.appendChild(dragElement);

      this.dragElement = dragElement;
      this._updateDraggableLocation(e);

      this.currentDragObjectVisible = true;
   },

   /**
   _adjustForDraggableSize: function(e) {
      var dragElementWidth  = this.dragElement.offsetWidth;
      var dragElementHeight = this.dragElement.offsetHeight;
      if ( this.startComponentX > dragElementWidth )
         this.startx -= this.startComponentX - dragElementWidth + 2;
      if ( e.offsetY ) {
         if ( this.startComponentY > dragElementHeight )
            this.starty -= this.startComponentY - dragElementHeight + 2;
      }
      this.adjustedForDraggableSize = true;
   },
   **/

   _leftOffset: function(e) {
	   return e.offsetX ? document.body.scrollLeft : 0
	},

   _topOffset: function(e) {
	   return e.offsetY ? document.body.scrollTop:0
	},

		
   _updateDraggableLocation: function(e) {
      var dragObjectStyle = this.dragElement.style;
      dragObjectStyle.left = (e.screenX + this._leftOffset(e) - this.startx) + "px"
      dragObjectStyle.top  = (e.screenY + this._topOffset(e) - this.starty) + "px";
   },

   _updateDropZonesHover: function(e) {
      var n = this.dropZones.length;
      for ( var i = 0 ; i < n ; i++ ) {
         if ( ! this._mousePointInDropZone( e, this.dropZones[i] ) )
            this.dropZones[i].hideHover();
      }

      for ( var i = 0 ; i < n ; i++ ) {
         if ( this._mousePointInDropZone( e, this.dropZones[i] ) ) {
            if ( this.dropZones[i].canAccept(this.currentDragObjects) )
               this.dropZones[i].showHover();
         }
      }
   },

   _startDrag: function(e) {
      for ( var i = 0 ; i < this.currentDragObjects.length ; i++ )
         this.currentDragObjects[i].startDrag();

      this._makeDraggableObjectVisible(e);
   },

   _mouseUpHandler: function(e) {
      if ( ! this.hasSelection() )
         return;

      var nsEvent = e.which != undefined;
      if ( (nsEvent && e.which != 1) || (!nsEvent && e.button != 1))
         return;

      this.interestedInMotionEvents = false;

      if ( this.dragElement == null ) {
         this._terminateEvent(e);
         return;
      }

      if ( this._placeDraggableInDropZone(e) )
         this._completeDropOperation(e);
      else {
         this._terminateEvent(e);
         new Rico.Effect.Position( this.dragElement,
                              this.origPos.x,
                              this.origPos.y,
                              200,
                              20,
                              { complete : this._doCancelDragProcessing.bind(this) } );
      }

     Event.stopObserving(document.body, "mousemove", this._mouseMove);
     Event.stopObserving(document.body, "mouseup",  this._mouseUp);
   },

   _retTrue: function () {
      return true;
   },

   _completeDropOperation: function(e) {
      if ( this.dragElement != this.currentDragObjects[0].getMouseDownHTMLElement() ) {
         if ( this.dragElement.parentNode != null )
            this.dragElement.parentNode.removeChild(this.dragElement);
      }

      this._deactivateRegisteredDropZones();
      this._endDrag();
      this.clearSelection();
      this.dragElement = null;
      this.currentDragObjectVisible = false;
      this._terminateEvent(e);
   },

   _doCancelDragProcessing: function() {
      this._cancelDrag();

        if ( this.dragElement != this.currentDragObjects[0].getMouseDownHTMLElement() && this.dragElement)
           if ( this.dragElement.parentNode != null )
              this.dragElement.parentNode.removeChild(this.dragElement);


      this._deactivateRegisteredDropZones();
      this.dragElement = null;
      this.currentDragObjectVisible = false;
   },

   _placeDraggableInDropZone: function(e) {
      var foundDropZone = false;
      var n = this.dropZones.length;
      for ( var i = 0 ; i < n ; i++ ) {
         if ( this._mousePointInDropZone( e, this.dropZones[i] ) ) {
            if ( this.dropZones[i].canAccept(this.currentDragObjects) ) {
               this.dropZones[i].hideHover();
               this.dropZones[i].accept(this.currentDragObjects);
               foundDropZone = true;
               break;
            }
         }
      }

      return foundDropZone;
   },

   _cancelDrag: function() {
      for ( var i = 0 ; i < this.currentDragObjects.length ; i++ )
         this.currentDragObjects[i].cancelDrag();
   },

   _endDrag: function() {
      for ( var i = 0 ; i < this.currentDragObjects.length ; i++ )
         this.currentDragObjects[i].endDrag();
   },

   _mousePointInDropZone: function( e, dropZone ) {

      var absoluteRect = dropZone.getAbsoluteRect();

      return e.clientX  > absoluteRect.left + this._leftOffset(e) &&
             e.clientX  < absoluteRect.right + this._leftOffset(e) &&
             e.clientY  > absoluteRect.top + this._topOffset(e)   &&
             e.clientY  < absoluteRect.bottom + this._topOffset(e);
   },

   _addMouseDownHandler: function( aDraggable )
   {
       htmlElement  = aDraggable.getMouseDownHTMLElement();
      if ( htmlElement  != null ) { 
         htmlElement.draggable = aDraggable;
         Event.observe(htmlElement , "mousedown", this._onmousedown.bindAsEventListener(this));
         Event.observe(htmlElement, "mousedown", this._mouseDown);
      }
   },

   _activateRegisteredDropZones: function() {
      var n = this.dropZones.length;
      for ( var i = 0 ; i < n ; i++ ) {
         var dropZone = this.dropZones[i];
         if ( dropZone.canAccept(this.currentDragObjects) )
            dropZone.activate();
      }

      this.activatedDropZones = true;
   },

   _deactivateRegisteredDropZones: function() {
      var n = this.dropZones.length;
      for ( var i = 0 ; i < n ; i++ )
         this.dropZones[i].deactivate();
      this.activatedDropZones = false;
   },

   _onmousedown: function () {
     Event.observe(document.body, "mousemove", this._mouseMove);
     Event.observe(document.body, "mouseup",  this._mouseUp);
   },

   _terminateEvent: function(e) {
      if ( e.stopPropagation != undefined )
         e.stopPropagation();
      else if ( e.cancelBubble != undefined )
         e.cancelBubble = true;

      if ( e.preventDefault != undefined )
         e.preventDefault();
      else
         e.returnValue = false;
   },


	   initializeEventHandlers: function() {
	      if ( typeof document.implementation != "undefined" &&
	         document.implementation.hasFeature("HTML",   "1.0") &&
	         document.implementation.hasFeature("Events", "2.0") &&
	         document.implementation.hasFeature("CSS",    "2.0") ) {
	         document.addEventListener("mouseup",   this._mouseUpHandler.bindAsEventListener(this),  false);
	         document.addEventListener("mousemove", this._mouseMoveHandler.bindAsEventListener(this), false);
	      }
	      else {
	         document.attachEvent( "onmouseup",   this._mouseUpHandler.bindAsEventListener(this) );
	         document.attachEvent( "onmousemove", this._mouseMoveHandler.bindAsEventListener(this) );
	      }
	   }
	}

	var dndMgr = new Rico.DragAndDrop();
	dndMgr.initializeEventHandlers();


//-------------------- ricoDraggable.js
Rico.Draggable = Class.create();

Rico.Draggable.prototype = {

   initialize: function( type, htmlElement ) {
      this.type          = type;
      this.htmlElement   = $(htmlElement);
      this.selected      = false;
   },

   /**
    *   Returns the HTML element that should have a mouse down event
    *   added to it in order to initiate a drag operation
    *
    **/
   getMouseDownHTMLElement: function() {
      return this.htmlElement;
   },

   select: function() {
      this.selected = true;

      if ( this.showingSelected )
         return;

      var htmlElement = this.getMouseDownHTMLElement();

      var color = Rico.Color.createColorFromBackground(htmlElement);
      color.isBright() ? color.darken(0.033) : color.brighten(0.033);

      this.saveBackground = RicoUtil.getElementsComputedStyle(htmlElement, "backgroundColor", "background-color");
      htmlElement.style.backgroundColor = color.asHex();
      this.showingSelected = true;
   },

   deselect: function() {
      this.selected = false;
      if ( !this.showingSelected )
         return;

      var htmlElement = this.getMouseDownHTMLElement();

      htmlElement.style.backgroundColor = this.saveBackground;
      this.showingSelected = false;
   },

   isSelected: function() {
      return this.selected;
   },

   startDrag: function() {
   },

   cancelDrag: function() {
   },

   endDrag: function() {
   },

   getSingleObjectDragGUI: function() {
      return this.htmlElement;
   },

   getMultiObjectDragGUI: function( draggables ) {
      return this.htmlElement;
   },

   getDroppedGUI: function() {
      return this.htmlElement;
   },

   toString: function() {
      return this.type + ":" + this.htmlElement + ":";
   }

}


//-------------------- ricoDropzone.js
Rico.Dropzone = Class.create();

Rico.Dropzone.prototype = {

   initialize: function( htmlElement ) {
      this.htmlElement  = $(htmlElement);
      this.absoluteRect = null;
   },

   getHTMLElement: function() {
      return this.htmlElement;
   },

   clearPositionCache: function() {
      this.absoluteRect = null;
   },

   getAbsoluteRect: function() {
      if ( this.absoluteRect == null ) {
         var htmlElement = this.getHTMLElement();
         var pos = RicoUtil.toViewportPosition(htmlElement);

         this.absoluteRect = {
            top:    pos.y,
            left:   pos.x,
            bottom: pos.y + htmlElement.offsetHeight,
            right:  pos.x + htmlElement.offsetWidth
         };
      }
      return this.absoluteRect;
   },

   activate: function() {
      var htmlElement = this.getHTMLElement();
      if (htmlElement == null  || this.showingActive)
         return;

      this.showingActive = true;
      this.saveBackgroundColor = htmlElement.style.backgroundColor;

      var fallbackColor = "#ffea84";
      var currentColor = Rico.Color.createColorFromBackground(htmlElement);
      if ( currentColor == null )
         htmlElement.style.backgroundColor = fallbackColor;
      else {
         currentColor.isBright() ? currentColor.darken(0.2) : currentColor.brighten(0.2);
         htmlElement.style.backgroundColor = currentColor.asHex();
      }
   },

   deactivate: function() {
      var htmlElement = this.getHTMLElement();
      if (htmlElement == null || !this.showingActive)
         return;

      htmlElement.style.backgroundColor = this.saveBackgroundColor;
      this.showingActive = false;
      this.saveBackgroundColor = null;
   },

   showHover: function() {
      var htmlElement = this.getHTMLElement();
      if ( htmlElement == null || this.showingHover )
         return;

      this.saveBorderWidth = htmlElement.style.borderWidth;
      this.saveBorderStyle = htmlElement.style.borderStyle;
      this.saveBorderColor = htmlElement.style.borderColor;

      this.showingHover = true;
      htmlElement.style.borderWidth = "1px";
      htmlElement.style.borderStyle = "solid";
      //htmlElement.style.borderColor = "#ff9900";
      htmlElement.style.borderColor = "#ffff00";
   },

   hideHover: function() {
      var htmlElement = this.getHTMLElement();
      if ( htmlElement == null || !this.showingHover )
         return;

      htmlElement.style.borderWidth = this.saveBorderWidth;
      htmlElement.style.borderStyle = this.saveBorderStyle;
      htmlElement.style.borderColor = this.saveBorderColor;
      this.showingHover = false;
   },

   canAccept: function(draggableObjects) {
      return true;
   },

   accept: function(draggableObjects) {
      var htmlElement = this.getHTMLElement();
      if ( htmlElement == null )
         return;

      n = draggableObjects.length;
      for ( var i = 0 ; i < n ; i++ )
      {
         var theGUI = draggableObjects[i].getDroppedGUI();
         if ( RicoUtil.getElementsComputedStyle( theGUI, "position" ) == "absolute" )
         {
            theGUI.style.position = "static";
            theGUI.style.top = "";
            theGUI.style.top = "";
         }
         htmlElement.appendChild(theGUI);
      }
   }
}


//-------------------- ricoEffects.js

Rico.Effect = {};

Rico.Effect.SizeAndPosition = Class.create();
Rico.Effect.SizeAndPosition.prototype = {

   initialize: function(element, x, y, w, h, duration, steps, options) {
      this.element = $(element);
      this.x = x;
      this.y = y;
      this.w = w;
      this.h = h;
      this.duration = duration;
      this.steps    = steps;
      this.options  = arguments[7] || {};

      this.sizeAndPosition();
   },

   sizeAndPosition: function() {
      if (this.isFinished()) {
         if(this.options.complete) this.options.complete(this);
         return;
      }

      if (this.timer)
         clearTimeout(this.timer);

      var stepDuration = Math.round(this.duration/this.steps) ;

      // Get original values: x,y = top left corner;  w,h = width height
      var currentX = this.element.offsetLeft;
      var currentY = this.element.offsetTop;
      var currentW = this.element.offsetWidth;
      var currentH = this.element.offsetHeight;

      // If values not set, or zero, we do not modify them, and take original as final as well
      this.x = (this.x) ? this.x : currentX;
      this.y = (this.y) ? this.y : currentY;
      this.w = (this.w) ? this.w : currentW;
      this.h = (this.h) ? this.h : currentH;

      // how much do we need to modify our values for each step?
      var difX = this.steps >  0 ? (this.x - currentX)/this.steps : 0;
      var difY = this.steps >  0 ? (this.y - currentY)/this.steps : 0;
      var difW = this.steps >  0 ? (this.w - currentW)/this.steps : 0;
      var difH = this.steps >  0 ? (this.h - currentH)/this.steps : 0;

      this.moveBy(difX, difY);
      this.resizeBy(difW, difH);

      this.duration -= stepDuration;
      this.steps--;

      this.timer = setTimeout(this.sizeAndPosition.bind(this), stepDuration);
   },

   isFinished: function() {
      return this.steps <= 0;
   },

   moveBy: function( difX, difY ) {
      var currentLeft = this.element.offsetLeft;
      var currentTop  = this.element.offsetTop;
      var intDifX     = parseInt(difX);
      var intDifY     = parseInt(difY);

      var style = this.element.style;
      if ( intDifX != 0 )
         style.left = (currentLeft + intDifX) + "px";
      if ( intDifY != 0 )
         style.top  = (currentTop + intDifY) + "px";
   },

   resizeBy: function( difW, difH ) {
      var currentWidth  = this.element.offsetWidth;
      var currentHeight = this.element.offsetHeight;
      var intDifW       = parseInt(difW);
      var intDifH       = parseInt(difH);

      var style = this.element.style;
      if ( intDifW != 0 )
         style.width   = (currentWidth  + intDifW) + "px";
      if ( intDifH != 0 )
         style.height  = (currentHeight + intDifH) + "px";
   }
}

Rico.Effect.Size = Class.create();
Rico.Effect.Size.prototype = {

   initialize: function(element, w, h, duration, steps, options) {
      new Rico.Effect.SizeAndPosition(element, null, null, w, h, duration, steps, options);
  }
}

Rico.Effect.Position = Class.create();
Rico.Effect.Position.prototype = {

   initialize: function(element, x, y, duration, steps, options) {
      new Rico.Effect.SizeAndPosition(element, x, y, null, null, duration, steps, options);
  }
}

Rico.Effect.Round = Class.create();
Rico.Effect.Round.prototype = {

   initialize: function(tagName, className, options) {
      var elements = document.getElementsByTagAndClassName(tagName,className);
      for ( var i = 0 ; i < elements.length ; i++ )
         Rico.Corner.round( elements[i], options );
   }
};

Rico.Effect.FadeTo = Class.create();
Rico.Effect.FadeTo.prototype = {

   initialize: function( element, opacity, duration, steps, options) {
      this.element  = $(element);
      this.opacity  = opacity;
      this.duration = duration;
      this.steps    = steps;
      this.options  = arguments[4] || {};
      this.fadeTo();
   },

   fadeTo: function() {
      if (this.isFinished()) {
         if(this.options.complete) this.options.complete(this);
         return;
      }

      if (this.timer)
         clearTimeout(this.timer);

      var stepDuration = Math.round(this.duration/this.steps) ;
      var currentOpacity = this.getElementOpacity();
      var delta = this.steps > 0 ? (this.opacity - currentOpacity)/this.steps : 0;

      this.changeOpacityBy(delta);
      this.duration -= stepDuration;
      this.steps--;

      this.timer = setTimeout(this.fadeTo.bind(this), stepDuration);
   },

   changeOpacityBy: function(v) {
      var currentOpacity = this.getElementOpacity();
      var newOpacity = Math.max(0, Math.min(currentOpacity+v, 1));
      this.element.ricoOpacity = newOpacity;

      this.element.style.filter = "alpha(opacity:"+Math.round(newOpacity*100)+")";
      this.element.style.opacity = newOpacity; /*//*/;
   },

   isFinished: function() {
      return this.steps <= 0;
   },

   getElementOpacity: function() {
      if ( this.element.ricoOpacity == undefined ) {
         var opacity = RicoUtil.getElementsComputedStyle(this.element, 'opacity');
         this.element.ricoOpacity = opacity != undefined ? opacity : 1.0;
      }
      return parseFloat(this.element.ricoOpacity);
   }
}

Rico.Effect.AccordionSize = Class.create();

Rico.Effect.AccordionSize.prototype = {

   initialize: function(e1, e2, start, end, duration, steps, options) {
      this.e1       = $(e1);
      this.e2       = $(e2);
      this.start    = start;
      this.end      = end;
      this.duration = duration;
      this.steps    = steps;
      this.options  = arguments[6] || {};

      this.accordionSize();
   },

   accordionSize: function() {

      if (this.isFinished()) {
         // just in case there are round errors or such...
         this.e1.style.height = this.start + "px";
         this.e2.style.height = this.end + "px";

         if(this.options.complete)
            this.options.complete(this);
         return;
      }

      if (this.timer)
         clearTimeout(this.timer);

      var stepDuration = Math.round(this.duration/this.steps) ;

      var diff = this.steps > 0 ? (parseInt(this.e1.offsetHeight) - this.start)/this.steps : 0;
      this.resizeBy(diff);

      this.duration -= stepDuration;
      this.steps--;

      this.timer = setTimeout(this.accordionSize.bind(this), stepDuration);
   },

   isFinished: function() {
      return this.steps <= 0;
   },

   resizeBy: function(diff) {
      var h1Height = this.e1.offsetHeight;
      var h2Height = this.e2.offsetHeight;
      var intDiff = parseInt(diff);
      if ( diff != 0 ) {
         this.e1.style.height = (h1Height - intDiff) + "px";
         this.e2.style.height = (h2Height + intDiff) + "px";
      }
   }

};


//-------------------- ricoLiveGrid.js
// Rico.LiveGridMetaData -----------------------------------------------------

Rico.LiveGridMetaData = Class.create();

Rico.LiveGridMetaData.prototype = {

   initialize: function( pageSize, totalRows, columnCount, options ) {
      this.pageSize  = pageSize;
      this.totalRows = totalRows;
      this.setOptions(options);
      this.ArrowHeight = 16;
      this.columnCount = columnCount;
   },

   setOptions: function(options) {
      this.options = {
         largeBufferSize    : 7.0,   // 7 pages
         nearLimitFactor    : 0.2    // 20% of buff
