/*
	A collection of useful javascript functions
	(c) Daniel Winterstein
*/

//IE does not provide an array.indexOf function, so add one
if (!Array.prototype.indexOf) {
  Array.prototype.indexOf = function(elt) {
    var len = this.length;
    for (var i=0; i<len; i++) {
    	// uses strict equality (no type conversion) for compatibility with Mozilla
    	if (this[i] === elt) return i;
    }
    return -1;
  };
}

var URL_REGEX = /([hf]tt?ps?:\/\/[a-zA-Z0-9_%\-\.,\?&\/=\+'~#!\*:]+[a-zA-Z0-9_%\-&\/=\+])/g;

//Add a GET url argument, triggering a reload
// TODO a remove-arg to strip page=2 when altering a filter 
function addArg(name, value) {
	var url = ""+window.location;
	url = addArg2(url, name, value, [name]);
	window.location = url;
}
function addRemoveArg(name, value, removeNames) {
	var url = ""+window.location;
	removeNames.push(name);
	url = addArg2(url, name, value, removeNames);
	window.location = url;
}

//Add a set of GET url arguments, triggering a reload
function addArgs(args) {
	var url = ""+window.location;
	for(var name in args) {
		url = addArg2(url, name, args[name], [name]);
	}
	window.location = url;
}

/**
 * @param url
 * @param name
 * @param value
 * @param removeNames
 * @returns url with name=value (escaped), and with any of removeNames gone
 */
function addArg2(url, name, value, removeNames) {		
	// There must be a better way!
	var eName = escape(name);
	// remove old
	if ( ! removeNames) removeNames = [name];	
	for(var ri=0; ri<removeNames.length; ri++) {		
		url = removeArg(url, removeNames[ri]);
	}
	if ( ! value) {
		return url;
	}
	// prep for adding
	var lc = url.charAt(url.length-1);
	if (url.indexOf("?") == -1) url += "?";
	else {		
		if (lc != "&" && lc != "?") url += "&";
	}
	// add new
	url += eName+"="+escape(value);
	return url;
}
/**
 * @returns url without name=?
 */
function removeArg(url, name) {
	var reName = escape(name);	
	url = url.replace("?"+reName, "?&"+reName);	
	var oldValRE = new RegExp("&"+reName+"=[^&]*");
	url = url.replace(oldValRE,"");
	// clean up trailing ?&
	while(true) {
		var lc = url.charAt(url.length-1);
		if (lc=="?" || lc=="&") url = url.substring(0,url.length-1);
		else break;
	}
	url = url.replace("?&", "?");
	return url;
}

// Write an email mailto link into a document. Hopefully spam-bot proof.
function email(name, domain) {
	document.write("<a href='mailto:"+name+"@"+domain+"'>");
	document.write(name+"@"+domain);
	document.write("</a>");
}

/** Shorthand for document.getElementById() */
function get(id) {
	return document.getElementById(id);
}
/** 
  name - name of the desired cookie
  Return a string containing the value of specified cookie, or null if cookie does not exist
*/
function getCookie(name) {
  var dc = document.cookie;
  var prefix = name + "=";
  var begin = dc.indexOf("; " + prefix);
  if (begin == -1) {
    begin = dc.indexOf(prefix);
    if (begin != 0) return null;
  } else begin += 2;
  var end = document.cookie.indexOf(";", begin);
  if (end == -1) end = dc.length;
  return unescape(dc.substring(begin + prefix.length, end));
}

// Convert a cookie into a number (otherwise it will be a string)
function getIntCookie(name) {
   return parseInt( getCookie(name) );
}

/** Create a cookie
   name - name of the cookie
   value - value of the cookie
These cookies will ask to stay alive for a year.
*/
function setCookie(name, value) {
   var largeExpDate = new Date ();
   largeExpDate.setTime(largeExpDate.getTime() + (365 * 24 * 3600 * 1000)); // Last for a year - note that the browser may not respect this.
   // Create the cookie string
   var curCookie = name + "=" + escape(value) + "; expires="+largeExpDate.toGMTString()+";";
   // Add it to the document
   document.cookie = curCookie; // Note that this *doesn't* re-assign document.cookie (which would delete all existing cookies).
   // It magically appends the new cookie to the list.
}

//This function takes an array as input, and returns a randomly chosen element.
function pickRandom(myarray) {
 x=Math.floor( Math.random() * myarray.length);
 return myarray[x];
}

// IE and Mozilla
function setOpacity(elem, opacity) {
	var opie = Math.floor(100*opacity);
	elem.filter= "alpha(opacity="+opie+")";
	elem.style.filter="alpha(opacity="+opie+")";
	elem.style.opacity = opacity;
}

function setVisible(element, bool) {
	if (bool) element.style.display = 'block';
	else element.style.display = 'none';
}

// Toggle the element between visible and hidden.
// return: true if it is now visible, false if it is now hidden
function toggle(element) {
	if (element.style.display == 'none') {
		element.style.display = 'block';
		return true;
	}
	element.style.display = 'none';
	return false;
}

function getWidth(elem) {	
	return elem.offsetWidth;
}

function getHeight(elem) {	
	return elem.offsetHeight;
}
// Set width and height in pixels
function setSize(elem, width, height) {
	if (width) elem.style.width = width+"px";
	if (height) elem.style.height = height+"px";
}

//Find x and y positions
//Public domain, by Peter-Paul Koch & Alex Tingle
// Returns: [x,y]
function getPosition(obj) {
	var curleft = 0;
	var curtop = 0;
	if(obj.offsetParent) {
	   while(true) {
	     curleft += obj.offsetLeft;
	     curtop += obj.offsetTop;
	     if(!obj.offsetParent) break;
	     obj = obj.offsetParent;
	   }
	} else if(obj.x) {
	   curleft += obj.x;
	   curtop += obj.y;
	}
	return [curleft,curtop];
}

// Set position in pixels
// Also stores the x,y coordinates in element.myx, element.myy
function setPosition(element, x, y) {
	element.myx = x;
	element.myy = y;
	element.style.top = y+'px';
	element.style.left = x+'px';
}

// A nice readable date
function getDateString() {
    now = new Date();
    bits = now.toString().split(" ");
    // Arrays, which we use to convert numbers from the date object into strings
    days = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"];
    months = ["January","February","March","April","May","June","July","August","September","October","November","December"];
    mystring = days[now.getDay()-1] + ", " + now.getDate() + " " + months[now.getMonth()];
    return mystring;
}

/** Parse url arguments 
 * @returns a map */
function getUrlVars() {
	var url = ""+window.location;
	var s = url.indexOf("?");
	if (s==-1 || s==url.length-1) return {};
	var varstr = url.substring(s+1);
	var kvs = varstr.split("&");
	var urlVars = {};
	for(i=0; i<kvs.length; i++) {
		var kv = kvs[i];
		var e = kv.indexOf("=");
		if (e!=-1 && e!=kv.length-1) {
			k = kv.substring(0,e);
			k = unescape(k);
			v = kv.substring(e+1);
			v = unescape(v);
			urlVars[k] = v;
		}
	}	
	return urlVars;
}

/**
 * Set in body using <body onKeyPress="return handleKeyPress(event);">
 */
function handleKeyPress(e) {
	var key = handleKeyPress2(e);
	var handler = keyPressHandlers[key];
	if (handler) {
		return handler(key);
	}
	return true;		
}
var keyPressHandlers = {};
function handleKeyPress2(e) {
	var keynum, keychar;
	if(window.event) // IE
	{
		keynum = e.keyCode;
	} else if (e.which) // Netscape/Firefox/Opera
	{
		keynum = e.which;
	} else return false;
	// Special keys
	if (keynum==8) return "DEL";
	keychar = String.fromCharCode(keynum);
	keychar = keychar.toUpperCase();
	// Combo?
	if (e.ctrlKey) {
		keychar = "CTRL+"+keychar;
	}
	return keychar;
}

function showInfoPop(parentElement, text) {
	var xy = getPosition(parentElement);
	var newDiv = document.createElement("div");
	newDiv.innerHTML = text;
	newDiv.style.position="absolute";
	setPosition(newDiv, xy[0], xy[1]);	  
	document.body.insertAfter(parentElement, newDiv);
}

/**
 * Works with handleKeyPress() (which must be setup)
 * fn: takes in the keypress string (eg "X" or "CTRL+S"). 
 * Returns true/false, with false indicating that the browser should NOT handle the keypress.
 */
function setKeyPressHandler(key, fn) {
	keyPressHandlers[key] = fn;
}



