// common javascript functions
// copyright 2000 oscar music and media all rights reserved
//  author: djt@state51.co.uk feb.2000
// revised: djt@state51.co.uk dec.2000 for DOM browsers (Moz/NS6)
// could javascript BE any more stupid?????
//////////////////////////////////////////////////////////////////////

var objArray = new Array;
var nameArray = new Array;
var layerSelected = null;
var glideID = null;
var isNav = false;
var isMoz = false;
var isIE = false;
var appVer = parseInt(navigator.appVersion);

if(navigator.appName=="Netscape" && appVer==4) {
  isNav = true; // Navigator version 4
} else if(navigator.appName=="Netscape" && appVer > 4) {
  isMoz = true; // Navigator version 5/6 and Mozilla
} else if(appVer >= 4) {
  isIE = true;  // Internet Explorer 4/5
}

function initEvents() {
  if(isNav || isMoz) {
    document.captureEvents(Event.MOUSEMOVE);
  }
  document.onmousemove = moveLayer;
}


//////////////////////////////////////////////////////////////////////
// popup window

var openerName='playloudermain';
function spawnLinkedPopup(popupName,popupURL,popupOptions) {
  popupWindow = window.open(popupURL,popupName,popupOptions);
  if(openerName!='') {
    if(popupWindow.opener!=null) { popupWindow.opener = self; }
    popupWindow.opener.name = openerName;
  }
  popupWindow.focus(); return popupWindow;
}


//////////////////////////////////////////////////////////////////////
// set functions

function setZIndex(layer,zOrder) { 
  if(isNav) {
    layer.zIndex = zOrder;
  } else if(isMoz) {
    layer.style.zIndex = zOrder;
  } else {
    layer.style.zIndex = zOrder; 
  }
}

function setVisibility(layer,vis) { 
  if(vis) {
    if(isNav) {
      layer.visibility = vis;
    } else {
      layer.style.visibility = vis; 
    }
  }
}

function setLayerAbs(layer,x,y) {
  if(isNav) { 
    layer.moveTo(x,y);
  } else if(isMoz) {
    layer.style.left = x;
    layer.style.top = y;
  } else { 
    layer.style.pixelLeft = x;
    layer.style.pixelTop = y;
  }
}

function setLayerRel(layer,x,y) {
  if(isNav) { 
    layer.moveBy(x,y);
  } else if(isMoz) {
    layer.style.left = parseInt(layer.offsetLeft)+x;
    layer.style.top = parseInt(layer.offsetTop)+y;
  } else { 
    layer.style.pixelLeft += x;
    layer.style.pixelTop += y;
  }
}

//////////////////////////////////////////////////////////////////////
// get functions

function getEventX(evt) {
  if(isNav) {
    return evt.pageX;
  } else if(isMoz) {
    return evt.clientX;
  } else {
    return event.x+document.body.scrollLeft;
  }
}

function getEventY(evt) {
  if(isNav) {
    return evt.pageY;
  } else if(isMoz) {
    return evt.clientY;
  } else {
    return event.y+document.body.scrollTop;
  }
}

function getLayerByName(strLayerName) {
  if(isNav) {
    return eval("document."+strLayerName);
  } else if(isMoz) {
    return document.getElementById(strLayerName);
  } else {
    return eval("document.all."+strLayerName);
  }
}

function getLayerByEvent(evt) {
  var x = getEventX(evt);
  var y = getEventY(evt);

  for(var i = 0; i < nameArray.length; i++) {
    var layer = getLayerByName(nameArray[i]);
    var dist  = getDistanceFromLayer(layer,x,y);
    if(dist == 0) { return layer; }
  }
  return null;
}

function getDistanceFromLayerPlane(x,s,w) {
  if(x < s) { return s-x+1; }
  if(x >= (s+w)) { return x-s-w; }
  return 0;
}

function getDistanceFromLayer(layer,x,y) {
  var t,l,w,h;
  if(isNav) {
    l = layer.left;
    t = layer.top;    
    w = layer.clip.width;
    h = layer.clip.height;
  } else if(isMoz) {
    l = parseInt(layer.offsetLeft);
    t = parseInt(layer.offsetTop);
    w  = parseInt(layer.offsetWidth);
    h  = parseInt(layer.offsetHeight);
  } else {
    l = layer.style.pixelLeft;
    t = layer.style.pixelTop;
    w  = layer.clientWidth;
    h  = layer.clientHeight;
  }
  var disty = getDistanceFromLayerPlane(y,t,h);
  var distx = getDistanceFromLayerPlane(x,l,w);

  if(distx==0 && disty==0) {
    return 0;
  } else {
    return (distx*distx + disty*disty);
  }
}

//////////////////////////////////////////////////////////////////////

function glideLayerAbs(layer,x,y) {
  // get style object
  var name = layer.id;
  var style = objArray[name];
  if(!style) { return false; }

  // set glide co-ordinates for layer, set active=true
  style.glideX = x;
  style.glideY = y;
  style.glideA = true;

  // set up interval timer if not set
  if(!glideID) {
    glideID = setInterval("glideLayerInterval()",15);
  }
  return true;
}

function glideLayerInterval() {
  // indicates whether we should cancel timeout
  var bCancel = true;
  var nVelocity = 40;

  // check each style object
  for(var i = 0; i < nameArray.length; i++) {
    var strLayerName = nameArray[i];
    var style = objArray[strLayerName];
    if(!style.glideA) { continue; }

    var layer = getLayerByName(strLayerName);
    if(!layer) { continue; }

    // determine distance from glide origin    
    var diffX,diffY;
    if(isNav) {
      diffX = style.glideX - layer.left;
      diffY = style.glideY - layer.top;
    } else if(isMoz) {
      diffX = style.glideX - layer.offsetLeft;
      diffY = style.glideY - layer.offsetTop;
    } else {
      diffX = style.glideX - layer.style.pixelLeft;
      diffY = style.glideY - layer.style.pixelTop;
    }

    var distance = (diffX * diffX) + (diffY * diffY);
    if(distance == 0) { 
      style.glideA = false;
      continue;
    }
    if(distance < (nVelocity * nVelocity * 2)) {
      setLayerAbs(layer,style.glideX,style.glideY);
      bCancel = false;
      continue;
    }
   
    var accelX = glideLayerTimeoutAccel(nVelocity,diffX);
    var accelY = glideLayerTimeoutAccel(nVelocity,diffY);
    setLayerRel(layer,accelX,accelY);
    bCancel = false;
  }

  if(bCancel && glideID) {
    clearInterval(glideID);
    glideID = null;
  }
  return bCancel;
}

function glideLayerTimeoutAccel(velocity,sign) {
  if(sign < 0) { 
    return -velocity;
  } else if(sign > 0) { 
    return velocity; 
  } else {
    return 0;
  }
}

//////////////////////////////////////////////////////////////////////

function activateLayer(strLayerName) {
  // get layer object
  var layer = getLayerByName(strLayerName);
  if(!layer) { return false; }
  // get style object
  var style = objArray[strLayerName];
  if(!style) { return false; }

  // activate layer
  if(style.effect=="drag") {
    setLayerAbs(layer,style.left+style.horizInc,style.top+style.vertInc);
    style.state = 1;
  } else {
    glideLayerAbs(layer,style.targetLeft,style.targetTop);
    style.state = 3; // layer stuck to page
  }
  setZIndex(layer,1000);
  setVisibility(layer,'visible');
  layerSelected = strLayerName;
  return true;
}

function deactivateLayer(strLayerName) {
  // get layer object
  var layer = getLayerByName(strLayerName);
  if(!layer) { return false; }
  // get style object
  var style = objArray[strLayerName];
  if(!style) { return false; }

  // return a layer to it's original position
  setVisibility(layer,style.visibility);
  setZIndex(layer,style.zIndex);
  if(style.effect=="drag") {
    glideLayerAbs(layer,style.left,style.top);
  } else {
    setLayerAbs(layer,style.left,style.top);
  }
  style.state = 0;
  layerSelected = null;
  return true;
}

function moveLayer(evt) {
  // get layer object
  var layer = getLayerByEvent(evt);
  var strLayerName;
  if(!layer) { 
    if(layerSelected) {
      layer = getLayerByName(layerSelected);
      strLayerName = layerSelected;
    } else { 
      return true;
    }
  } else {
    strLayerName = layer.id;
  }

  // get style object
  var style = objArray[strLayerName];
  if(!style) { return true; }

  // ignore moving layer
  if(style.glideA==true) { return true; }

  // get distance from layer if layer not moving
  var x = getEventX(evt);
  var y = getEventY(evt);
  var distance = getDistanceFromLayer(layer,x,y);
  if(distance > 75*75) {
    return deactivateLayer(strLayerName);
  }

  if(style.state==0 || style.state==3 || distance==0) {
    // layer is stuck to page or deactivated
    return true;
  }

  if(style.state==1) {
    // activated layer, set offsets
    if(isNav) {
      style.offsetX = evt.pageX - layer.left;
      style.offsetY = evt.pageY - layer.top;
    } else if(isMoz) {
      style.offsetX = evt.pageX;
      style.offsetY = evt.pageY;
    } else {
      style.offsetX = window.event.offsetX;
      style.offsetY = window.event.offsetY;
    }
  }
  
  // set state to moving, make this the layer that is selected
  style.state = 2;
  layerSelected = strLayerName;

  // determine new coordinates
  var nX,nY;
  if(isNav) {
    nX = evt.pageX - style.offsetX;
    nY = evt.pageY - style.offsetY;
  } else if(isMoz) {
    nX = evt.clientX - style.offsetX;
    nY = evt.clientY - style.offsetY;
  } else {
    nX = window.event.clientX - style.offsetX;
    nY = window.event.clientY - style.offsetY;
  }

  if(!nX || !nY) { return true; }

  // constrain movement
  if(style.horizInc) {
    nY = style.top;
    if(nX < style.left) { nX = style.left; }
    if(isNav || isMoz) {
      if(nX < layer.left) { nX = layer.left; }
    } else {
      if(nX < layer.style.pixelLeft) { nX = layer.style.pixelLeft; }
    }
  } else {
    nX = style.left;
    if(nY < style.top) { nY = style.top; }
    if(isNav || isMoz) {
      if(nY < layer.top) { nY = layer.top; }
    } else {
      if(nY < layer.style.pixelTop) { nY = layer.style.pixelTop; }
    }
  }
  setLayerAbs(layer,nX,nY);
  return true;
}

function startDrag(strLayerName) {
  // get layer object
  var layer = getLayerByName(strLayerName);
  if(!layer) { return false; }
  // get style object
  var style = objArray[strLayerName];
  if(!style) { return false; }
   
  if(style.effect=="rollout") {
    // deactivate all other rollout layers
    for(var i = 0; i < nameArray.length; i++) {
      var name = nameArray[i];
      if(name != strLayerName) {
        var s = objArray[name];     
        if(s.effect=='rollout' && s.state==3) {
          var l = getLayerByName(name);
          setVisibility(l,s.visibility);
          setZIndex(l,s.zIndex);
          setLayerAbs(l,s.left,s.top);
          s.state = 0;
        }
      }
    }
  }

  if(style.state==0) {
    // activate the layer
    return activateLayer(strLayerName);
  }
  return true;
}

function endDrag(strLayerName) {
  // get layer object
  var layer = getLayerByName(strLayerName);
  if(!layer) { return false; }
  // get style object
  var style = objArray[strLayerName];
  if(!style) { return false; }

  // if layer still moving, do nothing
  if(style.glideA==false) { return true; }

  if(style.state==1) {
    // deactivate the layer if activated and not moving
    return deactivateLayer(strLayerName);
  }
  return true;
}

//////////////////////////////////////////////////////////////////////

function initDrag(strLayerName,h,v) {
  // create style for this layer
  var layer = getLayerByName(strLayerName);
  if(!layer) { return false; }

  var style = new Object;

  // object's drag state
  if(isNav) {
    style.zIndex = layer.zIndex;
    style.left = layer.left;
    style.top = layer.top;
  } else {
    style.zIndex = layer.style.zIndex;
    style.left = parseInt(layer.offsetLeft);
    style.top = parseInt(layer.offsetTop);
  }
  style.effect = 'drag';
  style.state = 0;
  style.horizInc = h;
  style.vertInc = v;

  // object's glide state
  style.glideX = 0;
  style.glideY = 0;
  style.glideA = false;

  // add object to list of objects
  nameArray[nameArray.length] = strLayerName;
  objArray[strLayerName] = style;

  // move object to position
  setLayerAbs(layer,style.left,style.top);
  return true;
}

function canDragHorizontal(strLayerName) { 
  return initDrag(strLayerName,5,0);
}

function canDragVertical(strLayerName) {
  return initDrag(strLayerName,0,5);
}

function canRollout(strLayerName,strTarget,offX,offY) {
  // create style for this layer
  var layer = getLayerByName(strLayerName);
  if(!layer) { return false; }
  var layerTarget = getLayerByName(strTarget);
  if(!layerTarget) { return false; }

  var style = new Object;

  // object's drag state
  if(isNav) {
    style.zIndex = layer.zIndex;
    style.visibility = layer.visibility;
    style.left = layer.left;
    style.top = layer.top;
    style.targetLeft = layerTarget.left + offX;
    style.targetTop = layerTarget.top + offY;
  } else {
    style.zIndex = layer.style.zIndex;
    style.visibility = layer.style.visibility;
    style.left = parseInt(layer.offsetLeft);
    style.top = parseInt(layer.offsetTop);
    style.targetLeft = parseInt(layerTarget.offsetLeft) + offX;
    style.targetTop = parseInt(layerTarget.offsetTop) + offY;
  }
  style.effect = 'rollout';
  style.state = 0;

  // object's glide state
  style.glideX = 0;
  style.glideY = 0;
  style.glideA = false;

  // add object to list of objects
  nameArray[nameArray.length] = strLayerName;
  objArray[strLayerName] = style;

  // move object to position
  setLayerAbs(layer,style.left,style.top);

  return true;
}
