function trim(str, chars) {
	return ltrim(rtrim(str, chars), chars);
}

function ltrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("^[" + chars + "]+", "g"), "");
}

function rtrim(str, chars) {
	chars = chars || "\\s";
	return str.replace(new RegExp("[" + chars + "]+$", "g"), "");
}

function getElementById(id)
{
	return document.getElementById(id);
}

function clearElementText(node)
{
 if (typeof node.innerText != "undefined") {
   node.innerText = '';
 } else {
   while (node.firstChild) {
     node.removeChild(node.firstChild);
   }
 }
}

function setElementText(node, text) {
 if (typeof node.innerText != "undefined") {
   node.innerText = text;
 } else {
   while (node.firstChild) {
     node.removeChild(node.firstChild);
   }
   node.appendChild(document.createTextNode(text));
 }
}

function getElementText(node)
{
 if (typeof node.innerText != "undefined") {
   return node.innerText;
 } else {
	 return node.textContent;
 }
}

function hide(id)
{
	getElementById(id).style.display = 'none';
}

function show(id)
{
	getElementById(id).style.display = '';
}

function select_all()
{
        var elements = document.forms[0].elements;
        var eleCount = elements.length;
        var check = document.forms[0].elements[0].checked;

        for(var i=0; i < eleCount ; i++)
        {
                elements[i].checked=check;
                //alert(document.forms[0].elements[0].value);
        }
}

/**
 * when adding new items we need to refresh the left frame that contains the
 * list of current users. Otherwise some administrators get confused. 
 */
function refresh_left()
{
    window.top.frames['left'].location.reload();
}

/* Client-side access to querystring name=value pairs
	Version 1.3
	28 May 2008

	License (Simplified BSD):
	http://adamv.com/dev/javascript/qslicense.txt
*/
function Querystring(qs) { // optionally pass a querystring to parse
	this.qs = qs;
	this.params = {};

	if (qs == null) qs = location.search.substring(1, location.search.length);
	if (qs.length == 0) return;

// Turn <plus> back to <space>
// See: http://www.w3.org/TR/REC-html40/interact/forms.html#h-17.13.4.1
	qs = qs.replace(/\+/g, ' ');
	var args = qs.split('&'); // parse out name/value pairs separated via &

// split out each name=value pair
	for (var i = 0; i < args.length; i++) {
		var pair = args[i].split('=');
		var name = decodeURIComponent(pair[0]);

		var value = (pair.length==2)
			? decodeURIComponent(pair[1])
			: name;

		this.params[name] = value;
	}
}

Querystring.prototype.get = function(key, default_) {
	var value = this.params[key];
	return (value != null) ? value : default_;
}

Querystring.prototype.contains = function(key) {
	var value = this.params[key];
	return (value != null);
}

var Url = {

    // public method for url encoding
    encode : function (string) {
        return escape(this._utf8_encode(string));
    },

    // public method for url decoding
    decode : function (string) {
        return this._utf8_decode(unescape(string));
    },

    // private method for UTF-8 encoding
    _utf8_encode : function (string) {
		if(!isNaN(string))
			string = string.toString();

        string = string.replace(/\r\n/g,"\n");
        var utftext = "";

        for (var n = 0; n < string.length; n++) {

            var c = string.charCodeAt(n);

            if (c < 128) {
                utftext += String.fromCharCode(c);
            }
            else if((c > 127) && (c < 2048)) {
                utftext += String.fromCharCode((c >> 6) | 192);
                utftext += String.fromCharCode((c & 63) | 128);
            }
            else {
                utftext += String.fromCharCode((c >> 12) | 224);
                utftext += String.fromCharCode(((c >> 6) & 63) | 128);
                utftext += String.fromCharCode((c & 63) | 128);
            }

        }

        return utftext;
    },

    // private method for UTF-8 decoding
    _utf8_decode : function (utftext) {
        var string = "";
        var i = 0;
        var c = c1 = c2 = 0;

        while ( i < utftext.length ) {

            c = utftext.charCodeAt(i);

            if (c < 128) {
                string += String.fromCharCode(c);
                i++;
            }
            else if((c > 191) && (c < 224)) {
                c2 = utftext.charCodeAt(i+1);
                string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
                i += 2;
            }
            else {
                c2 = utftext.charCodeAt(i+1);
                c3 = utftext.charCodeAt(i+2);
                string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
                i += 3;
            }

        }

        return string;
    }
}

function addUrlArg(url, name, value)
{
	var origUrl= url;
	try
	{
		url = url.replace(/#\w*/,'');
		var re = new RegExp(name+'='+'[^&]*');
		if(value == '')
		{
			url = url.replace(re, '');
			if(url.charAt(url.length-1) == '?' || url.charAt(url.length-1) == '&')
				url = url.substr(0,url.length-1);
			url = url.replace(/\?&/,'?');
			url = url.replace(/&&/,'&');
			return url;
		}
		else
			url = url.replace(re, name+'='+value)
		if(url.indexOf(name+'=') != -1) return url;

		if(url.indexOf('?') == -1)
			url += '?';
		else
			url += '&';

		url += name+'='+Url.encode(value);
	}
	catch(e)
	{
		alert(e);
		return origUrl;
	}
	return url;
}

function scrollToAnchor(anchor)
{
	if(document.body.innerHTML == undefined)
	{
		var url = location_href;
		url = url.replace(/#.*/,'');
		location.href = url + '#'+anchor;
	}
	else
		location.hash = '#'+anchor;
}

function selectAll(formId, check)
{
	var form = document.getElementById(formId);

	for(var i = 0; i < form.elements.length; i++)
	{
		if(form.elements[i].type=='checkbox')
			form.elements[i].checked = check;
	}
}

function onSelectAll(formId)
{
	var cb = document.getElementById('cbSelectAll');
	selectAll(formId, cb.checked);
}

var qs = new Querystring();

function SimpleTab(argsObj)
{
	this.div = null;
	this.classMain = "selection-control";
	this.classNavActive = "current";
	this.REclassMain = new RegExp('\\b' + this.classMain + '\\b', 'gi');
	this.activeIndex = -1;

	for (arg in argsObj) { this[arg] = argsObj[arg]; }
	this.tabs = new Array();
  /* If the main tabber div was specified, call init() now */
	if (this.div)
	{
		this.init(this.div);
		/* We don't need the main div anymore, and to prevent a memory leak
		   in IE, we must remove the circular reference between the div
		   and the tabber object. */
		this.div = null;
	}
}

SimpleTab.prototype.init = function(e)
{
  /* Set up the tabber interface.

     e = element (the main containing div)

     Example:
     init(document.getElementById('mytabberdiv'))
   */

  var
  childNodes, /* child nodes of the tabber div */
  i, i2, /* loop indices */
  t, /* object to store info about a single tab */
  defaultTab=0, /* which tab to select by default */
  DOM_ul, /* tabbernav list */
  DOM_li, /* tabbernav list item */
  DOM_a, /* tabbernav link */
  aId, /* A unique id for DOM_a */
  headingElement; /* searching for text to use in the tab */

  /* Verify that the browser supports DOM scripting */
  if (!document.getElementsByTagName) { return false; }

  /* If the main DIV has an ID then save it. */
  if (e.id) {
    this.id = e.id;
  }

  /* Clear the tabs array (but it should normally be empty) */
  this.tabs.length = 0;

  /* Loop through an array of all the child nodes within our tabber element. */
  e = e.getElementsByTagName('ul');
  e = e[0];
  childNodes = e.getElementsByTagName('li');

  for(i=0; i < childNodes.length; i++)
  {
	  /* Find the nodes where class="" */
	  var li = childNodes[i];
	  var className=li.className;
	  if(className == 'current')
		this.activeIndex = i;

      /* Create a new object to save info about this tab */
      t = new Object();

      /* Save a pointer to the div for this tab */
      t.li = li;

      /* Add the new object to the array of tabs */
      this.tabs[this.tabs.length] = t;

	  // get A tag from li
	  var nodes = li.getElementsByTagName('a');
	  nodes[0].userOnClick = nodes[0].onclick;
	  nodes[0].onclick = this.navClick;
	  nodes[0].tabber = this;
	  nodes[0].tabberIndex = i;

  }

  /* If the user specified an onLoad function, call it now. */
  if (typeof this.onLoad == 'function') {
    this.onLoad({tabber:this});
  }

  return this;
};

var onClickArgs = null;
SimpleTab.prototype.navClick = function(event)
{
  /* This method should only be called by the onClick event of an <A>
     element, in which case we will determine which tab was clicked by
     examining a property that we previously attached to the <A>
     element.

     Since this was triggered from an onClick event, the variable
     "this" refers to the <A> element that triggered the onClick
     event (and not to the tabberObj).

     When tabberObj was initialized, we added some extra properties
     to the <A> element, for the purpose of retrieving them now. Get
     the tabberObj object, plus the tab number that was clicked.
  */

  var
  rVal, /* Return value from the user onclick function */
  a, /* element that triggered the onclick event */
  self, /* the tabber object */
  tabberIndex; /* index of the tab that triggered the event */
//  onClickArgs; /* args to send the onclick function */

  a = this;
  if (!a.tabber) { return false; }

  self = a.tabber;
  tabberIndex = a.tabberIndex;

  /* Remove focus from the link because it looks ugly.
     I don't know if this is a good idea...
  */
  a.blur();

  /* If the user specified an onClick function, call it now.
     If the function returns false then do not continue.
  */
  if (typeof a.userOnClick == 'function') {

    onClickArgs = {'tabber':self, 'index':tabberIndex, 'event':event};

    /* IE uses a different way to access the event object */
    if (!event) { onClickArgs.event = window.event; }

    rVal = a.userOnClick(onClickArgs);
    if (rVal === false) { return false; }
  }

  self.navClearActive(self.activeIndex);
  self.navSetActive(tabberIndex);
  self.activeIndex = tabberIndex;

  return false;
};

SimpleTab.prototype.navSetActive = function(tabberIndex)
{
  /* Note: this method does *not* enforce the rule
     that only one nav item can be active at a time.
  */

  /* Set classNavActive for the navigation list item */
  this.tabs[tabberIndex].li.className = this.classNavActive;

  return this;
};


SimpleTab.prototype.navClearActive = function(tabberIndex)
{
  /* Note: this method does *not* enforce the rule
     that one nav should always be active.
  */

  if(tabberIndex == -1) return this;
  /* Remove classNavActive from the navigation list item */
  this.tabs[tabberIndex].li.className = '';

  return this;
};

simpleTabbers = new Array();

function simpleTabberAutomatic(tabberArgs)
{
  /* This function finds all DIV elements in the document where
     class=tabber.classMain, then converts them to use the tabber
     interface.

     tabberArgs = an object to send to "new tabber()"
  */
  var
    tempObj, /* Temporary tabber object */
    divs, /* Array of all divs on the page */
    i; /* Loop index */

  if (!tabberArgs) { tabberArgs = {}; }

  /* Create a tabber object so we can get the value of classMain */
  tempObj = new SimpleTab(tabberArgs);

  /* Find all DIV elements in the document that have class=tabber */

  /* First get an array of all DIV elements and loop through them */
  divs = document.getElementsByTagName("div");
  for (i=0; i < divs.length; i++) {

    /* Is this DIV the correct class? */
    if (divs[i].className &&
	divs[i].className.match(tempObj.REclassMain)) {

      /* Now tabify the DIV */
      tabberArgs.div = divs[i];
      divs[i].tabber = new SimpleTab(tabberArgs);
	  simpleTabbers[divs[i].id] = divs[i].tabber;	  
    }
  }

  return this;
}


/*==================================================*/


function simpleTabberAutomaticOnLoad(tabberArgs)
{
  /* This function adds tabberAutomatic to the window.onload event,
     so it will run after the document has finished loading.
  */
  var oldOnLoad;

  if (!tabberArgs) { tabberArgs = {}; }

  /* Taken from: http://simon.incutio.com/archive/2004/05/26/addLoadEvent */

  oldOnLoad = window.onload;
  if (typeof window.onload != 'function') {
    window.onload = function() {
      simpleTabberAutomatic(tabberArgs);
    };
  } else {
    window.onload = function() {
      oldOnLoad();
      simpleTabberAutomatic(tabberArgs);
    };
  }
}

function setCookie (name, value, expires, path, domain, secure)
{
	if (!expires)
	{
		expires = new Date();
	}

      document.cookie = name + "=" + escape(value) +
        ((expires) ? "; expires=" + expires.toGMTString() : "") +
        ((path) ? "; path=" + path : "") +
        ((domain) ? "; domain=" + domain : "") +
        ((secure) ? "; secure" : "");
}

function isNumeric(sText)
{
   var ValidChars = "0123456789";
   var IsNumber=true;
   var Char;

   for (i = 0; i < sText.length && IsNumber == true; i++)
      {
      Char = sText.charAt(i);
      if (ValidChars.indexOf(Char) == -1)
         {
         IsNumber = false;
         }
      }
   return IsNumber;

}

function getDateRangeIndex(val)
{
	switch(val) {
		case 'today':
			return 0;
		case 'week':
			return 1;
		case 'month':
			return 2;
		case 'year':
			return 3;
		case 'last week':
			return 4;
		case 'last month':
			return 5;
		case 'last 30 days':
			return 6;
		case 'custom':
			return 7;
	}
	return 0;
}

function getDateRangeFromIndex(index)
{
	var res = '';
	switch(index) {
		case 0:
			res = 'today';
			break;
		case 1:
			res = 'week';
			break;
		case 2:
			res = 'month';
			break;
		case 3:
			res = 'year';
			break;
		case 4:
			res = 'last week';
			break;
		case 5:
			res = 'last month';
			break;
		case 6:
			res = 'last 30 days';
			break;
		case 7:
			res = 'custom';
			break;
	}
	return res;
}

var browserName = null;
function detectClient() {
	if(browserName == null) {
		if((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i)))
			browserName = 'iPhone';
		else if(navigator.userAgent.match(/Android/i))
			browserName = 'Android';
		else
			browserName = '';
	}
	return browserName;
}

