/*
 * Wildfire Spark
 * Copyright(c) 2003-2010, Wildfire Technology Limited
 * licensing@wildfire-it.com
 *
 * http://www.wildfire-it.com
 */

var HTMLDomElement = null;

if (document.all){
	HTMLDomElement = !window.XMLHttpRequest ? HTMLElement : Element;
}else
	HTMLDomElement = HTMLElement;

HTMLDomElement.prototype.getElementByClassName = function(cls, tag){
	var sel = this.getElementsByClassName(cls, tag);
	return sel.length == 0 ? null : sel[0];
};

HTMLDomElement.prototype.getElementsByClassName = function(cls, tag){
	var sel = [];

	if (!cls)
		return sel;

	var el = this;

	if (!tag)
		tag = "*";

	var els = (tag == "*" && el.all) ? el.all : el.getElementsByTagName(tag);

	cls = cls.replace(/\-/g, "\\-");

	var reg = new RegExp("(^|\\s)" + cls + "(\\s|$)");
	var ob;
	for(var i = 0; i < els.length; i++) {
		ob = els[i];
		if(reg.test(ob.className))
			sel.push(ob);
	}
	return sel;
};


HTMLFormElement.prototype.addField = function(k, cfg){

	var field = document.createElement('input');
	field.setAttribute('type', cfg.type || 'text');

	if (k)
		field.setAttribute('name', k);

	field.setAttribute('value', cfg.value || '');

	this.addElement(field, cfg);

	return field;
};

HTMLFormElement.prototype.addTextarea = function(k, cfg){

	cfg = cfg || {};

	var field = document.createElement('textarea');

	if (k)
		field.setAttribute('name', k);

	field.innerHTML = cfg.value || '';

	this.addElement(field, cfg);

	return field;
};

HTMLFormElement.prototype.addElement = function(field, cfg){
	var el;

	if (cfg.label){
		var label = document.createElement('label');

		if (!cfg.hideLabel)
			label.innerHTML = cfg.label;

		label.appendChild(field);
		el = label;
	}else
		el = field;

	this.appendChild(el);
};

String.prototype.endsWith = function(s) {
	return new RegExp(s + '$').test(this);
};

String.prototype.startsWith = function(s) {
	return new RegExp('^' + s).test(this);
};

String.prototype.contains = function(s) {
	return this.indexOf(s) > -1;
};

String.prototype.trim = function() {
	return this.replace(new RegExp('(^[\\s]+|[\\s]+$)', 'g'), '');
};

function put(s, t) {
	if (window.console){

		s = s || '';

		if (t)
			s += ' (@' + new Date().getTime() + ')';

		window.console.log(s);
	}
}

function addOnloadEvent(fn){
	if (typeof window.addEventListener != "undefined")
      window.addEventListener("load", fn, false);
   else if (typeof window.attachEvent != "undefined")
      window.attachEvent("onload", fn);
   else if (window.onload != null) {
         var oldOnload = window.onload;
         window.onload = function (e) {
			 oldOnload(e);
			 window[fn]();
		  };
   }else
      window.onload = fn;
}

/**
 * Throughout, whitespace is defined as one of the characters
 *  "\t" TAB \u0009
 *  "\n" LF  \u000A
 *  "\r" CR  \u000D
 *  " "  SPC \u0020
 *
 * This does not use Javascript's "\s" because that includes non-breaking
 * spaces (and also some other characters).
 */

/**
 * Determine whether a node's text content is entirely whitespace.
 *
 * @param nod  A node implementing the |CharacterData| interface (i.e.,
 *             a |Text|, |Comment|, or |CDATASection| node
 * @return     True if all of the text content of |nod| is whitespace,
 *             otherwise false.
 */
function isAllWS(nod) {
	// Use ECMA-262 Edition 3 String and RegExp features
	return !(/[^\t\n\r ]/.test(nod.data));
}

/**
 * Determine if a node should be ignored by the iterator functions.
 *
 * @param nod  An object implementing the DOM1 |Node| interface.
 * @return     true if the node is:
 *                1) A |Text| node that is all whitespace
 *                2) A |Comment| node
 *             and otherwise false.
 */

function isIgnorable(nod) {
	return (nod.nodeType == 8) || // A comment node
		((nod.nodeType == 3) && isAllWS(nod)); // a text node, all ws
}

/**
 * Version of |previousSibling| that skips nodes that are entirely
 * whitespace or comments.  (Normally |previousSibling| is a property
 * of all DOM nodes that gives the sibling node, the node that is
 * a child of the same parent, that occurs immediately before the
 * reference node.)
 *
 * @param sib  The reference node.
 * @return     Either:
 *               1) The closest previous sibling to |sib| that is not
 *                  ignorable according to |isIgnorable|, or
 *               2) null if no such node exists.
 */
function previousSibling(sib) {
	while ((sib = sib.previousSibling)) {
		if (!isIgnorable(sib)) return sib;
	}
	return null;
}

/**
 * Version of |nextSibling| that skips nodes that are entirely
 * whitespace or comments.
 *
 * @param sib  The reference node.
 * @return     Either:
 *               1) The closest next sibling to |sib| that is not
 *                  ignorable according to |isIgnorable|, or
 *               2) null if no such node exists.
 */
function nextSibling(sib) {
	while ((sib = sib.nextSibling)) {
		if (!isIgnorable(sib)) return sib;
	}
	return null;
}

/**
 * Version of |lastChild| that skips nodes that are entirely
 * whitespace or comments.  (Normally |lastChild| is a property
 * of all DOM nodes that gives the last of the nodes contained
 * directly in the reference node.)
 *
 * @param sib  The reference node.
 * @return     Either:
 *               1) The last child of |sib| that is not
 *                  ignorable according to |isIgnorable|, or
 *               2) null if no such node exists.
 */
function lastChild(par) {
	var res=par.lastChild;
	while (res) {
		if (!isIgnorable(res)) return res;
		res = res.previousSibling;
	}
	return null;
}

/**
 * Version of |firstChild| that skips nodes that are entirely
 * whitespace and comments.
 *
 * @param sib  The reference node.
 * @return     Either:
 *               1) The first child of |sib| that is not
 *                  ignorable according to |isIgnorable|, or
 *               2) null if no such node exists.
 */
function firstChild(par) {
	var res=par.firstChild;
	while (res) {
		if (!isIgnorable(res)) return res;
		res = res.nextSibling;
	}
	return null;
}

/**
 * Version of |data| that doesn't include whitespace at the beginning
 * and end and normalizes all whitespace to a single space.  (Normally
 * |data| is a property of text nodes that gives the text of the node.)
 *
 * @param txt  The text node whose data should be returned
 * @return     A string giving the contents of the text node with
 *             whitespace collapsed.
 */
function dataOf(txt) {
	var data = txt.data;
	// Use ECMA-262 Edition 3 String and RegExp features
	data = data.replace(/[\t\n\r ]+/g, " ");
	if (data.charAt(0) == " ")
		data = data.substring(1, data.length);
	if (data.charAt(data.length - 1) == " ")
		data = data.substring(0, data.length - 1);
	return data;
}

function microAjax(B,A){this.bindFunction=function(E,D){return function(){return E.apply(D,[D])}};this.stateChange=function(D){if(this.request.readyState==4){this.callbackFunction(this.request.responseText)}};this.getRequest=function(){if(window.ActiveXObject){return new ActiveXObject("Microsoft.XMLHTTP")}else{if(window.XMLHttpRequest){return new XMLHttpRequest()}}return false};this.postBody=(arguments[2]||"");this.callbackFunction=A;this.url=B;this.request=this.getRequest();if(this.request){var C=this.request;C.onreadystatechange=this.bindFunction(this.stateChange,this);if(this.postBody!==""){C.open("POST",B,true);C.setRequestHeader("X-Requested-With","XMLHttpRequest");C.setRequestHeader("Content-type","application/x-www-form-urlencoded");C.setRequestHeader("Connection","close")}else{C.open("GET",B,true)}C.send(this.postBody)}};

