////////////////////////////////////////////////////////////////////
//  2006 SightWorks, LLC. All Rights Reserved.
//  This programming code is the property of SightWorks. LLC
//  Reproduction and use of this code is by permission only.
//  Removal of this text header is unlawful and forbidden.
//  Contact Information: info@sightworks.com
////////////////////////////////////////////////////////////////////

/*
fieldFocus - forces input focus to the fieldName input element
*/
function fieldFocus(fieldName)
{

	try
	{
		var oItem = document.getElementById(fieldName);

		oItem.focus();
		oItem.select();
	}
	catch(e)
	{
		
	}
}

function showLayer(layerID)
{
	ShowLayer(layerID);
}

function hideLayer(layerID)
{
	HideLayer(layerID);
}


/*
ShowLayer -	Makes a hidden and/or non-displayed element visible and sets display to 'block'
*/
function ShowLayer(layerID)
{

  var style_sheet = getStyleObject(layerID);
  
  if (style_sheet)
  {
    //hideAll();
    changeObjectVisibility(layerID, "visible");
    changeObjectDisplay(layerID, "block");
  }
  else 
  {
    status = "Layer not found: " + layerID;
  }
 
}

/*
HideLayer -	Makes a visible and/or displayed element hidden and sets display to 'none'
*/
function HideLayer(layerID)
{
  var style_sheet = getStyleObject(layerID);
  if (style_sheet)
  {
    //hideAll();
    changeObjectVisibility(layerID, "hidden");
    changeObjectDisplay(layerID, "none");
  }
  else 
  {
    status = "Layer not found: " + layerID;
  }
}



/*
getStyleObject - Get the style object for a given element, required for cross-browser compatability
*/
function getStyleObject(objectId) {
  // checkW3C DOM, then MSIE 4, then NN 4.
  //
 
  if(document.getElementById && document.getElementById(objectId)) {
	return document.getElementById(objectId).style;
   }
   else if (document.all && document.all(objectId)) {  
	return document.all(objectId).style;
   } 
   else if (document.layers && document.layers[objectId]) { 
	return document.layers[objectId];
   } else {
	return false;
   }
}


/*
getObject - Get the object for a given element, required for cross-browser compatability
*/

function getObject(objectId) {
  // checkW3C DOM, then MSIE 4, then NN 4.
  //
 
  if(document.getElementById && document.getElementById(objectId)) {
	return document.getElementById(objectId);
   }
   else if (document.all && document.all(objectId)) {  
	return document.all(objectId);
   } 
   else if (document.layers && document.layers[objectId]) { 
	return document.layers[objectId];
   } else {
	return false;
   }
}



function getPageObject(objectId)

{

 // checkW3C DOM, then MSIE 4, then NN 4.
  //
 
  if(document.getElementById && document.getElementById(objectId)) {
	return document.getElementById(objectId);
   }
   else if (document.all && document.all(objectId)) {  
	return document.all(objectId);
   } 
   else if (document.layers && document.layers[objectId]) { 
	return document.layers[objectId];
   } else {
	return false;
   }

}


function changeObjectVisibility(objectId, newVisibility) {
    // first get the object's stylesheet
    var styleObject = getStyleObject(objectId);

    // then if we find a stylesheet, set its visibility
    // as requested
    //
    if (styleObject) {
		styleObject.visibility = newVisibility;
		return true;
    } else {
		return false;
    }

}

function changeObjectDisplay(objectId, newDisplay) {
    // first get the object's stylesheet
    var styleObject = getStyleObject(objectId);

    if (styleObject) {
	styleObject.display = newDisplay;
	return true;
    } else {
	return false;
    }

}


function moveLayer(objectId,x,y)
{
	var styleObject = getStyleObject(objectId);

	styleObject.top = y;
	styleObject.left = x;
}

function showTip(layerID,x,y)
{
				
	moveLayer(layerID,x,y);
	ShowLayer(layerID);
	
}





function preloadImages() { 
var d=document; if(d.images){ if(!d.p) d.p=new Array();
var i,j=d.p.length,a=preloadImages.arguments; for(i=0; i<a.length; i++)
if (a[i].indexOf("#")!=0){ d.p[j]=new Image; d.p[j++].src=a[i];}}
}

function swapImgRestore() { 
  var i,x,a=document.sr; for(i=0;a&&i<a.length&&(x=a[i])&&x.oSrc;i++) x.src=x.oSrc;
}

function findObj(n, d) { 
  var p,i,x;  if(!d) d=document; if((p=n.indexOf("?"))>0&&parent.frames.length) {
    d=parent.frames[n.substring(p+1)].document; n=n.substring(0,p);}
  if(!(x=d[n])&&d.all) x=d.all[n]; for (i=0;!x&&i<d.forms.length;i++) x=d.forms[i][n];
  for(i=0;!x&&d.layers&&i<d.layers.length;i++) x=findObj(n,d.layers[i].document); return x;
}

function swapImage() { 
  var i,j=0,x,a=swapImage.arguments; document.sr=new Array; for(i=0;i<(a.length-2);i+=3)
   if ((x=findObj(a[i]))!=null){document.sr[j++]=x; if(!x.oSrc) x.oSrc=x.src; x.src=a[i+2];}

}


// HIDE SHOW LAYERS
function showHide(id,vis) 
{ 
document.getElementById(id).style.visibility=vis; 
} 

// POP UP WINDOW
function newWindow(mypage, myname, w, h, scroll) {
	var winl = (screen.width - w) / 2;
	var wint = (screen.height - h) / 2;
	winprops = 'height='+h+',width='+w+',top='+wint+',left='+winl+',scrollbars='+scroll+',noresize';
	win = window.open(mypage, myname, winprops)
	if (parseInt(navigator.appVersion) >= 4) { win.window.focus(); }
}

	
// HANDLE TABLE ROW HIGHLIGHT ON MOUSEOVER
function listMouseOver(layerID) {
  if (document.layers)   { document.layers[layerID].bgColor='#FFFF99'; }
  else if (document.all) { document.getElementById(layerID).style.background='#FFFF99'; }

}

function listMouseOver2(layerID, color) {
  if (document.layers)   { document.layers[layerID].bgColor=color; }
  else if (document.all) { document.getElementById(layerID).style.background=color; }

}

function listMouseOut(layerID, oldColor) {
  if (document.layers)   { document.layers[layerID].bgColor=oldColor; }
  else if (document.all) { document.getElementById(layerID).style.background=oldColor; }
}

// LINK TO URL WHEN ROW IS CLICKED
function listClickRow(URL)
{
  document.location = URL;
}

// SHOW HIDE LAYER
/*function showLayer(id) { 
document.getElementById(id).style.visibility="visible"; 
document.getElementById(id).style.display="block";
} 

// SHOW HIDE LAYER
function hideLayer(id) { 
document.getElementById(id).style.visibility="hidden";
document.getElementById(id).style.display="none";  
} 
*/

// CENTERED POP UP WINDOW
function newWindow(mypage, myname, w, h, scroll) {
var winl = (screen.width - w) / 2;
var wint = (screen.height - h) / 2;
winprops = 'height='+h+',width='+w+',top='+wint+',left='+winl+',scrollbars='+scroll+',noresize';
win = window.open(mypage, myname, winprops)
if (parseInt(navigator.appVersion) >= 4) { win.window.focus(); }
}


// GET POPUP DATE SET CALENDAR
function fillDate(y, m, d) 
{
function setselectbyvalue(theSelect,avalue)
	{
		for( var i=0,n=theSelect.options.length; i<n; i++ )
		{
			if(theSelect.options[i].value==avalue)
			{
				return(theSelect.selectedIndex=i);
			}
		}
		return(-1);
	}

setselectbyvalue(document.FormName.year, y)
setselectbyvalue(document.FormName.month, m)
setselectbyvalue(document.FormName.day, d)
}


/*************************************************************
 *BEGIN LAYER TWEENING FUNCTIONS AND CLASSES
 *
 *
 *************************************************************/

//The tween object represents the animation progress of a particular
//property tween animation
function Tween(layerID,prop)
{
	this.curTimer = 0;
	this.layerID = layerID;
	this.prop = prop;
	this.curVal = this.startVal = this.endVal = 0;
	this.step = 1;
	
	
}

var g_activeTweens = new Object();
var g_msgTimerID;



//Either returns a tween that matches layerID and prop or creates
// a new tween if no matching tween is found
function getTween(layerID,prop,startVal,endVal,time,animType,valSuffix,callBack)
{
	var dtNow = new Date();
	dtNow = dtNow.getTime();
	if(g_activeTweens[layerID] )
	{
		if(!g_activeTweens[layerID].propTween[prop])
		{
		

			g_activeTweens[layerID].propTween[prop] = new Tween(layerID,prop);	
			g_activeTweens[layerID].propTween[prop].curVal = startVal;
			g_activeTweens[layerID].propTween[prop].startVal = startVal;
			g_activeTweens[layerID].propTween[prop].endVal = endVal;
			g_activeTweens[layerID].propTween[prop].time = time;
			g_activeTweens[layerID].propTween[prop].animType = animType;
			g_activeTweens[layerID].propTween[prop].callBack = callBack;
			g_activeTweens[layerID].propTween[prop].valSuffix = valSuffix;


//	status = g_activeTweens[layerID] + g_activeTweens[layerID].propTween[prop] + prop;
		g_activeTweens[layerID].propTween[prop].timeStart = dtNow;

		}
		return g_activeTweens[layerID].propTween[prop];
	}
	else
	{
		g_activeTweens[layerID] = new Object();
		g_activeTweens[layerID].propTween = new Object();
		g_activeTweens[layerID].propTween[prop] = new Tween(layerID,prop);	
		g_activeTweens[layerID].propTween[prop].curVal = startVal;
		g_activeTweens[layerID].propTween[prop].startVal = startVal;
		g_activeTweens[layerID].propTween[prop].endVal = endVal;
		g_activeTweens[layerID].propTween[prop].time = time;
		g_activeTweens[layerID].propTween[prop].timeStart = dtNow;
		g_activeTweens[layerID].propTween[prop].animType = animType;
			g_activeTweens[layerID].propTween[prop].callBack = callBack;
			g_activeTweens[layerID].propTween[prop].valSuffix = valSuffix;

		return g_activeTweens[layerID].propTween[prop];
	}
}

/*************************************************************
 *tweenLayerProperty is used to animate any style propery of a 
 *layer.  It is useful for animating layers
 *
 *************************************************************/
function tweenLayerProperty(layerID, prop,startVal, endVal,time,animType,valSuffix,callBack,extra1,extra2)
{

	var dtNow = new Date();  
	dtNow = dtNow.getTime(); 
if(g_activeTweens[layerID] && g_activeTweens[layerID].propTween[prop])
{
	g_activeTweens[layerID].propTween[prop].timeStart =dtNow; 
}

	tweenProperty(layerID, prop,startVal, endVal,time,animType,valSuffix, callBack,extra1,extra2);

} 

function tweenCallback()
{
	var oTween = arguments[0];
	var oLayer = document.getElementById(oTween.layerID);
	var oStyle = getStyleObject(oTween.layerID);
	tweenLayerProperty(oTween.layerID,oTween.prop,oStyle.left,Math.random() * 800,2000, oTween.animType,oTween.valSuffix, oTween.callBack);
}

function tweenProperty(layerID, prop,startVal, endVal,time,animType,valSuffix, callBack,extra1,extra2)
{
	var startVal;
	var oStyle =  getStyleObject(layerID);
	//eval("startVal = oStyle." + prop + ";");
	var oTween = getTween(layerID,prop,startVal,endVal,time,animType,valSuffix, callBack);
	var dtNow = new Date();
	dtNow = dtNow.getTime();
	oTween.startVal = startVal;
	oTween.endVal = endVal;
	//status = oTween.curVal + oTween.layerID+ oTween.propTween[prop];

//	if((endVal < startVal && oTween.curVal < endVal) ||
//			(endVal >= startVal && oTween.curVal > endVal) ||
	if		((dtNow - oTween.timeStart ) > oTween.time)
	{
		if(callBack != 'undefined')
		{

			eval(callBack + "(oTween);");
		}
		return;
	}
	else
	{
		var val = new Array(4);
		if(prop == "clip")
		{
			for(i = 0; i < startVal.length; i++)
			{
				if(startVal[i] == "auto")
				{
					val[i] = "auto";
				}
				else
				{
					val[i]  = Math.ceil(findTweenValue (parseInt(startVal[i]), parseInt(endVal[i]), oTween.timeStart, 
									dtNow, oTween.timeStart + oTween.time, animType,0,0) );	
				}
					
			}
			oTween.curVal = val;
	
			status = oTween.curVal;
	
//		alert("oStyle." + oTween.prop + "=\"rect(" + oTween.curVal[0] +oTween.valSuffix[0]+" " +  oTween.curVal[1] +
//					oTween.valSuffix[1]+" " +oTween.curVal[2] +oTween.valSuffix[2]+" " +oTween.curVal[3] +oTween.valSuffix[3]+ ")\";");
	
eval("oStyle." + oTween.prop + "=\"rect(" + oTween.curVal[0] +oTween.valSuffix[0]+" " +  oTween.curVal[1] +
					oTween.valSuffix[1]+" " +oTween.curVal[2] +oTween.valSuffix[2]+" " +oTween.curVal[3] +oTween.valSuffix[3]+ ")\";");
		
			strTimeout = 'tweenProperty(\'' + layerID + '\',\''+ prop + '\',['+  startVal + '],['+  endVal + '],\''+ oTween.time +'\',\'' + animType + '\',\'' + valSuffix + '\',\''  + callBack +'\',\'' + extra1 +'\',\'' + extra2 + '\');';
		}
		else
		{
			var val  = findTweenValue (parseInt(startVal), parseInt(endVal), oTween.timeStart, 
									dtNow, oTween.timeStart + oTween.time, animType,0,0) ;
	//	var val = parseInt(oTween.curVal) + parseInt(step);
		//oTween.curVal = ;
	    //alert(val);
			oTween.curVal = val;
			
			eval("oStyle." + oTween.prop + "='" + oTween.curVal +oTween.valSuffix+ "';");
			
			strTimeout = 'tweenProperty(\'' + layerID + '\',\''+ prop + '\',\''+  startVal + '\',\''+  endVal + '\',\''+ oTween.time +'\',\'' + animType + '\',\'' + valSuffix + '\',\''  + callBack +'\',\'' + extra1 +'\',\'' + extra2 + '\');';
		}
//status = "oStyle." + oTween.prop + "=" + oTween.curVal + ";" + step +";" ;
		//alert('tweenProperty(\'' + layerID + '\',\''+ prop + '\',\''+  startVal + '\',\''+  endVal + '\',\''+ oTween.time +'\',\'' + animType + '\',\'' + valSuffix + '\',\''  + callBack +'\',\'' + extra1 +'\',\'' + extra2 + '\');');
		try{
		//alert(strTimeout);
		oTween.curTimer = setTimeout(strTimeout,10);
		}
		catch(e)
		{

		}
	}
}

function findTweenValue (_propStart, _propDest, _timeStart, _timeNow, _timeDest, _animType, _extra1, _extra2) {
  var t = _timeNow - _timeStart;  // current time (frames, seconds)
  var b = _propStart;             // beginning value
  var c = _propDest - _propStart; // change in value
  var d = _timeDest - _timeStart; // duration (frames, seconds)
  var a = _extra1;                // amplitude (optional - used only on *elastic easing)
  var p = _extra2;                // period (optional - used only on *elastic easing)
  var s = _extra1;                // overshoot ammount (optional - used only on *back easing)
var val;
var foo = document.getElementById("debug");
//foo.innerHTML +=  "c=" + c + " : t=" + t + " : d=" + d + " : val=" + val + "anim=" + _animType + "<BR>";
//status =  "c=" + c + " : t=" + t + " : d=" + d + " : val=" + val +  "<BR>";
 switch (_animType.toLowerCase()) {
  case "linear":
    // simple linear tweening - no easing
    return c*t/d + b;

  case "easeinquad":
    // quadratic (t^2) easing in - accelerating from zero velocity
    return c*(t/=d)*t + b;
  case "easeoutquad":
    // quadratic (t^2) easing out - decelerating to zero velocity
    return -c *(t/=d)*(t-2) + b;
  case "easeinoutquad":
    // quadratic (t^2) easing in/out - acceleration until halfway, then deceleration
    if ((t/=d/2) < 1) return c/2*t*t + b;
    return -c/2 * ((--t)*(t-2) - 1) + b;

  case "easeincubic":
    // cubic (t^3) easing in - accelerating from zero velocity
    return c*(t/=d)*t*t + b;
  case "easeoutcubic":
    // cubic (t^3) easing out - decelerating to zero velocity
    return c*((t=t/d-1)*t*t + 1) + b;
  case "easeinoutcubic":
    // cubic (t^3) easing in/out - acceleration until halfway, then deceleration
    if ((t/=d/2) < 1) return c/2*t*t*t + b;
    return c/2*((t-=2)*t*t + 2) + b;

  case "easeinquart":
    // quartic (t^4) easing in - accelerating from zero velocity
    return c*(t/=d)*t*t*t + b;
  case "easeoutquart":

    // quartic (t^4) easing out - decelerating to zero velocity
    return -c * ((t=t/d-1)*t*t*t - 1) + b;
  case "easeinoutquart":
    // quartic (t^4) easing in/out - acceleration until halfway, then deceleration
    if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
    return -c/2 * ((t-=2)*t*t*t - 2) + b;

  case "easeinquint":
    // quintic (t^5) easing in - accelerating from zero velocity
    return c*(t/=d)*t*t*t*t + b;
  case "easeoutquint":
    // quintic (t^5) easing out - decelerating to zero velocity
    return c*((t=t/d-1)*t*t*t*t + 1) + b;
  case "easeinoutquint":
    // quintic (t^5) easing in/out - acceleration until halfway, then deceleration
    if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
    return c/2*((t-=2)*t*t*t*t + 2) + b;

  case "easeinsine":
    // sinusoidal (sin(t)) easing in - accelerating from zero velocity
    return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
  case "easeoutsine":
    // sinusoidal (sin(t)) easing out - decelerating to zero velocity
    return c * Math.sin(t/d * (Math.PI/2)) + b;
  case "easeinoutsine":
    // sinusoidal (sin(t)) easing in/out - acceleration until halfway, then deceleration
    return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;

  case "easeinexpo":
    // exponential (2^t) easing in - accelerating from zero velocity
    return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
  case "easeoutexpo":
    // exponential (2^t) easing out - decelerating to zero velocity
    return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
  case "easeinoutexpo":
    // exponential (2^t) easing in/out - acceleration until halfway, then deceleration
    if (t==0) return b;
    if (t==d) return b+c;
    if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
    return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;

  case "easeincirc":
    // circular (sqrt(1-t^2)) easing in - accelerating from zero velocity
//foo.innerHTML +=  "<br>" + t +"<BR>";
    val =  -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
//foo.innerHTML +=  "b=" + b + " :  c=" + c + " : t=" + t + " : d=" + d + " : val=" + val +  "<BR><br>";
		return val;
  case "easeoutcirc":
    // circular (sqrt(1-t^2)) easing out - decelerating to zero velocity
    return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
  case "easeinoutcirc":
    // circular (sqrt(1-t^2)) easing in/out - acceleration until halfway, then deceleration
    if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
    return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;

  case "easeinelastic":
    // elastic (exponentially decaying sine wave)
    if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
    if (a < Math.abs(c)) { a=c; var s=p/4; }
    else var s = p/(2*Math.PI) * Math.asin (c/a);
    return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
  case "easeoutelastic":
    // elastic (exponentially decaying sine wave)
    if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
    if (a < Math.abs(c)) { a=c; var s=p/4; }
    else var s = p/(2*Math.PI) * Math.asin (c/a);
    return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
  case "easeinoutelastic":
    // elastic (exponentially decaying sine wave)
    if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
    if (a < Math.abs(c)) { a=c; var s=p/4; }
    else var s = p/(2*Math.PI) * Math.asin (c/a);
    if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
    return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;

  // Robert Penner's explanation for the s parameter (overshoot ammount):
  //  s controls the amount of overshoot: higher s means greater overshoot
  //  s has a default value of 1.70158, which produces an overshoot of 10 percent
  //  s==0 produces cubic easing with no overshoot
  case "easeinback":
    // back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing in - backtracking slightly, then reversing direction and moving to target
    if (s == undefined) s = 1.70158;
    return c*(t/=d)*t*((s+1)*t - s) + b;
  case "easeoutback":
    // back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing out - moving towards target, overshooting it slightly, then reversing and coming back to target
    if (s == undefined) s = 1.70158;
    return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
  case "easeinoutback":
    // back (overshooting cubic easing: (s+1)*t^3 - s*t^2) easing in/out - backtracking slightly, then reversing direction and moving to target, then overshooting target, reversing, and finally coming back to target
    if (s == undefined) s = 1.70158; 
    if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
    return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;

  // This were changed a bit by me (since I'm not using Penner's own Math.* functions)
  // So I changed it to call findTweenValue() instead (with some different arguments)
  case "easeinbounce":
    // bounce (exponentially decaying parabolic bounce) easing in
    return c - findTweenValue (0, c, 0, d-t, d, "easeOutBounce") + b;
  case "easeoutbounce":
    // bounce (exponentially decaying parabolic bounce) easing out
    if ((t/=d) < (1/2.75)) {
      return c*(7.5625*t*t) + b;
    } else if (t < (2/2.75)) {
      return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
    } else if (t < (2.5/2.75)) {
      return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
    } else {
      return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
    }
  case "easeinoutbounce":
    // bounce (exponentially decaying parabolic bounce) easing in/out
    if (t < d/2) return findTweenValue (0, c, 0, t*2, d, "easeInBounce") * .5 + b;
    return findTweenValue(0, c, 0, t*2-d, d, "easeOutBounce") * .5 + c*.5 + b;
	}
return val;
}

//***Cross browser attach event function. For 'evt' pass a string value with the leading "on" omitted
//***e.g. AttachEvent(window,'load',MyFunctionNameWithoutParenthesis,false);

function AttachEvent(obj,evt,fnc,useCapture){
	
	try
	{
		if (!obj) obj = {};
		if (!useCapture) useCapture=false;
		if (obj.addEventListener){

			obj.addEventListener(evt,fnc,useCapture);
			
			return true;
		} else if (obj.attachEvent) return obj.attachEvent("on"+evt,fnc);
		else{
			MyAttachEvent(obj,evt,fnc);
			obj['on'+evt]=function(){ MyFireEvent(obj,evt) };
		}
	}
	catch(e)
	{
	
	}
} 

//The following are for browsers like NS4 or IE5Mac which don't support either
//attachEvent or addEventListener
function MyAttachEvent(obj,evt,fnc){
	try
	{
		if (!obj.myEvents) obj.myEvents={};
		if (!obj.myEvents[evt]) obj.myEvents[evt]=[];
		var evts = obj.myEvents[evt];
		evts[evts.length]=fnc;
	} catch (e) {}
}
function MyFireEvent(obj,evt){
	try
	{
		if (!obj || !obj.myEvents || !obj.myEvents[evt]) return;
		var evts = obj.myEvents[evt];
		for (var i=0,len=evts.length;i<len;i++) evts[i]();
	} catch (e){}
}

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 {
    status = "Handler could not be removed";
  }
}

function showPagedObjectProperties(obj)
{
	var str = "";
	var i = 0;
	for(o in obj)
	{
		str += o + " = " + obj[o] + "\n ** ";
		i++;
		
		if(i % 20 == 0)
		{
			alert(str);
			str = "";
		}
	}
	
	alert(str);
}




/**
 *  Useful style functions to follow
 *
 *
 **/

// ugly workaround for missing support for selectorText in Netscape6/Mozilla
// call onLoad() or before you need to do anything you would have otherwise used
// selectorText for.
var ugly_selectorText_workaround_flag = false;
var allStyleRules;
// code developed using the following workaround (CVS v1.15) as an example.
// http://lxr.mozilla.org/seamonkey/source/extensions/xmlterm/ui/content/XMLTermCommands.js


function ugly_selectorText_workaround() {
	if((navigator.userAgent.indexOf("Gecko") == -1) ||
	   (ugly_selectorText_workaround_flag)) {
		return; // we've already been here or shouldn't be here
	}
	var styleElements = document.getElementsByTagName("style");
	
	for(var i = 0; i < styleElements.length; i++) {
		var styleText = styleElements[i].firstChild.data;
		// this should be using match(/\b[\w-.]+(?=\s*\{)/g but ?= causes an
		// error in IE5, so we include the open brace and then strip it
		allStyleRules = styleText.match(/\b[\w-.]+(\s*\{)/g);
	}

	for(var i = 0; i < allStyleRules.length; i++) {
		// probably insufficient for people who like random gobs of 
		// whitespace in their styles
		allStyleRules[i] = allStyleRules[i].substr(0, (allStyleRules[i].length - 2));
	}
	ugly_selectorText_workaround_flag = true;
}



// setStyleById: given an element id, style property and 
// value, apply the style.
// args:
//  i - element id
//  p - property
//  v - value
//
function setStyleById(i, p, v) {
	var n = document.getElementById(i);
	n.style[p] = v;
}

// getStyleById: given an element ID and style property
// return the current setting for that property, or null.
// args:
//  i - element id
//  p - property
function getStyleById(i, p) {
	var n = document.getElementById(i);
	var s = eval("n.style." + p);

	// try inline
	if((s != "") && (s != null)) {
		return s;
	}

	// try currentStyle
	if(n.currentStyle) {
		var s = eval("n.currentStyle." + p);
		if((s != "") && (s != null)) {
			return s;
		}
	}
	
	// try styleSheets
	var sheets = document.styleSheets;
	if(sheets.length > 0) {
		// loop over each sheet
		for(var x = 0; x < sheets.length; x++) {
			// grab stylesheet rules
			var rules = sheets[x].cssRules;
			if(rules.length > 0) {
				// check each rule
				for(var y = 0; y < rules.length; y++) {
					var z = rules[y].style;
					// selectorText broken in NS 6/Mozilla: see
					// http://bugzilla.mozilla.org/show_bug.cgi?id=51944
			//		ugly_selectorText_workaround();
					if(allStyleRules) {
						if(allStyleRules[y] == i) {
							return z[p];
						}			
					} else {
						// use the native selectorText and style stuff
						if(((z[p] != "") && (z[p] != null)) ||
						   (rules[y].selectorText == i)) {
							return z[p];
						}
					}
				}
			}
		}
	}
	return null;
}

// setStyleByClass: given an element type and a class selector,
// style property and value, apply the style.
// args:
//  t - type of tag to check for (e.g., SPAN)
//  c - class name
//  p - CSS property
//  v - value
var ie = (document.all) ? true : false;

function setStyleByClass(t,c,p,v){
	var elements;
	if(t == '*') {
		// '*' not supported by IE/Win 5.5 and below
		elements = (ie) ? document.all : document.getElementsByTagName('*');
	} else {
		elements = document.getElementsByTagName(t);
	}
	for(var i = 0; i < elements.length; i++){
		var node = elements.item(i);
		for(var j = 0; j < node.attributes.length; j++) {
			if(node.attributes.item(j).nodeName == 'class') {
				if(node.attributes.item(j).nodeValue == c) {
					eval('node.style.' + p + " = '" +v + "'");
				}
			}
		}
	}
}

// getStyleByClass: given an element type, a class selector and a property,
// return the value of the property for that element type.
// args:
//  t - element type
//  c - class identifier
//  p - CSS property
function getStyleByClass(t, c, p) {
	// first loop over elements, because if they've been modified they
	// will contain style data more recent than that in the stylesheet
	var elements;
	var length;
	if(t == '*') {
		// '*' not supported by IE/Win 5.5 and below
		elements = (ie) ? document.all : document.getElementsByTagName('*');
	} else {
		elements = document.getElementsByTagName(t);
	}

	for(var i = 0; i < elements.length; i++){
		var node = elements.item(i);
		try {
			length = node.attributes.length;
		}
		catch (e) { length = 0; }
		
		for(var j = 0; j < length; j++) {
			if(node.attributes.item(j).nodeName == 'class') {
				if(node.attributes.item(j).nodeValue == c) {
					var theStyle = eval('node.style.' + p);
					if((theStyle != "") && (theStyle != null)) {
						return theStyle;
					}
				}
			}
		}		
	}
	
	
	// if we got here it's because we didn't find anything
	// try styleSheets
	var sheets = document.styleSheets;
	if(sheets.length > 0) {
	
		// loop over each sheet
		for(var x = 0; x < sheets.length; x++) {
			// grab stylesheet rules
			var rules = sheets[x].cssRules;
			
			try {
				length = rules.length;
			}
			catch (e) { length = 0; }
			if(length > 0) {
		
				// check each rule
				for(var y = 0; y < rules.length; y++) {
					var z = rules[y].style;
					// selectorText broken in NS 6/Mozilla: see
					// http://bugzilla.mozilla.org/show_bug.cgi?id=51944
					//ugly_selectorText_workaround();
					if(allStyleRules) {
						if((allStyleRules[y] == c) ||
						   (allStyleRules[y] == (t + "." + c))) {
							return z[p];
						}			
					} else {
						// use the native selectorText and style stuff
						if(((z[p] != "") && (z[p] != null)) &&
						   ((rules[y].selectorText == c) ||
						    (rules[y].selectorText == (t + "." + c)))) {
							return z[p];
						}
					}
				}
			}
		}
	}

	return null;
}

// setStyleByTag: given an element type, style property and 
// value, and whether the property should override inline styles or
// just global stylesheet preferences, apply the style.
// args:
//  e - element type or id
//  p - property
//  v - value
//  g - boolean 0: modify global only; 1: modify all elements in document
function setStyleByTag(e, p, v, g) {
	var length;
	if(g) {
		var elements = document.getElementsByTagName(e);
		for(var i = 0; i < elements.length; i++) {
			elements.item(i).style[p] = v;
		}
	} else {
	
		var sheets = document.styleSheets;
		try {
			length = sheets.length;
		}
		catch (e) { length = 0; }
		if(length > 0) {
			for(var i = 0; i < sheets.length; i++) {
				var rules = sheets[i].cssRules;
				
				try {
					length = rules.length;
				}
				catch (e) { length = 0; }
				if(length > 0) {
					for(var j = 0; j < rules.length; j++) {
						var s = rules[j].style;
						// selectorText broken in NS 6/Mozilla: see
						// http://bugzilla.mozilla.org/show_bug.cgi?id=51944
					//	ugly_selectorText_workaround();
						if(allStyleRules) {
							if(allStyleRules[j] == e) {
								
								s[p] = v;
							}			
						} else {
							// use the native selectorText and style stuff
							if(((s[p] != "") && (s[p] != null)) &&
							   (rules[j].selectorText == e)) {
								s[p] = v;
							}
						}

					}
				}
			}
		}
	}
}

// getStyleByTag: given an element type and style property, return
// the property's value
// args:
//  e - element type
//  p - property
function getStyleByTag(e, p) {
	var sheets = document.styleSheets;
	if(sheets.length > 0) {
		for(var i = 0; i < sheets.length; i++) {
			var rules = sheets[i].cssRules;
			if(rules.length > 0) {
				for(var j = 0; j < rules.length; j++) {
					var s = rules[j].style;
					// selectorText broken in NS 6/Mozilla: see
					// http://bugzilla.mozilla.org/show_bug.cgi?id=51944
				//	ugly_selectorText_workaround();
					if(allStyleRules) {
						if(allStyleRules[j] == e) {
							return s[p];
						}			
					} else {
						// use the native selectorText and style stuff
						if(((s[p] != "") && (s[p] != null)) &&
						   (rules[j].selectorText == e)) {
							return s[p];
						}
					}

				}
			}
		}
	}

	// if we don't find any style sheets, return the value for the first
	// element of this type we encounter without a CLASS or STYLE attribute
	var elements = document.getElementsByTagName(e);
	var sawClassOrStyleAttribute = false;
	for(var i = 0; i < elements.length; i++) {
		var node = elements.item(i);
		for(var j = 0; j < node.attributes.length; j++) {
			if((node.attributes.item(j).nodeName == 'class') ||
			   (node.attributes.item(j).nodeName == 'style')){
			   sawClassOrStyleAttribute = true;
			}
		}
		if(! sawClassOrStyleAttribute) {
			return elements.item(i).style[p];
		}
	}
}



function getElementsByClassName(sTagName, sClassName)
{
	var  aElems = document.getElementsByTagName(sTagName); 
	var aRetElems = [];
	for( var i = 0; i < aElems.length; i++ ) 
	{ 
		if( aElems[i].className == sClassName ) 
		{
			aRetElems.push(aElems[i]);
		}
			
	} 
	return aRetElems;
}

// Function to create page elements within a specified container element
function insertElement(oContainer,elementType, oAttributes)
{
    var newElement = document.createElement(elementType);
    
    for(att in oAttributes)
    {
        newElement.setAttribute(att,oAttributes[att]);
         //
        if(att == "style")
        {
			var aStyles = String(oAttributes[att]).split(";");
			var oStyle = newElement.getAttribute("style");
			for(i = 0; i < aStyles.length; i++)
			{
			
				var aParts = String(aStyles[i]).split(':');
				try
				{
					newElement.style.setAttribute(aParts[0],aParts[1],0);
					newElement.style[aParts[0]] = aParts[1];
				//	alert(aParts[0] + "  " + aParts[1]);
				} catch(e) {
				//	alert("ERROR " + aParts[0]);
				}
				
				//newElement.style.textOverflow = "hidden";
				//newElement.style.overflowX = "hidden";

			}
		//	showPagedObjectProperties(newElement.style)
			//alert(att + " = " + newElement.getAttribute(att).width);
        }
    }
    oContainer.appendChild(newElement);
   
    return newElement;
}

function clearInnerHTML(obj) {
	// so long as obj has children, remove them
	while(obj.firstChild) obj.removeChild(obj.firstChild);
	//Problematic
	/*
	// perform a shallow clone on obj
	nObj = obj.cloneNode(false);
	var tempID = obj.id;
	
	// insert the cloned object into the DOM before the original one
	obj.parentNode.insertBefore(nObj,obj);
	// remove the original object
	obj.parentNode.removeChild(obj);
	nObj.setAttribute("id",obj.id);
	*/

}



function toggleObjectClass(id,class1,class2)

{
	var oElem = getObject(id);
	if(oElem.className == class1)
	{
		oElem.className = class2
	}
	else
	{
		oElem.className = class1
	}
}



/*
GetElement - Get the object for a given element, required for cross-browser compatability

*/

function GetElement(objectId) {

  // checkW3C DOM, then MSIE 4, then NN 4.

  //

	if(document.getElementById && document.getElementById(objectId)) 
	{
		return document.getElementById(objectId);
	}
	else if (document.all && document.all(objectId)) 
	{  
		return document.all(objectId);
	} 
	else if (document.layers && document.layers[objectId]) 
	{ 
		return document.layers[objectId];
	} 
	else 
	{
		return false;
	}
}


function ShowElements(aElementIDs)
{
	if(!aElementIDs) return;
	for(var i = 0; i < aElementIDs.length; i++)
	{
		ChangeObjectVisibility(aElementIDs[i], "visible")
		ChangeObjectDisplay(aElementIDs[i], "block")
	}
}

function HideElements(aElementIDs)
{
	if(!aElementIDs) return;

	for(var i = 0; i < aElementIDs.length; i++)
	{
		ChangeObjectVisibility(aElementIDs[i], "hidden")
		ChangeObjectDisplay(aElementIDs[i], "none")
	}
}

function ChangeObjectVisibility(objectId, newVisibility) {
    // first get the object's stylesheet
    var styleObject = GetStyleObject(objectId);

    // then if we find a stylesheet, set its visibility
    // as requested
    //
    if (styleObject) {
		styleObject.visibility = newVisibility;
		return true;
    } 
    else 
    {
		return false;
    }

}

function ChangeObjectDisplay(objectId, newDisplay) {
    // first get the object's stylesheet
    var styleObject = GetStyleObject(objectId);

    if (styleObject) 
    {
		styleObject.display = newDisplay;
		return true;
    } 
    else 
    {
		return false;
    }
}

/*
GetStyleObject - Get the style object for a given element, required for cross-browser compatability
*/
function GetStyleObject(objectId) {
  // checkW3C DOM, then MSIE 4, then NN 4.
  //
	if(document.getElementById && document.getElementById(objectId)) 
	{
		return document.getElementById(objectId).style;
	}
	else if (document.all && document.all(objectId)) 
	{  
		return document.all(objectId).style;
	} 
	else if (document.layers && document.layers[objectId]) 
	{ 
		return document.layers[objectId];
	} 
	else 
	{
		return false;
	}
}
