/** 
 * This class holds code for cross-platform compatibility that would otherwise
 * bulk up the rest of the logic.  It is a static class.
 */
function CrossPlatformCode() {
  if ((navigator.appVersion.indexOf("Mac")!=-1) 
      && (navigator.userAgent.indexOf("MSIE")!=-1) 
      && (parseInt(navigator.appVersion)==3)) {
    CrossPlatformCode.booIsIE3Mac = true;
  } else {
    CrossPlatformCode.booIsIE3Mac = false;
    CrossPlatformCode.objIs = new Is(); 
  }
}

// Properties:
CrossPlatformCode.objIs = null;
CrossPlatformCode.booIsIE3Mac = false;
// Methods:
CrossPlatformCode.getBorderAdjustment       = CrossPlatformCode_getBorderAdjustment;
CrossPlatformCode.getFancyDivHtml           = CrossPlatformCode_getFancyDivHtml;
CrossPlatformCode.getFillerMarkup           = CrossPlatformCode_getFillerMarkup;
CrossPlatformCode.writeToDiv                = CrossPlatformCode_writeToDiv;
CrossPlatformCode.getReferenceToDocProperty = CrossPlatformCode_getReferenceToDocProperty;   
CrossPlatformCode.getPlatform               = CrossPlatformCode_getPlatform;
CrossPlatformCode.canGetStackTrace          = CrossPlatformCode_canGetStackTrace; 
CrossPlatformCode.getListSupportedPlatforms = CrossPlatformCode_getListSupportedPlatforms;
CrossPlatformCode.getPlatformBugAdvisory    = CrossPlatformCode_getPlatformBugAdvisory;
CrossPlatformCode.getHatchAndLabelHtml      = CrossPlatformCode_getHatchAndLabelHtml;

/**
 * This method compensates for the incorrect handling of border attributes on some browsers.
 */
function CrossPlatformCode_getBorderAdjustment() { 
  var objIs = CrossPlatformCode.objIs;
  if (objIs.gecko || objIs.nav6 || objIs.opera || objIs.ie5_5 || objIs.ie6) {
    return 0; // CSS border widths are handled correctly.
  } else if (objIs.ie5) { // Descend into dealing with errors in implementing the CSS spec:
    return ( (ContainerDiv.BORDER_WIDTH*2) ); 
  }
} 


/** 
 * This method compensates for IE5.0's intermittant (not always present, but definitely sometimes 
 * present) problems with having the height and width of a 
 * div in an inline style declaration.  The factors in the intermittancy are unknown to the author.  
 * @param intHeight  An integer specifying the height of the div.
 * @param intWidth   An integer specifying the width of the div. 
 * @return string    A string that returns the height and/or width in either the style attribute format
 *                   or the html attribute format, and always along with the beginning of the style 
 *                   string.  
 */
function CrossPlatformCode_getFancyDivHtml(intHeight, intWidth) {
    var objIs = CrossPlatformCode.objIs;
    if (objIs.ie5) {
      return ("  height='"+intHeight+"px'  width='"+intWidth+"px'  style=' ");
    } else {
      return ("  style=' height: "+intHeight+"px;  width: "+intWidth+"px; ");
    }
}


/**
 * This method handles the different ways of putting content into a div.
 * @param divPlotContainer  The div container to be written to.
 * @param strContens  The HTML markup to put inside the div.
 */
function CrossPlatformCode_writeToDiv(divPlotContainer, strContents) { 
    var objIs = CrossPlatformCode.objIs;
    if (objIs.nav4 || (objIs.nav4up && !objIs.nav6 && !objIs.gecko) || objIs.ie4) {
      divPlotContainer.document.open();
      divPlotContainer.document.write(strContents);
      divPlotContainer.document.close();
    } else {
      divPlotContainer.innerHTML = strContents;
    }
}          

/**
 * This method supports two basic ways of getting a reference to a document 
 * property in a frame: by a) the whole chain i.d. starting after the frame document,
 * and by b) getting the reference from just the target i.d., starting from the frame document. 
 * @param frmFram  A reference to the frame.
 * @param strId  The i.d. of the target item, with the dot-separated reference chain up to the 
 *               frame-level if needed.
 * @return A reference to the object named by 'strId', or null;
 */
function CrossPlatformCode_getReferenceToDocProperty(frmFrame, strId, booForceDirectIdent) { 
  var objIs = CrossPlatformCode.objIs;
  if (objIs.ie4) {
    alert("bug");
  }
  if (booForceDirectIdent || objIs.ie4 || objIs.nav4 || (objIs.nav4up && !objIs.nav6 && !objIs.gecko)) { 
    alert("shockabrah: "+strId);
    // Use direct identification.
    if (typeof frmFrame.name != "string") {
      frmFrame.name = frmFrame.id;
    } 
    return eval("window.top."+frmFrame.name+".document."+strId);  // We must use the .name property for Nav4.x (instead of id).
  } else { // Use getElementById
    rxpMoreThanOneId = new RegExp("\.[^.]*$", "g");
    var arrResults = strId.match(rxpMoreThanOneId);
    if (arrResults != null) { // Have more than one i.d.; extract just the last one:
      strId = arrResults[0].replace("\.", "");
    }
    return frmFrame.document.getElementById(strId);
  }
}   

/**
 * This method returns the browser and operating system currently running.
 */
function CrossPlatformCode_getPlatform() {
   return navigator.userAgent;
}


/**
 *  This method tells whether or not the version of JavaScript 
 *  supported can execute the stack trace code in GloScope.StackTrace.  
 *  The current code that produces a stack trace relies on arguments.caller, 
 *  which is not supported in JS 1.5.  In JS 1.5, stack tracing is done 
 *  in interpretive mode through a debugger only, for performance reasons.
 */
function CrossPlatformCode_canGetStackTrace() {
  if (CrossPlatformCode.objIs.js > 1.4) {
    return false;
  } else {
    return true;
  }
}


/** 
 * This method provides optimized markup for accomplishing the rendering of 
 * div's on the screen that do not wrap anything but blank space.
 * The less markup needed, the better, because this filler code is used
 * to render single pixels.
 * @param intHeight  The height of the enclosing div.
 * @param intWidth   The width of the enclosing div.
 * @param strContents  OPTIONAL  The contents of the table.
 */ 
function CrossPlatformCode_getFillerMarkup(intHeight, intWidth, strContents) {
  if (!strContents) {
    strContents = "";
  }
  if (CrossPlatformCode.objIs.ie5up) { // IE5.5 might not need this.
    return (
            "     <table height='"+intHeight+"px'  width='"+intWidth+"px'  border='0px' "
            +          " cellpadding='Opx'  cellspacing='Opx'><tr border='0px'><td border='Opx'>"
            +  "     </td></tr></table>"
            +  strContents
            );
  } else {
    return ("<div height='"+intHeight+"px'  width='"+intWidth+"px'></div>");
  }
}


/**
 * This method provides general platform information about this package.
 * @return string  A string containing the above.
 */ 
function CrossPlatformCode_getListSupportedPlatforms() {
  var strResult = "Welcome to all-JavaScript 'Compare-the-Graphs' (an application of the Grapher package)! \n "
    + "  Copyright (c)  Christopher M. Balz  2001.\n\n "
    + "  This application is currently  ported to any equation or function"
    + "  in two variables, and is completely extensible.  \n"
    + "  You may download the code and modify it per the stipulation in the Notice in the 'About' text " 
    + "  (see button in lower frame to get the code and 'About' text)."
    + "  Feedback about ports to other types of equations is welcome."
    + "  \n This has been tested and found to work correctly on the following platforms: "
    + "  \n     *   IE6.0 on Windows98. "
    + "  \n     *   IE5.5 on Windows98. "
    + "  \n     *   IE5 on Windows2000 and Windows98. "
    + "  \n     *   Netscape6.1 on Windows2000 and Mac OS X. "
    + "  \n     *   Mozilla0.9.4 on Linux and Windows98. "
    + "  \n  -> Note that it has not been tested on several platforms, and may work on those platforms. ";
  return strResult;
}


/**
 * This method provides information about resolving bugs with the performance of this package
 * across different platforms.
 * @return string  A string containing the above.
 */ 
function CrossPlatformCode_getPlatformBugAdvisory() {
  var objIs = CrossPlatformCode.objIs;
  var strTitle = "Cross-platform Bug Advisory: \n\n";
  if (objIs.gecko || objIs.nav6up) {
    return ( strTitle 
             +"There are two possible bugs on this browser: \n a)     Sometimes the labels are not "
             +"drawn until you switch windows (alt-tab) away from and back to the browser window. "
             +"\n b)     Do not press the 'Enter' key in the text entry boxes. ");
  } else if (objIs.ie5 || objIs.ie5_5 || objIs.ie6) {
    return ( strTitle + "This browser draws a small green square in the upper left corner.  Ignore." );
  }
}


/**
 * This method provides the interior HTML for a hatch/label div.
 * @param strLabelHtml  The HTML for the label, that lives inside the hatch div.
 * @param funGetFillerMarkup  A reference to a function or method that returns markup that
 *                            will force IE5.0 to render the hatch marks correctly.
 * @param intHeight  The height of the filler markup table.
 * @param intWidth   The width of the filler markup table.
 */
function CrossPlatformCode_getHatchAndLabelHtml(strLabelHtml, funGetFillerMarkup, intHeight, intWidth) {
  var objIs = CrossPlatformCode.objIs;
  if (objIs.ie5up) {
    return (funGetFillerMarkup(intHeight, intWidth, strLabelHtml));
  } else {
    return strLabelHtml;
  }
}






