
var applianceJSVersion = "3.0";

/////////////////////////////////////////////////////

function getRef(divID)
{
	try
	{
    	return document.getElementById(divID);
    }
    catch (e)
    {
    	return null;
    }
}

function showHide(section,gif)
{
    if (getRef(section).style.display == "")
    {
        getRef(section).style.display = "none";
        getRef(gif).src = "/PMM/Images/Tree/plus.gif";
    }
    else
    {
        getRef(section).style.display = "";
        getRef(gif).src = "/PMM/Images/Tree/minus.gif";
    }
}
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////

function hideItem(item) {
	getRef(item).style.display="none";
}
function showItem(item) {
	getRef(item).style.display="";
}
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
//	Methods used to show and hide the various types
//	of panels.
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////

function showHidePanel(panel)
{
    if (getRef(panel).style.display == "")
    {
        getRef(panel).style.display = "none";
        png_Change(getRef(panel + "Button"), "/PMM/Images/collapse-down.png");
        getRef(panel + "State").value = "collapsed";
    }
    else
    {
        getRef(panel).style.display = "";
        png_Change(getRef(panel + "Button"), "/PMM/Images/collapse-up.png");
        getRef(panel + "State").value = "expanded";
    }
}

/////////////////////////////////////////////////////

function navigateLink(page)
{
	var nav = page + ".aspx";
	parent.frames.main.location.href=nav;
	
	try
	{
		if (selected != null)
			selected.className = "menuLoLight";
		
		selected = getRef(page);
	
		selected.className = "menuSelected";
	}
	catch (e)
	{
	}
}

function navigateUrl(page)
{
	location.href = page;
}

function confirmBeforeNavigateUrl(page, msg)
{
	if (confirm(msg))
		navigateUrl(page);
}

/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
//	Key handlers for testing event object
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////

function isCtrlKeyPressed(e)	{ try{return e.ctrlKey;}catch (e) {return false;}}
function isAltKeyPressed(e)		{ return e.altKey; }
function isShiftKeyPressed(e)	{ return e.shiftKey; }

/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
//	List handling
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
//
//	Methods to support the single selection list control

function listSelection(controlID)
{
	var selection = getRef(controlID + 'Selection');
	if (selection == null)
		alert("Missing <input id=" + controlID + "Selection>");
		
	return selection;
}

function listSelectItem(controlID, item)
{
	var table = getRef(controlID);
	var selected = listSelection(controlID);

	if (selected.value != "")
		getRef(selected.value).childNodes[0].className = 'listUnselected';

	selected.value = item;
	
	getRef(selected.value).childNodes[0].className = 'listSelected';
	
	try
	{
		var validate = getRef(controlID+"SelectionChanged").value;
		eval(validate);
	}
	catch(Exception)
	{
	}
}

function listMouseOver(controlID, item)
{
	getRef(item).childNodes[0].className = 'listHover';
}

function listMouseOut(controlID, item)
{
	var selected = listSelection(controlID);
	
	getRef(item).childNodes[0].className = (selected.value == item ? "listSelected" : "listUnselected");
}

/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
//	PNG handling for Internet Explorer
//
//	For this to correctly work each page is requried
//	to set the ie55up flag to indicate Explorer 5.5
//	or later.
//
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////

function png_Fix(myImage)
{
	if (window.ie55up)
	{
		if (myImage.imgWidth == null)
			myImage.imgWidth = myImage.width;
			
		if (myImage.imgHeight == null)
			myImage.imgHeight = myImage.height;
	
		var imgID = (myImage.id) ? "id='" + myImage.id + "' " : "";
		var imgClass = (myImage.className) ? "class='" + myImage.className + "' " : "";
		var imgTitle = (myImage.title) ? "title='" + myImage.title + "' " : "";
		var imgStyle = "xdisplay:inline-block;" + myImage.style.cssText ;
		var imgOnclick = (myImage.ieclick) ? "onclick=\"" + myImage.ieclick + "\" ieclick=\"" + myImage.ieclick + "\" " : "";
		var imgHelperProperties = " imgWidth='" + myImage.imgWidth + "' imgHeight='" + myImage.imgHeight + "' ";

		var imgMouseOver = (myImage.iemouseover) ? " onmouseover=\"" + myImage.iemouseover + "\" iemouseover=\"" + myImage.iemouseover + "\" " : "";
		var imgMouseOut = (myImage.iemouseout) ? " onmouseout=\"" + myImage.iemouseout + "\" iemouseout=\"" + myImage.iemouseout + "\" " : "";

		var imgSrc = " iesrc='" + myImage.src + "' ";
		var reloadImg = myImage.id ? " iereloadimg=\"png_Refresh('" + myImage.id + "','" + myImage.src + "')\" " : "";
		
		var strNewHTML = "<div " + imgID + imgClass + imgTitle + imgOnclick + imgHelperProperties + imgMouseOver + imgMouseOut + imgSrc + reloadImg;

		strNewHTML += " style=\"" + "width:" + myImage.imgWidth + "px; height:" + myImage.imgHeight + "px;" + imgStyle + ";";
		strNewHTML += "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader";
		strNewHTML += "(src=\'" + myImage.src + "\', sizingMethod='image');\"></div>";
		
		myImage.outerHTML = strNewHTML;
	}
}
   
function png_Refresh(myImage, src)
{
	if (window.ie55up)
	{
		var imgID = (myImage.id) ? "id='" + myImage.id + "' " : "";
		var imgClass = (myImage.className) ? "class='" + myImage.className + "' " : "";
		var imgTitle = (myImage.title) ? "title='" + myImage.title + "' " : "";
		var imgStyle = "display:inline-block;";// + myImage.style.cssText ;
		var imgOnclick = (myImage.ieclick) ? "onclick=\"" + myImage.ieclick + "\" ieclick=\"" + myImage.ieclick + "\" " : "";
		var imgHelperProperties = " imgWidth='" + myImage.imgWidth + "' imgHeight='" + myImage.imgHeight + "' ";

		var imgMouseOver = (myImage.iemouseover) ? " onmouseover=\"" + myImage.iemouseover + "\" iemouseover=\"" + myImage.iemouseover + "\" " : "";
		var imgMouseOut = (myImage.iemouseout) ? " onmouseout=\"" + myImage.iemouseout + "\" iemouseout=\"" + myImage.iemouseout + "\" " : "";

		var imgSrc = " iesrc='" + src + "' ";
		var reloadImg = myImage.id ? " iereloadimg=\"png_Refresh('" + myImage.id + "','" + src + "')\" " : "";

		var strNewHTML = "<span " + imgID + imgClass + imgTitle + imgOnclick + imgHelperProperties + imgMouseOver + imgMouseOut + imgSrc + reloadImg;
				 	
		strNewHTML += " style=\"" + "width:" + myImage.imgWidth + "px; height:" + myImage.imgHeight + "px;" + imgStyle + ";";
		strNewHTML += "filter:progid:DXImageTransform.Microsoft.AlphaImageLoader";
		strNewHTML += "(src=\'" + src + "\', sizingMethod='image');\"></span>";
		
		myImage.outerHTML = strNewHTML;
	}
	else
		myImage.src = src;
}

//	Method that allows an image to be changed safely. Ensures
//	that if the image is a png that the transparency is maintained.

function png_Change(myImage, src)
{
	if (window.ie55up)
	{
		if (myImage.iesrc != src)
			png_Refresh(myImage, src);
	}
	else if (myImage.src != src)
		myImage.src = src;
}

//	Method can be used to cause the pngs to be reloaded. It is generally
//	used when an element has been faded into view.
function png_FixAllChildPNGs(element)
{
	var children = element.children;
	
	for (var index = 0; index < children.length; index++)
	{
		var child = children.item(index);
		
		if (child.iereloadimg != null)
			eval(child.iereloadimg);
		
		png_FixAllChildPNGs(child);
	}
}

/////////////////////////////////////////////////////
//	Method used to extract the list of values contained
//	in a hidden control.The list of values must be separated
//	by spaces.
//	Once split into a list of strings, the list of strings
//	is pushed back into a preParsed property of the same control
//	thereby reducing the effort on subsequent calls.

function getListFromControl(control)
{
	var items = getRef(control);
	
	if (items == null)
	{
		return new Array();
	}
	else if (items.preParsed == null)
	{
		items.preParsed = items.value.split('.');
		var endItem = items.preParsed.pop();
		
		//	Seem to end up with a dead item at the end of the list
		//	so if it is dead throw it away, otherwise add it back
		//	on the end
		if ((endItem != ".") && (endItem != ""))
			items.preParsed.push(endItem);
	}
		
	return items.preParsed;
}

function getRefListFromControl(control)
{
	if (control == null) {
		return new Array();
	}
	else if (control.refItems == null) {
		ids = getListFromControl(control.id);
				
		control.refItems = new Array();
		
		for (var index = ids.length - 1; index >= 0; index--)
			control.refItems.push(getRef(ids[index]));
	}

	return control.refItems;	
}


function getRefListFromControlWithPrefix(control, prefix)
{
	if (control == null) {
		return new Array();
	}
	else if (control.refItems == null) {
		ids = getListFromControl(control.id);
				
		control.refItems = new Array();
		
		for (var index = ids.length - 1; index >= 0; index--)
			control.refItems.push(getRef(prefix + ids[index]));
	}

	return control.refItems;	
}
/////////////////////////////////////////////////////
//	Methods used to determine the height, width or
//	position of an element.

/**
 * COMMON DHTML FUNCTIONS
 * These are handy functions I use all the time.
 *
 * By Seth Banks (webmaster at subimage dot com)
 * http://www.subimage.com/
 *
 * Up to date code can be found at http://www.subimage.com/dhtml/
 *
 * This code is free for you to use anywhere, just keep this comment block.
 */

function getViewportHeight() {
	if (window.innerHeight!=window.undefined) return window.innerHeight;
	if (document.compatMode=='CSS1Compat') return document.documentElement.clientHeight;
	if (document.body) return document.body.clientHeight; 
	return window.undefined; 
}
function getViewportWidth() {
	if (window.innerWidth!=window.undefined) return window.innerWidth; 
	if (document.compatMode=='CSS1Compat') return document.documentElement.clientWidth; 
	if (document.body) return document.body.clientWidth; 
	return window.undefined; 
}

function elementHeight(element) { return element.innerHeight != null ? element.innerHeight : element.offsetHeight; }
function elementWidth(element)	{ return element.innerWidth != null ? element.innerWidth : element.offsetWidth; }
function elementLeft(element)	{ return (element.offsetParent) ? elementPosition(element, "offsetLeft") : element.x; }
function elementTop(element)	{ return (element.offsetParent) ? elementPosition(element, "offsetTop") : element.y; }

function elementPosition(element, which)
{
	var pos = 0;
	while (element != null)
	{
		pos += element[which];
		element = element.offsetParent;
	}
	
	return pos;
}

//	-4 on IE to adjust for scroll bar nonsense
function windowHeight()			{ return window.innerHeight != null ? window.innerHeight : document.body.offsetHeight - 4; }
function windowWidth()			{ return window.innerWidth != null ? window.innerWidth : document.body.offsetWidth - 4; }

function moveElementTo(elementToMove, elementParent, offsetX, offsetY)
{
	elementToMove = getRef(elementToMove);
	elementParent = getRef(elementParent);

	var x = elementLeft(elementParent) + offsetX;
	var y = elementTop(elementParent) + offsetY;

	elementToMove.style.left = x;
	elementToMove.style.top = y;
}

/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
//	Alpha handling
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////

//	Keep calling the method until the method returns false
//	indicating that the method does not need to be called
//	again to make the element fully visible.
function fadeUp_ApplyStep(element,step)
{
	var andAgain = false;
		
	if (ie55up)
	{
		if (element.filters.alpha.opacity < 100)
		{		
			element.filters.alpha.opacity = Math.max(element.filters.alpha.opacity + 5, 100);
			andAgain = true;
		}
		else
			element.filters.alpha.enabled = 0;
		
		//	Some of the graphic elements maybe PNGs so make sure they
		//	are correctly displayed.
		png_FixAllChildPNGs(element);
	}
	else if (!document.all && document.getElementById)
	{	
		if (element.style.MozOpacity < 1)
		{
			element.style.MozOpacity += step / 100;
			andAgain = true;
		}
	}
	
	return andAgain;
}

function fadeUp_Start(element)
{
	if (ie55up)
	{
		element.filters.alpha.opacity = 0;
		element.filters.alpha.enabled = 1;
	}
	else if (!document.all && document.getElementById)
	{	
		element.style.MozOpacity = 0;
	}
}

//	Determine if the specified element is visible due to the
//	alpha level.
function fadeUp_IsVisible(element)
{
	if (ie55up)
		return element.filters.alpha.opacity != 0;
	else
		return element.style.MozOpacity != 0;
}

//	Ensure the specified element is hidden, i.e. the alpha
//	level is zero

function fadeUp_HideElement(element)
{
	if (ie55up)
		return element.filters.alpha.opacity = 0;
	else
		return element.style.MozOpacity = 0;
}

/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
//	Form data handling
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////

var hexVals = new Array("0", "1", "2", "3", "4", "5", "6", "7", "8", "9","A", "B", "C", "D", "E", "F");
var escapeChars = "$&+/:;=?@%#\\<>{}|^~[]`\"'";

//	Ensure that the supplied string is escaped for use in the form data encoding.
//	Returns the encoded string.

function form_escapeString(value)
{
	var escaped = "";
	var string = new String(value);
	var len = string.length;

	for (var index = 0; index < len; index++)
	{
		var c = string.charAt(index);
		var code = string.charCodeAt(index);
		
		if ((escapeChars.indexOf(c) != -1) && (code > 32) && (code < 123))
			escaped += "%" + hexVals[code >> 4] + hexVals[code & 0x0f];
		else if (code < 32)
			escaped += "%" + hexVals[code >> 4] + hexVals[code & 0x0f];
		else if (c == ' ')
			escaped += '+';
		else
			escaped += c;
	}
	return escaped;
}

/////////////////////////////////////////////////////
//	This method will walk the DOM tree of the provided
//	element and build an encoded string containing what
//	would have been the form data. Note for asp.net to
//	decide that any request is a PostBack it will look
//	for the __VIEWSTATE form value.

//	The types of tags to encode.
var formTagNames = [ "input", "textarea", "select" ];

function form_buildPostData(formElement)
{
	var first = true;
	var data = "";

	//	For each type of tag, find all the instances of that type
	//	and if the name has not already been seen, encode the name value pair.
	for (var tagIndex = 0; tagIndex < formTagNames.length; tagIndex++)
	{
		var elements = formElement.getElementsByTagName(formTagNames[tagIndex]);
		var ignoreNames = new Array();

		for (var elementIndex = 0; elementIndex < elements.length; elementIndex++)
		{
			var control = elements[elementIndex];
			var ignore = false;
			var name = control.name;
			var value = control.value;
			
			if ((name != null) && (value != null) && (name != ""))
			{
				//	Have we already seen this name before - deals with
				//	radio buttons that will have multiple elements with the
				//	same name, but differing Ids.
				for (var input = 0; input < ignoreNames.length; input++)
				{
					if (ignoreNames[input] == name)
						ignore = true;
				}
				
				if (control.type == "checkbox") {
					if (elements[elementIndex].checked == false)
						ignore = true;
				}
				else if ((control.className == "unchecked") || (control.className == "disabled_unchecked"))
					ignore = true;
				
				if (ignore == false)
				{
					//	if this is an input and it's a radio button
					//	walk all the associated radio buttons and find
					//	the value of the one that is checked.
					if (control.type == "radio")
					{
						var group = document.getElementsByName(name);
						for(var i = 0;i < group.length; i++)
						{
							if (group[i].checked)
								value = group[i].value;
						}
					}
					else if (isDefaultValue(control.id))
						value = "";

					//	Need to make sure it's ignored next time around
					ignoreNames.push(name);
					
					//	Ampersand is used to combine the value pairs together.
					if (first)
						first = false;
					else
						data += "&";
						
					//	Add this value pair to the encoded data
					data += form_escapeString(name) + "=" + form_escapeString(value);
				}
			}
		}
	}
	return data;
}

/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
//	String manipluation.
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
//	Trim the supplied string and remove spaces and
//	carriage returns at the head and end of the the
//	string.

function trimString(string)
{
	// Remove leading spaces and carriage returns
	var remove = 0;
	var end = string.length;
	
	for (var index = 0; index < end; index++)
	{
		var c = string.charAt(index);
		
		if ((c == ' ') || (c == '\n') || (c == '\r') || (c < ' '))
			remove++;
		else
			break;
	}
	
	if (remove > 0)
		string = string.substring(remove, end);

	// Remove trailing spaces and carriage returns
	var remove = 0;
	var end = string.length;
	
	for (var index = end - 1; index >= 0; index--)
	{
		var c = string.charAt(index);
		
		if ((c == ' ') || (c == '\n') || (c == '\r') || (c < ' '))
			remove++;
		else
			break;
	}
	
	if (remove > 0)
		string = string.substring(0,end-remove);

	return string;
}

function stringHasContent(string) {
	return trimString(string).length > 0;
}

function stringHasMinLength(string, minlen) {
	return trimString(string).length >= minlen;
}

function controlHasValue(id) {
	return trimString(getRef(id).value).length > 0;
}

function stringStartsWith(string,other) {
	return string.substr(0, other.length) == other;
}

/////////////////////////////////////////////////////
//	Method removes any charactes in the string that
//	are not numeric characters. Only provides positive
//	integer

function stripNonNumericsFromString(string)
{
	var newString = "";
	
	for (var index = 0; index < string.length; index++)
	{
		var c = string.charAt(index);
		
		if ((c >= '0') && (c <= '9'))
			newString += c;
	}
	
	return newString;
}

function stripNonNumerics(control)
{
	var string = control.value;
	var newString = stripNonNumericsFromString(string);
	
	control.value = newString;
	
	return (newString.length == string.length);
}

function hasNumericsOnlyControl(control)
{
	if (stringHasContent(control.value) == false)
		return false;
	else
		return (control.value == stripNonNumericsFromString(control.value));
}

function hasNumericsOnly(control) {
	var value = getRef(control).value;
	
	if (stringHasContent(value))
		return (value == stripNonNumericsFromString(value));
		
	return false;
}

function isNumericBetween(control, lower, upper) {
	if (hasNumericsOnly(control)) {
		var value = parseInt(getRef(control).value,10);
		
		if ((value >= parseInt(lower,10)) && (value <= parseInt(upper,10)))
			return true;
	}
	
	return false;
}

/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////

function notImplemented()
{
	alert("Not Implemented");
}

/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////

function buttonChangeStyle(btnID, newStyle) {
	var button = getRef(btnID);
	
	if ((button.disabled != true) && (button.pushed != true))
		button.className=newStyle;
}
function buttonMouseOver(btnID)				{ buttonChangeStyle(btnID, 'flatButtonHover');		}
function buttonMouseOut(btnID)				{ buttonChangeStyle(btnID, 'flatButton');			}
function buttonMouseOutWithBorder(btnID)	{ buttonChangeStyle(btnID, 'flatButtonWithBorder');	}

function Rollover( button, img, file )
{
	if ( ! button.disabled )
	{
		img.src = '/PMM/Images/' + file;
	}
}

/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////

function showHideDetail(id) {
	if (getRef(id + 'Detail').style.display == "")
		hideDetail(id);
	else
		showDetail(id);
}

function showDetail(id) {
	var img = getRef(id + 'Img');
	var detail = getRef(id + 'Detail');

	detail.style.display = "";
	
	if (img != undefined)
		img.src = "/PMM/Images/Tree/minus.gif";
}
	
function hideDetail(id) {
	var img = getRef(id + 'Img');
	var detail = getRef(id + 'Detail');

	detail.style.display = "none";

	if (img != undefined)
		img.src = "/PMM/Images/Tree/plus.gif";
}
	
/////////////////////////////////////////////////////
/////////////////////////////////////////////////////
//	Function provides the support required for scrollable
//	tables.

function resizeColumns(control, columns, padding, noCache)
{
      var numOfColumns = columns.length;
      var elementList = getListFromControl(control);

      if ((numOfColumns == 0) || (elementList.length == 0))
            return;
            
      var columnWidths = new Array(numOfColumns);

      //    Get the width of all the column headers.  
      for (var column = 0; column < numOfColumns; column++)
			columnWidths[column] = Math.max(0,(elementWidth(getRef(columns[column] + 'Header')) - padding)) + "px";

      for (var index = 0; index < elementList.length; index++)
      {      
            var element = getRef(elementList[index]);
            var cache;

            //    Pre-cache the cell objects - faster next time!
            if (element.columns == undefined) {
                  cache = new Array(numOfColumns);
                  var id = element.id;
                  
                  for (var column = 0; column < numOfColumns; column++)
                  {
                        cache[column] = getRef(id + columns[column]);
                        cache[column].div = getRef(id + columns[column] + "Div");
                  }
            }

            //    Apply the column widths
            for (var column = 0; column < numOfColumns; column++) {
            	  var style = cache[column].div.style;
                  style.width = columnWidths[column];
                  style.display = "";
            }

            if (noCache != true)
                  element.cell = cache;
      }     
}



function resizeContainer( container, bottomMargin ) 
{
	try 
	{ 
		var control = getRef(container);
		topVal = elementTop( control );
		minHeight = 150;
		myHeight = minHeight;

		if ( document.body.clientHeight - bottomMargin - topVal - myHeight < 0 )
		{
			myHeight = minHeight;
		}
		else
		{
			myHeight = document.body.clientHeight - bottomMargin - topVal;
		}
		control.style.height = myHeight;
	}
	catch (e) { }
}

////////////////////////////////////////////
//Gets a date object from a standard date of
//format yyyy-MM-dd
//
function getDateFromStandard( standardDate )
{
	var dateParts = standardDate.split("-");
	return new Date( dateParts[1] + "/" + dateParts[2] + "/" + dateParts[0] );
}

////////////////////////////////////////////

////////////////////////////////////////////
//Gets a date object from a standard date of
//format yyyy-MM-dd
//
function getDateTimeFromStandard( datetime )
{
	var parts = datetime.split(" ");
	var dateParts = parts[0].split("-");
	return new Date( dateParts[1] + "/" + dateParts[2] + "/" + dateParts[0] + " " + parts[1]);
}

////////////////////////////////////////////

var dragging = null;

function beginDrag(item,event) {
	item.dragX = event.screenX - elementLeft(item);
	item.dragY = event.screenY - elementTop(item);
	item.style.position = "absolute";

	item.style.left = event.screenX - item.dragX;
	item.style.top = event.screenY - item.dragY;

	dragging = item;
}

function dragItem(ep) {
	if (dragging != null) {
		if (ep == undefined)
			e = event;
		else
			e = ep;
									
		dragging.style.left = e.screenX - dragging.dragX;
		dragging.style.top = e.screenY - dragging.dragY;
	}
}

function endDrag() {
	dragging = null;
}

document.onmouseup = endDrag;
document.onmousemove = dragItem;

////////////////////////////////////////////
//	Button state methods

function disableButton(id)	{ enableDisableButton(id, false); }
function enableButton(id)	{ enableDisableButton(id, true); }

function enableDisableButton(id, state)
{
	var btn = getRef(id);
	
	if (btn != null)
	{
		btn.disabled = !state;
		if (stringStartsWith(btn.className, "stdButton"))
			btn.className = state ? "stdButton" : "stdButtonDisabled";
		else
			btn.className = state ? "thinButton" : "thinButtonDisabled";
	}
}

////////////////////////////////////////////
////////////////////////////////////////////
//	Method used to shorten a url for display in a confined space.

function shortenUrl(url, maxlen)
{
	var sep = url.lastIndexOf('/');
	
	if (sep > 0)
	{
		var path = url.substring(0,sep);
		var filename = url.substring(sep);
		var pathLength  = maxlen - filename.length;
		
		if (pathLength > 3)	//	Path would still have some length
			path = ellipsisEndOfString(path, pathLength);
		else
		{
			path = "";
			filename = ellipsisStartOfString(filename, maxlen);
		}
		
		return path + filename;
	}
	else	//	No / separator
		return ellipsisStartOfString(url, maxlen);
}

function testShortenUrl()
{
	alert(shortenUrl("http://www.clearswift.com/fred.zip", 20));
	alert(shortenUrl("http://www.clearswift.com/fred.zip", 80));
	alert(shortenUrl("http://www.clearswift.com.fred.zip", 20));
	alert(shortenUrl("httpwww.clearswift.com.fred.zip", 20));
}

////////////////////////////////////////////
////////////////////////////////////////////
//	Methods used to ellipsis a string at either the beginning or
//	end of the supplied string.

function ellipsisEndOfString(x, maxlen)
{
	if (x.length <= maxlen)
		return x
	else if (maxlen < 4)
		return x.substring(0, maxlen) // no room for ellipsis
	else return x.substring(0, maxlen-3) + "...";
}

function ellipsisStartOfString(x, maxlen)
{
	if (x.length <= maxlen)
		return x
	else if (maxlen < 4)
		return x.substring(x.length, x.length+maxlen) // no room for ellipsis
	else return "..." + x.substring(x.length-maxlen+3, x.length);
}

////////////////////////////////////////////
////////////////////////////////////////////

function updateOpacity(target) {
	if (target.m_opacity > 1)
		target.m_opacity = 1;
	target.style.opacity = target.m_opacity;
	target.style.MozOpacity = target.m_opacity;
	target.style.filter = "alpha(opacity=" + (target.m_opacity*100) + ")";
}

////////////////////////////////////////////
////////////////////////////////////////////
/**
 * X-browser event handler attachment and detachment
 *
 * @argument obj - the object to attach event to
 * @argument evType - name of the event - DONT ADD "on", pass only "mouseover", etc
 * @argument fn - function to call
 */
function addEvent(obj, evType, fn){
 if (obj.addEventListener){
    obj.addEventListener(evType, fn, true);
    return true;
 } else if (obj.attachEvent){
    var r = obj.attachEvent("on"+evType, fn);
    return r;
 } else {
    return false;
 }
}
function removeEvent(obj, evType, fn, useCapture){
  if (obj.removeEventListener){
    obj.removeEventListener(evType, fn, useCapture);
    return true;
  } else if (obj.detachEvent){
    var r = obj.detachEvent("on"+evType, fn);
    return r;
  } else {
    //alert("Handler could not be removed");
  }
}
////////////////////////////////////////////
////////////////////////////////////////////
