/****************************************
  Navslide V1.1
  Copyright (C) 2007   Steve H
  http://www.fullvolume.co.uk/
  
  Instructions for use:
  http://www.fullvolume.co.uk/scripts/navslide/
  ****************************************
  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.
  
  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.
  
  http://www.gnu.org/copyleft/gpl.html
****************************************/

// Global Variables
var selected = 0;
var timeout = false;
var unsettimeout = false;
var idle = true;

//
// Startup Script
//
function navslide(navslide,ul,li) {
  if (!navslide) {navslide = 'navslide';}
  if (!ul) {ul = 'ul';}
  if (!li) {li = 'li';}
  if (document.getElementById(navslide).getElementsByTagName(ul)[0].getElementsByTagName(li)[0]) {
    var navslide = document.getElementById(navslide);
    var navlist = navslide.getElementsByTagName(ul)[0];
    var navitems = navlist.getElementsByTagName(li);
    
    // Add shadowbox - hide for the time being
    if (!document.getElementById('shadowbox')) {
      var shadowbox = document.createElement('div');
      shadowbox.setAttribute('id','shadowbox');
      shadowbox.setAttribute('style','width:0px; height:0px; display:none;');
      navslide.insertBefore(shadowbox,navlist);
      shadowbox = document.getElementById('shadowbox');
    }
    
    // Set hover events and starting position
    for (var x=0 ; x<navitems.length ; x++) {
      if ( (navitems[x].className == 'selected') || (navitems[x].getElementsByTagName('a')[0].className == 'selected') ) {
        selected = x;
      }
      navitems[x].id = 'navli' + x;
      navitems[x].onmouseover = function() {navslide_hover(this.id);}
      navitems[x].onmouseout = function() {navslide_unhover(2000);}
      navitems[x].onclick = function() {navslide_setselected(this.id);}
    }
    
    // Create a slippy environment (CSS)
    shadowbox.style.display = 'block';
    shadowbox.style.position = 'absolute';
    navslide.style.position = 'static';
    navlist.style.position = 'relative';
    
    // Completed Startup Successfuly
    navslide_unhover();
    return true;
  } else {
    // Nowhere to control
    return false;
  }
}


//
// Set shadowbox back to original place
//
function navslide_unhover(offset) {
  if (offset) {
    // Clear any old unhover queue
    if (unsettimeout) {
      clearTimeout(unsettimeout);
    }
    
    unsettimeout = setTimeout("navslide_hover('navli" + selected + "',true);",offset);
  } else {
    navslide_hover('navli' + selected);
  }
}


//
// Move shadowbox
//
function navslide_hover(id,unhover) {
  // Tred carefuly if this is an unhover command
  if (unhover) {
    if (idle != true) {
      return false;
    }
  }
  idle = false;
  
  // Cancel any ongoing requests
  if (timeout) {
    if (timeout != 'safe') {
      clearTimeout(timeout);
    }
    timeout = false;
  }
  
  var hoverlink = document.getElementById(id);
  var shadowbox = document.getElementById('shadowbox');
  
  // Get co-ordinates of where we're heading
  var heading = navslide_coordinates(hoverlink);
  // Get co-ordinates of where we're coming from
  var origin = navslide_coordinates(shadowbox);
  
  // Decide Speed
  var diffx = Math.abs(heading[3] - origin[3]);
  var diffy = Math.abs(heading[0] - origin[0]);
  var checkpos = diffx + diffy;
  if (checkpos < 10) {
    var steps = 2;
  } else if (checkpos < 20) {
    var steps = 4;
  } else if (checkpos < 40) {
    var steps = 6;
  } else if (checkpos < 70) {
    var steps = 8;
  } else {
    var steps = 10;
  }
  
  // Start the movement
  timeout = setTimeout("navslide_shadow(" + steps + "," + heading[3] + "," + heading[0] + "," + heading[4] + "," + heading[5] + ")",40);
  
  // Finish
  return true;
}


//
// Move/Streach shadowbox
//
function navslide_shadow(steps,x,y,h,w) {
  var shadowbox = document.getElementById('shadowbox');
  timeout = 'safe';
  if (steps <= 0) {
    // Complete Movement
    shadowbox.style.left = x + "px";
    shadowbox.style.top = y + "px";
    shadowbox.style.height = h + "px";
    shadowbox.style.width = w + "px";
    // End Movement Loop
    idle = true;
    timeout = false;
    return true;
  } else {
    var origin = navslide_coordinates(shadowbox);
    
    var streachy = ( (h - origin[4]) / steps );
    var streachx = ( (w - origin[5]) / steps );
    var movey = ( (y - origin[0]) / steps );
    var movex = ( (x - origin[3]) / steps );
    
    var gox = origin[3] + movex;
    var goy = origin[0] + movey;
    var goh = origin[4] + streachy;
    var gow = origin[5] + streachx;
    
    shadowbox.style.left = gox + "px";
    shadowbox.style.top = goy + "px";
    shadowbox.style.height = goh + "px";
    shadowbox.style.width = gow + "px";
    
    if (timeout == 'safe') {
      // Continue Movement
      timeout = setTimeout("navslide_shadow(" + (steps - 1) + "," + x + "," + y + "," + h + "," + w + ")",40);
    } else {
      // Cancel Movement
      return false;
    }
  }
}


//
// Set ID as the selected link
//
function navslide_setselected(id) {
  
  // Smart-detect which elements to aply the class to
  if (document.getElementById('navli' + selected).className == 'selected') {
    document.getElementById(id).className = 'selected';
  }
  if (document.getElementById('navli' + selected).getElementsByTagName('a')[0].className == 'selected') {
    document.getElementById(id).getElementsByTagName('a')[0].className = 'selected';
  }
  
  // Unset previously selected link
  document.getElementById('navli' + selected).className = '';
  document.getElementById('navli' + selected).getElementsByTagName('a')[0].className = '';
  
  // Set as default for navslide
  selected = id.substr(5);
  
  return true;
}


//
// Read co-ordinates of a given element
//
function navslide_coordinates(obj) {
  var height = obj.offsetHeight;
  var width = obj.offsetWidth;
  
  var detect = navigator.userAgent.toLowerCase();
  
  if (detect.indexOf('msie') + 1) {
    var top =  obj.offsetTop;
    var left =  obj.offsetLeft;
  } else {
    var top = 0;
    var left =  0;
    if (obj.offsetParent) {
      while (obj.offsetParent) {
        top += obj.offsetTop;
        left += obj.offsetLeft;
        obj = obj.offsetParent;
      }
    }  else if (obj.x) {
      left += obj.x;
      top += obj.y;
    }
  }
  
  var right = left + width;
  var bottom = top + height;
  
  // Return array
  return new Array(top,right,bottom,left,height,width);
}