﻿
var map;
var geocoder;
var positioner;

var merchantMarkers;

function loadGoogleMaps() {
  if (GBrowserIsCompatible()) {

    // draw the map and center to flims
    map = new GMap2(document.getElementById("map"), {mapTypes:[G_NORMAL_MAP, G_SATELLITE_MAP, G_HYBRID_MAP]});
    map.setCenter(new GLatLng(47.369024, 8.538033), 15);
    map.enableScrollWheelZoom();
    // we also need geocoder
    geocoder = new GClientGeocoder();
 
    // map types:
    // G_SATELLITE_MAP
    // G_NORMAL_MAP
    // G_HYBRID_MAP

    // map.addControl(new GSmallMapControl());
    map.addControl(new GLargeMapControl())
    map.addControl(new GMapTypeControl());
    
    // map.setMapType(G_HYBRID_MAP);

  }
}

function findCoordinates(addr) {

    geocoder.getLatLng(
        addr,
        function(point) {
            if(!point) {
                alert(addr + " not found");
            }
            else {
                // setLatLng(point.lat(), point.lng());
                map.clearOverlays()
                map.setCenter(point, 14);
                var marker = new GMarker(point, {draggable: false});  
                map.addOverlay(marker);
            }
        });
}

function findMerchants() {

	var city = $("inputCity").value;
	
	var cantonSelectField = document.getElementById('selectState');
	var cantonId = cantonSelectField.selectedIndex >= 0 ? cantonSelectField.options[cantonSelectField.selectedIndex].value : 0;
	
	var mList = $("merchantList");

	if(city.length == 0 && cantonId > 0) {
		// search by canton
		mList.innerHTML = 'Liste wird geladen..';

		new Ajax.Request(
			"templates/ajax/merchantsByState.cfm?state="+cantonId,
			{
				method: "get",
				onSuccess: merchantsResult
			}
		);
		
		map.clearOverlays()
	}
	else if(city.length) {
		// get the coordinates
		var addr = $("inputStreet").value + " " + $("inputCity").value;
		
		var radField = $("selectRadius");
		var radius = radField.options[radField.selectedIndex].value;
		
		geocoder.getLatLng(
			addr,
			function(point) {
				if(!point) {
					// alert("leider wurde die Adresse '" + addr + "' nicht gefunden");
					mList.innerHTML = txt_addrnotfound;
				}
				else {
					// set on map
					map.clearOverlays();
					map.setCenter(point, 14);
					var marker = new GMarker(point, {draggable: false});  
					map.addOverlay(marker);

					// request merchant list
					mList.innerHTML = 'Liste wird geladen..';
					
					new Ajax.Request(
						"templates/ajax/merchantsByRadius.cfm?radius="+radius+"&lat="+point.lat()+"&long="+point.lng(),
						{
							method: "get",
							onSuccess: merchantsResult
						}
					);
				}
			});
	}
	else {
		// cannot search whole switzerland atm
	}
}

function merchantsResult(result) {
	
	merchantMarkers = new Array();

	// display the results
	var mList = $("merchantList");
	var mListHtml = '';

	var merchants = result.responseXML.documentElement.getElementsByTagName("merchant");

	if(merchants.length) {
		var bounds = new GLatLngBounds;
	
		mListHtml += '<table cellpadding="0" cellspacing="0" border="0">';

		for(var i = 0; i < merchants.length; i++) {
			var m = XmlNodeToHashtable(merchants[i]);
			if(m.address && m.name) {
				mListHtml += ["<tr>",'<td class="merchantTitle" width="320"><a href="javascript:merchantShow(', merchantMarkers.length, ')" class="merchangTitle">',m.name,'</a></td><td class="merchantDistance" align="right">'].join("");
				
				if(parseInt(m.distance) >= 0) mListHtml += m.distance + " km";
				
				mListHtml += ["</td>","</tr>","<tr>",'<td class="merchantAddress" colspan="2">',m.address.replace(/\n/,"<br />")].join("");
				if(m.website && m.website.length > 0) {
					mListHtml += ["<br />", '<a href="http://', m.website, '" target="_blank">', m.website, '</a>'].join("");
				}
				mListHtml += ["</td>",'</tr><tr><td colspan="2">&nbsp;</td></tr>'].join("");

				var mmarker = createTinyMarker(m.latitude, m.longitude, ["<strong>", m.name, "</strong><br />", m.address.replace(/\n/,"<br />"), "<br /><br />", m.tel].join(""));
				merchantMarkers.push(mmarker);

				map.addOverlay(mmarker);
				
				bounds.extend(new GLatLng(m.latitude, m.longitude));
			}
		}

		mListHtml += "</table>";

		// set map center
		map.setCenter(bounds.getCenter(), map.getBoundsZoomLevel(bounds));

	}
	else {
		mListHtml += txt_noresults;
	}

	mList.innerHTML = mListHtml;
}

function merchantShow(n) {
	merchantMarkers[n].openInfoWindowHtml(merchantMarkers[n].ffsstxt);
}

function createTinyMarker(lat, long, txt) {
	// create a marker on the map
	var icon = new GIcon();

	icon.image = document.all ? "images/tinymarker.gif" : "images/tinymarker.png";
	icon.shadow = document.all ? "images/spacer.gif" : "images/shadow-tinymarker.png";

	icon.shadowSize = new GSize(19.0, 17.0);
	icon.iconSize = new GSize(10.0, 17.0);
	icon.iconAnchor = new GPoint(5.0, 8.0);
	icon.infoWindowAnchor = new GPoint(5.0, 8.0);

	var marker = new GMarker(new GLatLng(lat, long), {draggable: false, icon: icon});

	marker.ffsstxt = '<div style="color:black">' + txt + '</div>';
	GEvent.addListener(marker, "click", function() {
		marker.openInfoWindowHtml(marker.ffsstxt);
	});
	
	return marker;
}

function XmlNodeToHashtable(xmlNode) {
	var result = {};
	var cs = xmlNode.childNodes;
	for(var i = 0; i < cs.length; i++) {
		var c = cs[i];
		if(c.nodeType == 1 && c.nodeName && c.nodeName.length > 0) {
			result[c.nodeName] = c.textContent ? c.textContent : c.text;
		}
	}
	
	return result;
}

/*
function XmlParse(xmlText) {
	// parse data
	var doc;
	if (window.ActiveXObject) {
		doc = new ActiveXObject("Microsoft.XMLDOM");
		doc.async = "false";
		doc.loadXML(xmlText);
	}
	// code for Mozilla, Firefox, Opera, etc.
	else {
		var parser = new DOMParser();
		doc = parser.parseFromString(xmlText, "text/xml");
	}
	
	return doc;
}
*/

/*** fs autocompleter ***/
var autocompleterInterval = {};
var autocompleterLastWasBackspace = {};
var autocompleterMaxItems = 8;

function initAutocompleter(fieldName, listElementName) {
	// get the form element
	var autocompleteElement = $(listElementName);
	var fieldElement = $(fieldName);
	autocompleteElement.style.position = 'absolute';
	autocompleteElement.selectedIndex = -1;

	fieldElement.onkeydown = function(event) {
		keyPress(event, fieldElement, autocompleteElement);
	}

	var delayedHideFunction = function() {
		hideAutocompleter(fieldElement, autocompleteElement);
	}
	
	if(document.all) Event.observe(document.body, 'click', delayedHideFunction);
	else Event.observe(fieldElement, 'blur', delayedHideFunction);

	// make invisible
	hideAutocompleter(fieldElement, autocompleteElement);
}

function keyPress(event, fieldElement, autocompleteElement) {
	if(event == undefined) event = window.event;
	if(autocomplete != null) clearTimeout(autocompleterInterval[fieldElement.id]);
	autocompleterLastWasBackspace[fieldElement.id] = false;
	// codes: 8 = backspace, 13 = enter, 188 = , 38 = up, 40 = down, 27 = esc, 9 = tab
	if(event.keyCode == 13) {
		// enter pressed
		insertResult(fieldElement, autocompleteElement, null, false);
		hideAutocompleter(fieldElement, autocompleteElement);
		return false;
	}
	else if(event.keyCode == 9) {
		// tab pressed
		insertResult(fieldElement, autocompleteElement, null, true);	// prevent focus return
		hideAutocompleter(fieldElement, autocompleteElement);
		return true;
	}
	else if(event.keyCode == 27) {
		// esc or tab
		hideAutocompleter(fieldElement, autocompleteElement);
	}
	else if(event.keyCode == 38 && !event.shiftKey) {
		selectResult(fieldElement, autocompleteElement, autocompleteElement.selectedIndex-1);
		return autocompleteElement.childNodes.length == 0;	// make key usable if no result
	}
	else if(event.keyCode == 40 && !event.shiftKey) {
		selectResult(fieldElement, autocompleteElement, autocompleteElement.selectedIndex+1);
		return autocompleteElement.childNodes.length == 0;	// make key usable if no result
	}
	else if(event.keyCode == 8) {
		// backspace
		autocompleterLastWasBackspace[fieldElement.id] = true;
		autocompleterInterval[fieldElement.id] = setTimeout(function() {
			autocomplete(fieldElement, autocompleteElement, -1);
		}, 100);
	}
	else if(event.keyCode != 91 && (event.keyCode < 16 || event.keyCode > 18) && event.keyCode != 37 && event.keyCode != 39) { // no shift, ctrl, alt, left, right
		// start an autocompleter in 100 ms
		autocompleterInterval[fieldElement.id] = setTimeout(function() {
			autocomplete(fieldElement, autocompleteElement);
		}, 100);
	}
	return true;
}

function showAutocompleter(fieldElement, autocompleteElement) {
	// position
	var dimensions = fieldElement.getDimensions();
	var position = getPositionedOffset(fieldElement);

	var firstElement = $(autocompleteElement.childNodes[0]);

	if(firstElement != null) {
		var elemDim = firstElement.getDimensions();
		var elemHeight = elemDim.height + parseInt(autocompleteElement.getStyle('paddingBottom')) + parseInt(autocompleteElement.getStyle('paddingTop'));
		// adjust height
		if(autocompleteElement.childNodes.length > autocompleterMaxItems) {
			autocompleteElement.style.height = (autocompleterMaxItems*elemHeight) + 'px';
		}
		else {
			autocompleteElement.style.height = 'auto';
		}
	}
	else {
		autocompleteElement.style.height = 'auto';
	}

	var paddingTotal = parseInt(autocompleteElement.getStyle('paddingLeft')) + parseInt(autocompleteElement.getStyle('paddingRight'));
	
	var acTop = (dimensions.height + position[1]);
	var acLeft = position[0];
	
	if(document.all) {
		acTop += 14;
		acLeft += 10;
	}
	
	var borderTotal = parseInt(autocompleteElement.getStyle('borderLeftWidth')) + parseInt(autocompleteElement.getStyle('borderRightWidth'));
	autocompleteElement.style.width = (dimensions.width - paddingTotal - borderTotal) + 'px';
	autocompleteElement.style.top = acTop + 'px';
	autocompleteElement.style.left = acLeft + 'px';
	autocompleteElement.style.visibility = 'visible';

	if(document.all) {
		document.getElementById("selectRadius").style.visibility = 'hidden';
	}
	
}

function hideAutocompleter(fieldElement, autocompleteElement) {
	autocompleteElement.style.visibility = 'hidden';
	autocompleteElement.selectedIndex = -1;

	if(document.all) {
		document.getElementById("selectRadius").style.visibility = 'visible';
	}
}

function hideAutocompleterDelayed(fieldElement, autocompleteElement) {
	setTimeout(function() {
		hideAutocompleter(fieldElement, autocompleteElement);
	}, 200);	
}



function insertResult(fieldElement, autocompleteElement, i, keepCaretPos, caretPosFix) {
	if(i == null) i = autocompleteElement.selectedIndex;
	if(i >= autocompleteElement.childNodes.length || i < 0) return;

	
	if(caretPosFix == null) caretPosFix = 0;
	var currentCaretPos = getCaretPosition(fieldElement) + caretPosFix;

	var selectedValue = autocompleteElement.childNodes[i].value;
	fieldElement.value = selectedValue;
	
	if(keepCaretPos) {
		// set position again
		setCaretPosition(fieldElement, currentCaretPos, selectedValue.length - currentCaretPos);
	}
	
}

function selectResult(fieldElement, autocompleteElement, i) {
	if(i >= autocompleteElement.childNodes.length || i < 0) {
		return;
	}
	
	// de-highlight last selection
	if(autocompleteElement.selectedIndex >= 0 && autocompleteElement.selectedIndex < autocompleteElement.childNodes.length) {
		autocompleteElement.childNodes[autocompleteElement.selectedIndex].className = 'fsAutocompleterOption';
	}
	
	// highlight new
	autocompleteElement.childNodes[i].className = 'fsAutocompleterOptionSelected';
	
	// store selection
	autocompleteElement.selectedIndex = i;
	
	// make sure it is visible
	if(autocompleteElement.childNodes.length > autocompleterMaxItems) {
		// objDiv.scrollTop = objDiv.scrollHeight;
		var firstElement = autocompleteElement.childNodes[0];
		var elemDim = firstElement.getDimensions();
		var elemHeight = elemDim.height + parseInt(autocompleteElement.getStyle('paddingBottom')) + parseInt(autocompleteElement.getStyle('paddingTop'));
		var minScrollTop = (i-autocompleterMaxItems+1) * elemHeight;
		var maxScrollTop = i * elemHeight;

		if(autocompleteElement.scrollTop < minScrollTop) autocompleteElement.scrollTop = minScrollTop;
		else if(autocompleteElement.scrollTop > maxScrollTop) autocompleteElement.scrollTop = maxScrollTop;

	}
}

function autocomplete(fieldElement, autocompleteElement, caretPosFix) {
	// get the current val
	var txt = fieldElement.value;

	if(caretPosFix == null) caretPosFix = 0;

	if(caretPosFix < 0 && txt.length > (-caretPosFix)) {
		txt = txt.substring(0, txt.length + caretPosFix);
	}

	if(txt.length == 0) {
		hideAutocompleter(fieldElement, autocompleteElement);
		return;
	}

	var stateField = document.getElementById('selectState');
	var stateQ = '';
	if(stateField && stateField.selectedIndex > 0) {
		stateQ = '&state=' + stateField.options[stateField.selectedIndex].value;
	}

	// get the elements (ajax call)
	new Ajax.Request(
		'templates/ajax/citiesByFirstPart.cfm?q='+escape(txt)+stateQ, {
			method: 'get',
			onSuccess: function(result) {
				var rx = result.responseXML;
				var cn = rx.documentElement.childNodes;

				var rs = new Array();
				for(var i = 0; i < cn.length; i++) {
					var n = cn[i];
					var vn = n.getAttribute("n");
					if(vn) {
						rs.push({value: vn, text: vn});
					}
				}
				autocompleterPopulate(fieldElement, autocompleteElement, rs, caretPosFix);
			}
		});
}

function autocompleterPopulate(fieldElement, autocompleteElement, resultSet, caretPosFix) {
	// populate the autocompleteElement
	removeChildNodes(autocompleteElement);
	autocompleteElement.selectedIndex = -1;

	if(resultSet.length == 0) {
		hideAutocompleter(fieldElement, autocompleteElement);
		return;
	}

	for(var i = 0; i < resultSet.length; i++) {
		var r = resultSet[i];
		var optionElement = document.createElement("div");
		optionElement.className = 'fsAutocompleterOption';
		optionElement.innerHTML = r.text;
		optionElement.value = r.value;
		optionElement.index = i;
		
		autocompleteElement.appendChild(optionElement);
		
		// attach the click event
		optionElement.onmousedown = function(e) {
			insertResult(fieldElement, autocompleteElement, this.index, false);
		}
	}

	// show
	showAutocompleter(fieldElement, autocompleteElement);
	
	// if only one, select
	if(resultSet.length == 1 && autocompleterLastWasBackspace[fieldElement.id] != true) {
		selectResult(fieldElement, autocompleteElement, 0);
		insertResult(fieldElement, autocompleteElement, 0, true, caretPosFix);
	}
}

function removeChildNodes(p) {
	while(p.childNodes[0]) {
		p.removeChild(p.childNodes[0]);
	}
}

function getCaretPosition(input) {
	if(input.selectionStart) {
		return input.selectionStart;
	}
	else if(document.selection) {
		// ie
		
		var range = document.selection.createRange();
		var bookmark = range.getBookmark();
		var caret_pos = bookmark.charCodeAt(2) - 2;
		
		return caret_pos;
		
		/*
		var range = document.selection.createRange(); // We'll use this as a 'dummy'
		var stored_range = range.duplicate(); // Select all text
		stored_range.moveToElementText(input); // Now move 'dummy' end point to end point of original
		stored_range.setEndPoint('EndToEnd', range); // Now we can calculate start and end points
		return stored_range.text.length - range.text.length;
		// element.selectionEnd = element.selectionStart + range.text.length;
		*/
	}
	return -1;
}
function setCaretPosition(node, pos, len) { 
	var selStart = pos;
	var selEnd = pos + len;
	if(node.setSelectionRange) { 
		node.focus(); 
		node.setSelectionRange(selStart, selEnd); 
	}
	else if(node.createTextRange) { 
		var range = node.createTextRange(); 
		range.collapse(true); 
		range.moveEnd('character', selEnd); 
		range.moveStart('character', selStart); 
		range.select(); 
	} 
}

function getPositionedOffset(element) {
	var valueT = 0, valueL = 0;
	do {
		valueT += element.offsetTop  || 0;
		valueL += element.offsetLeft || 0;
		element = element.offsetParent;
		if(element) {
			if(element.tagName == 'BODY') break;
			var p = element.style.position;
			if(p == 'relative' || p == 'absolute') break;
		}
	} while (element);
	return [valueL, valueT];
}