// Demonstration cross-browser compatibility API
// only tested for Netscape 6 and IE5.5
// Written by Dave Taylor - taylor@intuitive.com - for the
// book "Dynamic HTML Weekend Crash Course"
//    online at  http://www.intuitive.com/dhtml/

var useID = 0, useLayers = 0, useAll = 0, N6 = 0, MSIE = 0;

if (document.getElementById) useID = 1;
if (document.layers) useLayers = 1;
if (document.all) useAll = 1;

var MSIE = (useID && useAll);
var N6   = (useID && (! useAll) );
var NS   = (navigator.appName.indexOf('Netscape') != -1)? 1 : 0;

function getObj(obj) {
  // cross platform tool for accessing the object style
  var myObj;
  
  if (useID) myObj = document.getElementById(obj).style;
  else if (useAll) myObj = document.all[obj].style;
  else if (useLayers) myObj = document.layers[obj];
  
  return myObj;
}

function getObjCore(obj) {
  // same as getObj() except it lets you access the core object
  var myObj;
  if (useID) myObj = document.getElementById(obj);
  else if (useAll) myObj = document.all[obj];
  else if (useLayers) myObj = document.layers[obj];
  return myObj;
}

// -- library routines for frame-based access - see session 22

function getFrameObj(fname, id)
{
  // get the object of the specified ID in the specified frame name
  var myObj;
  
  if (useID) {
    myObj = top[fname].document.getElementById(id).style;
  } else if (useAll) {
    myObj = top[fname].document.all[id].style;
  } else if (useLayers) {
    myObj = top[fname].document.layers[id];
  }
  return ( myObj );
}

function getFrameObjCore(fname, id)
{
  // get the object of the specified ID in the specified frame name
  var myObj;
  
  if (useID) {
    myObj = top[fname].document.getElementById(id);
  } else if (useAll) {
    myObj = top[fname].document.all[id];
  } else if (useLayers) {
    myObj = top[fname].document.layers[id];
  }
  return ( myObj );
}

// -- - - - end of frame-based functions

function moveObj(obj, x, y)
{
  // move the specified object to the specified x,y coordinates
  var myObj = getObj(obj);
  
  if (document.moveTo) {
    myObj.moveTo(x,y);
  } else {
    myObj.left = x;
    myObj.top = y;
  }
}

// ------ the following implements the slideObj function, as discussed
// ------ in depth within session 22 of the book.

var delayTime = 5;	// milliseconds. Smaller = faster animation
var skipFactor = 2;	// smaller is more scroll steps

var deltaX=0, deltaY=0, x, y; // shared across both functions

function slideObj(obj, newX, newY)
{
  // move the object to the new coordinates, one XY pixel at a time
  
  x = getX(obj), y = getY(obj); // start by identifying the current spot
  
  if (skipFactor > 1) {
    if ((newX % skipFactor != 0) || (newY % skipFactor != 0)) {
      alert("slideObj can't move object to a spot that isn't\nan even " + 
        "multiple of the skipFactor (" + skipFactor + ").\nMove cancelled.");
      return;
    }
  }

  if (x < newX) deltaX = skipFactor;
  if (x > newX) deltaX = -skipFactor;
  if (y < newY) deltaY = skipFactor;
  if (y > newY) deltaY = -skipFactor;
  
  doSlide(obj, newX, newY);
}

function doSlide(obj, newX, newY)
{
  // do the actual slide...
  
  if ((x != newX) || (y != newY)) {
    if (x == newX) deltaX = 0; // reached spot on x axis
    if (y == newY) deltaY = 0; // reached spot on y axis
    
    if (deltaX + deltaY == 0) return; // done!

    x += deltaX; // increment element
    y += deltaY; // by delta values
  
    moveObj(obj, x, y); // and do the actual move
    
    cmd = "doSlide('" + obj + "'," + newX + ", " + newY + ")";    
    setTimeout(cmd, delayTime); // loop through again after delayTime msecs
  }
}

// -- end of slider functions 

// -- The following implement the various form functions as discussed in
// -- chapter 24 of Dynamic HTML Weekend Crash Course

var formName = "forms[0]";		// default value

function setFormName(fName) 
{
  // easy shortcut for setting form name. Used with getFormObj
  formName = fName;
}

function getFormObj(elementName) {
  // cross platform tool for accessing a form object
  return( eval("document." + formName + "." + elementName) );
}

// -- end of form functions

function nudgeObj(obj, x, y)
{
  // move the object (x,y) away from where it is currently
  var myObj = getObj(obj);
  
  if (myObj.moveBy) {
    myObj.moveBy(x, y);
  } else if (MSIE) {
    myObj.pixelLeft += x;
    myObj.pixelTop  += y;
  } else {
    myObj.left = parseInt(myObj.left) + x;
    myObj.top = parseInt(myObj.top) + y;
  }
}

function getX(obj)
{
  // return the y coordinate of the object
  var myObj = getObj(obj);

  if (MSIE) {
    x = myObj.pixelLeft;
  } else {
    x = myObj.left;
  }
  return(parseInt(x));  
}

function getY(obj)
{
  // return the y coordinate of the object
  var myObj = getObj(obj);

  if (MSIE) {
    y = myObj.pixelTop;
  } else {
    y = myObj.top;
  }
  return(parseInt(y));  
}

// -- The following two let you identify the x,y location of
//    the users' mouseclick on the page. Only use it with an
//    an event-based script, like:
//   <BODY OnClick="x=getEventX(event);y=getEventY(event);
//           alert('you clicked at '+x+','+y);">
//    note that 'event' is a global JavaScript variable and
//    doesn't have to be defined anywhere.

function getEventX(eventObj)
{
  // returns the x coordinate of where the user clicked. 
  
  if (document.all && eventObj.x) return eventObj.x;
  if (eventObj.pageX) return eventObj.pageX;
  return -1;
}

function getEventY(eventObj)
{
  if (document.all && eventObj.y) return eventObj.y;
  if (eventObj.pageY) return eventObj.pageY;
  return -1;
}

// ----------------------------
function windowWidth()
{
  // return the width of the browser window.  Special note for MSIE: you
  // must have some output on the window before this test will work, 
  // because the body object isn't instantiated until then. You can get
  // around this, if needed, with document.write("&nbsp;"); or similar.
  if (MSIE) {
    width = document.body.clientWidth;
  } else {
    width = window.innerWidth;
  }
  return(parseInt(width));
}

function windowHeight()
{
  // return the width of the browser window
  if (MSIE) {
    height = document.body.clientHeight;
  } else {
    height = window.innerHeight;
  }
  return(parseInt(height));
}

function screenWidth()
{
  // return the width of the users screen
  return(parseInt(window.screen.width));
}

function screenHeight()
{
  // return the height of the users screen
  return(parseInt(window.screen.height));
}

function objHeight(obj)
{
  // return the height of the specified object 
  var myObj = getObjCore(obj);
  
  if (myObj.offsetHeight) {
    ht = myObj.offsetHeight;
  } else {
    ht = myObj.clip.height;
  }
  return(parseInt(ht));
}

function objWidth(obj)
{
  // return the height of the specified object 
  var myObj = getObjCore(obj);
  
  if (myObj.offsetWidth) {
    wd = myObj.offsetWidth;
  } else {
    wd = myObj.clip.width;
  }
  return(parseInt(wd));
}

function centerObj(obj)
{
  // center the object in the window (horizontally only)
  var y = getY(obj), width = windowWidth(), owidth = objWidth(obj);
  var newX = Math.floor((width - owidth) / 2);
  moveObj(obj, newX, y);
}


// -- the following are examples of how to easily set a specific
// attribute using the crashcourse.js functions. In the first case, it'd
// be easy to have a link on your page that'd let the user change a
// dark background color to a lighter one, for example, with a link
// like "OnClick="setBgColor('id', 'blue')".

function setBgColor(obj, color) 
{
  // set the background color for the specified object
  var myObj = getObj(obj);
  myObj.backgroundColor = color;
}

function showObj(obj)
{
  // turn on visibility for the object
  var myObj = getObj(obj);
  
  myObj.visibility = "visible";
}

function hideObj(obj)
{
  // turn off visibility, hiding the object
  var myObj = getObj(obj);
  
  myObj.visibility = "hidden";
}

// and more functions to come?
