//======================================================================================
// utility.js (should be inherited from "shared.ntf")
//   18-APR-2006 Mark Carson
//   02-JUN-2006 Mark Carson (added embedded cookie functions)
//   05-JUN-2006 Mark Carson (debugged embedded cookie functions)
//   14-JUL-2006 Mark Carson (added extractNumber function)
//   13-NOV-2006 Mark Carson (added and debugged embedded cookie functions)
//   01-AUG-2007 Mark Carson (fixed attribute with no value issue in paramReplace())
//   16-APR-2008 Mark Carson (added paramRemove and login functions)
//--------------------------------------------------------------------------------------
// 
// centerWindow()
// clearCookie(name, prompt)
// clearCookiesByPrefix(prefix, prompt)
// clearEmbeddedCookie(realCookie, virtualCookie, prompt) 
// clearEmbeddedCookiesByPrefix(realCookie, prefix, prompt)  
// embedCookie(realCookieName, virtualCookieName, virtualCookieValue) : returns nbr embedded cookies
// embeddedCookie(realCookie) : pops up a javascript alert with stats (diagnostic)
// extractCookie(realCookie, virtualCookie) : returns embedded value, blank string or null
// extractNumber(source) : return a number, default is 0
// getCookie(name)
// getCookiesByPrefix(prefixList) 
// getEmbeddedCookie(realCookie, showAlert) 
// getEventElement (event) 
// getEventX (event)
// getEventY (event) 
// getMSXMLVersion() 
// getParam(url, param)
// getParams(url, param)
// getWindowHeight()
// getWindowWidth()
// isIE()
// login() : uses Domino computed text
// paramRemove (url, attr)
// paramReplace (url, attr, value)
// picPopup(obj)
// popup (url, title, width, height)
// relativeURL (url)
// removeSuffix (str, suffix)
// setCookie(name, value)
// setChecked (id, value) 
// setSelected (id, value)
// showCookiesByPrefix(prefix)
// submitOnEnter(e)
// trim (source)
// urlGetServer (url)
// 
//--------------------------------------------------------------------------------------
 
function login() {
  var userName = "CN=Mark Carson/O=FSET";
  var url = document.location.href;
  if (userName == "") {
    url = paramRemove(url, "logout");
    url = paramReplace(url, "login", "");
  }
  else {
    url = paramRemove(url, "login");
    url = paramRemove(url, "logout");
    var qm = url.indexOf("?");
    if (qm >= 0)
      url = url.substring(0,qm) + "?logout&redirectto=" + url;
    else
      url += "?logout&redirectto=" + url;
  }
  //alert("login()\nurl=" + url);
  document.location.href = url;
}
//--------------------------------------------------------------------------------------
 
function setSelected (id, value) {
  //alert("setSelected('" + id + "','" + value + "');");
  var obj = document.getElementById(id);
  if (!obj || !obj.options) {
    //alert("setSelected('" + id + "','" + value + "')\nobject not found.");
    return;
  }		 
  for (var i = 0; i < obj.options.length; i++) {
    if (obj.options[i].value == value) {
		   obj.options[i].selected = true;
      //alert("setSelected('" + id + "','" + value + "');\nset item #" + i);
		   return;
		 }  
  }		 
  //alert("setSelected('" + id + "','" + value + "');\nNothing set");
}
//--------------------------------------------------------------------------------------
 
function setChecked (id, value) {
  //alert("setChecked('" + id + "','" + value + "');");
  var obj = document.getElementById(id);
  if (!obj) {
    //alert("setChecked('" + id + "','" + value + "')\nobject not found.");
    return;
  }		 
  if (obj.value && obj.value != '') {
    if (obj.value == value) 
      obj.checked = true;
    else
	  obj.checked = false;
  }  
  else {
    if (obj.innerHTML == value) 
      obj.checked = true;
    else
	  obj.checked = false;
  }		 
  return;
}
//--------------------------------------------------------------------------------------
 
function extractNumber(source) { // useful for getting pixel values from DOM style attrs
  var target = "";
  for (var i = 0; i < source.length; i++) {
     switch (source.charAt(i)) {
	   case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9':
	   case '-': case '.':
	     target += source.charAt(i);
		 break;
	 } // end switch
  } // end for
  var value = 0;
  if (target != "") {
    try { value =  new Number (target); }
	catch (err) { value = 0; }
  }
  return value;	
}	
 
//======================================================================================
// Embedded cookie sub-system
//   Requires: functions getCookie() and setCookie(); 
//   DOM and Embedded Cookie format (Backus-Naur Form):
//     <cookie> ::= <cookieName> "=" <embeddedCookie> ";"
//     <embeddedCookie> ::= <cookieName> ":" <cookieValue> | "," <embeddedCookie>

//     Example:
//       bullet=bulletOne:won/bulletTwo:too;animal=Aardvark:Artie/Bee:Beatrice/Cow:Clara;
//   Notes: Cookie names & value can not contain "=" or ";" characters
//          Embedded cookie names & value should not contain ":" or "," or "=" or ";" 
//          however these characters will be escaped and they will appear as hex values
//   Functions: 
//     embedCookie(realCookie, virtualCookie, value) : returns nbr embedded cookies
//     extractCookie(realCookie, virtualCookie) : returns embedded value, blank string or null
//     embeddedCookie(realCookie) : pops up a javascript alert with stats (diagnostic)
//
//--------------------------------------------------------------------------------------
 
var embeddedCookieSep  = ",";
var embeddedAttrValSep = ":";
 
//--------------------------------------------------------------------------------------
// embedCookie()
//   realCookie: actual browser cookie in which embedded cookied are stored
//   virtualCookie: name of embedded cookie
//   value: value to be associated with the virtualCookie name
//
//   If value is null, the embedded cookie name/value will be removed
//
//--------------------------------------------------------------------------------------
 
function embedCookie(realCookieName, virtualCookieName, virtualCookieValue) { // returns nbr embedded cookies
  
  //alert("embedCookie(" + realCookieName + ", " + virtualCookieName + ", " + virtualCookieValue + "')");
  virtualCookieName = escape(virtualCookieName);
  if (virtualCookieValue && virtualCookieValue != "")
    virtualCookieValue = escape(virtualCookieValue);
  
  var realCookie = getCookie(realCookieName);
  if (!realCookie) {
    if (virtualCookieValue) {
      var realCookieValue = virtualCookieName + embeddedAttrValSep + virtualCookieValue;
      //alert("No realCookie\nCalling setCookie() with realCookieValue:\n" + realCookieValue);
      setCookie(realCookieName, realCookieValue);
      //alert("embedCookie()\nAfter setCookie()\ngetCookie()=" + getCookie(realCookieName));
      return 1;
    }
    else {
      //alert("embedCookie()\nrealCookie is null and virtualCookieValue is null.\nReturning 0");
      return 0;
    }
  }
  /*
  if (!virtualCookieValue)
    alert("embedCookie()\nrealCookie=" + realCookie);
  */
  var embeddedCookies = realCookie.split(embeddedCookieSep);
  /*
  str = "embeddedCookies:\n";
  for (var i = 0; i < embeddedCookies.length; i++) 
    str += embeddedCookies[i] + "\n";
  alert(str);
  */
 
  var newCookie = "";
  if (virtualCookieValue)
    newCookie = virtualCookieName + embeddedAttrValSep + virtualCookieValue; // updated virtual cookie - head of list
  for (var i = 0; i < embeddedCookies.length; i++) {
    var attrValue = embeddedCookies[i].split(embeddedAttrValSep);
    //alert("realCookieName=" + realCookieName + "\n\nembeddedCookies[" + i + "]=" + embeddedCookies[i]);
    if (attrValue[0] != "" && attrValue[0] != virtualCookieName) {
      if (!virtualCookieValue)
        ; //alert("attrValue[0]=" + attrValue[0] + "\nvirtualCookieName=" + virtualCookieName);
      if (realCookie.length + newCookie.length + embeddedCookies[i].length < 4090) { // 4K max cookie size
        if (newCookie != "")
          newCookie += embeddedCookieSep + embeddedCookies[i];
        else
          newCookie = embeddedCookies[i];
        //alert("attrValue[0]=" + attrValue[0] + "\nnewCookie=" + newCookie);
      }
    }
    else {
      if (!virtualCookieValue)
        ; //alert("Skipping\nattrValue[0]=" + attrValue[0] + "\nvirtualCookieName=" + virtualCookieName + "\nnewCookie=" + newCookie);
    }
  }
  if (newCookie != "")
    setCookie(realCookieName, newCookie);
  else
    clearCookie(realCookieName, false);
  //alert("embedCokie()\nAfter setCookie()\ngetCookie()=" + getCookie(realCookie));
  return embeddedCookie.length;
}
//------------------------------------------------------------------------------
 
function extractCookie(realCookie, virtualCookie) { // returns embedded value
  virtualCookie = escape(virtualCookie);
  var cookie = getCookie(realCookie);
  if (!cookie) {
    //alert("extractCookie(" + realCookie + ", " + virtualCookie + ")\ngetCookie() returned null");
    return null;
  }
  if (cookie.indexOf(virtualCookie + embeddedAttrValSep) >= 0) { // exists
    var embeddedCookie = cookie.split(embeddedCookieSep);
    //var embeddedCookie = cookie.split(escape(embeddedCookieSep));
    for (var i = 0; i < embeddedCookie.length; i++) {
      var attrValue = embeddedCookie[i].split(embeddedAttrValSep);
      //alert("extractCookie(" + realCookie + ", " + virtualCookie + ")\nembeddedCookie.length=" + embeddedCookie.length + "\ni=" + i + "\nattrValue=" + attrValue);
      //var attrValue = embeddedCookie[i].split(escape(embeddedAttrValSep));
      if (attrValue[0] == virtualCookie) {
        if (attrValue[1])
          return unescape(attrValue[1]);
        else
          return "";
      }
    } // end for
  } // end if
  return null;
}
//------------------------------------------------------------------------------
 
function getEmbeddedCookie(realCookie, showAlert) { 
  var cookie = getCookie(realCookie);
  if (!cookie) {
    if (showAlert)
      alert("Cookie: " + realCookie + "\n\nDoes not exist."); 
    return "";
  }
  var embeddedCookie = cookie.split(embeddedCookieSep);
  var str = "";
  for (var i = 0 ; i < embeddedCookie.length; i++)
    str += "\n" + embeddedCookie[i];
  var result = "Browser Cookie: " + realCookie + "\nBrowser Cookie Size: " + cookie.length + "\nEmbedded Cookies: " + embeddedCookie.length + "\n" + str; 
  if (showAlert)
    alert(result);
  return result;
}
//------------------------------------------------------------------------------
 
function embeddedCookie(realCookie) { 
  getEmbeddedCookie(realCookie, true); 
}
//------------------------------------------------------------------------------
 
function clearEmbeddedCookie(realCookie, virtualCookie, prompt) { 
  if (prompt) {
    if (!confirm("Confirm you want to clear your '" + realCookie + " embedded browser cookie named '" + virtualCookie + "'."))
      return;
  }
  embedCookie(realCookie, virtualCookie, null);
}
//------------------------------------------------------------------------------
 
function clearEmbeddedCookiesByPrefix(realCookie, prefix, prompt) { 
  if (prompt) {
    if (!confirm("Confirm you want to clear your '" + realCookie + "' embedded browser cookies which begin with '" + prefix + "'."))
      return;
  }
  prefix = escape(prefix);
  var cookie = getCookie(realCookie);
  if (!cookie) {
    if (prompt)
      alert("Cookie: " + realCookie + "\n\nDoes not exist."); 
    return;
  }
  //alert("realCookie=" + realCookie + "\ncookie=" + cookie); 
  var embeddedCookie = cookie.split(embeddedCookieSep);
  var str = "";
  var aDelete = new Array();
  //alert("clearEmbeddedCookiesByPrefix('" + realCookie + ", '" + prefix + "', " + prompt + ")\nembeddedCookie.length=" + embeddedCookie.length);
  for (var i = 0 ; i < embeddedCookie.length; i++) {
    var attrValue = embeddedCookie[i].split(embeddedAttrValSep);
    //alert("clearEmbeddedCookiesByPrefix('" + realCookie + "', '" + prefix + "', " + prompt + ")\n[" + i + "]\nattrValue=" + attrValue + "\nattrValue[0]=" + attrValue[0] + "\nattrValue[1]=" + attrValue[1]);
    if (attrValue[0].substring(0,prefix.length) == prefix) {
      aDelete[aDelete.length] = unescape(attrValue[0]); // mark for deletion
    }
  }
  for (var i = 0; i < aDelete.length; i++) {
    clearEmbeddedCookie(realCookie, aDelete[i], false);
  }
}
//------------------------------------------------------------------------------
 
function clearCookiesByPrefix(prefix, prompt) { 
  if (isIE()) {
    alert("Cookie clearing is not supported in Internet Explorer.");
    return;
  }
  if (prompt) {
    if (!confirm("Confirm you want to clear your browser cookies which begin with '" + prefix + "'."))
      return;
  }
  //alert("clearCookiesByPrefix('" + prefix +")");
  var cookies;
  if (document.cookie.indexOf("&") >= 0)
    cookies = document.cookie.split("&");
  else
    cookies = document.cookie.split(";");
  //alert("document.cookie=" + document.cookie + "\n\ncookies.length=" + cookies.length);
  if (!cookies) {
    var attrValue = document.cookie.split("=");
    //alert("Sole cookie=" + document.cookie);
    if (trim(attrValue[0]).indexOf(prefix) == 0) {
      //alert("Clearing sole cookie: " + attrValue[0]);
      clearCookie(attrValue[0], false);
    }
    return;
  }
  var arrayPrefix = prefix.split(",");
  for (var i = 0 ; i < cookies.length; i++) {
   // alert("cookies[" + i + "]=" + cookies[i]);
    var attrValue = cookies[i].split("=");
    for (var p = 0 ; p < arrayPrefix.length; p++) {
      //alert("arrayPrefix[" + p + "]=" + arrayPrefix[p]);
      if (trim(attrValue[0]).indexOf(arrayPrefix[p]) == 0) {
        //alert("Clearing cookie: ]" + trim(attrValue[0]) + "[");
        clearCookie(trim(attrValue[0]), false);
      }
    }
  }
}
//--------------------------------------------------------------------------------------
 
function showCookiesByPrefix(prefix) { 
  var allCookies = "";
  var arrayPrefix = prefix.split(",");
  for (var i = 0 ; i < arrayPrefix.length; i++) {
    var theseCookies = getCookiesByPrefix(arrayPrefix[i]);
    //alert("showCookiesByPrefix('" + prefix + "')\narrayPrefix[" + i + "]=" + arrayPrefix[i] + "\n\ntheseCookies=" + theseCookies);
    if (theseCookies && theseCookies != "") {
      if (allCookies!= "")
        allCookies += ", ";
      allCookies += theseCookies;
    }
  }
  alert("Document Cookies:" + allCookies);
}
//--------------------------------------------------------------------------------------
 
function getCookiesByPrefix(prefixList) { 
  prefixes = prefixList.split(",");
  var result = "";
  var cookies = document.cookie.split(";");
  var skipped = "" ;
  for (var i = 0 ; i < cookies.length; i++) {
    var attrValue = cookies[i].split("=");
    var attr = trim(attrValue[0]);
    for (var p = 0 ; p < prefixes.length; p++) {
      var prefix = prefixes[p];
      if (attr.substring(0,prefix.length) == prefix) {
        //alert("getCookiesByPrefix('" + prefix + "')\nFound a match\nAppending:" + unescape(attrValue[1]));
        //result += cookies[i] + " [i=" + i + "][p=" + p + "]\n";
        result += cookies[i] + "\n";
      }
      else {
        //skipped += cookies[i] + " (attr.length=" + attr.length + ", prefix.length=" + prefix.length + ")\n";
      }
    }
  }
  /*
  if (skipped != "")
    alert("getCookiesByPrefix('" + prefix + "')\nSkipped:\n" + skipped);
  */
  return result;
}
//--------------------------------------------------------------------------------------
 
function getCookie(name) { 
  name = trim(name);
  var cookies = document.cookie.split(";");
  for (var i = 0 ; i < cookies.length; i++) {
    var attrValue = cookies[i].split("=");
    var attr = trim(attrValue[0]);
    if (attr == name) {
      //alert("getCookie('" + name + "')\nFound a match\nReturning:" + unescape(attrValue[1]));
      return unescape(attrValue[1]);
    }
    else {
      ; //alert("getCookie('" + name + "')\nSkipping [" + i + "]:\nattrValue[0]:" + attrValue[0] + "\nattrValue[1]:" + attrValue[1]);
    }
  }
  return "";
}
//--------------------------------------------------------------------------------------
 
function setCookie(name, value) { 
  //alert("setCookie('" + name + "', '" + value + "');");
  if (!name || name == "")
    return;
  var zero = 0;
  if (value == zero) 
    value = "0";
  var now = new Date();
  var expires = new Date(now.getTime() + (90 * 24 * 60 * 60 * 1000)); // expires in 90 days
  if (value != null && value != "")
    document.cookie = name + "=" + escape(value) + "; expires=" + expires.toGMTString() + " path=/";
}
//--------------------------------------------------------------------------------------
 
function clearCookie(name, prompt) { 
  if (prompt) {
    if (!confirm("Confirm you want to clear browser cookies named '" + prefix + "'."))
      return;
  }
  var cookieDate = new Date();
  cookieDate.setTime (cookieDate.getTime() - 1);
  document.cookie = name += "=; expires=" + cookieDate.toGMTString();
  /*
  var newCookie = "";
  var cookies = document.cookie.split(";");
  for (var i = 0; i < cookies.length; i++) {
    attrValue = cookies[i].split("=");
    if (attrValue[0] != name) {
      if (newCookie != "")
        newCookie += ";"
      newCookie += cookies[i];
    }
  }
  alert("clearCookie(" + name + ", " + prompt + ")\document.cookie=" + document.cookie + "\n\nnewCookie=" + newCookie);
  document.cookie = newCookie;
  */
}
//--------------------------------------------------------------------------------------
 
 
//======================================================================================
 
function submitOnEnter(e) {  // Submits the first form ([0]) on Enter/Return keypress.
                             // e is event object passed from function invocation.
  var characterCode;
  if (e && e.which)            // Netscape 4 test
    characterCode = e.which;   // character code is contained in NN4's which property
  else 
    characterCode = e.keyCode; //character code is contained in IE's keyCode property
  switch (characterCode) {
    case 13: //if generated character code is equal to ascii 13 (Carriage Return key)
      if (submitChecks(document.forms[0])) 
        document.forms[0].submit(); //submit the first form
      return false;
    default:
      return true;
  }
} 
//--------------------------------------------------------------------------------------
 
function urlGetServer (url) {
  var server;
  var idx = url.indexOf("://");
  if (idx >= 0)  // protocol (such as "http://" or "https://") detected, server name implied
    server = url.substring(idx + 3);
  else
    server = url;
  idx = server.indexOf("/");
  if (idx == 0)
    return "";
  if (idx > 0)
    server = server.substring (0,idx);
  return server;
}
//--------------------------------------------------------------------------------------
 
function relativeURL (url) {
  var urlServer = urlGetServer(url);
  if (urlServer == "") 
    return url;
  var docServer = urlGetServer(document.location.href);
  var relURL = url;
  if (docServer.toUpperCase() == urlServer.toUpperCase()) 
    relURL = url.substring(url.indexOf(urlServer) + urlServer.length);
  /*
  alert("relativeURL()\nurl=" + url + 
       "\ndocument.location.href=" + document.location.href + 
       "\nurlServer=" + urlServer + 
       "\ndocServer=" + docServer +
       "\nrelURL=" + relURL);
  */
  return relURL;
}
//--------------------------------------------------------------------------------------
// paramReplace()  Replaces existing query string attribute's value with a specified
//                 value, or adds the attribute/value to the query string if the 
//                 attribute is not part of the existing query string.
//   Inputs: url - typically document.location.href
//           attr - attribute name
//           value - replacement value
//   Return: string (url with replaced/appended new query string value)
//--------------------------------------------------------------------------------------
 
function paramReplace (url, attr, value) {
  //alert("paramReplace()\nurl=" + url + "\nattr=" + attr + "\nvalue=" + value);
  var qm = url.indexOf("?");                //document.location.href.indexOf("?");
  var eq;
  if (qm >= 0) {
    queryString = url.substring(qm + 1);    //document.location.href.substring(qm + 1);
    resource = url.substring(0, qm);        //document.location.href.substring(0, qm);
  }
  else {
    queryString = "";
    resource = document.location.href;
  }
  //alert("paramReplace(" + attr + ", " + value + ") - Before\n\nresource = " + resource + "\n\nqueryString = " + queryString);
 
  var newQueryString = "";
  var replaced = false;
  var paramArray = queryString.split("&");
  var attrArray  = new Array();
  var valueArray = new Array();
 
  //--- Parsing pass ---
  for (var i = 0 ; i < paramArray.length; i++) {
    eq = paramArray[i].indexOf("=");
    if (eq > 0) {
      attrArray[i]  = paramArray[i].substring(0,eq);
      valueArray[i] = paramArray[i].substring(eq + 1);
    }
    else {
      attrArray[i]  = paramArray[i];
      valueArray[i] = "";
    }
  }
 
  //--- Rebuilding pass ---
  var qmAmp;
  var replaced = false;
  for (var i = 0 ; i < paramArray.length; i++) {
    if (i == 0)
      qmAmp = "?";
    else
      qmAmp = "&";
    if (attrArray[i].toLowerCase() == attr.toLowerCase()) {
      newQueryString += qmAmp + attr;
      if (value && value != "")
        newQueryString += "=" + value;
      else
        newQueryString += "=";
      replaced = true;
    }
    else {
      newQueryString += qmAmp + attrArray[i];
      if (valueArray[i] != "")
        newQueryString += "=" + valueArray[i];
      else
        newQueryString += "=";
    }
  }
    
  if (!replaced) {
    if (newQueryString == "" || newQueryString == "?")
      newQueryString = "?" + attr;
    else
      newQueryString += "&" + attr;
    if (value && value != "")
      newQueryString += "=" + value;
  }
  var returnValue = resource + newQueryString;
  //alert("paramReplace()\nreturnValue=" + returnValue);
  return returnValue;
}
//--------------------------------------------------------------------------------------
// paramRemove()  Removes existing query string attribute and it's value
//   Inputs: source - typically document.location.href
//           attr - attribute name
//   Return: string (url with removed attribute and it's value)
//--------------------------------------------------------------------------------------
 
function paramRemove(url, attr) {
  //alert("paramRemove()\nurl=" + url + "\nattr=" + attr);
  var qm = url.indexOf("?");                //document.location.href.indexOf("?");
  var eq;
  if (qm >= 0) {
    queryString = url.substring(qm + 1);    //document.location.href.substring(qm + 1);
    resource = url.substring(0, qm);        //document.location.href.substring(0, qm);
  }
  else {
    queryString = "";
    resource = document.location.href;
  }
  //alert("paramReplace(" + attr + ", " + value + ") - Before\n\nresource = " + resource + "\n\nqueryString = " + queryString);
 
  var newQueryString = "";
  var removed = false;
  var paramArray = queryString.split("&");
  var attrArray  = new Array();
  var valueArray = new Array();
 
  //--- Parsing pass ---
  for (var i = 0 ; i < paramArray.length; i++) {
    eq = paramArray[i].indexOf("=");
    if (eq > 0) {
      attrArray[i]  = paramArray[i].substring(0,eq);
      valueArray[i] = paramArray[i].substring(eq + 1);
    }
    else {
      attrArray[i]  = paramArray[i];
      valueArray[i] = "";
    }
  }
 
  //--- Rebuilding pass ---
  var qmAmp;
  var removed = false;
  for (var i = 0 ; i < paramArray.length; i++) {
    if (i == 0)
      qmAmp = "?";
    else
      qmAmp = "&";
    if (attrArray[i].toLowerCase() != attr.toLowerCase()) {
      newQueryString += qmAmp + attrArray[i];
      if (valueArray[i] != "")
        newQueryString += "=" + valueArray[i];
      else
        newQueryString += "=";
    }
  }
    
  var returnValue = resource + newQueryString;
  //alert("paramRemove()\nreturnValue=" + returnValue);
  return returnValue;
}
//-----------------------------------------------------------------------------
 
function trim (source) {
  if (!source || source == "")
    return source;
  var target = "";
  var first = -1 ;
  var last  = -1;
  for (var i = 0; i < source.length; i++) {
    switch (source.charCodeAt(i)) {
      case   7: // Tab
      case  10: // Line Feed
      case  13: // Carriage Return
      case  32: // Space
        break;
      default:
        if (first < 0)
          first = i;
        last = i;
    }
  }
  if (first >= 0)
    target = source.substring(first, last + 1);
  //alert("trim(" + source + ")\nfirst=" + first + "\nlast=" + last + "\nsource.length=" + source.length + "\ntarget=[" + target + "]\ntarget.length=" + target.length);
  return target;
}
//-----------------------------------------------------------------------------
 
function removeSuffix (str, suffix) {
  var pos = str.lastIndexOf(suffix);
  if (pos < 0)
    return str;
  else
    return str.substring(0,pos);
}
//-----------------------------------------------------------------------------
 
function getWindowWidth() {
  if (parseInt(navigator.appVersion) > 3) {
    if (navigator.appName=="Netscape") 
      return window.innerWidth;
  }
  if (navigator.appName.indexOf("Microsoft")!= -1) {
    return document.body.offsetWidth;
  }
}
//-----------------------------------------------------------------------------
 
function getWindowHeight() {
  if (parseInt(navigator.appVersion) > 3) {
    if (navigator.appName=="Netscape") 
      return window.innerHeight;
  }
  if (navigator.appName.indexOf("Microsoft")!= -1) {
    return document.body.offsetHeight;
  }
}
//--------------------------------------------------------------------------------------
// getParam(url, param) 
//   Generic attribute/value query string decoder
//   Returns a string value of the first/only named attribute
//--------------------------------------------------------------------------------------
 
function getParam(url, param) { //--- Generic attribute/value query string decoder
  urlArray = url.split("?")
  if (urlArray.length > 1) {
    var queryString = urlArray[1]; 
    var qsArray = queryString.split("&");
    for (var i = 0 ; i < qsArray.length; i++) {
      attrValue = qsArray[i];
      avArray = attrValue.split("=");
      if (avArray[0].toLowerCase() == param.toLowerCase()) {       
        return avArray[1];
      }  
    }
  }
  return "";
}  
//--------------------------------------------------------------------------------------
// getParams(url, param)
//   Multiple attribute/value query string decoder
//   Returns an array of values of the named attribute
//   Eaxmple "fubar?snafu=big&snafu=total" would return an array of 2 values for "snafu"
//--------------------------------------------------------------------------------------
 
function getParams(url, param) { 
  var valueArray = new Array();
  urlArray = url.split("?")
  if (urlArray.length > 1) {
    var queryString = urlArray[1]; 
    var qsArray = queryString.split("&");
    for (var i = 0 ; i < qsArray.length; i++) {
      attrValue = qsArray[i];
      avArray = attrValue.split("=");
      if (avArray[0].toLowerCase() == param.toLowerCase()) {       
        valueArray[valueArray.length] = avArray[1];
      }  
    }
  }
  return valueArray;
}  
//-----------------------------------------------------------------------------
 
function getEventX (event) {
  if (isIE()) {
    if (window.event)
      return window.event.x;
  }
  else {
    if (event)
      return event.clientX;
  }
  return null;
}     
//-----------------------------------------------------------------------------
 
function getEventY (event) {
  if (isIE()) {
    if (window.event)
      return window.event.y;
  }
  else {
    if (event)
      return event.clientY;
  }
  return null;
}     
//-----------------------------------------------------------------------------
 
function getEventElement (event) {
  if (isIE()) {
    if (window.event)
      return window.event.srcElement;
  }
  else {
    if (event && event.target)
      return (event.target.tagName ? event.target : event.target.parentNode);
  }
  return null;
}     
//------------------------------------------------------------------------------
 
var _browser = null;
 
function isIE() {
  if (!_browser) {
    if (document.all)
      _browser = "IE";
    else
      _browser = "W3C";
  }      
  if (_browser == "IE")
    return true;
  else
    return false;
}        
//-----------------------------------------------------------------------------
 
function centerWindow() {
  var left = (screen.width - getWindowWidth()) / 2;
  if (left < 0)
    left = 0;
  var top  = (screen.height - getWindowHeight()) / 2;
  if (top < 0)
    top = 0;
  window.moveTo(left, top);
}
//-----------------------------------------------------------------------------

function popup (url, windowName, width, height) {
  var left = (screen.width - width) / 2;
  var top  = (screen.height - height) / 2;
  var win = window.open(url, windowName, "height=" + height + ", width=" + width + ", top=" + top + ", left=" + left + ", resizeable=yes, scrollbars=yes");
  win.focus();
  return false;
}
//-----------------------------------------------------------------------------

function picPopup(url) {
  var prefix = "http://";
  //alert("picPopup()\nurl=" + url) ;
  if (url.toLowerCase().indexOf(prefix) != 0)
    url = "../Images/Gallery/" + url;
  //alert("picPopup()\Now nurl=" + url) ;
  var width  = 300;
  var height = 400;
  return popup (url, "popup", width, height);;
}
//-----------------------------------------------------------------------------
 
function getMSXMLVersion() {
  var msxml = null;
  if (!isIE())
    return -1;
  try {
    msxml = new ActiveXObject("MSXML2.DOMDocument.4.0");
    return 4.0;
  }
  catch(msxmlError) {
    try {
      msxml = new ActiveXObject("MSXML2.DOMDocument.3.0");
      return 3.0;
    }
    catch(msxmlError) {
      try {
        msxml = new ActiveXObject("MSXML2.DOMDocument.2.6");
        return 2.6;
      }
      catch(msxmlError) {
        try {
          msxml = new ActiveXObject("MSXML2.DOMDocument.2.5");
          return 2.5;
        }
        catch(msxmlError) {
          try {
            msxml = new ActiveXObject("MSXML2.DOMDocument");
            return 2.0;
          }
          catch(msxmlError) {
            return 0.0;
          } // catch 2.0
        } // catch 2.5
      } // catch 2.6
    } // catch 3.0
  } // catch 4.0
  return -1;
}
//-----------------------------------------------------------------------------
 

