/* 
 * Cross-browser event handling, by Scott Andrew
 */
function addEvent(element, eventType, lamdaFunction, useCapture) {
    if (element.addEventListener) {
        element.addEventListener(eventType, lamdaFunction, useCapture);
        return true;
    } else if (element.attachEvent) {
        var r = element.attachEvent('on' + eventType, lamdaFunction);
        return r;
    } else {
        return false;
    }
}

/* 
 * Kills an event's propagation and default action
 */
function knackerEvent(eventObject) {
    if (eventObject && eventObject.stopPropagation) {
        eventObject.stopPropagation();
    }
    if (window.event && window.event.cancelBubble ) {
        window.event.cancelBubble = true;
    }
    
    if (eventObject && eventObject.preventDefault) {
        eventObject.preventDefault();
    }
    if (window.event) {
        window.event.returnValue = false;
    }
}

/* 
 * Safari doesn't support canceling events in the standard way, so we must
 * hard-code a return of false for it to work.
 */
function cancelEventSafari() {
    return false;        
}

/* 
 * Cross-browser style extraction, from the JavaScript & DHTML Cookbook
 * <http://www.oreillynet.com/pub/a/javascript/excerpt/JSDHTMLCkbk_chap5/index5.html>
 */
function getElementStyle(elementID, CssStyleProperty) {
    var element = document.getElementById(elementID);
    if (element.currentStyle) {
        return element.currentStyle[toCamelCase(CssStyleProperty)];
    } else if (window.getComputedStyle) {
        var compStyle = window.getComputedStyle(element, '');
        return compStyle.getPropertyValue(CssStyleProperty);
    } else {
        return '';
    }
}

/* 
 * CamelCases CSS property names. Useful in conjunction with 'getElementStyle()'
 * From <http://dhtmlkitchen.com/learn/js/setstyle/index4.jsp>
 */
function toCamelCase(CssProperty) {
    var stringArray = CssProperty.toLowerCase().split('-');
    if (stringArray.length == 1) {
        return stringArray[0];
    }
    var ret = (CssProperty.indexOf("-") == 0)
              ? stringArray[0].charAt(0).toUpperCase() + stringArray[0].substring(1)
              : stringArray[0];
    for (var i = 1; i < stringArray.length; i++) {
        var s = stringArray[i];
        ret += s.charAt(0).toUpperCase() + s.substring(1);
    }
    return ret;
}

/*
 * Disables all 'test' links, that point to the href '#', by Ross Shannon
 */
function disableTestLinks() {
  var pageLinks = document.getElementsByTagName('a');
  for (var i=0; i<pageLinks.length; i++) {
    if (pageLinks[i].href.match(/[^#]#$/)) {
      addEvent(pageLinks[i], 'click', knackerEvent, false);
    }
  }
}

/* 
 * Cookie functions
 */
/**
 * Creates a cookie with the given name, value and expiry period.
 * 
 * @param name the cookie name
 * @param value the value of the cookie
 * @param days the expiry period in days
 */
function createCookie(name, value, days) {
    var expires = '';
    if (days) {
        var date = new Date();
        date.setTime(date.getTime() + (days*24*60*60*1000));
        var expires = '; expires=' + date.toGMTString();
    }
    document.cookie = name + '=' + value + expires + '; path=/';
}

/**
 * Reads a cookie by name.
 *  
 * @param name the cookie name
 * @returns the cookie.
 */
function readCookie(name) {
    var cookieCrumbs = document.cookie.split(';');
    var nameToFind = name + '=';
    for (var i = 0; i < cookieCrumbs.length; i++) {
        var crumb = cookieCrumbs[i];
        while (crumb.charAt(0) == ' ') {
            crumb = crumb.substring(1, crumb.length); /* delete spaces */
        }
        if (crumb.indexOf(nameToFind) == 0) {
            return crumb.substring(nameToFind.length, crumb.length);
        }
    }
    return null;
}

/**
 * Remove a cookie.
 * 
 * @param name the cookie name
 */
function eraseCookie(name) {
    createCookie(name, '', -1);
}

/**
 * Extract the parameters from the URL string.
 * 
 * @returns A hash, the keys are the parameter names, the values their values.
 */
function parseUrlParameters() {
	var parameters = {};
    var results,
        plusToSpace = /\+/g,  // Regex for replacing addition symbol with a space
        rexExp = /([^&=]+)=?([^&]*)/g,
        decode = function (string) { return decodeURIComponent(string.replace(plusToSpace, " ")); },
        queryString = window.location.search.substring(1);
	
    while (results = rexExp.exec(queryString)) {
    	parameters[decode(results[1])] = decode(results[2]);
    }
    
    return parameters;
};

/**
 * Amazingly, IE7 does not support the String.trim() function, add it.
 */
function ensureStringTrimDefined() {
	if (typeof String.prototype.trim !== 'function') {
		String.prototype.trim = function() {
			return this.replace(/^\s+|\s+$/g, ''); 
		};
	}
};

/**
 * Normally, 'console' is a global variable defined to log to the developer tools console in browsers. Some older 
 * browsers don't have this by default, in which case logging isn't possible, but to ensure it does not cause a problem,
 * we define it here (but does nothing). 
 */
function ensureConsoleDefined() {
	if (typeof(window.console) == 'undefined' || typeof(window.console.log) == 'undefined' || typeof(window.console.dir) == 'undefined') {
		// If the log function *is* defined, then it's just the extended functions that are missing					
		if (typeof(window.console) != 'undefined') {
			if (typeof(window.console.log) != 'undefined') {
				window.console = { dir: function() {}, error: function() {}, warn: function() {} };
			} 
		}
		else {
			window.console = { log: function() {}, dir: function() {}, error: function() {}, warn: function() {} };
		}
	}
};

/**
 * Trying to fix a bug in jQuery with IE - http://forum.jquery.com/topic/internet-explorer-9-jquery-and-divx
 */
function fixBugInJQueryAppend() {
    jQuery.fn.append = function() {
        return this.domManip(arguments, true, function(elem) {
            if (this.nodeType === 1) {
                var ob = this;
                if (jQuery.nodeName(this, "body")) ob = $(this).find(">div").get(0);
                ob.appendChild(elem);
            }
        });
    }
};

/**
 * Common javascript to be run on page load, always.
 */
function commonOnLoad() {
	ensureStringTrimDefined();
	ensureConsoleDefined();
	
	fixBugInJQueryAppend();
};

