/***********************************************
* Browser utilities © Tim Reed (unless otherwise noted)
* This notice must stay intact for use
* Visit http://www.i4synthesis.com for contact info
***********************************************/

function closeWindow() {
  if((parent.opener==null) || parent.opener.closed) {
    parent.close();
  } else {
    parent.close();
    parent.opener.focus();
  }
}

/**
 * refactored the popWindow call in debugOutput() to allow usage elsewhere
**/
function popWinSimple(urlStr,winName) {
  if (null == urlStr) return;
  if (null == winName) winName = "";
  var tmpURL = debugOutputBuildURL(urlStr);
  var userName = "";
  try {
    userName = top.header_frame.UserName;
  } catch (e) {}
  popWindow(tmpURL,600,900,'ALLON',userName + winName);
}

/**
 * popWindow(string popURL, integer popWidth, integer popHeight, string parameters)
 * opens new windows with given URL, width, and height.
 * Scrollbars and menu on, everything else turned off.
**/
function popWindow(popURL, popWidth, popHeight, parameters, winName, returnWindow) {
  if (!popWidth) popWidth=600;
  if (!popHeight) popHeight=400;
  if (!winName) winName = "HUB_popWindow";
  if (!parameters) {
    parameters="";
  } else {
    if (parameters.toUpperCase() == "ALLON") {
      parameters = "toolbar,location,directories,status,menubar,scrollbars,resizable,";
    } else {
      var pArray = parameters.split(",");
      var pLen = pArray.length;
      var pTmp = "";
      for (var i = 0; i < pLen; i++) {
        pTmp+=(pArray[i]) ? pArray[i]+"," : "" ; // concat clean comma sep list of options
      }
      parameters=pTmp;
    }
  }
  var winLeft = (screen.availWidth - popWidth) / 2;
  var winTop = (screen.availHeight - popHeight) / 2;
  theWindow = window.open(popURL, winName, parameters + "width=" + popWidth + ",height=" + popHeight + ",left=" + winLeft + ",top=" + winTop);
  if (null != theWindow) { setTimeout("theWindow.focus();",10); }
  if (returnWindow) return theWindow;
}

/**
 * openModalDialog(string popURL, integer popWidth, integer popHeight, var sArguments)
 * Function:
 *  opens a modal dialog box (Win IE only) using passed URL (popURL)
 *  sizes and positions accordingly
 *  removes all unnecessary window widgets
 *  passes arguments to the dialog box
 *
 * @param popURL      - URL to load in dialog box
 * @param popWidth    - width in pixels of dialog box
 * @param popHeight   - height in pixes of dialog box
 * @parem sArguments  - values to pass to modal dialog. Can be ANY type (object,array,string,int,boolean,etc)
**/
  function openModalDialog(popURL,popWidth,popHeight,sArguments) {
    var bInfo = checkBrowser();
    var winLeft = bInfo.xPos + (bInfo.width-popWidth)/2; // set position for left of dialog box
    var winTop = bInfo.yPos + (bInfo.height-popHeight)/2; // set position for top of dialog box
    var dlgParams="dialogHeight: "+popHeight+"px; dialogWidth: "+popWidth+"px; dialogTop: "+winTop+"px; dialogLeft: "+winLeft+"px; edge: Raised; center: no; help: no; resizable: no; status: no; scroll: no;";
    var oResults=window.showModalDialog(popURL,sArguments,dlgParams); // call dialog function in stpmui-control.js
    return oResults;
}

/**
 * this method will open a window and write the contents you specify
 * this permits viewing of dynamically generated code that you can't see by
 * viewing source
 *
 * @param winName  -- use this if you want to specify a window name (permits multiple simultaneous outputs)
 * @param tmpStr   -- this is the string you want to output
 * @param mimeType -- self-explanatory. Used to tell browser how to handle document.
**/
function writeDataWindow(winName,tmpStr,mimeType) {
  if (!tmpStr) tmpStr = document.body.innerHTML;
  if (!winName) winName = "dataWindowPopUp";
  if (!mimeType) mimeType = "text/plain";
  var popWidth=720;
  var popHeight=400;
  var winLeft = (screen.availWidth - popWidth) / 2;
  var winTop = (screen.availHeight - popHeight) / 2;
  //parameters = "toolbar,location,directories,status,menubar,scrollbars,resizable,";
  parameters = "resizable,scrollbars,menubar,";
  dataWindow = window.open('', winName, parameters + "width=" + popWidth + ",height=" + popHeight + "left=" + winLeft + ",top=" + winTop);
  if (null != dataWindow) {
    dataWindow.document.open(mimeType);
    dataWindow.document.write(tmpStr);
    dataWindow.document.close();
    dataWindow.focus();
  }
  return dataWindow;
}

/**
 * check browser type & version
 *
 * creates object with these properties:
 *   bInfo.isValid  - boolean value indicating passes requirements
 *   bInfo.type   - browser type
 *   bInfo.ver    - version
 *   bInfo.xPos   - left position of window
 *   bInfo.yPos   - top position of window
 *   bInfo.width  - width of top-most window object
 *   bInfo.height - height of top-most window object
 *   bInfo.xCenter  - center of browser x coord
 *   bInfo.yCenter  - center of browser y coord
**/
// modified original non-attributed code (don't have source URL)
function checkBrowser() {
  var bType = navigator.appName;
  var bVer= parseInt(navigator.appVersion);
  var bInfo = new Object();
  //  bInfo.isValid = false;
  bInfo.type = bType;
  bInfo.ver = bVer;
  bInfo.xPos = 0;
  bInfo.yPos = 0;
  //record basic browser/screen data
  if ((bType.indexOf("Netscape")>=0) && (bVer >= 4)) {
    //    bInfo.isValid = true;
    bInfo.type = "NS";
    bInfo.xPos = (window.top == window.self) ? window.top.screenX : window.self.screenX;
    bInfo.yPos = (window.top == window.self) ? window.top.screenY : window.self.screenY;
    bInfo.docWidth = document.width;
    bInfo.docHeight = document.height;
  }
  if ((bType.indexOf("Explorer")>=0) && (bVer >= 4)) {
    //    bInfo.isValid = true;
    bInfo.type = "IE";
    bInfo.xPos = (window.top == window.self) ? window.top.screenLeft : window.self.screenLeft;
    bInfo.yPos = (window.top == window.self) ? window.top.screenLeft : window.self.screenLeft;
    bInfo.docWidth = document.body.scrollWidth;
    bInfo.docHeight = document.body.scrollHeight;
  }
  // record browser window width
  if (typeof( window.innerWidth ) == 'number' ) {
    //Non-IE
    bInfo.width = (window.top == window.self) ? window.top.innerWidth : window.self.innerWidth;
    bInfo.height = (window.top == window.self) ? window.top.innerHeight : window.self.innerHeight;
  } else {
    if (document.documentElement && (document.documentElement.clientWidth || document.documentElement.clientHeight ) ) {
      //IE 6+ in 'standards compliant mode'
      bInfo.width = (window.top == window.self) ? window.top.document.documentElement.clientWidth : window.self.document.documentElement.clientWidth;
      bInfo.height = (window.top == window.self) ? window.top.document.documentElement.clientHeight : window.self.document.documentElement.clientHeight;
    } else {
      if( document.body && ( document.body.clientWidth || document.body.clientHeight ) ) {
        //IE 4 compatible
        bInfo.width = (window.top == window.self) ? window.top.document.body.clientWidth : window.self.document.body.clientWidth;
        bInfo.height = (window.top == window.self) ? window.top.document.body.clientHeight : window.self.document.body.clientHeight;
      }
    }
  }
  bInfo.xCenter = Math.round(bInfo.xPos + bInfo.width/2);
  bInfo.yCenter = Math.round(bInfo.yPos + bInfo.height/2);
  return bInfo;
}

/* :::::::::::::::::::::::::: fun browser moving code ::::::::::::::::::::::: */
function moveLeft(x) {
  if (null==x) x=-10;
  window.moveBy(x,0);
}
function moveRight(x) {
  if (null==x) x=10;
  window.moveBy(x,0);
}
function moveUp(y) {
  if (null==y) y=-10;
  window.moveBy(0,y);
}
function moveDown(y) {
  if (null==y) y=10;
  window.moveBy(0,y);
}

var maxJigs  = 30;
var jigCount = 0;
var speed    = 15;
var xAmplitude = 10;
var yAmplitude = 10;
function jigger(motion,vector,cnt,max,speed,xAmp,yAmp) {
  if (null==max) max = maxJigs;
  if (null==cnt) cnt = jigCount;
  if (null==speed) speed = 10;
  if (null==xAmp) xAmp = xAmplitude;
  if (null==yAmp) yAmp = yAmplitude;
  jigCount = cnt;
  maxJigs = max;
  if (cnt < max) {
    switch (vector) {
      case "up":
        moveUp();
        if ("y"==motion) {
          vector = "down";
        } else {
          vector = "right";
        }
        break;
      case "down":
        moveDown();
        if ("y"==motion) {
          vector = "up";
        } else {
          vector = "left";
        }
        break;
      case "left":
        moveLeft();
        if ("x"==motion) {
          vector = "right";
        } else {
          vector = "up";
        }
        break;
      case "right":
        moveRight();
        if ("x"==motion) {
          vector = "left";
        } else {
          vector = "down";
        }
        break;
      default:
        return;
    }
    jigCount++;
    setTimeout("jigger('"+motion+"','"+vector+"',"+jigCount+")",speed);
  }
}

/**
 * returns an object with these properties
 *   obj.string = full query
 *   obj.array = array with name/value pairs as sub arrays
 *   obj.labels = array of names
 *   obj.values = associative array of values indexed by the names (eg. obj.values['userid'])
**/
function getQueryString(URLStr) {
  try { if (LOG.showTrace()) LOG.trace("getQueryString("+URLStr+")"); } catch (e) {}
  //pattern = new RegExp("\?(.*)","gi");
  var pattern = new RegExp("\\?(.*)","gi");
  var qStr = new Object();
  qStr.string = (URLStr) ? (pattern.exec(URLStr) ? RegExp.$1 : "") : (pattern.exec(String(document.location)) ? RegExp.$1 : "");
  qStr.values = new Array();
  qStr.labels = new Array();
  qStr.array  = new Array();
  if (qStr.string) {
    var x = qStr.string.split("&");
    var xLen = x.length;
    for (var i=0; i < xLen; i++) {
      if (x[i].indexOf("=") != -1) {
        //do this if value & label are passed
      y = x[i].split("=");
      qStr.array[i] = [y[0],y[1]]; // array of names and values
      try { if (LOG.showTrace()) LOG.trace("qStr.array["+i+"]="+qStr.array[i]); } catch (e) {}
      qStr.values[eval('\'' + decodeURIComponent(y[0]) + '\'')] = decodeURIComponent(y[1]); // permit referring to query string by parameter name
      qStr.labels[i] = decodeURIComponent(y[0]); // list of query string parameters
      } else {
        //do this if just a value is passed
        qStr.array[i] = [x[i],x[i]]; // array of names and values
        qStr.values[eval('\'' + decodeURIComponent(x[i]) + '\'')] = decodeURIComponent(x[i]); // permit referring to query string by parameter name
        qStr.labels[i] = decodeURIComponent(x[i]); // list of query string parameters
      }
    }
  }
  return qStr;
}

/**
 * parse URL string to locate named anchor (starts with #) in URL
 * returns a string
 * parameters:
 *    url = optional, string URL
**/
function getAnchor(url) {
  // collect data on the document URL
  if (null==url) url = document.location.href;
  var anchorStr = "";
  var anchorLoc = url.indexOf("#");

  // if url contains an anchor reference, extract the anchor tag
  if (anchorLoc+1) {
    anchorStr = url.substring(anchorLoc+1,url.length);
    // locate the / or ? that denote a possible query string and grab the string before that char
    if (anchorStr.search(/[\/\?]/)+1) anchorStr = anchorStr.substring(0,anchorStr.search(/[\/\?]/));
  }
  return anchorStr;
}


/**
 * parse object and traverse internal objects
 * return object structure data as a string
 * parameters:
 *    obj          = required, object to parse
 *    parentObjStr = optional, string name of object to be parsed (for clarity in output)
 *    max          = optional, max depth to traverse
 *    cnt          = optional, current depth of traversal
 *    spacer       = optional, used in output (to create hierarchical structure) if desired
**/
function parseObject(obj, parentObjStr, max, cnt, spacer) {
  if (null == parentObjStr) { parentObjStr = ""; }
  if (null == cnt) { cnt = 1; } // depth to traverse an object
  if (null == max) { max = 10; } // depth to traverse an object
  if (cnt > max) {
    return spacer + parentObjStr + " *** MAX DEPTH REACHED ["+max+"] ***\n";
  }
  if (null == spacer) { spacer = ""; }
  if ("" == parentObjStr) { spacer += "  "; }
  if (parentObjStr.substring(parentObjStr.length-1,parentObjStr.length) != ".") { parentObjStr += "."; }
  if (parentObjStr.substring(0,1) == ".") { parentObjStr = parentObjStr.substring(1,parentObjStr.length); }
  var str = "";
  var isIE = (window.showModalDialog) ? true : false;
  if (isIE) {
    // tuned for IE, if IE DOM object is passed, traversing the parentElement object creates a meaningless loop
    for (prop in obj) {
      str += spacer + parentObjStr + prop + " = "
          + (((typeof obj[prop] == "object") && ("parentElement" != prop))
               ? ((null != obj[prop])
                  ? "[object]\n" + parseObject(obj[prop],parentObjStr+prop+".",max,cnt+1,spacer)
                  : "null\n")
               : obj[prop] + "\n"
            );
    }
    //str += "-- level " + cnt + " --\n";
  } else {
    // tuned for Mozilla, if Mozilla DOM object is passed, traversing the
    // parentNode and previousSibling objects creates a meaningless loop
    for (prop in obj) {
      try {
        str += spacer + parentObjStr + prop + " = "
            + (((typeof obj[prop] == "object") && ("parentNode" != prop) && ("previousSibling" != prop))
                 ? ((null != obj[prop])
                    ? "[object]\n" + parseObject(obj[prop],parentObjStr+prop+".",max,cnt+1,spacer)
                    : "null\n")
                 : obj[prop] + "\n"
              );
      } catch (e) {
        str += parseObject(e,parentObjStr+prop+".ERROR.",max,cnt+1,spacer);
      }
    }
  }
  return str;
}

// render properties of error object
function parseError(e) {
  str="ERROR:\n";
  return str+=parseObject(e,'e');
}

