/**
 * Copyright (c) 2008, visitcity Ltd. & vianovis GmbH
 * 
 * @author: Florian Schnell
 * @date: 07/06/2008
 */

// if window has finished loading we start to create the visitcity object ...
window.onload = function () {
	visitcity.load();
};

// monitor deeplink change ...
/*
var old_hash = location.hash;
window.setInterval(function () {
	if (location.hash != old_hash) {
		if (visitcity)
			visitcity.deeplinkChanged();
		old_hash = location.hash;
	}
}, 1000);
*/

// ##########################################################
// HELPERS
// ----------------------------------------------------------

function shortenString(str, maxlen) {
	if (str.length > maxlen) {
		return str.substr(0, maxlen-3) + "...";
	} else
		return str;
}

function clone(obj) {
    if(obj == null || typeof(obj) != 'object')
        return obj;
    var temp = new obj.constructor(); // changed (twice)
    for(var key in obj)
        temp[key] = clone(obj[key]);
    return temp;
}

function buildProxyUrl(url, cache) {
	if (cache == null) {
		cache = '';
	} else {
		cache = '&file=' + escape(cache);
	}
	return visitcity.app_path+"proxy.php?url=" + escape(url) + cache;
}

function getURLParam(strParamName) {
	var strReturn = "";
	var strHref = window.location.href;
	if (strHref.indexOf("#") > -1 ) {
		var strQueryString = strHref.substr(strHref.indexOf("#")).toLowerCase();
		var aQueryString = strQueryString.split("&");
		for ( var iParam = 0; iParam < aQueryString.length; iParam++ ) {
			if (aQueryString[iParam].indexOf(strParamName + "=") > -1 ) {
				var aParam = aQueryString[iParam].split("=");
				strReturn = aParam[1];
				break;
			}
		}
	}

	if (strParamName == 'page' && !strReturn) {
		return strReturn = 1;
	} else {
		return strReturn;
	}
}

function writeCookie(name,value,days) {
	if (days) {
		var date = new Date();
		date.setTime(date.getTime()+(days*24*60*60*1000));
		var expires = "; expires="+date.toGMTString();
	}
	else var expires = "";
	document.cookie = name+"="+value+expires+"; path=/";
}

function readCookie(name) {
	var nameEQ = name + "=";
	var ca = document.cookie.split(';');
	for(var i=0;i < ca.length;i++) {
		var c = ca[i];
		while (c.charAt(0)==' ') c = c.substring(1,c.length);
		if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length,c.length);
	}
	return null;
}

function removeCookie(n) {
	document.cookie = n+'=; expires=Thu, 01-Jan-70 00:00:01 GMT;';
}

var anim = null;
function displayStatus(msg) {
	if (anim) clearInterval(anim);
	var statuslbl = document.getElementById('statuslbl');
	statuslbl.innerHTML = "<b>Bitte warten</b><br /><font color='"+visitcity.styles.color_tab_selected+"'>" + msg + "</font>";
	statuslbl.style.top = (YAHOO.util.Dom.getDocumentHeight()/2 + 50) + "px";
	statuslbl.style.left = '0px';
	statuslbl.style.display = 'block';
}

function hideStatus() {
	if (anim) clearInterval(anim);
	anim = setInterval("moveOutStatus()", 50);
}

function moveOutStatus() {
	var statuslbl = document.getElementById('statuslbl');
	if (parseInt(statuslbl.style.left) > -200)
		statuslbl.style.left = (parseInt(statuslbl.style.left) - 20) + "px";
	else {
		statuslbl.style.display = 'none';
		if (anim) clearInterval(anim);
	}
}

//##########################################################
// VISIT CITY DATA TYPES
// ----------------------------------------------------------

function VCCategory (data) {
	this.Id = 0;
	this.KwisId = 0;
	this.Parent = null;
	this.Name = '';
	this.HasChilds = false;
	this.IconId = 0;
	this.Symbols = 0;
	this.Active = false;
	
	if (data) {
		this.Id = parseInt(data.id);
		this.KwisId = data.tx_msitecxp_catid;
		this.Name = data.name;
		if (data.son_exists == '0')
			this.HasChilds = false;
		else
			this.HasChilds = true;
		this.IconId = parseInt(data.iconid);
		this.Symbols = parseInt(data.symbole);
	}
}

function VCBusiness (data) {
	
	// basic information ...
	this.Uid = 0;
	this.KwisId = 0;
	this.ObjectName = '';
	this.CategoryId = 0;
	this.CategoryName = '';
	this.IconId = 0;
	this.OnMap = false;
	this.Premium = false;
	this.InUse = 0;
	this.Nodes = [];
	this.Visible = true;
	
	// some details ...
	this.Name = '';
	this.Forname = '';
	this.Title = '';
	this.Email = '';
	this.Phone = '';
	this.Mobile = '';
	this.Picture = '';
	this.Fax = '';
	this.Web = '';
	this.Description = '';
	
	// geo stuff ...
	this.Shapes = [];
	this.IsTiny = false;
	this.Address = '';
	this.City = '';
	this.Zip = 0;
	this.Country = '';
	this.StyleString = '';
	this.Style = null;
	this.Location = '';
	this.Geometry = '';
	
	if (data) {
		this.Uid = data.uid;
		this.KwisId = data.tx_msitecxp_id;
		this.ObjectName = data.objektname;
		this.CategoryName = data.catname;
		this.CategoryId = data.catid;
		this.IconId = data.id_node;
		this.OnMap = false;
		this.Points = [];
		
		// some details ...
		this.Company = data.company;
		this.Name = data.name;
		this.Forname = data.tx_msitegis_firstname;
		this.Title = data.titel;
		this.Email = data.email;
		this.Phone = data.telefon;
		this.Mobile = data.mobile;
		this.Picture = data.pic;
		this.Fax = data.fax;
		this.Web = data.web;
		this.Description = data.description;
		
		// geo stuff ...
		this.Address = data.strasse;
		this.City = data.ort;
		this.Zip = data.plz;
		this.Country = data.country;
		this.StyleString = data.style;
		this.Location = data.location;
		this.Geometry = data.geometry;
		
		if (data.tx_msitepremium_state == '1') {
			this.Premium = true;
		} else {
			this.Premium = false;
		}
		
		// now create the shape object ...
		this.createShapes();
	}
}

VCBusiness.prototype.copy = function () {
	var data = {
		'uid': this.Uid,
		'geometry': this.Geometry,
		'location': this.Location,
		'address': this.Address,
		'catname': this.CategoryName,
		'strasse': this.Address,
		'ort': this.City,
		'plz': this.Zip,
		'company': this.Company,
		'description': this.Description,
		'id_node': this.IconId,
		'titel': this.Title,
		'name': this.Name,
		'telefon': this.Phone,
		'email': this.Email,
		'mobile': this.Mobile,
		'web': this.Web,
		'pic': this.Picture,
		'fax': this.Fax,
		'style': this.StyleString,
		'tx_msitecxp_id': this.KwisId
	};
	return (new VCBusiness(data));
};

VCBusiness.prototype.addNode = function (node) {
	this.Nodes.push(node);
	return this.Nodes.length;
};

VCBusiness.prototype.removeNode = function (node) {
	// this.Nodes.push();
};

VCBusiness.prototype.show = function () {
	for (var n = 0; n < this.Shapes.length; n++) {
		this.Shapes[n].show();
	}
	for (var n = 0; n < this.Nodes.length; n++) {
		this.Nodes[n].setCheckState(2);
		this.Nodes[n].updateCheckHtml();
		this.Nodes[n].updateParent();
	}
	this.Visible = true;
};

VCBusiness.prototype.hide = function () {
	for (var n = 0; n < this.Shapes.length; n++) {
		this.Shapes[n].hide();
	}
	for (var n = 0; n < this.Nodes.length; n++) {
		this.Nodes[n].setCheckState(0);
		this.Nodes[n].updateCheckHtml();
		this.Nodes[n].updateParent();
	}
	this.Visible = false;
};

VCBusiness.prototype.createShapes = function () {
	
	var iconmode = 1;
	
	// get the styling ...
	if (this.StyleString) {
		this.Style = visitcity.getStyleInformation(this.StyleString);
		iconmode = this.Style.icon.mode;
		}
	
	// decide what to parse ...
	// parse a simple location or POI ...
	
	if ((this.Location && this.Location.length > 0) && iconmode == 1) {
	
		var	marker = visitcity.locationToShape(this.Location);
		this.Points.push(marker.location);
		
		// set info text ...
		var pic = "";
		var adresse = "";
		var strasse = "";
		var phone = "";
		var fax = "";
		var email = "";
		var web = "";
		var description = "";
		var detaillink = "";
			
		if (this.Picture.length > 0) {
			if (visitcity.map.getMapType() == 'EARTH') {
			pic = "<div id='infoimg'><span></span><img src='" + visitcity.resizepath + visitcity.imagepath + this.Picture + "&width=" + visitcity.resizewidth + "&height=" + visitcity.resizewidth + "'></div>";
			} else {
			pic = "<div id='infoimg'><span></span><a href='" + visitcity.imagepath + this.Picture + "' title='"+this.Company+"' class='highslide' onclick='return hs.expand(this)'><img src='" + visitcity.resizepath + visitcity.imagepath + this.Picture + "&width=" + visitcity.resizewidth + "&height=" + visitcity.resizewidth + "' alt='"+this.Company+"' title='Klick zum vergrößern'><span>Bild vergr&ouml;&szlig;ern</span></a></div>";			
			}
		}
				
		if (this.Address.length > 0) {
			strasse = this.Address + "<br />";
		}
				
		if (this.City.length > 0) {
			adresse = this.Zip + "&nbsp;" + this.City + "<br />";
		}
		
		if (this.Phone.length > 0 && this.Mobile.length == 0) {
			phone = visitcity.ln.iw_phone+"&nbsp;" + this.Phone + "<br />";
		}

		if (this.Mobile.length > 0 && this.Phone.length == 0) {
			phone = visitcity.ln.iw_mobile+"&nbsp;" + this.Mobile + "<br />";
		}

		if (this.Fax.length > 0) {
			fax = visitcity.ln.iw_fax+"&nbsp;" + this.Fax + "<br />";
		}		

		if (this.Email.length > 0) {
			email = "<a href='mailto:" + this.Email + "' target='_blank'>"+visitcity.ln.iw_mail+"</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;";
		}		
		
		if (this.Web.length > 0) {
			web = "<a href='"+ this.Web + "' target='_blank'>"+visitcity.ln.iw_web+"</a><br />";
		}
		
		if (visitcity.details_mode == 1 && this.Description.length > 0) {
		description = "<div id='desc'>"  + this.Description + "</div>";
		}
			
		if (this.Premium) {
			var detaillink = "<br /><a href='javascript:visitcity.displayTooltipDetailsWindow(" + this.Uid + ");'>Premium-Visitenkarte anzeigen</a><br />";
		} else if(visitcity.details_mode == 2){
			var detaillink = "<br /><a href='javascript:visitcity.displayTooltipDetailsWindow(" + this.Uid + ");'><b>"+visitcity.ln.iw_detaillink+"</b></a><br />";		
		}

		if (visitcity.map.api == 'microsoft') {
			var infostyle = "<div id='info' style='margin-bottom:-28px;'>";
			//var routefrom = "<a href='http://maps.live.de/LiveSearch.LocalLive?rtp=~" + this.Address + ", " + this.Zip + "&nbsp;" + this.City + ", Deutschland' target='_blank'>Route hierher berechnen...</a>";
			var routefrom = "<a href='http://maps.live.de/LiveSearch.LocalLive?rtp=~" + this.Address + ", " + this.Zip + "&nbsp;" + this.City + ", Deutschland' target='_blank'><img src='"+visitcity.app_path+"img/detail_routing.gif' alt='"+visitcity.ln.iw_route+"' title='"+visitcity.ln.iw_route+"'></img></a>";
		} else {
			var infostyle = "<div id='info'>";
			//var routefrom = "<a href='http://maps.google.de/maps?f=d&source=s_d&hl=de&ie=UTF8&daddr=" + this.Address + ", " + this.Zip + "&nbsp;" + this.City + ", Deutschland' target='_blank'>Route hierher berechnen...</a>";
            var routefrom = "<a href='http://maps.google.de/maps?f=d&source=s_d&hl=de&ie=UTF8&daddr=" + this.Address + ", " + this.Zip + "&nbsp;" + this.City + ", Deutschland' target='_blank'><img src='"+visitcity.app_path+"img/detail_routing.gif' alt='"+visitcity.ln.iw_route+"' title='"+visitcity.ln.iw_route+"'></img></a>";			
		}			
		
		marker.setInfoBubble(
			infostyle +
			"<img id='infoicon' src='" + visitcity.iconpath + "leg_" + this.IconId + ".gif' width='15' height='15' ></img>" +
			"<div id='infocat'>" + this.CategoryName + "</div>" +
			"<div><hr /></div>" +
			pic +
			"<div id='infoheader'>" + this.Company + "</div>" +
			"<div id='infotext'>" +	strasse + adresse + phone + fax + email + web + detaillink + "</div>" +
			description + 
			"<div id='infofooter'>" +
			//"<a href='javascript:visitcity.doPrint(" + this.Uid + ", false, false, true);'>drucken...</a><br />" +			
			//"<a href='javascript:visitcity.addToFavorites(" + this.Uid + ");'>zu Favoriten hinzuf&uuml;gen...</a><br />" +
			//"<a href=" + visitcity.vcardpath + this.Uid + ">Outlook vCard erstellen...</a><br />" +
			"<a href='javascript:visitcity.doPrint(" + this.Uid + ", false, false, true);'><img src='"+visitcity.app_path+"img/detail_print.gif' alt='"+visitcity.ln.iw_print+"' title='"+visitcity.ln.iw_print+"'></img></a>" +
			"<a href='javascript:visitcity.addToFavorites(" + this.Uid + ");'><img src='"+visitcity.app_path+"img/detail_fav.gif' alt='"+visitcity.ln.iw_fav+"' title='"+visitcity.ln.iw_fav+"'></img></a>" +
			"<a href=" + visitcity.vcardpath + this.Uid + "><img src='"+visitcity.app_path+"img/detail_vcard.gif' alt='"+visitcity.ln.iw_vcard+"' title='"+visitcity.ln.iw_vcard+"'></img></a>" +
			routefrom +
			"</div></div>"
		);
			
		// set a custom icon ...
		marker.setShadowIcon(visitcity.iconpath + 'shadow.png', [37,27]);
		marker.setIcon( visitcity.iconpath + this.IconId + '.gif', [19,24], [6,-10]);
		marker.Uid = this.Uid;
		
		// on click open details ...
		marker.onclick = function (e) {
			visitcity.active_poi = visitcity.businesses[this.Uid];
			setTimeout("visitcity.updateDeeplink()",2000);
			this.onmouseout(e);
			var business = visitcity.businesses[this.Uid];
			if (business.Geometry && business.Geometry.length > 0 && visitcity.earth_mode == "ON") {
				visitcity.map.map.closeInfoWindow();
				visitcity.displayTooltipDetailsWindow(this.Uid);
			}
		};
		
		marker.onmouseover = function (e) {
			
			// only show tooltip if theres no open tooltip window yet ...
			if (!visitcity.map.map.getInfoWindow().isHidden()) return;
			
			// position the tooltip ...
			var point = visitcity.map.map.fromLatLngToContainerPixel(new GLatLng(e.lat(), e.lng()));
			var tooltip = new YAHOO.util.Element("tooltip");
			tooltip.setStyle("display", "block");
			tooltip.setStyle("left", (point.x - 10) + "px");
			tooltip.setStyle("top", (point.y - 101) + "px");
			
			// fill with useful information ...
			var business = visitcity.businesses[this.Uid];
			var tooltip_content = new YAHOO.util.Element("tooltip_content");
			if (business.Address.length > 0) tooltip_content.set('innerHTML', '<b>' + shortenString(business.Company, 27) + '</b><br />' + shortenString(business.Address + ', ' + business.City, 35) + '<br /><i>' + shortenString( visitcity.ln.category+': ' + business.CategoryName, 35) + '</i>');
			if (business.Address.length = 0 || business.Address == '') tooltip_content.set('innerHTML', '<b>' + shortenString(business.Company, 27) + '</b><br />' + shortenString(business.City, 35) + '<br /><i>' + shortenString( visitcity.ln.category+': ' + business.CategoryName, 35) + '</i>');		
		};
		
		marker.onmouseout = function (e) {
			var tooltip = new YAHOO.util.Element("tooltip");
			tooltip.setStyle("display", "none");
		};
		
		// overwrite default with style information if available ...
		if (this.Style) {
			var scale = parseFloat(this.Style.icon.scale);
			marker.setIcon( visitcity.iconpath + this.IconId + '.gif', [19+scale,24+scale], [6-(scale/2),-(10+(scale/2))]);
		}
		
		this.Shapes.push(marker);
	}
	
	// parse a line or multiline ...
	if (this.Geometry && this.Geometry.length > 0) {
	
		var lines = visitcity.linestringToShape(this.Geometry);
		
		// add information to each line ...
		for (i = 0; i < lines.length; i++) {
		
			var line = lines[i];
			//var line = new GPolyline.fromEncoded("#" + visitcity.map.color, visitcity.map.width, visitcity.map.alpha, this.Geometry, visitcity.map.zoomFactor, visitcity.map.levels, visitcity.map.numLevels);;
			
			for (var n = 0; n < line.points.length; n++) {
				this.Points.push(line.points[n]);
			}
			
			// specify the default line ...
			line.uid = this.Uid;
			line.setWidth(3);
			line.setColor("FF0000", 0.8);
				
			line.setTitle(this.Company);
			line.setDescription(this.Description);
			
			// overwrite default with style information if available ...
			if (this.Style) {
				visitcity.line_color = this.Style.normal.line.color.replace("0x", "");
				visitcity.line_alpha = this.Style.normal.line.alpha/100;
				visitcity.line_width = this.Style.normal.line.width;
				
				line.setColor(visitcity.line_color, visitcity.line_alpha);
				line.setWidth(visitcity.line_width);
			}			
		
			// on click event ...
			line.onclick = function (mapevent) {
				var tooltip = document.getElementById('tooltip');
				tooltip.style.display = "none";
				visitcity.displayTooltipDetailsWindow(line.uid);
			};
			
			line.onmouseover = function (mapevent) {
				//document.body.style.cursor = 'pointer';
				
				// http://www.bdcc.co.uk/Gmaps/BdccGmapBits.htm
				
				line.setStrokeStyle("#"+visitcity.line_color,parseFloat(visitcity.line_width)+2,1.0);
				
				var options = {
					'backgroundColor': '#fff', 
					'border': '1px solid #ccc',
					fontSize: '10px'
				};

				this.overlay = new MapTooltip(this, '<b>' + line.title + '</b><br />' + visitcity.ln.tooltipp_cat,options);
				visitcity.map.addOverlay(this.overlay);
				


				
				/* VE only
				var tooltip = document.getElementById('tooltip');
				tooltip.style.left = (mapevent.clientX + 10) + "px";
				tooltip.style.top = (mapevent.clientY + 10) + "px";
				if (tooltip.style.display == "none") {
					tooltip.innerHTML = "<b>" + line.title + "</b><br />" + "f&uuml;r Details klicken ...";
					tooltip.style.display = "block";
				}
				*/
			};
			
			line.onmouseout = function (mapevent) {
				//document.body.style.cursor = 'default';
				//document.body.style.cursor = "url("+visitcity.app_path+"img/openhand.cur)";
				
				line.setStrokeStyle("#"+visitcity.line_color,visitcity.line_width,visitcity.line_alpha);
				//visitcity.map.map.getDragObject().setDraggableCursor("openhand");
				
				visitcity.map.removeOverlay(this.overlay);
				
				/*
				 * VE only var tooltip = document.getElementById('tooltip');
				 * tooltip.style.display = "none";
				 */
			};
			
			this.Shapes.push(line);
		}
	}
};

// ##########################################################
// LOADING QUEUE
// ----------------------------------------------------------

function LoadingQueue (callback) {
	this.locked = false;
	this.queue = [];
	this.element = null;
	this.parts = {};
	this.callback = callback;
}

LoadingQueue.prototype.add = function (node) {
	this.queue.push(node);
};

LoadingQueue.prototype.next = function () {
	this.locked = false;
	this.process();
};

LoadingQueue.prototype.remove = function (node) {
	for (var i = 0; i < this.queue.length; i++) {
		if (this.queue[i] == node) {
			this.queue.splice(i, 1);
		}
	}
};

LoadingQueue.prototype.process = function () {
	if (this.locked) return;
	this.locked = true;
	
	if (this.element) this.element.stopLoading();
	
	if (this.queue.length == 0) {
		this.element = null;
		this.locked = false;
		return;
	}
	
	var node = this.queue.shift();
	this.element = node;
	this.element.startLoading();
	this.callback(node.data);
};

LoadingQueue.prototype.finishPart = function (id) {
	this.parts[id] = true;
};

LoadingQueue.prototype.addPart = function (id) {
	this.parts[id] = false;
};

LoadingQueue.prototype.allPartsFinished = function () {
	for (var id in this.parts) {
		if (!this.parts[id]) return false;
	}
	return true;
};

// ##########################################################
// VISIT CITY INIT
// ----------------------------------------------------------

visitcity.layout_outer = null;
visitcity.layout_inner = null;
visitcity.map = null;
visitcity.tab_nav = null;
visitcity.tree_cats = null;
visitcity.tree_places = null;
visitcity.tree_businesses = null;
visitcity.businesses = {};
visitcity.loading_queue = null;
visitcity.active_poi = null;

// load this at startup ...
visitcity.categories_to_load = [];
visitcity.uids_to_load = [];
visitcity.kwis_short = '';

visitcity.locations = [];			// used for routing
visitcity.selectedLL = null;		// used for right click actions
visitcity.startShape = null;		// where the routing begins

visitcity.favorites = [];
visitcity.searches = [];
visitcity.uids = {};

visitcity.line_color = '';
visitcity.line_alpha = '';
visitcity.line_width = '';

visitcity.weather_today = false;
visitcity.weather_tomorrow = false;

visitcity.viewborder = false;
visitcity.kml_border = new GGeoXml(visitcity.kmlpath);

visitcity.earth_html = '';

//##########################################################
// INITIALIZATION
// ----------------------------------------------------------

/**
 * this method loads visitcity.
 */
visitcity.load = function () {

	// change loader description ...
	visitcity.setLoaderText(visitcity.ln.loader_sys);
	
	// Instantiate and configure Loader:
	var loader = new YAHOO.util.YUILoader({base: visitcity.basepath + 'yui/'}); 
		
	loader.insert(
		{require: ["tabview", "treeview", "layout", "element", "connection", "json", "container"],
		loadOptional: true,
		onSuccess: visitcity.loadSettings,
		onFailure: function () { alert('could not load dependencies!'); },
		allowRollup: false,
		skin: {
			defaultSkin: 'sam',
			overrides: {
				resize: ['visitcity'],
				layout: ['visitcity'],
				tabview: ['visitcity'],
				treeview: ['visitcity'],
				container: ['visitcity']
			}
		}
	});
	
	visitcity.loading_queue = new LoadingQueue(visitcity.addCategory);
};

visitcity.loadSettings = function (response, not_create_interface) {

	visitcity.showLoader();

	if (not_create_interface == null)
		not_create_interface = false;

	visitcity.setLoaderText(visitcity.ln.loader_styles);
	
	// load categories ...
	visitcity.categories_to_load = getURLParam('cats').split(',');
	
	// load shortcut if there is one ...
	visitcity.kwis_short = getURLParam('short');
	
	// load uids ...
	visitcity.uids_to_load = getURLParam('uid').split(',');

	// load sid ...
	var cur_sid = getURLParam('sid');
	if (cur_sid != '') {
		visitcity.sid = cur_sid.toUpperCase();
	}

	var cur_maptype = getURLParam('map');
	if (cur_maptype != '') {	
		visitcity.maptype = cur_maptype.toUpperCase();
	}
	
	// just invoke the apply styles method ...
	visitcity.applyStyles();
	
	// continue creating the interface ...
	visitcity.createInterface();
};

// ##########################################################
// LAYOUT CREATION AND INTERFACE
// ----------------------------------------------------------

/**
 * this method creates the visitcity interface.
 */
 
function makeBlank(){
	if ((document.getElementById('txt_fstr').value) == visitcity.ln.search_item) {
		document.getElementById('txt_fstr').value = '';
		}
} 
 
visitcity.createInterface = function () {
	
	// outer layout ...
	visitcity.layout_outer = new YAHOO.widget.Layout({
		units: [
			{ position: 'top', id: 'unit_header', height: visitcity.headerheight, gutter: '0 0 0 0', body: '<div id="header"></div>' },
			{ position: 'center', id: 'unit_inner', body: '', gutter: '0 0 0 0' }
    	]
    });
    
    var searchbar_html =
    '<table width="100%" id="searchbar">' +
    	'<tr>' +
    		'<td>' +
    			'<table width="600px">' +
    				'<tr>' +
    					//'<td width="80" id="search_for">'+visitcity.ln.search_for+'</td>' +
    					'<td><input name="q" id="txt_fstr" type="text" value="'+visitcity.ln.search_item+'" onclick="makeBlank();"></input></td>' +
    					'<td width="80" align="center"><input id="btn_search" type="button" value="'+visitcity.ln.find+'" title="'+visitcity.ln.find+'"></td>' +
    					'<td width="70" align="center"><label for="radSTypeB">'+visitcity.ln.category+'</label><input id="radSTypeB" name="radSType" type="radio" value="1" checked="checked" ></input></td>' +
    					'<td width="70" align="center"><label for="radSTypeP">'+visitcity.ln.location+'</label><input id="radSTypeP" name="radSType" type="radio" value="2"></input></td>' +
    				'</tr>' +
					'<tr id="search_for">'+visitcity.ln.search_for+'</tr>' +
    			'</table>' +
    		'</td>' +
    		'<td>' +
    			'<table width="100%">' +
    				'<tr>' +
						'<td align="center"><div id="coords">Rechtswert <input id="coord_lon" type="text"></input>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Hochwert <input id="coord_lat" type="text"></input></div></td>' +
    					//'<td align="right"><img src="./img/modules/faq.png" width="28" height="28" alt="faq"></img</td>' +
    					//'<td align="right"><img src="./img/modules/faq.png" width="28" height="28" border="0" alt="faq"></img>&nbsp;&nbsp;<a href="javascript:visitcity.displayImpressWindow()"><img src="./img/modules/info.png" width="28" height="28" border="none" alt="Impressum"></img></a></td>' +
    					'<td align="right">' +
						'<a href="javascript:visitcity.doPrint(false, false, true, false);"><img src="./img/print.png" width="28" height="28" border="none" alt="'+visitcity.ln.info_print+'" title="'+visitcity.ln.info_print+'"></img></a>' +
						'&nbsp;&nbsp;' +
						'<a href="javascript:visitcity.displayImpressWindow();"><img src="./img/info.png" width="28" height="28" border="none" alt="'+visitcity.ln.info_imprint+'" title="'+visitcity.ln.info_imprint+'"></img></a>' +
						'&nbsp;&nbsp;' +
						//'<a href="#"><img src="./img/faq.png" width="28" height="28" border="none" alt="'+visitcity.ln.info_help+'" title="'+visitcity.ln.info_help+'"></img></a>'+
						'</td>' +
    				'</tr>' +
    			'</table>' +
    		'</td>' +
    	'</tr>' +
    '</table>';

    var map_html =
    '<div id="map" style="margin-top:14px;"></div><form action=""><div id="box" onmouseout="setClose(event)">'+
	'<input name="mark" type="checkbox" onclick="switchLayer(this.checked, layers[0].obj, layers[0].type)" /> '+visitcity.ln.more_photos+' <br />'+
	'<input name="mark" type="checkbox" onclick="switchLayer(this.checked, layers[1].obj, layers[1].type)" /> '+visitcity.ln.more_wikipedia+' <br />'+
	'<input name="mark" type="checkbox" onclick="switchLayer(this.checked, layers[2].obj, layers[2].type)" /> '+visitcity.ln.more_videos+' <br />'+
	'<input name="mark" type="checkbox" onclick="switchLayer(this.checked, layers[3].obj, layers[3].type)" /> '+visitcity.ln.more_webcams+' <br />'+
	'<hr style="width:92%;text-align:center;height:1px;border:1px;color:#e2e2e2;background-color:#e2e2e2;" />';
	
	if (visitcity.weather_ags != '') {
	map_html += '<input name="mark" id="wtoday" type="checkbox" onclick="switchLayer(this.checked, layers[4].obj, layers[4].type, layers[4].name);" /> Wetter aktuell<br /><input name="mark" id= "wtomorrow" type="checkbox" onclick="switchLayer(this.checked, layers[5].obj, layers[5].type, layers[5].name);" /> Wetter morgen'+
	'<hr style="width:92%;text-align:center;height:1px;border:1px;color:#e2e2e2;background-color:#e2e2e2;" />';
	}
	
	map_html += '<a id="boxlink" href="javascript:void(0)" onclick="hideAll()">'+visitcity.ln.more_remove_all+'</a></div></form>';

    // insert inner layout in the center body of the outer layout ...
    visitcity.layout_outer.on('render', function () {
    	var el = visitcity.layout_outer.getUnitByPosition('center').get('wrap'); 
	    visitcity.layout_inner = new YAHOO.widget.Layout(el, { 
	        parent: visitcity.layout_outer,
	        units: [ 
	            { position: 'top', id: 'unit_search', body: searchbar_html, height: 48, gutter: '5 5 0 5' },
	            { position: 'left', id: 'unit_navigation', width: 330, body: '<div id="navigation"></div>', gutter: '5 5 5 5', animate: false }, 
	            { position: 'center', id: 'unit_map', body: map_html, gutter: '0 5 5 5' } 
	        ] 
	    }); 
	    visitcity.layout_inner.render();
	});
	
	// render the layout_outer ...
	visitcity.layout_outer.render();
	
	var map = new YAHOO.util.Element('map');
	map.setStyle('border', '1px solid');
	
	// init with the google maps viewer ...
	visitcity.switchMap();
    
	// init search button ...
	var btn_search = new YAHOO.util.Element('btn_search');
	btn_search.on('click', visitcity.startSearch);
	var start_search = new YAHOO.util.Element('txt_fstr');
	start_search.on('keypress', visitcity.startSearchByKey);
	
	// create tabview ...
	visitcity.tab_nav = new YAHOO.widget.TabView(); 
	visitcity.tab_nav.setStyle('marginTop', '8px');
	
	if (visitcity.earth_mode != "ON") {
		visitcity.ln.categories = "&nbsp;"+visitcity.ln.categories+"&nbsp;";
		visitcity.ln.list = "&nbsp;"+visitcity.ln.list;
		visitcity.ln.favorites = "&nbsp;&nbsp;"+visitcity.ln.favorites+"&nbsp;&nbsp;";
		visitcity.ln.locations = "&nbsp;&nbsp;"+visitcity.ln.locations+"&nbsp;&nbsp;";
	}	
	
	// categories tab
	visitcity.tab_nav.addTab(new YAHOO.widget.Tab({ 
	    label: visitcity.ln.categories, 
	    content: '<div id="tools_categories"><a href="javascript:visitcity.hideNavigation()">'+visitcity.ln.categories_nav +'</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a id="collapse" href="#">'+visitcity.ln.categories_close+'</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a id="empty" href="javascript:visitcity.clearTreeCats()">'+visitcity.ln.categories_drop+'</a></div><div id="tree_cats"></div>',
	    active: true
	})); 
	
	// businesses tab
	visitcity.tab_nav.addTab(new YAHOO.widget.Tab({ 
	    label: visitcity.ln.list+' (0)', 
	    content:
	    	'<div id="tools_businesses"><a id="empty" href="javascript:visitcity.clearAll()">'+visitcity.ln.list_delete+'</a>&nbsp;&nbsp;|&nbsp;&nbsp;<a href="javascript:visitcity.doPrint(false, false, true, true, true);">'+visitcity.ln.list_print+'</a></div>' +
	    	'<div id="tree_businesses">'+visitcity.ln.list_help+'</div>'
	}));
	
	// places tab
	var places = new YAHOO.widget.Tab({ 
	    //label: visitcity.ln.locations+' (0)', 
	    label: visitcity.ln.locations, 
	    content:
	    	'<div id="tools_places"><a id="empty" href="javascript:visitcity.clearPlaces()">'+visitcity.ln.locations_remove+'</a></div>' +
	    	'<div id="tree_places">'+visitcity.ln.locations_text+'</div>' 
	});
	visitcity.tab_nav.addTab(places);
	places.subscribe('activeChange', visitcity.onPlacesActiveChange);

	// favorites tab
	visitcity.tab_nav.addTab(new YAHOO.widget.Tab({ 
	    label: visitcity.ln.favorites,
	    content: '<div id="tab_favorites"></div>'
	}));
	
	if (visitcity.earth_mode == "ON") {
		visitcity.earth_html = '<div id="earth_options">'+
		'<div id="earth_options">'+
		'<p class="tab_title"><b>3D-Modus</b></p>'+	
		'<p class="tab_tipps">TIPP: Im 3D-Modus k&ouml;nnen Sie mit gedr&uuml;cktem Mausrad die Ansicht kippen und rotieren.<br>Mit der "R"-Taste kommen Sie zur&uuml;ck in eine genordete Aufsicht.</p>'+
		'<p>Der 3D-Modus steht nur bei aktiviertem Kartentyp "EARTH" zur Verf&uuml;gung</p>'+
		'Um den 3D-Modus benutzen zu k&ouml;nnen ist au&szlig;erdem das Google-Earth-Plugin erforderlich. Die Installation erfolgt automatisch und ist f&uuml;r folgende Browser verf&uuml;gbar: MS Internet Explorer 7+, Mozilla Firefox 2+, Google Chrome</p>'+
		'<p>Sollten Sie schon Google Earth auf Ihrem Computer installiert haben, dann ist das Plugin schon installiert und Sie k&ouml;nnen gleich beginnen.</p>'+
		'Viel Spa&szlig; beim ausprobieren.</p><br><br>'+
		'<input type="button" onclick="visitcity.setMap3D();" value="3D-Modus starten"/>'+
		'</div>'+	
		'</div>';
		
		// earth tab
		visitcity.tab_nav.addTab(new YAHOO.widget.Tab({ 
			label: visitcity.ln.tab_earth,
			content: visitcity.earth_html
		}));
	}
	
	// Hide tab element ...
	var hide_tab = new YAHOO.widget.Tab({ 
	    label: '&lt;',
	    content: '' 
	});
	
	visitcity.tab_nav.addTab(hide_tab);
	hide_tab.subscribe('click', visitcity.hideNavigation);	
	
	// put the tabview into the container ...
	visitcity.tab_nav.appendTo('navigation'); 
	
	// resize map and keep track ...
	visitcity.layoutResize();
    visitcity.layout_inner.on('resize', visitcity.layoutResize);
	
	// init the places tab ...
	visitcity.InitPlacesTab();
	
	// init the businesses tab ...
	visitcity.InitBusinessesTab();
	
	// init the favorite tab ...
	visitcity.drawFavorites();
	
	// start building the tree ...
	visitcity.initTree();
};

visitcity.hideNavigation = function (ev) {
	visitcity.layout_inner.getUnitByPosition('left').collapse(); 
	visitcity.tab_nav.set('activeIndex', 0);
};

visitcity.layoutResize = function () {
	var c = visitcity.layout_inner.getUnitByPosition('center');
	var sizes = c.getSizes();

	c = visitcity.layout_inner.getUnitByPosition('center');
	sizes = c.getSizes();
	
	if (visitcity.earth_mode == "ON") {
		number_of_tabs = 5;
	} else {
		number_of_tabs = 4;
	}	

	for (var tab = 0; tab < number_of_tabs; tab++) {
		var a = visitcity.tab_nav.getTab(tab).get('contentEl');
		a.style.overflow = 'auto';
		a.style.height = (sizes.body.h - 48) + 'px';
	}
	
	visitcity.map.resizeTo(sizes.body.w-2, sizes.body.h-16);
};

visitcity.switchMap = function (api) {

	if (api != null)
		visitcity.api = api;
		
	visitcity.readDeeplink();
	
	if (visitcity.map) {
		visitcity.center = visitcity.map.getCenter();
  		visitcity.zoom = visitcity.map.getZoom();
  		visitcity.map.dispose();
	}

    // create map ...
    var c = visitcity.layout_inner.getUnitByPosition('center');
	var sizes = c.getSizes();
    visitcity.map = new MapApi('map', visitcity.api);
    
    // add and configure infobox div to map ...
    var map = new YAHOO.util.Element("map");
    var tooltip = new YAHOO.util.Element("tooltip");
    map.appendChild(tooltip);
    tooltip.setStyle("position", "absolute");
    

// ##########################################################
// API INIT
// ----------------------------------------------------------
	
    // now init ...
    visitcity.map.setCenterAndZoom(visitcity.center, visitcity.zoom);
	
	visitcity.map.setMapType(visitcity.maptype);

    // update deeplink on map move ...
	visitcity.map.registerEvent('moveend', visitcity.updateDeeplink);
    visitcity.map.registerEvent('zoomend', visitcity.updateDeeplink);
    visitcity.map.registerEvent('zoomend', visitcity.resizeIcons);
    visitcity.map.registerEvent('zoomend', visitcity.updateKMLOverlay);
    visitcity.map.registerEvent('onchangemapstyle', visitcity.changeMapStyle);
    visitcity.map.registerEvent('onbubbleclose', visitcity.closeBubble);


    visitcity.map.addLargeControls();

	//zuschaltbare Karte hinzuf&uuml;gen
	if(visitcity.set_map != ''){
		if(visitcity.set_map == 'DOK'){
			visitcity.map.map.addMapType(addNewSwitchMap('DOK'));
		}
		if(visitcity.set_map == 'TK50'){
			visitcity.map.map.addMapType(addNewSwitchMap('TK50'));
		}
	}
	
	// ====== Restricting the range of Zoom Levels =====
	// http://econym.org.uk/gmap/example_range.htm
	
	// Get the list of map types
	var mt = visitcity.map.getMapTypes();
	// Overwrite the getMinimumResolution() and getMaximumResolution() methods
	for (var i=0; i<mt.length; i++) {
		mt[i].getMinimumResolution = function() {return visitcity.minzoom;};
		mt[i].getMaximumResolution = function() {return visitcity.maxzoom;};
	}
	
	// visitcity.loadClientTileLayer();
	if(visitcity.tilelayer != '') {
		if(visitcity.tilelayer == 'OVERLAY'){
			visitcity.map.addOverlay(addClientTileLayer());
		}
		if(visitcity.tilelayer == 'DOP'){
			addClientTileLayer('DOP');
		}
	}
	
	if (visitcity.earth_mode == "ON") {
		visitcity.map.map.addMapType(G_SATELLITE_3D_MAP);
	}	
	
	if (visitcity.maptype == "EARTH") {
		visitcity.map.map.getEarthInstance(visitcity.setupEarth);
	}	

	visitcity.updateKMLOverlay();

};

visitcity.resizeIcons = function (e) {
	
	if (visitcity.map.getZoom() < visitcity.iconswitch) {
		for (var n in visitcity.businesses) {
			var business = visitcity.businesses[n];
			if (business.IsTiny) continue;
			visitcity.removeBusinessFromMap(business);
			for (var i = 0; i < business.Shapes.length; i++) {
				var shape = business.Shapes[i];
				if (shape.type == 'marker') {
					shape.setIcon(visitcity.iconpath + "tiny/" + business.IconId + '.gif', [6,6], [9,9]);
					shape.setShadowIcon(visitcity.iconpath + "tiny/shadow.png", [8,8]);
				}
			}
			visitcity.addBusinessToMap(business, false);
			business.IsTiny = true;
		}
	} else if (visitcity.map.getZoom() >= visitcity.iconswitch) {
		for (var n in visitcity.businesses) {
			var business = visitcity.businesses[n];
			if (!business.IsTiny) continue;
			visitcity.removeBusinessFromMap(business);
			for (var i = 0; i < business.Shapes.length; i++) {
				var shape = business.Shapes[i];
				if (shape.type == 'marker') {
					shape.setIcon(visitcity.iconpath + business.IconId + '.gif', [19,24], [6,-10]);
					shape.setShadowIcon(visitcity.iconpath + 'shadow.png', [37,27]);
				}
			}
			visitcity.addBusinessToMap(business, false);
			business.IsTiny = false;
		}
	}
};

visitcity.setLoaderText = function (text) {
	var loader = document.getElementById('txt_loader');
	loader.innerHTML = text;
};

visitcity.showLoader = function () {
	var loader = new YAHOO.util.Element('loader_bg');
	loader.setStyle('display', 'block');
	loader = new YAHOO.util.Element('loader');
	loader.setStyle('display', 'block');
};

visitcity.hideLoader = function () {
	var loader = new YAHOO.util.Element('loader_bg');
	loader.setStyle('display', 'none');
	loader = new YAHOO.util.Element('loader');
	loader.setStyle('display', 'none');
};

visitcity.displayTooltipDetailsWindow = function (uid) {
		
	// gathering information ...
	var uid = visitcity.businesses[uid].Uid;
	var kwisid = visitcity.businesses[uid].KwisId;
	var company = visitcity.businesses[uid].Company;
	var premium = visitcity.businesses[uid].Premium;
	var center = visitcity.map.getCenter();
	var zoom = visitcity.map.getZoom();	
	
	visitcity.active_poi = visitcity.businesses[uid];
	visitcity.updateDeeplink();
	
	if (parseInt(premium) > 0) {

		var premium_window = new YAHOO.widget.Panel("premium", {
			fixedcenter:true, 
			close:true, 
			draggable:false,
			zindex:1000,
			modal:true,
			visible:false,
			constraintoviewport:true
		});
	
		premium_window.setHeader("Premium-Visitenkarte " + company);
		var iframe = "<iframe src='" + visitcity.cardpath + uid +"&X="+center.lat+"&Y="+center.lon+"&Z="+zoom+"&MAP="+visitcity.maptype+"' width='850' height='450' border='0' frameborder='0'>loading ...</iframe>";
		premium_window.setBody(iframe);
		premium_window.render(document.body);
		premium_window.show();
		premium_window.hideMaskEvent.subscribe(function () { visitcity.active_poi = null; visitcity.updateDeeplink(); });
		
	} else {
	
		var details_window = new YAHOO.widget.Panel("wait", {
			width:visitcity.details_window_width, 
			fixedcenter:true, 
			close:true, 
			draggable:false,
			zindex:1000,
			modal:true,
			visible:false,
			constraintoviewport:true,
			iframe:true
		});

		details_window.setHeader( visitcity.ln.category + ":  " + visitcity.businesses[uid].CategoryName + " ");
		if (visitcity.sid == 'HEADER'){
			var iframe = "<iframe src='" + visitcity.detailpath + uid + "&X=" + center.lat + "&Y=" + center.lon + "&Z=" + zoom + "&MAP=" + visitcity.maptype + "' width='" + (visitcity.details_window_width-20) + "' height='300' border='0' frameborder='0'></iframe>";
		} else {
			var iframe = "<iframe src='" + visitcity.detailpath + uid + "&X=" + center.lat + "&Y=" + center.lon + "&Z=" + zoom + "&MAP=" + visitcity.maptype + "&SID=" + visitcity.sid + "' width='" + (visitcity.details_window_width-20) + "' height='300' border='0' frameborder='0'></iframe>";
		}		
		details_window.setBody(iframe);
		details_window.render(document.body);
		details_window.show();
		details_window.hideMaskEvent.subscribe(function () { visitcity.active_poi = null; visitcity.updateDeeplink(); });
	}
};

visitcity.displayImpressWindow = function () {
		var impress_window = new YAHOO.widget.Panel("impress", {
			width:"500px", 
			fixedcenter:true, 
			close:true, 
			draggable:false,
			zindex:1000,
			modal:true,
			visible:false,
			constraintoviewport:true
		});
	
		impress_window.setHeader(visitcity.ln.iwframe_impress);
		var iframe = "<iframe src='./impressum/impressum.html' width='480' height='240' border='0' frameborder='0'></iframe>";
		impress_window.setBody(iframe);
		impress_window.render(document.body);
		impress_window.show();
		
};


visitcity.onLayoutFinished = function () {

	// hide the loader screen ...
	visitcity.hideLoader();
	
	// load deeplink categories ...
	if (visitcity.kwis_short) {
		visitcity.loadKwisShortcut();
	} else {
		visitcity.loadDeeplinkUids();
		visitcity.loadDeeplinkCategories();
	}
	
	// load favorites ...
	visitcity.loadFavorites();
};


// use visitcity.doPrint(uid, favorites, selected, list)
visitcity.doPrint = function (uid, favorites, selected, list, autozoom) {
	var ids = "";
	var cats = "";
	
	if (autozoom) {
		autozoom = '&AUTOZOOM=true';
	} else {
		autozoom = '&AUTOZOOM=false';
	}
	
	if (list) {
		list = "true";
	} else {
		list = "false";
	}
	
	// print single symbol ...
	if (uid && uid > 0) {
		ids += uid;
		}
	
	// print selected categories ...
	if (selected) {
		var categories = visitcity.getActiveCategories();
		for (var i = 0; i < categories.length; i++) {
			cats += categories[i].Id;
			cats += ",";
		}
		cats = cats.substr(0,cats.length-1);
		
		// attach single added data ...
		for (var uid in visitcity.uids) {
			ids += uid;
			ids += ",";
		}
		ids = ids.substr(0,ids.length-1);
	}
	
	// print favorites ...
	if (favorites) {
	for (var i = 0; i < visitcity.favorites.length; i++) {
			ids += visitcity.favorites[i].Uid;
			ids += ",";
		}
		ids = ids.substr(0,ids.length-1);
	}
	
	var searches = '';
	var kwis_short = '';
	if (!favorites) {
		
		// print searches ...
		searches = "&SEARCH=";
		if (visitcity.searches.length > 0 && !uid) {
			for (var i = 0; i < visitcity.searches.length; i++) {
				searches += visitcity.searches[i] + ",";
			}
			searches = searches.substr(0, searches.length - 1);
		} else {
			searches = "";
		}
	
		// print kwis short ...
		if (visitcity.kwis_short) kwis_short = '&SHORT=' + visitcity.kwis_short;
	}
	
	var center = visitcity.map.getCenter();
	var zoom = visitcity.map.getZoom();
	
	window.open(visitcity.printpath + "#X=" + center.lat + "&Y=" + center.lon + "&Z=" + zoom + "&CATS=" + cats + "&UID=" + ids + "&MAP=" + visitcity.maptype + "&LIST=" + list + searches + kwis_short + autozoom , "Druckvorschau", "width=800,height=600,scrollbars=yes,resizeable=yes,menubar=yes");
};

// ##########################################################
// CATEGORY TREE LOADING/HANDLING
// ----------------------------------------------------------

visitcity.initTree = function () {

	visitcity.setLoaderText(visitcity.ln.loader_layers);

	extendTaskNode();

	visitcity.tree_cats = new YAHOO.widget.TreeView('tree_cats');
	visitcity.tree_cats.setDynamicLoad(visitcity.loadNodeData, 1); 
	visitcity.tree_cats.subscribe('checkClick', visitcity.catTreeCheck);
	visitcity.tree_cats.subscribe("expandComplete", visitcity.treeExpanded);

	var url = buildProxyUrl(visitcity.servicepath + "getTree/%27" + visitcity.client.catid + "%27/%27" + visitcity.client.pid + "%27/%270%27");
	var callback = 
	{
		success: visitcity.doneLoadNodeData,
		timeout: 20000
	};
	var transaction = YAHOO.util.Connect.asyncRequest('GET', url, callback);
	
	// handler for expanding all nodes
	YAHOO.util.Event.on("expand", "click", function(e) {
		visitcity.tree_cats.expandAll();
		YAHOO.util.Event.preventDefault(e);
	});
		
	// handler for collapsing all nodes
	YAHOO.util.Event.on("collapse", "click", function(e) {
		visitcity.tree_cats.collapseAll();
		YAHOO.util.Event.preventDefault(e);
	});
	
};

visitcity.loadNodeData = function (node, fnLoadComplete) {
	var url = buildProxyUrl(visitcity.servicepath + "getTree/%27" + visitcity.client.catid + "%27/%27" + visitcity.client.pid + "%27/%27" + node.data.Id + "%27");
	var callback = 
	{
		success: visitcity.doneLoadNodeData,
		timeout: 20000,
		argument: { 
			"node": node, 
			"fnLoadComplete": fnLoadComplete 
		}
	};
	var transaction = YAHOO.util.Connect.asyncRequest('GET', url, callback);
};

visitcity.doneLoadNodeData = function (o) {
	
	// parse the result ...
	var results = null;
	try { 
	    results = YAHOO.lang.JSON.parse(o.responseText); 
	} catch (e) { 
	    alert(e);
	}
	
	// either put all nodes below the root node, or another subnode,
	// depends on whether we are doing the initial load or just a dynamic one
	// ...
	var node = visitcity.tree_cats.getRoot();
	if (o.argument) node = o.argument.node;
	
	// create all nodes we have loaded ...
	for (var i = 0; i < results.length; i++) {
	
		// create the category Object ...
		var category = new VCCategory(results[i]);
		if (node.data && node.data.HasChilds) {
			category.Parent = node.data;
		}
		
		// create child node ...
		var tempNode = new YAHOO.widget.TaskNode(category, node, false, false);
		tempNode.label = "<b>" + category.Name + "</b>";
		
		// make it a leaf if it has no children ...
		if (results[i].son_exists == '0') {
			tempNode.label = "<b>" + category.Name + "</b>";
			tempNode.isLeaf = true;
			tempNode.setImage(visitcity.iconpath + 'leg_' + category.IconId + '.gif');
			tempNode.onLabelClick = visitcity.catTreeClick;
		}
	}
	
	// if incoming result object is a node, then mark it as completely loaded
	// ...
	if (o.argument) {
		o.argument.fnLoadComplete();
	
	// if we are doing the initial load, then draw the tree ...
	} else {

		visitcity.tree_cats.draw();
		visitcity.onLayoutFinished();
	}
};

visitcity.catTreeClick = function (node) {
	node.checkClick();
};

visitcity.catTreeCheck = function (node) {

	if (!node.isLeaf) {
		node.toggle();
		return;
	}

	// node has been checked ...
	if (node.checkState === 2) {
		visitcity.loading_queue.add(node);
	
	// node was checked and has been unchecked ...
	} else {
	
		// if the element is currently being loaded ...
		if (visitcity.loading_queue.element == node) {
			node.setCheckState(2);
			node.updateCheckHtml();
        	node.updateParent();
        	
        // if the element is not being loaded yet ...
		} else {
			visitcity.loading_queue.remove(node);
			visitcity.removeCategory(node);
		}
	}
	
	// continue loading data ...
	visitcity.loading_queue.process();
};

visitcity.getActiveCategories = function (node) {
	var categories = [];
	if (!visitcity.tree_cats) return categories;
	if (node == null) node = visitcity.tree_cats.getRoot();
	for (var i = 0; i < node.children.length; i++) {
		if (node.children[i].isLeaf) {
			if (node.children[i].checked) {
				categories.push(node.children[i].data);
			}
		} else {
			categories = categories.concat(visitcity.getActiveCategories(node.children[i]));
		}
	}
	return categories;
};

// ##########################################################
// CATEGORY LOADING
// ----------------------------------------------------------

visitcity.addCategory = function (category) {
	visitcity.loading_queue.addPart('businesses');
	visitcity.addBusiness(category);
};

visitcity.categoryLoaded = function (part) {

	// finish loading of part x ...
	visitcity.loading_queue.finishPart(part);
	
	// check whether all parts have loaded successfully ...
	if (!visitcity.loading_queue.allPartsFinished())
		return;
	
	// if loading is done, then continue ...
	visitcity.loading_queue.next();
	
	// refresh deeplink ...
	visitcity.updateDeeplink();
};

visitcity.removeCategory = function (node) {
	
	// remove category ...
	visitcity.removeBusiness(node);
	
	// refresh deeplink ...
	visitcity.updateDeeplink();
};

/**
 * Load a Category, also mark it in the category tree as loaded, this includes
 * expanding the tree.
 */
visitcity.loadCategory = function (catid) {
	var url = buildProxyUrl(visitcity.servicepath + "getParentNodes/%27" + catid + "%27/");
	var callback = 
	{
		success: visitcity.loadCategoryDone,
		timeout: 20000,
		argument: { catid: catid }
	};
	YAHOO.util.Connect.asyncRequest('GET', url, callback);
};

visitcity.loadCategoryDone = function (o) {
	var id = o.argument.catid;
	
	// parse the result ...
	var results = null;
	try { 
	    results = YAHOO.lang.JSON.parse(o.responseText); 
	} catch (e) { 
	    alert(e);
	}
	
	results.shift(); // no need to expand the root element ...
	results.push(id); // we need to select the cat to load ...
	
	var root = visitcity.tree_cats.getRoot();
	root.data = {};
	root.data.expand_after = results;
	visitcity.treeExpanded (root);
};

visitcity.treeExpanded = function (node) {
	if (node.data.expand_after.length == 1) {
		var to_check = node.data.expand_after.shift();
		for (var n = 0; n < node.children.length; n++) {
			if (node.children[n].data.KwisId == to_check) {
				node.children[n].checkClick();
				visitcity.loadDeeplinkCategories();
			}
		}
	} else if (node.data.expand_after.length > 0) {
		var to_expand = node.data.expand_after.shift();
		for (var n = 0; n < node.children.length; n++) {
			if (node.children[n].data.Id == to_expand) {
				node.children[n].data.expand_after = node.data.expand_after;
				if (node.children[n].expanded) {
					visitcity.treeExpanded(node.children[n]);
				} else {
					node.children[n].expand();
				}
			}
		}
	}
};

// ##########################################################
// GEO DATA CREATION
// ----------------------------------------------------------

visitcity.locationToShape = function (geostring) {

	// set up the marker ...
	var point = geostring.split(" ");
	var marker = new Marker(new LatLonPoint(parseFloat(point[0]), parseFloat(point[1])));
	
	return marker;
};

visitcity.linestringToShape = function (geostring) {

	var lines = [];
		
	// for multilinestring remove the "MULTILINESTRING(" and ")"
	// then split everything at "),(" and remove last backets ...
	// alert(geostring);
	if (geostring.indexOf("((") > 0) {
		geostring = geostring.substr(16, geostring.length-1);
		var multiline = geostring;
		lines = multiline.split('),(');
		for (var i = 0; i < lines.length; i++) {
			lines[i] = lines[i].split('(').join('').split(')').join('');
		}
	} else {
		lines.push(geostring.substr(11, geostring.length-1));
	}
			
	// process each line ...
	for (var l = 0; l < lines.length; l++) {
			
		// get the points of the line ...
		var points = lines[l].split(",");
		var line = new Line();
				
		// parse each point and add it to the line object ...
		for (var p = 0; p < points.length && points.length >= 1; p++) {
			var point = points[p].split(" ");
			if (point.length == 2) {
				var latlon = new LatLonPoint(parseFloat(point[0]), parseFloat(point[1]));
				line.addPoint(latlon);
			}
		}
		
		lines[l] = line;
	}
	
	return lines;
};

visitcity.getStyleInformation = function (stylestring) {
	if (!stylestring) return false;
	var xmlDoc = null;
	try {
		xmlDoc = new ActiveXObject("Microsoft.XMLDOM");
		xmlDoc.async = "false";
		xmlDoc.loadXML(stylestring);
	} catch(e) {
		try {
			parser = new DOMParser();
			xmlDoc = parser.parseFromString(stylestring,"text/xml");
		} catch(e) {
			alert(e.message);
			return;
		}
	}
	stylestring = visitcity.parseStyleNode(xmlDoc);
	if (stylestring.style)
		return stylestring.style;
	else
		return false;
};

visitcity.parseStyleNode = function (xmlnode) {
	var json = {};
	var childs = xmlnode.childNodes;
	for (var i = 0; i < childs.length; i++) {
		if (childs[i].childNodes.length > 1) {
			json[childs[i].nodeName] = visitcity.parseStyleNode(childs[i]);
		} else if (childs[i].childNodes.length == 1) {
			if (childs[i].childNodes[0].nodeName == "#text") {
				json[childs[i].nodeName] = childs[i].childNodes[0].nodeValue;
			} else {
				json[childs[i].nodeName] = visitcity.parseStyleNode(childs[i]);
			}
		} else {
			json[childs[i].nodeName] = childs[i].nodeValue;
		}
	}
	return json;
};

visitcity.addBusinessToMap = function (business, data) {

	// keep track of which businesses we added yet
	// we dont want to add a business twice -> performance loss!
	if (data == null || data == true)
		business = visitcity.addBusinessData(business);

	// put the shapes of our business onto the map ...
	if (!business.OnMap) {
		for (n = 0; n < business.Shapes.length; n++) {
			if (business.Shapes[n].type == 'marker') {
				visitcity.map.addMarker(business.Shapes[n]);
			} else {
				visitcity.map.addLine(business.Shapes[n]);
			}
		}
		business.OnMap = true;
	}
	
	return business;
};

visitcity.removeBusinessFromMap = function (business) {
	
	for (var i = 0; i < business.Shapes.length; i++) {
		var data = business.Shapes[i];
		switch (data.type) {
			case 'line':
				visitcity.map.removeLine(data);
			break;
			case 'marker':
				visitcity.map.removeMarker(data);
			break;
		}
	}
	business.OnMap = false;
};

// ##########################################################
// BUSINESSES MANAGEMENT
// ----------------------------------------------------------

visitcity.addBusinessData = function (business) {
// ### Dietmar: Bedingung ausmarkiert => Symbole die mehreren Kategorien
// zugeordnet sind, werden mehrfach geladen!!!
	// if (visitcity.businesses[business.Uid] == null) {
		business.InUse = 1;
		visitcity.businesses[business.Uid] = business;
		visitcity.resizeIcons();
	/*
	 * } else { visitcity.businesses[business.Uid].InUse++; }
	 */
	return visitcity.businesses[business.Uid];
};

visitcity.removeBusinessData = function (business) {
	if (--business.InUse == 0) {
		visitcity.removeBusinessFromMap(business);
		delete visitcity.businesses[business.Uid];
		delete visitcity.uids[business.Uid];
	}
};

visitcity.InitBusinessesTab = function () {
	visitcity.tree_businesses = new YAHOO.widget.TreeView('tree_businesses');
	visitcity.tree_businesses.subscribe('checkClick', visitcity.treeBusinessesCheck);
	visitcity.tree_businesses.count = 0;
};

visitcity.addBusiness = function (category) {
	category.Active = true;
	var url = buildProxyUrl(visitcity.servicepath + "getSymbols/%27" + category.Id + "%27/%27" + visitcity.client.pid + "%27//");
	var callback = 
	{
		success: visitcity.readyToAddBusiness,
		timeout: 20000,
		argument: { "category": category }
	};
	YAHOO.util.Connect.asyncRequest('GET', url, callback);
};

visitcity.readyToAddBusiness = function (o) {

	// if the node has been removed from the map ...
	var category = o.argument.category;
	if (!category.Active) {
		return;
	}

	// parse the result ...
	var results = null;
	try { 
	    results = YAHOO.lang.JSON.parse(o.responseText); 
	} catch (e) { 
	    alert(e);
	}
	
	// no businesses in current category ...
	if (!results[0]) {
		visitcity.categoryLoaded('businesses');
		return;
	}
	
	// convert results in business objects ...
	var business = null;
	var businesses = [];
	var points = [];	
	
	for (var i = 0; i < results.length; i++) {
	
		// parse business object from results ...
		business = new VCBusiness(results[i]);
		
		// create business on map ...
		business = visitcity.addBusinessToMap(business);
		businesses.push(business);
	}
	var root = visitcity.tree_businesses.getRoot();
	var childs = root.children;
	var parent = null;
	var icon_path =  visitcity.iconpath + 'leg_' + category.IconId + '.gif';
	
	// check if this is a freshly added business ...
	for (var i = 0; i < businesses.length; i++) {
		var same = false;
		for (var n = 0; n < childs.length; n++) {
			if (childs[n].data.Id == businesses[i].CategoryId)
				same = true;
		}
		if (!same) {
			business = businesses[i];
			break;
		}
	}
	
	// create parent element ...
	var node = {};
	node.Id = business.CategoryId;
	node.label = "<b>"+visitcity.ln.list_tree+" '" + business.CategoryName + "'</b> (" + results.length + ")";
	parent = new YAHOO.widget.TaskNode(node, null, false, false);
	parent.setImage(icon_path);
	
	if (root.hasChildren()) {
		parent.insertBefore(childs[0]);
	} else {
		parent.appendTo(root);
	}
	
	// now append each business to the category ...
	for (i = 0; i < businesses.length; i++) {
		business = businesses[i];
		if (business.Address && (business.Zip || business.City)) {
			business.label = "<b>" + business.Company + "</b><br>" + business.Address + "<br>" + business.Zip + "&nbsp;" + business.City;
		} else if (business.Zip || business.City) {
			business.label = "<b>" + business.Company + "</b><br>" + business.Zip + "&nbsp;" + business.City;
		} else {
			business.label = "<b>" + business.Company + "</b>";
		}
		var tempNode = new YAHOO.widget.TaskNode(business, parent, false, business.Visible, true);
		tempNode.setImage(icon_path);
		tempNode.onLabelClick = visitcity.treeBusinessesClick;
		points = points.concat(businesses[i].Shapes);
		business.addNode(tempNode);
	}
	
	visitcity.tree_businesses.count++;
	visitcity.tab_nav.getTab(1).set('label', visitcity.ln.list+' (' + visitcity.tree_businesses.count + ')');
	visitcity.tree_businesses.draw();
	if (visitcity.map.getMapType() != 'EARTH') {
		visitcity.map.zoomToBounds(points);
	}
	visitcity.categoryLoaded('businesses');
	
};

visitcity.readyToAddBusinessFromSearch = function (o) {
	
	hideStatus();
	var n = 0;

	// parse the result ...
	var results = null;
	try { 
	    results = YAHOO.lang.JSON.parse(o.responseText); 
	} catch (e) { 
	    alert(e);
	}
	
	var businesses = [];
	for (var i = 0; i < results.length; i++) {
	
		// count added businesses ...
		n++;
	
		// parse business object from results ...
		business = new VCBusiness(results[i]);

		// create a link in the businesses list ...
		business = visitcity.addBusinessToMap(business);
		
		// add to businesses ...
		businesses.push(business);
	}
	
	visitcity.tree_businesses.count++;
	visitcity.tab_nav.getTab(1).set('label', visitcity.ln.list+' (' + visitcity.tree_businesses.count + ')');
	visitcity.tab_nav.set('activeIndex', 1);
	
	var search_root = o.argument.parent_node;
	search_root.stopLoading();
	search_root.data.search = o.argument.search;
	search_root.isLeaf = false;
	
	if (results.length == 0) {
		var tempNode = new YAHOO.widget.TextNode(visitcity.ln.search_noresult, search_root, false);
		tempNode.isLeaf = true;
	}
	var counter = 0;
	var points = [];	
	for (var i = 0; i < businesses.length; i++) {
		
		var exists = false;
		for (var n = 0; n < search_root.children.length; n++) {
			if (search_root.children[n].data.Uid == businesses[i].Uid) exists = true;
		}
		if (exists) {
			visitcity.removeBusinessData(businesses[i]);
			continue;
		}
		
		if (businesses[i].Address && (businesses[i].Zip || businesses[i].City)) {
			businesses[i].label = "<b>" + businesses[i].Company + "</b><br>" + businesses[i].Address + ", " + businesses[i].Zip + " " + businesses[i].City;
		} else if (businesses[i].Zip || businesses[i].City) {
			businesses[i].label = "<b>" + businesses[i].Company + "</b><br>" + businesses[i].Zip + " " + businesses[i].City;
		} else {
			businesses[i].label = "<b>" + businesses[i].Company + "</b>";
		}

		var tempNode = new YAHOO.widget.TaskNode(businesses[i], search_root, false, businesses[i].Visible, true);
		tempNode.setImage(visitcity.iconpath + 'leg_' + businesses[i].IconId + '.gif');
		tempNode.onLabelClick = visitcity.treeBusinessesClick;
		businesses[i].addNode(tempNode);
		counter = counter + 1;
		points = points.concat(businesses[i].Shapes);		
	}
	search_root.data.Id = o.argument.search;

	search_root.label = "<b>"+visitcity.ln.search_result+" '" + o.argument.search + "'</b> (" + counter + ")";
	search_root.expand();

	visitcity.tree_businesses.draw();

if (points.length > 0) {
	//visitcity.map.setCenterAndZoom(visitcity.map.getCenter(), 3);
	visitcity.map.zoomToBounds(points);
}
	
	visitcity.updateDeeplink();
};

visitcity.treeBusinessesCheck = function (node) {
	
	// this is a category node, we need to hide all busnisses in there ...
	if (node.children.length > 0) {
	
		// decide whether to hide or show all childnodes ...
		var hide = false;
		if (node.checkState > 0) hide = true;
		
		for (var i = 0; i < node.children.length; i++) {
			if (hide) {
				node.children[i].data.hide();
			} else {
				node.children[i].data.show();
			}
		}
		return;
	}
	
	// this is a single business, just hide it ...
	if (node.checkState == 2) {
		node.data.show();
	} else {
		node.data.hide();
	}
};

visitcity.treeBusinessesClick = function (node) {
	if (node.children.length > 0) {
		node.checkClick();
		return;
	}
	// var point = node.data.Shapes[0].getLocation();
	var points = [];
	points = points.concat(node.data.Shapes);
	// if (visitcity.map.getMapType() != 'EARTH') {	
		visitcity.map.zoomToBounds(points);
	// }
	//visitcity.map.setCenterAndZoom(point, visitcity.maxpoizoom);
	if (node.data.Shapes[0].openBubble) node.data.Shapes[0].openBubble();
};

visitcity.removeBusiness = function (cat_node) {
	var root = visitcity.tree_businesses.getRoot();
	var childs = root.children;
	var removed = false;
	for (var i = 0; i < childs.length; i++) {
		if (childs[i].data.Id == cat_node.data.Id) {
			for (var n = 0; n < childs[i].children.length; n++) {
				visitcity.removeBusinessData(childs[i].children[n].data);
			}
			visitcity.tree_businesses.removeNode(childs[i]);
			removed = true;
		}
	}
	
	if (!removed) {
		return;
		cat_node.data.is_removed = true;
	}
	
	// display message if tree is empty ...
	if (childs.length <= 1) {
		visitcity.tree_businesses.count = 0;
		var btree = new YAHOO.util.Element('tree_businesses');
		btree.set('innerHTML', visitcity.ln.list_help);
	} else {
		visitcity.tree_businesses.count--;
		visitcity.tree_businesses.draw();
	}
	visitcity.tab_nav.getTab(1).set('label', visitcity.ln.list+' (' + visitcity.tree_businesses.count + ')');
};

visitcity.clearTreeCats = function () {
	var root = visitcity.tree_cats.getRoot();
	visitcity.clearCategoryTree(root);
};

visitcity.clearAll = function () {
	
	// reset searches and kwis short ...
	visitcity.searches = [];
	visitcity.kwis_short = null;
	
	// uncheck and unload categories ...
	var root = visitcity.tree_cats.getRoot();
	visitcity.clearCategoryTree(root);
	
	// clear search results ...
	root = visitcity.tree_businesses.getRoot();
	visitcity.clearBusinessesTree(root);
	
	// remove all root-childs ...
	visitcity.tree_businesses.removeChildren(root);
	visitcity.tree_businesses.draw();
	visitcity.tree_businesses.count = 0;
	(new YAHOO.util.Element('tree_businesses')).set('innerHTML', visitcity.ln.list_help);
	visitcity.tab_nav.getTab(1).set('label', visitcity.ln.list+' (' + visitcity.tree_businesses.count + ')');
};

visitcity.clearCategoryTree = function (node) {
	for (var i = 0; i < node.children.length; i++) {
		if (node.children[i].isLeaf && node.children[i].checkState == 2) {
			node.children[i].checkClick();
		} else {
			visitcity.clearCategoryTree(node.children[i]);
		}
	}
};

visitcity.clearBusinessesTree = function (node) {
	for (var i = 0; i < node.children.length; i++) {
		if (node.children[i].isLeaf) {
			visitcity.removeBusinessData(node.children[i].data);
		} else {
			visitcity.clearBusinessesTree(node.children[i]);
		}
	}
};

/**
 * Load a single business or more by its ID ...
 */
visitcity.loadBusinesses = function (ids, label, zoom) {
	if (zoom == null) zoom = false;

	ids = ids.join(",");
	
	var root = visitcity.tree_businesses.getRoot();
	var tempNode = new YAHOO.widget.TaskNode("Lade " + label + " ...", root, false, false);
	tempNode.isLeaf = true;
	tempNode.startLoading();
	
	visitcity.tab_nav.set('activeIndex', 1);
	visitcity.tree_businesses.draw();
	
	var url = buildProxyUrl(visitcity.servicepath + "getSymbol/%27" + ids + "%27/");
	var callback = 
	{
		success: visitcity.loadBusinessesDone,
		timeout: 20000,
		argument: { 'loading_node': tempNode, 'label': label, 'zoom': zoom }
	};
	YAHOO.util.Connect.asyncRequest('GET', url, callback);
};

visitcity.loadBusinessesDone = function (o) {

	// parse the result ...
	var results = null;
	try { 
	    results = YAHOO.lang.JSON.parse(o.responseText); 
	} catch (e) { 
	    alert(e);
	}
	
	var businesses = [];
	for (var i = 0; i < results.length; i++) {
	
		// parse business object from results ...
		business = new VCBusiness(results[i]);

		// create a link in the businesses list ...
		business = visitcity.addBusinessToMap(business);
		
		// add to businesses ...
		businesses.push(business);
		
		// add ...
		visitcity.uids[business.Uid] = 1;
	}
	
	visitcity.tree_businesses.count++;
	visitcity.tab_nav.getTab(1).set('label', visitcity.ln.list+' (' + visitcity.tree_businesses.count + ')');
	visitcity.tab_nav.set('activeIndex', 1);
	
	var search_root = o.argument.loading_node;
	search_root.stopLoading();
	search_root.isLeaf = false;
	
	if (businesses.length == 0) {
		var tempNode = new YAHOO.widget.TextNode(visitcity.ln.search_noresult, search_root, false);
		tempNode.isLeaf = true;
	}
	
	var points = [];
	for (var i = 0; i < businesses.length; i++) {
		
		if (businesses[i].Address && (businesses[i].Zip || businesses[i].City)) {
			businesses[i].label = "<b>" + businesses[i].Company + "</b><br>" + businesses[i].Address + ", " + businesses[i].Zip + " " + businesses[i].City;
		} else if (businesses[i].Zip || businesses[i].City) {
			businesses[i].label = "<b>" + businesses[i].Company + "</b><br>" + businesses[i].Zip + " " + businesses[i].City;
		} else {
			businesses[i].label = "<b>" + businesses[i].Company + "</b>";
		}

		var tempNode = new YAHOO.widget.TaskNode(businesses[i], search_root, false, businesses[i].Visible, true);
		tempNode.setImage( visitcity.iconpath + 'leg_' + businesses[i].IconId + '.gif');
		tempNode.onLabelClick = visitcity.treeBusinessesClick;
		businesses[i].addNode(tempNode);
		points = points.concat(businesses[i].Shapes);
	}
	search_root.data.Id = o.argument.label;
	search_root.label = "<b>" + o.argument.label + "</b> (" + businesses.length + ")";
	search_root.expand();
	visitcity.tree_businesses.draw();
	if (o.argument.zoom) {
		if (visitcity.map.getMapType() != 'EARTH') {
			//visitcity.map.setCenterAndZoom(visitcity.map.getCenter(), 3);
			visitcity.map.panToAndZoom(visitcity.map.getCenter(), 3);
			visitcity.map.zoomToBounds(points);
		}
	}
 if (businesses.length == 1) {
  if (businesses[0].Shapes[0].type == "marker")
   businesses[0].Shapes[0].openBubble();
  else {
  // to open a detailwindow by deeplinking to shapes:
   // visitcity.displayTooltipDetailsWindow(businesses[0].Uid);
	}
 }
};

// ##########################################################
// SEARCHING
// ----------------------------------------------------------

visitcity.startSearchByKey = function (e) {
	if (!e) e = window.event;
	
	if (e && e.keyCode == 13) {
		visitcity.startSearch();
	}
};

/**
 * Performs a geo search on the current map api.
 */
visitcity.startSearch = function () {
	
		var search_places = new YAHOO.util.Element('radSTypeP').get('checked');
		var fStr = new YAHOO.util.Element('txt_fstr');

	if (fStr.get('value') != '') {		
		if (search_places) {
			
			// initialise the map with your choice of API
			var geocoder = new MapstractionGeocoder(visitcity.displayPlaces, visitcity.api, visitcity.map.getMap());
			
			// create the address object ...
			var address = new Object();
			address.searchstring = fStr.get('value');
			
			// start search on the address object ...
			geocoder.geocode(address);
			
			// display loading status ...
			displayStatus("Suche nach Orten ...");
			
			// create loading node ...
			var root = visitcity.tree_places.getRoot();
			var tempNode = new YAHOO.widget.TaskNode(visitcity.ln.search_for+ " '" + fStr.get('value') + "' ...", null, false, false);
			
			if (root.hasChildren()) {
				tempNode.insertBefore(root.children[0]);
			} else {
				tempNode.appendTo(root);
			}
			
			tempNode.isLeaf = true;
			tempNode.startLoading();
			visitcity.tab_nav.set('activeIndex', 2);
			visitcity.tree_places.draw();
			
			// save the loading node in the geocode object ...
			geocoder.data.node = tempNode;
			
		} else {
			
			var root = visitcity.tree_businesses.getRoot();
			var node = new YAHOO.widget.TaskNode({ label:visitcity.ln.search_for+" '" + fStr.get('value') + "' ..." }, null, false, false);
			
			if (root.hasChildren()) {
				node.insertBefore(root.children[0]);
			} else {
				node.appendTo(root);
			}
			
			node.isLeaf = true;
			node.startLoading();
			visitcity.tab_nav.set('activeIndex', 1);
			visitcity.tree_businesses.draw();
			
			// display status msg ...
			displayStatus("Suche nach Objekten ...");
			var url = buildProxyUrl(visitcity.servicepath + "searchSymbols/" + escape(fStr.get('value').replace(' ', '%20')) + "/%2527" + visitcity.client.pid + "%2527/");
			var callback = 
			{
success: visitcity.readyToAddBusinessFromSearch,
timeout: 20000,
argument: { search: fStr.get('value'), parent_node: node }
			};
			YAHOO.util.Connect.asyncRequest('GET', url, callback);
			
			// add string to searches ...
			visitcity.searches.push(fStr.get('value'));
		}
	} else {
		alert("Bitte Suchbegriff eingeben");
	}
		fStr.set('value', '');
};

// ##########################################################
// PLACES MANAGEMENT
// ----------------------------------------------------------

visitcity.InitPlacesTab = function () {
	visitcity.tree_places = new YAHOO.widget.TreeView('tree_places');
	visitcity.tree_places.subscribe('checkClick', visitcity.treePlacesCheck);
	visitcity.tree_places.count = 0;
};

visitcity.treePlacesCheck = function (node) {

	if (node.children.length > 0) {
	
		// decide whether to hide or show all childnodes ...
		var hide = false;
		if (node.checkState > 0) hide = true;
		
		for (var i = 0; i < node.children.length; i++) {
			if (hide) {
				node.children[i].data.marker.hide();
				node.children[i].setCheckState(0);
				node.children[i].updateCheckHtml();
				node.children[i].updateParent();
			} else {
				node.children[i].data.marker.show();
				node.children[i].setCheckState(2);
				node.children[i].updateCheckHtml();
				node.children[i].updateParent();
			}
		}
	}

	if (node.checkState == 2) {
		node.data.marker.show();
	} else {
		node.data.marker.hide();	
	}
};

visitcity.treePlacesClick = function (node) {
	var parent = node.parent;
	for (var i = 0; i < parent.children.length; i++) {
		parent.children[i].setImage(null);
	}
	visitcity.map.setCenter(node.data.point);
	node.setImage(visitcity.app_path+'img/pin.png');
};

visitcity.onPlacesActiveChange = function (e) {
	if (e.newValue) {
		var search_places = new YAHOO.util.Element('radSTypeP');
		search_places.set('checked', 'checked');
	} else {
		var search_business = new YAHOO.util.Element('radSTypeB');
		search_business.set('checked', 'checked');
	}
};

visitcity.displayPlaces = function (places, geocoder) {
	
	hideStatus();
	
	var count = 0;
	if (places) count = places.length;
	
	var search_root = geocoder.data.node;
	search_root.stopLoading();
	search_root.label = "<b>"+visitcity.ln.search_result+" '" + geocoder.search + "'</b> (" + count + ")";
	search_root.data.search = geocoder.search;
	search_root.isLeaf = false;
	search_root.expand();
	
	visitcity.tree_places.count++;
	//visitcity.tab_nav.getTab(2).set('label', visitcity.ln.locations+' (' + visitcity.tree_places.count + ')');
	visitcity.tab_nav.getTab(2).set('label', visitcity.ln.locations);
	visitcity.tab_nav.set('activeIndex', 2);
	
	if (places) {
		for (var i = 0; i < places.length; i++) {
			places[i].label = places[i].name;
			var marker = new Marker(places[i].point);
			visitcity.map.addMarker(marker);
			var tempNode = new YAHOO.widget.TaskNode(places[i], search_root, false, true, true);
			tempNode.onLabelClick = visitcity.treePlacesClick;
			tempNode.data.marker = marker;
		}
	}
	visitcity.tree_places.draw();
};

visitcity.clearPlaces = function () {
	var root = visitcity.tree_places.getRoot();
	for (var i = 0; i < root.children.length; i++) {
		for (var n = 0; n < root.children[i].children.length; n++) {
			if (root.children[i].children[n].data.marker)
				visitcity.map.removeMarker(root.children[i].children[n].data.marker);
		}
	}
	
	visitcity.tree_places.removeChildren(root);
	visitcity.tree_places.count = 0;
	//visitcity.tab_nav.getTab(2).set('label', visitcity.ln.locations+' (' + visitcity.tree_places.count + ')');
	visitcity.tab_nav.getTab(2).set('label', visitcity.ln.locations);
	visitcity.tree_places.draw();
};

//##########################################################
// DEEPLINKING
// ----------------------------------------------------------

visitcity.updateDeeplink = function () {
	
	// get url ...
	var url = window.location.href.split('#');
	
	// get coords ...
	var center = visitcity.map.getCenter();
	var zoom = visitcity.map.getZoom();
	
	var categories = visitcity.getActiveCategories();
	var cats = '';
	for (var i = 0; i < categories.length; i++) {
		cats += categories[i].KwisId + ",";
	}
	cats = cats.substr(0, cats.length-1);
	
	var uids = '';
	
	// attach single added data ...
	for (var uid in visitcity.uids) {
		uids += visitcity.businesses[uid].KwisId;
		uids += ',';
	}
	
	// attach currently opened window ...
	if (visitcity.active_poi && !visitcity.uids[visitcity.active_poi.Uid]) {
		uids = visitcity.active_poi.KwisId;
		uids += ',';
	}
	uids = uids.substr(0,uids.length-1);
	
	var searches = "&SEARCH=";
	if (visitcity.searches.length > 0) {
		for (var i = 0; i < visitcity.searches.length; i++) {
			searches += visitcity.searches[i] + ",";
		}
		searches = searches.substr(0, searches.length - 1);
	} else {
		searches = "";
	}
	
	visitcity.maptype = visitcity.map.getMapType();
	
	// write deeplink ...
	if (visitcity.sid == 'HEADER') {
		window.location.href = url[0]+"#"+"X="+center.lat.toFixed(5)+"&Y="+center.lon.toFixed(5)+"&Z="+zoom+"&CATS="+cats+"&UID="+uids+"&MAP=" + visitcity.maptype + searches + "&LN=" + lang.toUpperCase();
	} else {
		window.location.href = url[0]+"#"+"X="+center.lat.toFixed(5)+"&Y="+center.lon.toFixed(5)+"&Z="+zoom+"&CATS="+cats+"&UID="+uids+"&SID="+visitcity.sid+"&MAP=" + visitcity.maptype + searches + "&LN=" + lang.toUpperCase();
	}
	
	// write coords
	document.getElementById("coord_lat").value = center.lat.toFixed(5);
	document.getElementById("coord_lon").value = center.lon.toFixed(5);
};

visitcity.readDeeplink = function () {

	// read X and Y params ...
	var cur_x = parseFloat(getURLParam('x'));
	var cur_y = parseFloat(getURLParam('y'));
	if (cur_x > 0 && cur_y > 0) {
		visitcity.center = new LatLonPoint(cur_x, cur_y);
	}
	
	// read Zoom param ...
	var cur_z = parseFloat(getURLParam('z'));
	if (cur_z > 0) {
		visitcity.zoom = cur_z;
	}
	
	// read client id
	var cur_client = parseInt(getURLParam('client'));
	if (cur_client > 0) {
		visitcity.client.id = cur_client;
	}
};

visitcity.loadDeeplinkCategories = function () {
	if (!visitcity.categories_to_load || visitcity.categories_to_load.length == 0) return;
	var category_to_load = visitcity.categories_to_load.shift();
	if (category_to_load == "") {
		visitcity.loadDeeplinkCategories();
		return;
	}
	visitcity.loadCategory(category_to_load);
};

visitcity.loadDeeplinkUids = function () {
	if (!visitcity.uids_to_load || visitcity.uids_to_load.length == 0 || !visitcity.uids_to_load[0]) return;
	var uids = visitcity.uids_to_load;
	visitcity.uids_to_load = [];
	visitcity.loadBusinesses(uids, "Verlinkte Objekte",true);
};

/*
 * 
 * visitcity.deeplinkChanged = function () {
 * 
 * var old_client = visitcity.client.id;
 * 
 * visitcity.readDeeplink(); visitcity.map.setCenterAndZoom(visitcity.center,
 * visitcity.zoom);
 * 
 * if (old_client != visitcity.client.id) { visitcity.loadSettings(null, true); } };
 * 
 */

// ##########################################################
// KWIS EXTRAS
// ----------------------------------------------------------

visitcity.loadKwisShortcut = function () {

	var root = visitcity.tree_businesses.getRoot();
	var tempNode = new YAHOO.widget.TaskNode(visitcity.ln.list_getshortcut, root, false, false);
	tempNode.isLeaf = true;
	tempNode.startLoading();
	visitcity.tab_nav.set('activeIndex', 1);
	visitcity.tree_businesses.draw();

	var url = buildProxyUrl(visitcity.servicepath + "getShortcutSymbols/%27" + visitcity.kwis_short + "%27/%27" + visitcity.client.pid + "%27/");
	var callback = 
	{
		success: visitcity.loadKwisShortcutDone,
		timeout: 20000,
		argument: { loading_node: tempNode }
	};
	YAHOO.util.Connect.asyncRequest('GET', url, callback);
};

visitcity.loadKwisShortcutDone = function (o) {

	// parse the result ...
	var results = null;
	try { 
	    results = YAHOO.lang.JSON.parse(o.responseText); 
	} catch (e) { 
	    alert(e);
	}
	
	var businesses = [];
	for (var i = 0; i < results.length; i++) {
	
		// parse business object from results ...
		business = new VCBusiness(results[i]);

		// create a link in the businesses list ...
		business = visitcity.addBusinessToMap(business);
		
		// add to businesses ...
		businesses.push(business);
		
		// add business to uids list ...
		visitcity.uids[business.Uid] = 1;
	}
	
	visitcity.tree_businesses.count++;
	visitcity.tab_nav.getTab(1).set('label', visitcity.ln.list+' (' + visitcity.tree_businesses.count + ')');
	visitcity.tab_nav.set('activeIndex', 1);
	
	var search_root = o.argument.loading_node;
	search_root.stopLoading();
	search_root.isLeaf = false;
	
	if (businesses.length == 0) {
		var tempNode = new YAHOO.widget.TextNode(visitcity.ln.search_noresult, search_root, false);
		tempNode.isLeaf = true;
	}
	
	var points = [];
	for (var i = 0; i < businesses.length; i++) {
		
		if (businesses[i].Address && (businesses[i].Zip || businesses[i].City)) {
			businesses[i].label = "<b>" + businesses[i].Company + "</b><br>" + businesses[i].Address + ", " + businesses[i].Zip + " " + businesses[i].City;
		} else if (businesses[i].Zip || businesses[i].City) {
			businesses[i].label = "<b>" + businesses[i].Company + "</b><br>" + businesses[i].Zip + " " + businesses[i].City;
		} else {
			businesses[i].label = "<b>" + businesses[i].Company + "</b>";
		}

		var tempNode = new YAHOO.widget.TaskNode(businesses[i], search_root, false, businesses[i].Visible, true);
		tempNode.setImage( visitcity.iconpath + 'leg_' + businesses[i].IconId + '.gif');
		tempNode.onLabelClick = visitcity.treeBusinessesClick;
		businesses[i].addNode(tempNode);
		points = points.concat(businesses[i].Shapes);
	}
	search_root.data.Id = o.argument.search;
	search_root.label = "<b>Kwis Daten</b> (" + businesses.length + ")";
	search_root.expand();
	visitcity.tree_businesses.draw();
	//visitcity.map.setCenterAndZoom(visitcity.map.getCenter(), 3);
	visitcity.map.zoomToBounds(points);
};

// ##########################################################
// DYNAMIC STYLING
// ----------------------------------------------------------

visitcity.applyStyles = function () {
	
	// set header image ...
	var header = new YAHOO.util.Element('header');
	header.setStyle('backgroundImage', 'url(./img/header.jpg)');
	header.setStyle('backgroundColor', '#'+visitcity.styles.bg_header);
	header.setStyle('position', 'absolute');
	header.setStyle('width', '100%');
	header.setStyle('height', '100%');
	header.setStyle('backgroundRepeat', 'no-repeat');
	header.set('innerHTML', '<div id="header_left"></div><div id="header_right"></div>');
	
	// set header_left ...
	var header_left = new YAHOO.util.Element('header_left');
	header_left.setStyle('position', 'absolute');
	header_left.setStyle('left', '0px');
	header_left.set('innerHTML', visitcity.headerleft);

	// set header_right ...
	var header_right = new YAHOO.util.Element('header_right');
	header_right.setStyle('position', 'absolute');
	header_right.set('innerHTML', visitcity.headerright);
	
	// unit search
	var unit_search = new YAHOO.util.Element('unit_search');
	unit_search.setStyle('backgroundColor', '#'+visitcity.styles.bg_searchbar);
	unit_search.setStyle('color', '#'+visitcity.styles.color_text);
    
	// unit navigation
	var unit_navigation = new YAHOO.util.Element('unit_navigation');
	unit_navigation.setStyle('backgroundColor', '#'+visitcity.styles.bg_main);
    
	// unit map
	var unit_map = new YAHOO.util.Element('unit_map');
	unit_map.setStyle('backgroundColor', '#'+visitcity.styles.bg_main);
	
	// map border
	var map = new YAHOO.util.Element('map');
	map.setStyle('borderColor', '#'+visitcity.styles.color_border);
	
	// status lbl
	var statuslbl = new YAHOO.util.Element("statuslbl");
	statuslbl.setStyle('background', '#' + visitcity.styles.bg_tab_selected);
	statuslbl.setStyle('color', '#' + visitcity.styles.color_tab_selected);
	
	var new_styles = {
		'.yui-skin-sam.yui-panel.hd': { 'color': '#'+visitcity.styles.color_tab_selected, 'background': '#'+visitcity.styles.bg_tab_selected },
		'.yui-skin-sam.yui-navset.yui-nav,.yui-skin-sam.yui-navset.yui-navset-top.yui-nav': { 'borderStyle':'solid', 'borderColor':'#'+visitcity.styles.bg_tab_selected },
		'.yui-skin-sam.yui-navset.yui-nava,.yui-skin-sam.yui-navset.yui-navset-top.yui-nava,.yui-skin-sam.yui-navset.yui-content': { 'background':'#'+visitcity.styles.bg_tab, 'borderStyle':'solid', 'borderColor':'#'+visitcity.styles.color_border, 'color':'#'+visitcity.styles.color_tab },
		'.yui-skin-sam.yui-navset.yui-navaem,.yui-skin-sam.yui-navset.yui-navset-top.yui-navaem': { 'borderStyle':'solid', 'borderColor':'#'+visitcity.styles.color_border },
		'.yui-skin-sam.yui-navset.yui-nav.selecteda,.yui-skin-sam.yui-navset.yui-nav.selecteda:focus,.yui-skin-sam.yui-navset.yui-nav.selecteda:hover': { 'background':'#'+visitcity.styles.bg_tab_selected, 'color':'#'+visitcity.styles.color_tab_selected },
		'.yui-skin-sam.yui-navset.yui-nava:hover,.yui-skin-sam.yui-navset.yui-nava:focus': { 'background':'#'+visitcity.styles.bg_tab_hovered, 'color':'#'+visitcity.styles.color_tab_hovered },
		'.yui-skin-sam.yui-navset.yui-content,.yui-skin-sam.yui-navset.yui-navset-top.yui-content': { 'borderColor':'#'+visitcity.styles.color_border },
		'.yui-skin-sam.yui-layout.yui-layout-clip': { 'backgroundColor': '#'+visitcity.styles.bg_tab_hovered },
		'.yui-skin-sam.yui-layout': { 'backgroundColor': '#'+visitcity.styles.bg_main }
	};
	
	var strCSS = 'cssRules';
	if (!document.styleSheets[0].cssRules) {
		strCSS = 'rules';
	}
	
	for (var sheet = 0; sheet < document.styleSheets.length; sheet++) {
		try {
			for (var rule = 0; rule < document.styleSheets[sheet][strCSS].length; rule++) {
				var ruleName = document.styleSheets[sheet][strCSS][rule].selectorText.split(" ").join("").toLowerCase();
				for (var sel in new_styles) {
					var parts = sel.split(",");
					parts.push(sel);
					for (var i = 0; i < parts.length; i++) {
						if (ruleName == parts[i]) {
							for (var att in new_styles[sel]) {
								document.styleSheets[sheet][strCSS][rule].style[att] = new_styles[sel][att];
							}
						}
					}
				}
			}
		} catch (e) {
			// read-protected properties cause exceptions sometimes ...
		}
	}
};

// ##########################################################
// FAVORITES TAB
// ----------------------------------------------------------

visitcity.addToFavorites = function (business) {

	if (!business.Uid) {
	
		// create copy ...
		business = visitcity.businesses[business].copy();
	}

	var favstring = readCookie("favoriten");
	if (favstring) {
		var favorites = favstring.split(",");
		for (var i = 0; i < favorites.length; i++) {
			if (favorites[i] == business.KwisId) {
				alert(visitcity.ln.favorites_alert);
				return;
			}
		}
		writeCookie("favoriten", favstring + ',' + business.KwisId, 365);
	} else {
		writeCookie("favoriten", business.KwisId, 365);
	}
	//alert("Eintrag wurde zu den Favoriten hinzugef&uuml;gt.");
	visitcity.favorites.push(business);
	visitcity.drawFavorites();
};

visitcity.removeFromFavorites = function (uid) {
	
	// let user confirm action ...
	if (!window.confirm(visitcity.ln.favorites_confirm)) return;
	
	var tempList = [];
	var favstring = '';
	for (var i = 0; i < visitcity.favorites.length; i++) {
		if (visitcity.favorites[i].Uid != uid) {
			tempList.push(visitcity.favorites[i]);
			favstring += visitcity.favorites[i].Uid + ',';
		}
	}
	favstring = favstring.substr(0, favstring.length - 1);
	writeCookie("favoriten", favstring, 365);
	visitcity.favorites = tempList;
	visitcity.drawFavorites();
};

visitcity.loadFavorites = function () {

	var ids = readCookie("favoriten");
	if (!ids) return;
	
	// display loading text ...
	var tab_favorites = new YAHOO.util.Element('tab_favorites');
	tab_favorites.set("innerHTML", visitcity.ln.favorites_wait);
	
	var url = buildProxyUrl(visitcity.servicepath + "getSymbol/%27" + ids + "%27/");
	var callback = 
	{
		success: visitcity.loadFavoritesDone,
		timeout: 20000
	};
	YAHOO.util.Connect.asyncRequest('GET', url, callback);
};

visitcity.loadFavoritesDone = function (o) {

	// parse the result ...
	var results = null;
	try { 
	    results = YAHOO.lang.JSON.parse(o.responseText); 
	} catch (e) { 
	    alert(e);
	}
	
	for (var i = 0; i < results.length; i++) {
	
		// parse business object from results ...
		visitcity.favorites.push(new VCBusiness(results[i]));
	}
	
	visitcity.drawFavorites();
};

visitcity.drawFavorites = function () {

	//visitcity.tab_nav.getTab(3).set('label', visitcity.ln.favorites+' (' + visitcity.favorites.length + ')');
	visitcity.tab_nav.getTab(3).set('label', visitcity.ln.favorites);
	
	if (visitcity.favorites.length == 0) {
		visitcity.tab_nav.getTab(3).set('content', '<div id="tools_favorites"><a id="empty" href="javascript:visitcity.doPrint(false, true, false, true, true);">'+visitcity.ln.favorites_print+'</a></div><div id="tab_favorites">'+visitcity.ln.favorites_text+'</div>');
		return;
	}

	var favhtml = '';
	for (var i = 0; i < visitcity.favorites.length; i++) {
		favhtml +=
		"<div class='favorites' onmouseover='javascript:this.className=\"favorites_highlited\";' onmouseout='javascript:this.className=\"favorites\";' id='tab_favorites_" + visitcity.favorites[i].Uid + "'>" +
			"<table width='100%' onclick='javascript:visitcity.addFavoriteToMap(" + visitcity.favorites[i].Uid + ")'>" +
				"<tr><td width='20'><img src='" +  visitcity.iconpath + "leg_" + visitcity.favorites[i].IconId + ".gif'></img></td><td><b>" + visitcity.favorites[i].Company + "</b><br /><i>" + visitcity.favorites[i].CategoryName + "</i></td></tr>" +
				"<tr><td colspan='2'>" + visitcity.favorites[i].Zip + " " + visitcity.favorites[i].City + "</td></tr>" +
				"<tr><td colspan='2'>" + visitcity.favorites[i].Address + "</td></tr>" +
			"</table>" +
			"<div style='text-align:right;'><a href='#' onclick='javascript:visitcity.addFavoriteToMap(" + visitcity.favorites[i].Uid + ")' title='"+visitcity.ln.favorites_showmap+"'><img src='"+visitcity.app_path+"img/fav_show.png' border='0'></a>&nbsp;<a href='" + visitcity.vcardpath + visitcity.favorites[i].Uid + "' title='"+visitcity.ln.favorites_vcard+"'><img src='"+visitcity.app_path+"img/fav_vcard.png' border='0'></a>&nbsp;<a href='javascript:visitcity.removeFromFavorites(" + visitcity.favorites[i].Uid + ");' title='"+visitcity.ln.favorites_delete+"'><img src='"+visitcity.app_path+"img/fav_delete.png' border='0'></a></div>" +
		"</div>";
	}
	
	// add new elements ...
	var tab_favorites = new YAHOO.util.Element('tab_favorites');
	tab_favorites.set("innerHTML", favhtml);
};

visitcity.addFavoriteToMap = function (uid) {

	var business = null;
	for (var i = 0; i < visitcity.favorites.length; i++) {
		if (visitcity.favorites[i].Uid == uid) {
		
			// copy the object into the businesses list, so later when we remove it
			// it doesnt affect the favorites object ...
			business = visitcity.addBusinessToMap(clone(visitcity.favorites[i]));
		}
	}
	
	if (!business) return;
	visitcity.uids[business.Uid] = 1;
	
	var root = visitcity.tree_businesses.getRoot();
	var favorites_node = null;
	for (var i = 0; i < root.children.length; i++) {
		if (root.children[i].data == '<b>'+visitcity.ln.favorites+'</b>') {
			favorites_node = root.children[i];
		}
	}
	
	if (favorites_node == null) {
		favorites_node = new YAHOO.widget.TaskNode("<b>"+visitcity.ln.favorites+"</b>", root, false, false);
		visitcity.tree_businesses.count++;
	}
	
	visitcity.tab_nav.getTab(1).set('label', visitcity.ln.list+' (' + visitcity.tree_businesses.count + ')');
	visitcity.tab_nav.set('activeIndex', 1);
	
	var exists = false;
	for (var i = 0; i < favorites_node.children.length; i++) {
		if (favorites_node.children[i].data.Uid == business.Uid) {
			visitcity.map.panToAndZoom(favorites_node.children[i].data.Points[0], visitcity.maxpoizoom);
			visitcity.removeBusinessData(business);
			return;
		}
	}
	
	if (business.Address && (business.Zip || business.City)) {
		business.label = "<b>" + business.Company + "</b><br>" + business.Address + ", " + business.Zip + " " + business.City;
	} else if (business.Zip || business.City) {
		business.label = "<b>" + business.Company + "</b><br>" + business.Zip + " " + business.City;
	} else {
		business.label = "<b>" + business.Company + "</b>";
	}
	
	var tempNode = new YAHOO.widget.TaskNode(business, favorites_node, false, business.Visible, true);
	tempNode.setImage(visitcity.iconpath + 'leg_' + business.IconId + '.gif');
	tempNode.onLabelClick = visitcity.treeBusinessesClick;
	business.addNode(tempNode);
	
	if (!business.Visible) {
		business.show();
	}
	
	favorites_node.expand();
	visitcity.tree_businesses.draw();
	visitcity.map.panToAndZoom(business.Points[0], visitcity.maxpoizoom);
};

//##########################################################
// 3D GOOGLE EARTH ADDONS
//----------------------------------------------------------

visitcity.setupEarth = function (instance) {

	// take reference to the earth instance ...
	visitcity.earth = instance;
	
	google.earth.setLoadingImageUrl(visitcity.url_app+'img/earth_loading.png');
	
	visitcity.earth.getNavigationControl().setVisibility(visitcity.earth.VISIBILITY_AUTO)
	
	visitcity.earth.getLayerRoot().enableLayerById(visitcity.earth.LAYER_ROADS, true);
	visitcity.earth.getLayerRoot().enableLayerById(visitcity.earth.LAYER_BORDERS, true);
	visitcity.earth.getOptions().setAtmosphereVisibility(true);
	visitcity.earth.getOptions().setStatusBarVisibility(true);

	

	visitcity.earth.getWindow().setVisibility(true);

	// Create the loading overlay.
	var continueImage = visitcity.earth.createIcon('');
	continueImage.setHref(visitcity.url_app+'img/tip_continue.png');
	
	//alert("continue");


	var continueOverlay = visitcity.earth.createScreenOverlay('');
	continueOverlay.setIcon(continueImage);
	continueOverlay.getOverlayXY().set(0.5, visitcity.earth.UNITS_FRACTION, 0.5, visitcity.earth.UNITS_FRACTION);
	continueOverlay.getScreenXY().set(0.5, visitcity.earth.UNITS_FRACTION, 0.5, visitcity.earth.UNITS_FRACTION);
	continueOverlay.getSize().set(-1, visitcity.earth.UNITS_FRACTION, -1, visitcity.earth.UNITS_FRACTION);
	visitcity.earth.getFeatures().appendChild(continueOverlay);
	
  var continueFn;
  continueFn = function() {
    visitcity.earth.getFeatures().removeChild(continueOverlay);
    google.earth.removeEventListener(visitcity.earth.getWindow(), 'mousedown', continueFn);
  };
  
    google.earth.addEventListener(visitcity.earth.getWindow(), 'mousedown', continueFn);
	
	// create the tour by fetching it out of a KML file
	var href1 = window.location.href.substring(0, window.location.href.lastIndexOf('/')) + '/';
	href1 += 'earthtour/murrtal.kmz';
	
	google.earth.fetchKml(visitcity.earth, href1, function(kmlObject) {
	  if (!kmlObject) {
		// wrap alerts in API callbacks and event handlers
		// in a setTimeout to prevent deadlock in some browsers
		setTimeout(function() {
		  alert('fehlerhaftes oder kein KML.');
		}, 0);
		return;
	  }
	  
		// Show the entire KML file in the plugin.
	  visitcity.earth.getFeatures().appendChild(kmlObject);

	  // Walk the DOM looking for a KmlTour
	  walkKmlDom(kmlObject, function() {
		if (this.getType() == 'KmlTour') {
		  tour1 = this;
		  return false; // stop the DOM walk here.
		}
	  });
	});

	/*
	// create the tour by fetching it out of a KML file
	var href2 = window.location.href.substring(0, window.location.href.lastIndexOf('/')) + '/';
	href2 += 'earthtour/schongau.kmz';
	
	google.earth.fetchKml(visitcity.earth, href2, function(kmlObject) {
	  if (!kmlObject) {
		// wrap alerts in API callbacks and event handlers
		// in a setTimeout to prevent deadlock in some browsers
		setTimeout(function() {
		  alert('fehlerhaftes oder kein KML.');
		}, 0);
		return;
	  }
	  
		// Show the entire KML file in the plugin.
	  visitcity.earth.getFeatures().appendChild(kmlObject);

	  // Walk the DOM looking for a KmlTour
	  walkKmlDom(kmlObject, function() {
		if (this.getType() == 'KmlTour') {
		  tour2 = this;
		  return false; // stop the DOM walk here.
		}
	  });
	});
*/
};

visitcity.enterTour1 = function () {
	if (!tour1) {
		alert('Tour konnte nicht geladen werden!');
		return;
	}
  visitcity.earth.getTourPlayer().setTour(tour1);
}

/*
visitcity.enterTour2 = function () {
	if (!tour2) {
		alert('Tour konnte nicht geladen werden!');
		return;
	}
  visitcity.earth.getTourPlayer().setTour(tour2);
}
*/

visitcity.playTour = function () {
  visitcity.earth.getTourPlayer().play();
}

visitcity.pauseTour = function () {
  visitcity.earth.getTourPlayer().pause();
}

visitcity.resetTour = function () {
  visitcity.earth.getTourPlayer().reset();
}

visitcity.exitTour = function () {
  // just like setBalloon(null)
  visitcity.earth.getTourPlayer().setTour(null);
}

visitcity.updateOptions = function () {
  var options = visitcity.earth.getOptions();
  var form = document.options;
  
  options.setStatusBarVisibility(form.statusbar.checked);
  options.setAtmosphereVisibility(form.atmosphere.checked);

}

visitcity.updateSun = function () {
  var form = document.options;
  if (form.sun.checked) {
    visitcity.earth.getSun().setVisibility(true);
  } else {
    visitcity.earth.getSun().setVisibility(false);
  }
}

visitcity.updateRoads = function () {
  var form = document.options;
  if (form.roads.checked) {
    visitcity.earth.getLayerRoot().enableLayerById(visitcity.earth.LAYER_ROADS, true);
  } else {
    visitcity.earth.getLayerRoot().enableLayerById(visitcity.earth.LAYER_ROADS, false);
  }
}

visitcity.updateBorders = function () {
  var form = document.options;
  if (form.borders.checked) {
	visitcity.earth.getLayerRoot().enableLayerById(visitcity.earth.LAYER_BORDERS, true);
  } else {
	visitcity.earth.getLayerRoot().enableLayerById(visitcity.earth.LAYER_BORDERS, false);
  }
}
/*
visitcity.addEarthModel = function (src, lat, long) {
	
	// create the model geometry
	var model = visitcity.earth.createModel('');

	// set up the model's location
	var loc = visitcity.earth.createLocation('');
	loc.setLatitude(lat);
	loc.setLongitude(long);
	model.setLocation(loc);

	// set up the model's link (must be a COLLADA file).
	// this model was created in SketchUp
	var link = visitcity.earth.createLink('');
	model.setLink(link);
	link.setHref(src);

	// create the model placemark and add it to Earth
	var modelPlacemark = visitcity.earth.createPlacemark('');
	modelPlacemark.setGeometry(model);
	visitcity.earth.getFeatures().appendChild(modelPlacemark);

};
*/
//##########################################################
// GOOGLE PANORAMIO & WIKIPEDIA LAYERS
// ----------------------------------------------------------
 
var timer;
var chosen = [];

/*
 * Array of GLayers The 'name' label is not being used here
 */
var layers = [
	{ name: "Pano", obj: new GLayer("lmc:panoramio"), type: "tile"},
	{ name: "Wiki", obj: new GLayer("lmc:wikipedia_de"), type: "tile"},
	{ name: "Youtube", obj: new GLayer("com.youtube.all"), type: "tile"},
    { name: "Webcams", obj: new GLayer("com.google.webcams"), type: "tile"},	
	{ name: "weather_today", obj: "", type: "weather"},
	{ name: "weather_tomorrow", obj: "", type: "weather"}
	];
	
function hideAll() {
	var boxes = document.getElementsByName("mark");
	for(var i = 0; i < boxes.length; i++) {
		if(boxes[i].checked) {
			boxes[i].checked = false;
			switchLayer(false, layers[i].obj, layers[i].type, layers[i].name);
			chosen.push(i);
		}
	}
}

/*
 * Returns true if a checkbox is still checked otherwise false
 */
function checkChecked() {
	var boxes = document.getElementsByName("mark");
	for(var i = 0; i < boxes.length; i++) {
		if(boxes[i].checked) return true;
	}
	return false;
}

/*
 * Function was originally borrowed from Esa:
 * http://esa.ilmari.googlepages.com/dropdownmenu.htm
 */
 
function switchLayer(checked, layer, type, name) {
	var layerbox = document.getElementById("box");
	var boxlink = document.getElementById("boxlink");
	var button = document.getElementById("more_inner");
	if(checked) {
		if (type == "tile") {
			visitcity.map.addOverlay(layer);
		}
		
		if (type == "weather" && visitcity.weather_ags != '') {
		
			if (visitcity.weather_today && name == "weather_today") {
				weather_today.show();
				weather_tomorrow.hide();
				document.getElementById("wtomorrow").checked = false;
			}
		
			if (!visitcity.weather_today && name == "weather_today") {
			
				var weathericon = new GIcon();
				weathericon.iconSize = new GSize(93, 68);
				weathericon.iconAnchor = new GPoint(35, 34);
				weathericon.infoWindowAnchor = new GPoint(20, 20);
			
					var weatherurl_today = buildProxyUrl("http://www.vianovis.net/weather/weather2maps.php?ags="+visitcity.weather_ags);
					weather_today = new EGeoXml("weather_today", visitcity.map, weatherurl_today,{
						baseicon:weathericon,
						iwwidth:420,
						titlestyle:'class = "weathertitle"',
						descstyle:'class = "weatherdesc"'
						}
					);
				weather_today.parse();
				visitcity.weather_today = true;
				
				if (document.getElementById("wtomorrow").checked) {
					document.getElementById("wtomorrow").checked = false;
					weather_tomorrow.hide();
				}				
				
			}
			
			if (visitcity.weather_tomorrow && name == "weather_tomorrow") {
				weather_tomorrow.show();
				weather_today.hide();
				document.getElementById("wtoday").checked = false;				
			}			
			
			if (!visitcity.weather_tomorrow && name == "weather_tomorrow") {
			
				var weathericon = new GIcon();
				weathericon.iconSize = new GSize(93, 68);
				weathericon.iconAnchor = new GPoint(35, 34);
				weathericon.infoWindowAnchor = new GPoint(20, 20);
			
					var weatherurl_tomorrow = buildProxyUrl("http://www.vianovis.net/weather/weather2maps.php?f=1&ags="+visitcity.weather_ags);
					weather_tomorrow = new EGeoXml("weather_tomorrow", visitcity.map, weatherurl_tomorrow,{
						baseicon:weathericon,
						iwwidth:420,
						titlestyle:'class = "weathertitle"',
						descstyle:'class = "weatherdesc"'
						}
					);
				weather_tomorrow.parse();
				visitcity.weather_tomorrow = true;
				
				if (document.getElementById("wtoday").checked) {
					document.getElementById("wtoday").checked = false;
					weather_today.hide();
				}				
				
			}
			
		}
		
		// Reset chosen array
		chosen.length = 0;
		/*
		 * Highlight the link and make the button font bold.
		 */
		boxlink.className ="highlight";
		layerbox.className ="highlight";
		button.className ="highlight";
	} else {
		if (type == "tile") {
			visitcity.map.removeOverlay(layer);
		}		
		
		if (type == "weather" && visitcity.weather_ags != '') {
			if (visitcity.weather_today && name == "weather_today") {
				weather_today.hide();
			}
			if (visitcity.weather_tomorrow && name == "weather_tomorrow") {
				weather_tomorrow.hide();
			}
		}
		
		/*
		 * Reset the link and the button if all checkboxes were unchecked.
		 */
		if(!checkChecked()) {
			boxlink.blur();
			boxlink.className ="";
			layerbox.className ="";
			button.className ="";
		}
	}
}

function showLayerbox() {

	var layerbox = document.getElementById("box");
	// Left size of more control plus mapdiv.style.left
	var offsetX = 65 + 50;
	// Top size of more control plus mapdiv.style.top plus more button height
	var offsetY = 6 + 30;

	var lpos = new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(offsetX, offsetY));
	lpos.apply(layerbox);
	if(window.timer) clearTimeout(timer);
	layerbox.style.display = "block";
}


function setClose(e) {

	if(!e) e = window.event;
	var layerbox = document.getElementById("box");

	if(checkMouseLeave(layerbox, e))
		timer = setTimeout(function() {
	layerbox.style.display = "none"; }, 400);
}

/*
 * Avoid firing a mouseout event when the mouse moves over a child element.
 * Borrowed from:
 * http://www.faqts.com/knowledge_base/view.phtml/aid/1606/fid/145
 */
function checkMouseLeave(element, evt) {
	if(element.contains && evt.toElement) {
		return !element.contains(evt.toElement);
	} else if(evt.relatedTarget) {
		return !containsDOM(element, evt.relatedTarget);
	}
}


function containsDOM(container, containee) {

 var isParent = false;
 do {
  if((isParent = container == containee))
   break;
   containee = containee.parentNode;
 }
 while(containee != null);
 return isParent;
}

/*
 * Make an independent copy of chosen array since switchLayer() resets the
 * chosen array, which may not be useful here.
 */
function toggleLayers() {
	if(chosen.length > 0 ) {
		var copy = chosen.slice();
		for(var i = 0; i < copy.length; i++) {
			var index = parseInt(copy[i]);
			switchLayer(true, layers[index].obj);
			document.getElementsByName("mark")[index].checked = true;
		}
	} else {
		hideAll();
	}
}


function MoreControl(){};

MoreControl.prototype = new GControl();
MoreControl.prototype.initialize = function(map) {
	var more = document.createElement("div");
	more.style.border = "1px solid black";
	more.title = visitcity.ln.more_tipp;
	var inner = document.createElement("div");
	inner.id = "more_inner";
	inner.appendChild(document.createTextNode(visitcity.ln.more));
	more.appendChild(inner);
	more.onmouseover = showLayerbox;
	more.onmouseout = setClose;
	more.onclick = toggleLayers;
	map.getContainer().appendChild(more);
	return more;
};

MoreControl.prototype.getDefaultPosition = function() {
	return new GControlPosition(G_ANCHOR_TOP_RIGHT, new GSize(100, 7));
};

visitcity.setMap3D = function (o) {
	visitcity.map.setMapType("EARTH");
}

visitcity.unsetMap3D = function (o) {
	visitcity.map.setMapType("ROAD");
}

visitcity.changeMapStyle = function (o) {
	if (visitcity.map.getMapType() == 'EARTH') {

		var earth_options = '<div id="tools_earth"></div>'+
		'<div id="earth_options">'+
		'Optionen<br>'+	
		'<form name="options" action="javascript:updateOptions();">'+
		'<input type="checkbox" onclick="visitcity.updateBorders()" name="borders" checked/>Orte & Grenzen<br />'+
		'<input type="checkbox" onclick="visitcity.updateRoads()" name="roads" checked/>Stra&szlig;en<br />'+
		'<input type="checkbox" onclick="visitcity.updateOptions()" name="atmosphere" checked />Atmosph&auml;re<br />'+
		'<input type="checkbox" onclick="visitcity.updateSun()" name="sun"/>Sonne<br />'+
		'<input type="checkbox" onclick="visitcity.updateOptions()" name="statusbar" checked/>Statuszeile<br />'+
		'</form>'+
		'</div>'+	
		'<div id="earth_tourplayer">'+
		'Tour-Player<br>'+
		'<div id="earth_touren">'+	
		'<input type="button" onclick="visitcity.enterTour1()" value="Flug laden - Entlang dem Murrtal (2:00 min)"/>'+
		//'<input type="button" onclick="visitcity.enterTour2()" value="Flug laden - Rund um Schongau (1:35 min)"/>'+
		'</div>'+	
		/*
		'<input type="button" onclick="visitcity.playTour()" value="Rundflug abspielen"/>'+
		'<input type="button" onclick="visitcity.pauseTour()" value="Pause"/>'+
		'<input type="button" onclick="visitcity.resetTour()" value="Stop/Neustart Rundflug"/>'+
		'<input type="button" onclick="visitcity.exitTour()" value="Rundflug beenden"/>'+
		*/
		'</div></div>';

		visitcity.tab_nav.getTab(4).set('content', earth_options);
		visitcity.tab_nav.set('activeIndex', 4);
		
		visitcity.map.map.getEarthInstance(visitcity.setupEarth);
		
		
	} else {
		visitcity.tab_nav.getTab(4).set('content', visitcity.earth_html);
	}
	visitcity.updateDeeplink();	
};

visitcity.closeBubble = function (o) {
	visitcity.active_poi = null;
	visitcity.updateDeeplink();
};

visitcity.updateKMLOverlay = function () {
	if(visitcity.map.getZoom() < visitcity.maxborderzoom && !visitcity.viewborder){
		visitcity.map.addOverlay(visitcity.kml_border);
		visitcity.viewborder = true;
	} else if(visitcity.map.getZoom() >= visitcity.maxborderzoom && visitcity.viewborder) {
		visitcity.map.removeOverlay(visitcity.kml_border);
		visitcity.viewborder = false;
	}
};

visitcity.displayWeatherWindow = function (url) {
		var weather_window = new YAHOO.widget.Panel("weather", {
			width:"340px", 
			fixedcenter:false, 
			close:true, 
			draggable:true,
			zindex:1000,
			modal:false,
			visible:false,
			constraintoviewport:true
		});
	
		weather_window.setHeader("10-Tage-Vorschau (de.weather.com)");
		var iframe = "<iframe src='"+url+"' width='330' height='400' border='0' frameborder='0'></iframe>";
		weather_window.setBody(iframe);
		weather_window.render(document.body);
		weather_window.show();
		
};
