var isIE6 =  /MSIE (5\.5|6\.)/.test(navigator.userAgent);
var isIE7 = (document.all && window.XMLHttpRequest) ? true : false;
var eshow = Element.show;
var evis = Element.visible;
var eacn = Element.addClassName;
var ercn = Element.removeClassName;
var ehcn = Element.hasClassName;
var eobs = Event.observe;
var esobs = Event.stopObserving;

function ehide(name)
{
	var v = $(name);
	if (!v) return;
//	v.blur();
	Element.hide(v);
}

function getWindowHeight() {
	var wh = 0;
	if (typeof(window.innerHeight) == 'number')
	{
		wh = window.innerHeight;
	}
	else if (document.documentElement && document.documentElement.clientHeight)
	{
		wh = document.documentElement.clientHeight;
	}
	else if (document.body && document.body.clientHeight)
	{
		wh = document.body.clientHeight;
	}
	return wh;
}

function convertToHTMLSafe(str, isMultiLine)
{
	if (!str) return "";
	var h = str.split("&").join("&amp;");
	h = h.split("<").join("&lt;");
	h = h.split(">").join("&gt;");
	h = h.split("\"").join("&quot;");
	if (!isMultiLine) return h;

	var lines = h.split("\n");
	h = new StringBuilder();
	for (var i = 0; i < lines.length; i++)
	{
		if (i > 0) h.a("<br/>");
		var line = lines[i];
		if (line.indexOf("\t") != -1)
			line = line.split("\t").join("&nbsp;&nbsp;");
		
		var words = line.split(" ");
		var prevSpace = false;
		for (var j = 0; j < words.length; j++)
		{
			var word = words[j];
			if (word == "")
			{
				h.a("&nbsp;");
				prevSpace = true;
			}
			else
			{
				if (j > 0) h.a(prevSpace ? "&nbsp;" : " ");
				prevSpace = false;
				h.a(word);
			}
		}
	}
	return h.toString();
}

function convertToHTTPOK(str)
{
	var sb = '';
	str = str.toLowerCase();
	for (var i = 0; i < str.length; i++)
	{
		var c = str.charAt(i);
		if ((c >= 'a' && c <= 'z') || (c >= '0' && c <= '9')) sb = concat(sb, c);
		else if (c == ' ') sb = concat(sb, '_');
	}
	return sb;
}

function genStaticJobURL(p)
{
  if (p.CID == 0) return '';
	return genStaticJobURLFromRoot(p, top.getConnFrame().staticJobRootDir);
}

function genStaticJobURLFromRoot(p, rootDir)
{
	var cl = p.WIAS.WIA[0];
	var l = "unknown";
	if (cl && cl.CIDESC)
	{
		l = cl.CIDESC.toLowerCase();
		var idx = l.indexOf(",");
		if (idx >= 0) l = l.substring(0, idx);
	}
	return concat(rootDir, "/", convertToHTTPOK(l), "/", convertToHTTPOK(p.CN), "/", p.POS.PID, ".html");
}

// Takes an input object and sorts based on the attribute/value pairs.  Returns back an array of attribute names
// in the sorted order.  Options include sortByValue, sortByKey, sortByKeyNumeric, sortDescending, forceToTop, and forceToBottom.
function sortList(keyValueObject, opts) {
	var o = new Array();
	if (keyValueObject.push)
		o = keyValueObject;
	else
		for (var index in keyValueObject)
		{
			var obj = new Object();
			obj.key = index;
			obj.value = keyValueObject[index];
			o.push(obj);
		}

	var sd = opts.sortDescending;
	if (opts.sortByValue)
	{
		if (sd)
			o.sort(function(a, b) { return a.value < b.value ? 1 : (a.value == b.value ? 0 : -1); } );
		else
			o.sort(function(a, b) { return a.value < b.value ? -1 : (a.value == b.value ? 0 : 1); } );
	}
	else if (opts.sortByValueInsensitive)
	{
		if (sd)
			o.sort(function(a, b) { return a.value.toLowerCase() < b.value.toLowerCase() ? 1 : (a.value.toLowerCase() == b.value.toLowerCase() ? 0 : -1); } );
		else
			o.sort(function(a, b) { return a.value.toLowerCase() < b.value.toLowerCase() ? -1 : (a.value.toLowerCase() == b.value.toLowerCase() ? 0 : 1); } );
	}
	else if (opts.sortByPName)
	{
		if (sd)
			o.sort(sortByPName);
		else
			o.sort(sortByPNameDesc);
	}
	else if (opts.sortByKey)
	{
		if (sd)
			o.sort(function(a, b) { return a.key < b.key ? 1 : (a.key == b.key ? 0 : -1); } );
		else
			o.sort(function(a, b) { return a.key < b.key ? -1 : (a.key == b.key ? 0 : 1); } );
	}
	else if (opts.sortByKeyNumeric)
	{
		if (sd)
			o.sort(function(a, b) { var ai = parseInt(a.key); var bi = parseInt(b.key); return ai < bi ? 1 : (ai == bi ? 0 : -1); } );
		else
			o.sort(function(a, b) { var ai = parseInt(a.key); var bi = parseInt(b.key); return ai < bi ? -1 : (ai == bi ? 0 : 1); } );
	}

	// Do any forced reordering now.
	if (opts.forceToTop)
	{
		for (var i = 0; i < opts.forceToTop.length; i++)
		{
			var key = opts.forceToTop[i];
			for (var j = i; j < o.length; j++)
			{
				var opt = o[j];
				if (opt.key == key)
				{
					o.splice(j, 1);
					o.splice(i, 0, opt);
					break;
				}
			}
		}
	}
	if (opts.forceToBottom)
	{
		for (var i = 0; i < opts.forceToBottom.length; i++)
		{
			var key = opts.forceToBottom[i];
			for (var j = 0; j < o.length - i; j++)
			{
				var opt = o[j];
				if (opt.key == key)
				{
					o.splice(j, 1);
					o.push(opt);
					break;
				}
			}
		}
	}
	var retval = new Array();
	for (var i = 0; i < o.length; i++) retval.push(o[i].key);
	return retval;
}

function sortByPName(a, b)
{
	var av = a.value.toLowerCase();
	var bv = b.value.toLowerCase();
	if (av.substring(0, 1) < 'a') av = concat("zzzzzzzzzzzzzz", av);
	if (bv.substring(0, 1) < 'a') bv = concat("zzzzzzzzzzzzzz", bv);
	return av < bv ? 1 : (av == bv ? 0 : -1);
}

function sortByPNameDesc(a, b)
{
	return sortByPName(a, b) * -1;
}


// STANDARD KEYSTROKE FILTERING FUNCTIONS AND VALIDATION METHODS

var standardErrMsg = "Please examine the fields highlighted in red. The data entered does not match the expected format and cannot be saved.<br/><br/>Hover your mouse over each field to view a tooltip with more details.";

var alphaOnlyKey = /[A-Za-z ',.-]/;
var alphaOnlyStr = /[^A-Za-z ',.-]/;
var numberOnlyKey = /[0-9-]/;
var numberOnlyStr = /[^0-9-]/;
var alphaNumOnlyKey = /[A-Za-z0-9-]/;
var alphaNumOnlyStr = /[^A-Za-z0-9-]/;
var noSpacesKey = /[^ ]/;  // allow no spaces
var noSpacesStr = /[ ]/;  // allow no spaces
var passwordCharKey = /[&<> ]/;   // characters not allowed in passwords
var passwordCharStr = /[&<> ]/;   // characters not allowed in passwords
var noSpecialCharKey = /[*?=%\"<>\[\]/^${}\\|]/;
var noSpecialCharStr = /[*?=%\"<>\[\]/^${}\\|]/;
var urlCharKey = /[\"<>\[\] `^{}\\]/;
var urlCharStr = /[\"<>\[\] `^{}\\]/;
var verifyEmail = /^[A-Za-z0-9]+([_\.-][A-Za-z0-9]+)*@[A-Za-z0-9]+([_\.-][A-Za-z0-9]+)*\.([A-Za-z]){2,4}$/i;

function testForTab(e)
{
	if (window.event) e = window.event;
	else if (e.length) e = e[0];
	else return false;
	var code = (e.keyCode) ? e.keyCode : e.which;
	if (code == 9) return true;
	return false;
}

function testForCharacters(str, regex, invert)
{
	var isGood = regex.test(str);
	return invert ? !isGood : isGood;
}

function testForKeystrokeEvent(e, regex, invert)
{
	if (window.event)
		e = window.event;
	var code = (e.keyCode) ? e.keyCode : e.which;
	if (code == 8)
		return true;
	else if (!(isIE6 || isIE7) && code == 9)
		return true;
	else
		return testForCharacters(String.fromCharCode(code), regex, invert);
}

function allowAlphaNumericOnly(e)
{
	return testForKeystrokeEvent(e, alphaNumOnlyKey, false);
}

function allowAlphaOnly(e)
{
	return testForKeystrokeEvent(e, alphaOnlyKey, false);
}

function allowNumbersOnly(e)
{
	return testForKeystrokeEvent(e, numberOnlyKey, false);
}

function allowNoSpecialChar(e)
{
	return testForKeystrokeEvent(e, noSpecialCharKey, true);
}

function allowURLCharOnly(e)
{
	return testForKeystrokeEvent(e, urlCharKey, true);
}

function allowPasswordChar(e)
{
	return testForKeystrokeEvent(e, passwordCharKey, true);
}

function allowNoSpaces(e)
{
	if (window.event) e = window.event;
	var code = (e.keyCode) ? e.keyCode : e.which;
	
	if (String.fromCharCode(code) == ' ')
		return false;
	else
    return true;
}

// StringBuilder needs to go into a common file - also in dal.js
function StringBuilder() { this.buffer = []; }
StringBuilder.prototype = {
	append: function () { for (var i = 0; i < arguments.length; i++) this.buffer.push(arguments[i]); return this; }, 
	a: function () { for (var i = 0; i < arguments.length; i++) this.buffer.push(arguments[i]); return this; }, 
	toString: function () {	return this.buffer.join(""); },
	clear: function () { this.buffer.length = 0; },
	xmlTag: function(name, value)
	{
		this.append("<", name, ">");
		for (var i = 1; i < arguments.length; i++)
			this.buffer.push(arguments[i]);
		this.append("</", name, ">");
		return this;
	}
};

function concat(args) {
	var s = new StringBuilder();
	for (var i = 0; i < arguments.length; i++)
		s.a(arguments[i]); 
	return s.toString();
}

// DJL - don't use prototype for this.
function setInnerHTML(dname, html)
{
	var d = document.getElementById(dname);
	d.innerHTML = html;
}

// function reorders a date for sorting and comparison
function setSortDate(dateObj)
{
  // split off time if included
  var token = dateObj.split(' ');
  
  // reorder date
  var ord = token[0].split('/');
  if (ord[0].length == 1) ord[0] = concat('0', ord[0]);
  if (ord[1].length == 1) ord[1] = concat('0', ord[1]);
  var newDate = concat(ord[2], ord[0], ord[1]);
  
  return newDate;
}

// function to limit names to sizes. Will convert to HTML safe at the end.
function getLimitString(str, maxLength)
{
	if (str.length <= maxLength) return str;

	// Split the string on spaces.
	maxLength -= 3;
	str = str.substring(0, maxLength);
	var spaceidx = -1;
	for (var i = maxLength - 1; i >= 0; i--)
	{
		var c = str.charAt(i);
		if (c == ' ' || c == '/' || c == '-' || c == '_')
		{
			spaceidx = i;
			break;
		}
	}
	if (spaceidx >= maxLength/2)
		str = str.substring(0, spaceidx);
	return concat(str, '...');
}

// function searches for single words over a certain limit and trims if found. Will convert to HTML safe.
function wordLengthScan(str, maxLength)
{
  if (str.length < maxLength) 
    return convertToHTMLSafe(str);
  var tot = '';
  var found = false;
  var tmp = str.split(' ');
  for (var i=0; i < tmp.length; i++)
  {
    if (tmp[i].length > maxLength)
    {
      str = concat(tot, tmp[i].substring(0, maxLength), "...");
      break;
    }
    tot = concat(tot, tmp[i], ' ');
  }
  return convertToHTMLSafe(str);
}

// Effects used for results page.
if (String.prototype.parseColor)
{
	Effect.SlideRightIntoView = function(element)
	{
		var e = $(element);
		e.style.width = '0px';
		e.style.overflow = 'hidden';
		e.firstChild.style.position = 'relative';
		eshow(e);
		var opts = { scaleContent: false, scaleY: false, scaleMode: 'contents', scaleFrom: 0 };
		Object.extend(opts, arguments[1] || {});
		new Effect.Scale(e, 100,opts);
	}

	Effect.SlideRightOutOfView = function(element)
	{
		var e = $(element);
		e.style.overflow = 'hidden';
		e.firstChild.style.position = 'relative';
		eshow(e);
		var opts = { scaleContent: false, scaleY: false, afterFinishInternal: function(effect) { ehide(effect.element); }};
		Object.extend(opts, arguments[1] || {});
		new Effect.Scale(e, 0, opts);
	}
}
