/**
  * (c) Paul Uithol, SMARTposition
  * http://www.smartposition.nl
  * 
  * date: 26 oct 2007
  * version: 0.2
  * -----------------
  * 0.1		16-01-2007	basic (dom) functions
  * 0.2 	26-10-2007	added ajax logging using, try-catch statement and a PHP script
  *						added extra comments to the javascript
  *
  *
  * BUGS
  * -
  */
  
//overwrite the onload function
window.onload = function() {
	loadCustomSettings(); // IE7 crash BUG 20080331
	init();
}
//overwrite the onunload function
window.onunload = function() {
	GUnload();
}

/**
  * Initialize javascript, retrieve parameters, set reload timeout
  */
function init() {
	try{
		var requestParams = getRequestParams();
		logErrorWithAjax('functions.init() Client time = "' + new Date() + '", URL = "' +document.location.search + '"');
		
		//
		//get the GET parameters of the URL
		//
		if (requestParams['geodata']) {
			gpxUrl = requestParams['geodata'];
		}
		
		if (requestParams['subkey']) {
			subKey = requestParams['subkey'];
		}
		
		if (requestParams['id']) {
			focusOn = requestParams['id'];
		}
	
		if (requestParams['tl']) {
			tailLength = requestParams['tl'];
		}
		
		if (requestParams['ts']) {
			trackStart = requestParams['ts'];
		}
		
		if (requestParams['zoom']) {
			zoomLevel = requestParams['zoom'];
		}
		
		if (requestParams['lat']) {
			initialLat = requestParams['lat'];
		}
		
		if (requestParams['lng']) {
			initialLong = requestParams['lng'];
		}
		
		if (requestParams['export']) {	//get the exported KML file (base64 encoded URL)
			exportFile = requestParams['export'];
		}
		
		setTimeout("reloadPage()", reloadPageInterval);
		
		setStatus("Initializing document");
		
		loadViewMap("map");
		
		loadData();
		setStatus("Document initialized");
	}catch(err){
		logErrorWithAjax('functions.init() ' + err);
	}
}//end init function

/**
  * reloads the page with new get parameters
  *
  */
function reloadPage() {
	try{
		params = document.location.search;
	
		params = insertGetParameter(params ,"id",focusOn);
		//add GPX parameters
		params = insertGetParameter(params ,"tl",tailLength);
		params = insertGetParameter(params ,"ts",trackStart);
		params = insertGetParameter(params ,"subkey",subKey);
		
		//add map parameters
		params = insertGetParameter(params ,"zoom",zoomLevel);
		params = insertGetParameter(params ,"lng",initialLong);
		params = insertGetParameter(params ,"lat",initialLat);
		
		//add UI parameters
		params = insertGetParameter(params ,"autocenter",autoCenter);
		params = insertGetParameter(params ,"audioalarm",audioAlarm);
		
		//export file parameter (base 64 kml file URL)
		params = insertGetParameter(params ,"export",exportFile);
		
		document.location.search = params;
		//logErrorWithAjax('functions.reloadPage() URL = ' + document.location.search);
		
		//window.location.reload(true);	// reload, set the 'forceGet' parameter to true
		//document.reload(true);		// reload, set the 'forceGet' parameter to true
	}catch(err){
		logErrorWithAjax('functions.reloadPage() ' + err);
	}
}//end reload page

/**
  * function that inserts, replaces or append a GET parameter
  *
  * @param url parameters
  * @param GET parameter name
  * @param GET parameter value
  *
  * @return params (updated input)
  *
  */
function insertGetParameter(params,name,value){
	// does the URL have the GET parameter already (name variable)?
	if (params.indexOf(name+"=") > -1) {
		// otherwise, replace it with the item that currently has focus
		var param = new RegExp(name+"=[0-9a-zA-Z\.]+", "gi" );
		var newParam = name+"=" + value;
		
		params = params.replace(param, newParam);
	}else {
		// if not, add it
		if (params.length > 1) {
			params += "&"+name+"=" + value;
		}else {
			params = "?"+name+"=" + value;
		}
	}//end if-else parameter
	return params;
}//end insertGetParameter


/**
  * Function that loads the GPX data into the javascript
  *
  * Errors and exceptions are cauth and dumped to the AJAX error logger
  *
  * @return, returns true incase the data load is successfull
  *
  */
function loadData() {
	try{
		setStatus("Refressing..");
		if (gpxUrl.length > 0) {
			// Make URL unique to circumvent problems with caching
			
			// Does the URL have parameters?
			var searchStr = gpxUrl.lastIndexOf("?");
			
			// Is the URL pointing to a different directory?
			var dirSeperator = gpxUrl.lastIndexOf("/");
			
			var glue = "&";	
			if (searchStr == -1 || dirSeperator > searchStr) {
				glue = "?";
			}
			
			fetchUrl = gpxUrl + glue + "t=" + (new Date()).getTime();
			
			//add GET parameters from the javascript
			if(tailLength && (tailLength != '')) fetchUrl += "&tl="+ tailLength;
			if(trackStart && (trackStart != '')) fetchUrl += "&ts="+ trackStart;
			if(subKey && (subKey != '')) fetchUrl += "&subkey="+ subKey;
	
			try{
				GDownloadUrl(fetchUrl, function(data, responseCode){
					onGPXLoad(data, responseCode);
				});
			
			}catch(err){
				logErrorWithAjax('functions.LoadData() ' + err);
				alert("A timeout has been detected, please reload the page. Our apologies for the inconvenient.");
			}//end try-catch GDownloadUrl
		}
		setStatus("Ok " + getTime());
		return true;
	}catch(err){
		logErrorWithAjax('functions.LoadData() ' + err);
	}
	return false;
}//end function loadData()

/**
  * function prints status information to the status DIV
  *
  * @param status, message that needs to be displayed
  *
  *
  */
function setStatus(status) {
	var statusNode = document.createTextNode(status);
	setContents(document.getElementById("status"), statusNode);
}//end function setStatus

/**
  * function that sets the GPX file
  *
  * @param url
  *
  */
function setGpxFile(url) {
	var gpxNode = document.createElement("a");
	gpxNode.setAttribute("href", "url");
	gpxNode.setAttribute("target", "_blank");
	gpxNode.appendChild(document.createTextNode("gpx file"));
	
	setContents(document.getElementById("gpx_file"), gpx);
}//end function setGpxFile

/*
 * Set a node's content
 *
 * @param node
 * @param content
 *
 */
function setContents(node, content) {
		clearChildren(node);
		node.appendChild(content);
}//end function setContents

/*
 * Remove all children of a node
 *
 * @param node id
 *
 */
function clearChildren(node) {
	for (i = node.childNodes.length - 1; i >= 0; i--){
		node.removeChild(node.childNodes[i]);
	}
}//end function clearChildren

/**
  * JS implementation of the printf function
  *
  * returns the compiled string
  *
  */
function printf(args) {
	var nS = "";
	var tS = arguments[0].split("%s");
	
	var L = [];
	for (var i = 1; i < arguments.length; i++){
    	L[i-1] = arguments[i];
	}
	for (var i=0; i<tS.length; i++){
		if (tS[i].lastIndexOf('%')==tS[i].length-1) tS[i] += "s"+tS.splice(i+1,1)[0];
	}
	
	if (tS.length != L.length+1){ 
		throw("printf input error");
	}

	for(var i=0; i<L.length; i++){
		nS += tS[i] + L[i];
	}
	
	return nS + tS[tS.length-1];
}//end function printf()

/**
  * Function to get the current GET parmeters of the URI
  *
  * @return
  */
function getRequestParams() {
	var qs = location.search.substring(1);
	var nv = qs.split('&');
	var url = new Object();
	for(i = 0; i < nv.length; i++){
		eq = nv[i].indexOf('=');
		url[nv[i].substring(0,eq).toLowerCase()] = unescape(nv[i].substring(eq + 1));
	}
	return url;
}//end function getRequestParams()

/**
  * function returns a human friendly time string of the current time
  *
  * @return human readable time, format: HH:mm:ss
  *
  */
function getTime() {
	var now = new Date();
	var secs = now.getSeconds();
	secs = (secs < 10) ? "0" + secs.toString() : secs.toString();
	return now.getHours() + ":" + now.getMinutes() + ":" + secs;
}//function getTime()

/**
  * Function returns a human friendly string of the current date
  *
  * @return human readable date, format: DD-MM-YYYY
  *
  */
function getDate() {
	var now = new Date();
	return now.getDate() + "-" + (now.getMonth()+1) + "-" + takeYear(now);
}//end function getDate()

/**
  * Function returns the correct year of a date
  *
  * @param date
  *
  * @return, correct presentation of the year beloning to the input date
  */
function takeYear(date) {
	var x = date.getYear();
	var y = x % 100;
	y += (y < 38) ? 2000 : 1900;
	return y;
}//end function takeYear

/* 
 * Escape XML special markup chracters: tag delimiter < > and entity
 * reference start delimiter &. The escaped string can be used in XML
 * text portions (i.e. between tags).
 *
 * @param string
 *
 * @return string with escaped XML tags
 */
function xmlEscapeText(s) {
  return ('' + s).replace(/&/, '&amp;').replace(/</, '&lt;').replace(/>/, '&gt;');
}//end function xmlEscapeText

/* 
 * Escape XML special markup characters: tag delimiter < > entity
 * reference start delimiter & and quotes ". The escaped string can be
 * used in double quoted XML attribute value portions (i.e. in
 *  attributes within start tags).
 *
 * @param s, string value of a attribute
 *
 * @return a escaped XML string
 */
function xmlEscapeAttr(s) {
  return xmlEscapeText(s).replace(/\"/, '&quot;');
}//end function xmlEscapeAttr

/* 
 * Escape markup in XML text, but don't touch entity references. The
 *  escaped string can be used as XML text (i.e. between tags).
 *
 * @param s, string
 *
 * @return a string with escapced XML tags
 */
function xmlEscapeTags(s) {
  return s.replace(/</, '&lt;').replace(/>/, '&gt;');
}//end function xmlEscapeTags

/**
  * Check if variable is defined 
  * for IE 6 and FF
  *
  * @param variable, this variable is check against its existance
  *
  * @return true if variable exists otherwise false
  *
  */
function isDefined(variable){
	return (typeof(window[variable]) == "undefined")?  false: true;
}//end function isDefined

/**
  * Simple popup function
  *
  * @param url, the url that needs to be opend in the popup window
  *
  * @return null
  */
function popup(url) {
	window.open( url, "SMARTposition", "status = 1, height = 300, width = 700, resizable = 1" );
}//end function popup


/**
  * This code was written by Tyler Akins and has been placed in the
  * public domain.  It would be nice if you left this header intact.
  * Base64 code from Tyler Akins -- http://rumkin.com
  *
  * @param input string
  *
  * @return, a base64 encoded string
  */
function encode64(input) {
	var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
	
	var output = "";
	var chr1, chr2, chr3;
	var enc1, enc2, enc3, enc4;
	var i = 0;
	
	do {
	  chr1 = input.charCodeAt(i++);
	  chr2 = input.charCodeAt(i++);
	  chr3 = input.charCodeAt(i++);
	
	  enc1 = chr1 >> 2;
	  enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
	  enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
	  enc4 = chr3 & 63;
	
	  if (isNaN(chr2)) {
	     enc3 = enc4 = 64;
	  } else if (isNaN(chr3)) {
	     enc4 = 64;
	  }
	
	  output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) + 
	     keyStr.charAt(enc3) + keyStr.charAt(enc4);
	} while (i < input.length);
	
	return output;
}//end function encode64

/**
  * Function to detect errors in javascript for remote debugging
  *
  * @param message, text that is logged
  *
  * @throw, no errors are thown
  */
function logErrorWithAjax(message){
	/*
	var logScriptUrl = "./ajax-logger.php?message=" + encode64(message);
	
	try{
		GDownloadUrl(logScriptUrl, function(data, responseCode){
		});
	}catch(err){
	}
	*/
}//end logErrorWithAjax Function

/**
  * Function translates decimal value to a human readable cours (e.g. NW)
  *
  * @param courseDegrees, int value between [0,360]
  *
  * @return human readable value, "North", "North east",etc.
  *
  */
function degreeToDirection(courseDegrees){
	var direction = "-";
	courseDegrees = parseInt(courseDegrees);
	
	//alert(courseDegrees);
	if(courseDegrees < (45/2)){
		direction =  "north";
	}else if(courseDegrees < ((45+90)/2)){
		direction =  "northeast";
	}else if(courseDegrees < ((90+135)/2)){
		direction =  "east";
	}else if(courseDegrees < ((135+180)/2)){
		direction =  "southeast";
	}else if(courseDegrees < ((180+225)/2)){
		direction =  "south";
	}else if(courseDegrees < ((225+270)/2)){
		direction =  "southwest";
	}else if(courseDegrees < ((270+315)/2)){
		direction =  "west";
	}else if(courseDegrees < ((315+360)/2)){
		direction =  "northwest";
	}else{
		direction =  "north";
	}
	
	return direction;
}//end function degreeToDirection
