/*
 * poiClient - created: 17.06.2007 (mj)
 * © 2007 xmachina GmbH, Heidelberg.
 * All rights reserved. Alle Rechte vorbehalten.
 *
 * xmachina und das xmachina-Logo sind eingetragene
 * Warenzeichen der xmachina GmbH, Heidelberg.
 *
 * xmachina and the xmachina logo are registered
 * trademarks of xmachina GmbH, Heidelberg, Gemany.
 *
 * xmachina GmbH - Maaßstr. 24 - D-69123 Heidelberg, Germany
 * Fon: +49 (0)6221.8220.20    - Fax: +49 (0)6221.8220.40
 * E-Mail: deus@xmachina.de    - http://www.xmachina.de/
 * 
 */

function XmPoiClient(iClientID, iServiceURL) {
	// Public methods
	this.submitQuery = submitQuery;
	this.highlightAddress = highlightAddress;
	this.clearAddress = clearAddress;
	this.selectAddress = selectAddress;
	this.setDefaultCountry = setDefaultCountry;
	this.setDefaultCategory = setDefaultCategory;
	this.setCenterPoint = setCenterPoint;
	this.setDefaultZoom = setDefaultZoom;
	this.setBusyImage = setBusyImage;
	this.onGotoPoi = onGotoPoi;
	this.onSavePoi = onSavePoi;
	this.doSearch = doSearch;
	this.setKeyOfUnitedKingdom = setKeyOfUnitedKingdom;
	
	// Attributes
	var initialLoad = true;
	var lang = getLanguage();
	var map = null;
	var selectedAddress = null;
	var selectedMarker = null;
	var devMode = getDevMode();
	var defaultZoom = 4;
	var centerPoint = new GLatLng(49.395893, 8.644524);
	var serviceURL = iServiceURL;
	var defaultCountry = "Deutschland";
	var defaultCategory = "plz";
	var busyImage = "/components/poiClient/images/busy.gif";
	var keyOfUnitedKingdom = "GB";

	// Event observer
	Event.observe(window, 'load', appInit);
	Event.observe(window, 'unload', GUnload);

	function appInit() {
		// Check requirements
		if (serviceURL == null)
			alert("Please specify your service URL");
			
		loadSearchForm(defaultCountry, defaultCategory,'');
    	initMap();
	}

// Loads the search form view into div 'poiSearchForm'
function loadSearchForm(country, category, query) {
	$('poiSearchForm').innerHTML = '<p align=center><img src="' + busyImage + '"></p>';
	
	var url = serviceURL;
	var pars = 'action=getsearchform&lang=' + lang + '&country=' + country + "&category=" + category;
	
	var myAjax = new Ajax.Updater('poiSearchForm',
		url, 
		{
			method: 'post', 
			parameters: pars,
			asynchronous:false,
			encoding: 'ISO-8859-1'
		});
		myAjax.updateContent();
		
	// Perform some convenicance work
	if (query == null || query == "" && initialLoad) {
		// Load cookie
		var query = GetCookie("xmQuery");
		if (query == null || query == "" || query == "null")
			query = "";
		$('query').value = query;
		initialLoad = false;
	}
	
	if (query != null)
		$('query').value = query;
	
	$('query').focus();
	new Ajax.Autocompleter("query", "autocomplete_choices", serviceURL + "?action=suggest&country=" + escape(country) + "&category=" + category, {minChars: 2, paramName: "query", afterUpdateElement : getSelectionId});
}

function getSelectionId(text, li) {
   submitQuery($F('category'));
}

// Initializes the map
function initMap() {
	// Load Google Map
    if (!GBrowserIsCompatible()) {
    	alert('Ihr Browser unterstützt Google Maps nicht.');
    	return false;
    }
    
    // Create map
    map = new GMap2(document.getElementById("poiMap"));
    map.addControl(new GLargeMapControl());
	map.addControl(new GMapTypeControl());
    map.setCenter(centerPoint, defaultZoom);
    map.enableScrollWheelZoom();
}

// Submits the query to backend in order to receive results
function submitQuery(category) {
	var query = $F('query');
		
	// Manage country
	var country = $F('country');
	
	if (query != "")
		doSearch(country, category, query, 0);
	else
		$('poiSearchResults').innerHTML = "";
		
	loadSearchForm(country, category , query);
}

// Queries the backend using an AJAX request
function doSearch(country, category, query, index) {
	$('poiSearchResults').innerHTML = '<p align=center><img src="' + busyImage + '"></p>';
	
	var url = serviceURL;
	var pars = 'action=search&lang=' + lang + '&country=' + encodeURIComponent(country) + '&category=' + encodeURIComponent(category) + "&query=" + query + "&page=" + index; 
	
	var myAjax = new Ajax.Updater('poiSearchResults',
		url, 
		{
			method: 'post', 
			parameters: pars
		});
	
	// For future use (store info in cookie)
	document.cookie = "xmCategory=" + category;
    document.cookie = "xmQuery=" +  query;
    
    if (country != keyOfUnitedKingdom) {
    	var url = serviceURL;
		var pars = 'action=search&format=xml&country=' + escape(country) + '&category=' + category + "&query=" + escape(query) + "&page=" + index; 
		loadMarkers(url + '?' + pars);
	} else {
		map.clearOverlays();
		map.setCenter(centerPoint, 4);
	}
}

// Load XML file containing markers from backend
function loadMarkers(url) {
	map.clearOverlays();
	
	GDownloadUrl(url, function(data, responseCode) {  
		var xml = GXml.parse(data);  
		var markers = xml.documentElement.getElementsByTagName("marker"); 
		if (markers.length > 0)
			setMarkers(markers); 
		else {
			map.setCenter(centerPoint, 4);
		}
	});
}

// Places the markers on the map and moves the center
function setMarkers(markers) {
	
	var lat1 = 1000, lat2 = 0, lng1 = 1000, lng2 = 0;

	for (var i = 0; i < markers.length; i++) {  
		var lat = parseFloat(markers[i].getAttribute("lat"));
		var lng = parseFloat(markers[i].getAttribute("lng"));
		
		if (lat < lat1)	lat1 = lat;
		if (lat > lat2) lat2 = lat;
		if (lng < lng1) lng1 = lng;
		if (lng > lng2) lng2 = lng;

		var point = new GLatLng(lat, lng);    
		map.addOverlay(createMarker(point, markers[i].getAttribute("id")));
	}
	
	//alert("Pos: " + lat1 + "," + lng1 + "," + lat2 + "," + lng2);
	
	// Place Map over the area
	var bounds = new GLatLngBounds(new GLatLng(lat1, lng1), new GLatLng(lat2, lng2));
	var zoom = map.getBoundsZoomLevel(bounds);
	
	// If zoom is too big, place viewport on the first hit
	//alert(zoom);
	if (zoom > 7) {
		if (zoom > 15) zoom = 15;
		map.setCenter(bounds.getCenter(), zoom);	
	} else {
		map.setCenter(new GLatLng(parseFloat(markers[0].getAttribute("lat")),
			parseFloat(markers[0].getAttribute("lng"))), 12);
	}
}

// Creates a marker at the given point with the given number label
function createMarker(point, id) {
	if (devMode)
		var marker = new GMarker(point, {draggable: true});
	else
		var marker = new GMarker(point);
		
  	GEvent.addListener(marker, "click", function() {	
    	selectAddress(id, point.lat(), point.lng(), marker);
  	});
		
  	return marker;
}

// Returns the value of a cookie parameter
function getCookieVal (offset) {
    var endstr = document.cookie.indexOf (";", offset);
    if (endstr == -1)
        endstr = document.cookie.length;
    var ret = document.cookie.substring(offset, endstr);
    if (ret == "na") ret = "";
    return ret;
}

// Returns a cookie
function GetCookie (name) {
    var arg = name + "=";
    var alen = arg.length;
    var clen = document.cookie.length;
    var i = 0;
    while (i < clen) {
        var j = i + alen;
        if (document.cookie.substring(i, j) == arg)
        return getCookieVal (j);
        i = document.cookie.indexOf(" ", i) + 1;
        if (i == 0) break; 
    }
    return null;
}

// Mouse over highlighting of address list
function highlightAddress(addressDiv) {
	if ($(addressDiv).className != "poiAddressSelected")
		$(addressDiv).className = "poiAddressActive";
}

function clearAddress(addressDiv) {
	if ($(addressDiv).className != "poiAddressSelected")
		$(addressDiv).className = "poiAddress";
}

// Selects a specific address item in the list
function selectAddress(id, lat, lng, marker) {
	// Handle address list
	if (selectedAddress != null && $('poiAddress' + selectedAddress) != null)
		$('poiAddress' + selectedAddress).className = "poiAddress";
	$('poiAddress' + id).className = "poiAddressSelected";
	selectedAddress = id;
	
	$('poiAddress' + id).scrollIntoView();
	
	// Handle map
	map.closeInfoWindow(); 
 	if (lat != null && lat != 0 && lat != 'null' && lng != null && lng != 0 && lng != 'null') {
		// Dev mode has an extra tab
		if (devMode && marker) {
			var point = marker.getPoint();
			
			var devTabContent = "ID:" + id + "<br>lat:" + lat + ", Lng:" + lng +
				"<hr><div id=\"poiDevSection\">" + 
				"lat <input type=\"text\" id=\"poiDevLat\" value=\"" + point.lat() + "\"><br>" +
				"lng <input type=\"text\" id=\"poiDevLng\" value=\"" + point.lng() + "\"><br>" +
				"Pass <input type=\"password\" id=\"poiDevPwd\"><br>" +
				"<input type=\"hidden\" id=\"poiDevId\" value=\"" + id + "\"><br>" +
				"<input type=\"button\" id=\"poiDevSave\" name=\"poiDevSave\" value=\"Speichern\" onClick=\"poiClient.onSavePoi();\"><br>" +
				"</div><hr>" + 
				"Gehe zu: <input type=\"text\" id=\"poiGoto\">" +
				"<input type=\"button\" id=\"poiGotoSubmit\" name=\"poiGotoSubmit\" value=\"Go\" onClick=\"poiClient.onGotoPoi();\"><br>";
			
			var infoTabs = [  
				new GInfoWindowTab("View", $('poiAddress' + id).innerHTML),  
				new GInfoWindowTab("Editor", devTabContent),
			];
			map.panTo(point);
			map.openInfoWindowTabs(point, infoTabs);
			selectedMarker = marker;
			
		} else {
			map.panTo(new GLatLng(lat, lng));
			map.openInfoWindow(new GLatLng(lat, lng),                   
				$('poiAddress' + id).innerHTML);
		}
	}	
}

// Returns the current language
function getLanguage() {
	// Default language
	var langTmp = "ger";

	// Try to extract from URI
	if (document.location.href.indexOf("/en/") > -1) {
		langTmp = "eng";
	}

	// Try to extract from search string
	var liste = new Werteliste(document.location.search);
	if (liste['lang'] != null) {
		langTmp = liste['lang'];
	}
		
	return langTmp;
}

function getDevMode() {
	var liste = new Werteliste(document.location.search);
	
	if (liste['dev'] != null) {
		return true;
	}
		
	return false;
}

// Returns property value pairs for the request parameters
function Werteliste(querystring) {
    if(querystring == '') 
        return;
    
    var wertestring = decodeURI(querystring);
    wertestring = wertestring.slice(1);
    var paare = wertestring.split("&");
    for (var i=0; i < paare.length; i++) {
        var name = paare[i].substring(0, paare[i].indexOf("="));
        var wert = paare[i].substring(paare[i].indexOf("=")+1, paare[i].length);
        this[name] = wert;
    }
}

// Saves modified position of a POI
function onSavePoi() {
	var lat = $F('poiDevLat');
	var lng = $F('poiDevLng');
	var id = $F('poiDevId');
	var pass = $F('poiDevPwd');
	
	var pars = "action=savepoi&id=" + id + "&lat=" + lat + "&lng=" + lng + "&pwd=" + pass;

	var url = serviceURL;
		
	var myAjax = new Ajax.Updater('poiDevSection',
		url, 
		{
			method: 'post', 
			parameters: pars
		});
}

function onGotoPoi() {
	var address = $F('poiGoto');
	
	// Retrive geo location
	var geocoder = new GClientGeocoder();
	geocoder.getLatLng(    
		address,    
		function(point) {      
			if (!point) {        
				alert(address + " ist nicht bekannt.");      
			} else {        
				map.setCenter(point, 13);        
				selectedMarker.setPoint(point);
				//marker.openInfoWindowHtml(address);     
				/*$('poiDevLat').value = point.lat();
				$('poiDevLng').value = point.lng();*/
			}    
		}  
	);
}

function setDefaultCountry(val) {
	defaultCountry = val;
}

function setDefaultCategory(val) {
	defaultCategory = val;
}

function setCenterPoint(lat, lng) {
	centerPoint = new GLatLng(lat,lng);
}

function setDefaultZoom(val) {
	defaultZoom = val;
}

function setBusyImage(val) {
	busyImage = val;
}

function setKeyOfUnitedKingdom(val) {
	keyOfUnitedKingdom = val;
}

} // of class

