/*
ctHover 2009.02.18


Copyright (C) 2006-2009 Jan Vorel
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.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

Any questions, suggestions or bug reports welcome: info@ctuser.net



May change anytime for new features or browser compatibility;
Not working with some browsers (e.g. Opera < 7 because does not support className modification (or firstChild) via javascript?)
manuall clicking not yet working for all targets!



Why use this:
  adds hovering for whole <td>s (or <tr>s etc), instead of <a>'s only; plus adds hilightning (initial / last clicked link)





Usage:
  include this js in your html, and call ctHoverInit() within body\onLoad


ElementsToSkip:
  Child/Parent relation ship difference between your A and TD (should be identically to sourceIndex difference!
NewStyleSubFix:
  SubFix for new class name(s)
    -> className = original className + NewStyleSubFix[+ '_hilight' / '_hover']
DefaultLinkUrl:
  Link numeric ID (base 0) or full path url (without domain!), e.g. home/test.php?default 
Flags
     1 (recommend) will modify link className:
       -> className = [original className] + NewStyleSubFix
     2 will also modify classes for hovering / hilightning!
       -> className = original className + NewStyleSubFix[+ '_hilight' / '_hover']
+   16 -> No Hovering
+   32 -> No Hilightning
+  256 -> No click handling
UpdateSecondFrameInfo
  Specifies another frame to be updated according to the 'id' of <a href...>
  Syntax: <frame name>,[<string>]#id#[<string>]
  e.g. home,/design/header_#id#.htm
  uses #id# instead of $ID$ now for Opera 6 compatibility
LinkClassName
  ClassName for links, in case not all links should be replaced
*/





var CurHilight;
var CurHilightP;
var CurHilightClassTD;
var CurHilightClassA;

var CurHover;
var CurHoverP;
var CurHoverClassTD;
var CurHoverClassA;
var xElementsToSkip;
var xExtraLnkClass;

var xNoHilightning;
var xNoHovering;
var xNoClickHandling;

var xUpdateSecondFrameFrame;
var xUpdateSecondFrameURL;

function ctHoverGetParent(xAnyObject)
{
  var xLong1;

  for (xLong1 = 0; xLong1 < xElementsToSkip; ++xLong1)
    {
      if (xAnyObject)
        xAnyObject = xAnyObject.parentNode;
    }
  return xAnyObject;
}

function IsNotRightThis(xObj, xExpression)
{
  var xChar1;
  var xLong1;
  var xLong2;

  xChar1 = xObj.className;
  xLong1 = xChar1.length;
  if (xLong1)
  {
    xLong2 = xExpression.length;
    if (xLong1 >= xLong2)
    {
      if (xChar1.substr(xLong1 - xLong2, xLong2) == xExpression)
        return false;
    }
    if (xLong1 > 7)
    {
      if (xChar1.substr(xLong1 - 8, 8) == '_hilight')
        return false;
    }
  }
  return true;
}

function ctHoverGetChild(xAnyObject)
{
  var xLong1;

  for (xLong1 = 0; xLong1 < xElementsToSkip; ++xLong1)
    {
      if (xAnyObject)
        xAnyObject = xAnyObject.firstChild;
    }
  return xAnyObject;
}

function ctHoverInit(ElementsToSkip, NewStyleSubFix, DefaultLinkUrl, Flags, UpdateSecondFrameInfo, LinkClassName)
{
  var xLong1;
  var xLong2;
  var xObj1;
  var xObj2;
  var xChar1;
  var xBool1;

  xElementsToSkip = ElementsToSkip;
  xExtraLnkClass = (Flags & 15);

  xNoHovering = (Flags & 16);
  xNoHilightning = (Flags & 32);
  xNoClickHandling = (Flags & 256);
  xUpdateSecondFrameURL = UpdateSecondFrameInfo;
  if (xUpdateSecondFrameURL)
  {
    xLong1 = xUpdateSecondFrameURL.indexOf(",");
    if (xLong1 != -1)
    {
      xUpdateSecondFrameFrame = xUpdateSecondFrameURL.slice(0, xLong1);
      xUpdateSecondFrameURL = xUpdateSecondFrameURL.slice(xLong1 + 1);
    }
  }

  for (xLong1 = 0; xLong1 < document.links.length; ++xLong1)
  {
    xObj1 = document.links[xLong1];
    xObj2 = ctHoverGetParent(xObj1)

    if (xObj2)
    {
      if ((xObj1.className == LinkClassName) || (!LinkClassName))
      {
        xChar1 = xObj1.href;
        if (xChar1)
        {
          if (xChar1.slice(xChar1.length - 1) == "#")
            xBool1 = 0;
          else
            xBool1 = 1;
        }
        else
          xBool1 = 0;

        if (xBool1)
        {
          if (!xNoHovering)
          {
            xObj2.onmouseover = function () { ctHoverDoHover(ctHoverGetChild(this)); };
            xObj2.onmouseout = function () { ctHoverDoUnHover(ctHoverGetChild(this)); };
          }
          xObj2.onclick = function () { ctHoverDoClickEx(ctHoverGetChild(this)); };
        }
        if (IsNotRightThis(xObj2, NewStyleSubFix))
          xObj2.className = xObj2.className + NewStyleSubFix;
        if (xExtraLnkClass)
        {
          if (IsNotRightThis(xObj1, NewStyleSubFix))
            xObj1.className = xObj1.className + NewStyleSubFix;
        }


        if (xBool1)
        {
/*
          if (!xNoHovering)
          {
            xObj1.onmouseover = function () { ctHoverDoHover(this); };
            xObj1.onmouseout = function () { ctHoverDoUnHover(this); };
          }
*/
          xObj1.onclick = function () { ctHoverDoClick(this); };
        }
        xChar1 = xObj1.href;


        xLong2 = xChar1.indexOf('//')
        if (xLong2) xChar1 = xChar1.slice(xLong2 + 2);
        xLong2 = xChar1.indexOf('/')
        if (xLong2) xChar1 = xChar1.slice(xLong2 + 1);

        if (xChar1 == DefaultLinkUrl)
          ctHoverDoClick(xObj1);
        else
        {
          if (xLong1 == DefaultLinkUrl)
            ctHoverDoClick(xObj1);
        }
      }
    }
  }
}

function ctHoverDoClickEx(Element)
{
  var xLong1;
  var xChar1;
  var xChar2;

  ctHoverDoClick(Element);

  if (!xNoClickHandling)
  {
    xChar2 = Element.href;
    if (xChar2)
    {
      xChar1 = Element.target;
      if (!xChar1)
      {
        xChar1 = document.getElementsByTagName("base")[0];
        if (xChar1)
          xChar1 = xChar1.target;
      }
      if (xChar1)
      {
        xChar1 = xChar1.toLowerCase();
        switch(xChar1)
        {
          case "_top":
            window.location.href = xChar2;
            window.location.reload;
            break;
          case "_parent":
            alert("parent");
            alert(xChar2);
            if (parent)
            {
              parent.location.href = xChar2;
              break;
            }
          case "_blank":
            window.open(xChar2, "_blank", "");
            break;
          case "_self":
            self.location.href = xChar2;
            self.location.reload;
            break;
          default:
            for (xLong1 = 0; xLong1 < top.frames.length; ++xLong1)
            {
              if (top.frames[xLong1].name == xChar1)
              {
                top.frames[xLong1].location.href = xChar2;
                top.frames[xLong1].reload;
                xChar1 = "";
                break;
              }
            }
            if (xChar1)
              window.open(xChar2, xChar1, "");
        }
      }
      else
      {
        self.location.href = xChar2;
        self.location.reload;
      }
    }
  }
}

function ctHoverDoClick(Element)
{
  if (!xNoHilightning)
  {
    if (Element !== CurHilight)
    {
      xPElement = ctHoverGetParent(Element);
      if (xPElement)
      {
        if (CurHilight)
        {
          CurHilightP.className = CurHilightClassTD;
          if (xExtraLnkClass & 2)
            CurHilight.className = CurHilightClassA;
        }
        if (CurHover == Element)
        {
          CurHilightClassTD = CurHoverClassTD;
          if (xExtraLnkClass & 2)
            CurHilightClassA = CurHoverClassA;
          CurHover = '';
        }
        else
        {
          CurHilightClassTD = xPElement.className;
          CurHilightClassA = Element.className;
        }
        CurHilight = Element;
        CurHilightP = xPElement;
        CurHilightP.className = CurHilightClassTD + '_hilight';
        if (xExtraLnkClass & 2)
          CurHilight.className = CurHilightClassA + '_hilight';
      }
    }
  }
  if (xUpdateSecondFrameFrame)
  {
    var xLong1;
    var xChar1;
    for (xLong1 = 0; xLong1 < top.frames.length; ++xLong1)
    {
      xChar1 = top.frames[xLong1].name;
      if (xChar1)
      {
        if (xChar1 == xUpdateSecondFrameFrame)
        {
          xChar1 = Element.id;
          if (xChar1)
          {
            top.frames[xLong1].location.href = xUpdateSecondFrameURL.replace("#ID#", xChar1);
            break;
          }
        }
      }
    }
  }

  StopEventIndirect();
  return false;
}

function StopEventIndirect(event)
{
  event = event || window.event;
  if (event)
    event.stopPropagation();
}

function ctHoverDoHover(Element)
{
  if (Element !== CurHilight)
  {
    if (CurHover)
    {
      CurHoverP.className = CurHoverClassTD;
      if (xExtraLnkClass & 2)
        CurHover.className = CurHoverClassA;
      CurHover = '';
    }
    CurHoverP = ctHoverGetParent(Element);
    if (CurHoverP)
    {
      CurHover = Element;
      CurHoverClassTD = CurHoverP.className;
      if (xExtraLnkClass & 2)
        CurHoverClassA = CurHover.className;
      CurHoverP.className = CurHoverClassTD + '_hover';
      if (xExtraLnkClass & 2)
        CurHover.className = CurHoverClassA + '_hover';
    }
  }
}

function ctHoverDoUnHover(Element)
{
  if (CurHover)
  {
    if (Element == CurHover)
    {
      CurHoverP.className = CurHoverClassTD;
      if (xExtraLnkClass & 2)
        CurHover.className = CurHoverClassA;
      CurHover = '';
    }
  }
}
