/* jlayer.js
 * @version 1.2
 * @author Matias Muhonen <matias.muhonen@ambientia.fi>
 * some dhtml concepts by Jussi Löf <jussi.lof@ambientia.fi>
 * (C)Copyright Ambientia Ltd.
 *
 * muutokset:
 * -onmouseout hide, jota varten jouduin lisäämään findProp(), onmouseout() onmouseover() funktiot (JL)
 *
 * Tested with: IE4+, NS4+ (Linux, Win32), Mozilla,
 * Opera6+ (Linux, Win32), KDE/Konqueror3, IE5/MacOS
 */

//Global variables

var isNS4 = false;
var isIE4 = false;
var isDOM = false;

if (document.layers) { isNS4 = true; }
else if (document.all && document.plugins) { isIE4 = true; }
else if (document.getElementById) { isDOM = true; }

var createdLayers = new Array();
var selectedLayer = false;
var zCounter = 0;

//Layer Object

function jLayer(xPos, yPos, content, isVisible)
{
  this.getLayer = function(layerID, obj) {
    if (isNS4)
    {
      var layer, i;

      if (!obj) { obj = document; }
      if (!(layer = obj[layerID]) && obj.all) { layer = obj.all[layerID]; }

      for(i=0; !layer && obj.layers && i<obj.layers.length; i++)
      {
        layer = this.getLayer(layerID, obj.layers[i].document);
      }
      return layer;
    }
    else if (isIE4) { return document.all[layerID]; }
    else if (isDOM) { return document.getElementById(layerID); }
  }

  this.getContent = function() {
    return this.content;
  }

  this.getHeight = function() {
    if (isNS4) { return this.object.clip.height; }
    else if (isIE4) { return this.object.scrollHeight; }
    else if (isDOM) { return this.object.offsetHeight; }
  }

  this.getWidth = function() {
    if (isNS4) { return this.object.clip.width; }
    else if (isIE4) { return this.object.scrollWidth; }
    else if (isDOM) { return this.object.offsetWidth; }
  }

  this.getScreenHeight = function() {
    if (isIE4) { return document.body.clientHeight; }
    else if (isDOM || isNS4)
    {
      if (document.width > window.innerWidth) { return window.innerHeight-16; }
      else { return window.innerHeight; }
    }
  }

  this.getScreenWidth = function() {
    if (isIE4) { return document.body.clientWidth; }
    else if (isDOM || isNS4)
    {
      if (document.height > window.innerHeight) { return window.innerWidth; }
      else { return window.innerWidth - 16; }
    }
  }

  this.look = function(content)
  {
    return content;
  }

  this.move = function(deltaX, deltaY) {
    this.setPosition(this.xPos() + deltaX, this.yPos() + deltaY);
  }

  this.setContent = function(content) {
    if (isIE4 || isDOM) { this.object.innerHTML = content; }
    else if (isNS4)
    {
      var layer = this.getLayer(this.name + '_container_content');

      layer.document.open();
      layer.document.write(content);
      layer.document.close();
    }

    this.content = content;
  }

  this.setPosition = function(x, y) {
    if (isNS4) { this.object.moveTo(x, y); }
    else if (isIE4)
    {
      this.object.style.pixelLeft = x;
      this.object.style.pixelTop = y;
    }
    else if (isDOM)
    {
      this.object.style.left = x + 'px';
      this.object.style.top = y + 'px';
    }

    this.xPos = x;
    this.yPos = y;
  }

  this.setVisibility = function(isVisible) {
    this.visibility = isVisible;
    //alert(this.visibility + ' ' + this.name);
    if (isIE4 || isDOM) { this.object.style.visibility = isVisible ? 'visible' : 'hidden'; }
    else if (isNS4) { this.object.visibility = isVisible ? 'show' : 'hide'; }
  }

  this.setZOrder = function(z) {
    if (isNS4) { this.object.zIndex = z; }
    else if (isDOM || isIE4) { this.object.style.zIndex = z; }

    this.zPos = z;
  }

  /* Constructor */

  var name = 'layer' + createdLayers.length;
  var zPos = ++zCounter;  
  if (isNS4)
  {
    var html =  '<layer id="' + name + '"' + ' left="' + xPos + '"' + ' top="' + yPos + '" ' +
                'visibility="' + (isVisible ? 'show' : 'hide') + '">' +
                this.look(content) +
                '</layer>';
  }
  else if (isIE4 || isDOM)
  {
    var html =  '<div class="dhtml" id="' + name + '" ' + 
                'style="position:absolute; left:' + xPos + 'px; ' +
                'top:' + yPos + 'px; ' + 'z-index: ' + zPos + '; ' +
                'visibility:' + (isVisible ? 'visible' : 'hidden') + ';">' +
                this.look(content) +
                '</div>';
  }

  document.writeln(html);

  /* Instance variables */

  this.name = name;
  this.offsetX = 0;
  this.offsetY = 0;
  this.xPos = xPos;
  this.yPos = yPos;
  this.zPos = zPos;
  this.isDraggable = true;
  this.moHide = false;
  this.content = content;
  this.visibility = isVisible;
  this.object = this.getLayer(name);

  createdLayers[createdLayers.length] = this;
  
  return this;
}

//Event handler functions

function setupEventObject(evt)
{
  if (isNS4 || isDOM)
  {
    window.event = evt;
    window.event.fromElement = evt.target;
    window.event.toElement = evt.target;
    window.event.srcElement = evt.target;

    if (isNS4)
    {
      window.event.x = evt.pageX;
      window.event.y = evt.pageY;
      window.event.srcElement.handleEvent(evt);
    }
    else if (isDOM)
    {
      window.event.x = evt.clientX;
      window.event.y = evt.clientY;
    }
  }

  return;
}

//Returns the layer with highest zIndex

function getSelectedLayer()
{
  var matchedLayers = new Array();
  var currentLayer = false;
  
  for(i=0, j=0; i<createdLayers.length; i++)
  {
    var xl = createdLayers[i].xPos;
    var xr = createdLayers[i].xPos + createdLayers[i].getWidth();
    var yt = createdLayers[i].yPos;
    var yb = createdLayers[i].yPos + createdLayers[i].getHeight();

    if (window.event.x >= xl && window.event.x <= xr && window.event.y >= yt && window.event.y <= yb)
    {
      matchedLayers[j++] = createdLayers[i];
    }
  }

  if (matchedLayers.length > 0)
  {
    currentLayer = matchedLayers[0];
    
    for(i=0; i<matchedLayers.length; i++)
    {
      if (!matchedLayers[i].visibility || !matchedLayers[i].isDraggable)
      {
        continue;
      }
      
      if (currentLayer.zPos <= matchedLayers[i].zPos)
      {
        currentLayer = matchedLayers[i];
      }
    }

    return currentLayer;
  }
}

function findProp( _src, prop )
{
/* funktio etsii nimetyn propertyn omistajan ulospäin rekursiivisesti */
    var searchRounds = 0;
    while ((!eval("_src."+prop)) && _src)
    {
        if (_src.parentElement) _src = _src.parentElement;
        else if (_src.parentNode) _src = _src.parentNode;
        searchRounds ++;
        if (searchRounds > 10) break;  //don't search for too long
    }    
    if (eval("_src."+prop)) return _src;
    else return null;
}

//Event handlers

if (isNS4)
  window.document.captureEvents(Event.MOUSEOUT | Event.MOUSEOVER | Event.MOUSEDOWN |  Event.MOUSEMOVE | Event.MOUSEUP );

document.onmousedown = function(evt)
{
  if (!selectedLayer)
  {
    setupEventObject(evt);
    selectedLayer = getSelectedLayer();
    if (selectedLayer)
    {
      //zIndex can grow relatively high, hope it's not a problem...
     // window.status = "select";
      selectedLayer.setZOrder(++zCounter);
      selectedLayer.offsetX = window.event.x - selectedLayer.xPos;
      selectedLayer.offsetY = window.event.y - selectedLayer.yPos;
    }
  }
}

document.onmousemove = function(evt)
{
  if (selectedLayer)
  {
    setupEventObject(evt);
    selectedLayer.setPosition(window.event.x - selectedLayer.offsetX, window.event.y - selectedLayer.offsetY);
  }
}

document.onmouseup = function(evt)
{
  selectedLayer = false;
}

/*disable text select */
//if (isIE4) document.onselectstart = function () { return false; };

/*
var layerTimeout = null;

document.onmouseout = function(evt)
{
    setupEventObject(evt);
    if ( (element = findProp(window.event.srcElement, "id")) != null && element.id.match('layer'))
      for (var i = 0; i < createdLayers.length; i++)
        if (element.id.match(createdLayers[i].name) && createdLayers[i].moHide)
        {
          clearTimeout(layerTimeout);
          layerTimeout = setTimeout( "createdLayers["+i+"].setVisibility(0)", 100);
        }
}

document.onmouseover = function(evt)
{
    setupEventObject(evt);
     if ( (element = findProp(window.event.srcElement, "id")) != null && element.id.match('layer') )
     for (var i = 0; i < createdLayers.length; i++)
       if (element.id.match(createdLayers[i].name))
         clearTimeout(layerTimeout);
}
*/
