/*
** TICODE rollover framework
*/

/*
** this code depends on the yui Event framework (and Dom to a lesser
** extent).  Mostly it relies on simple clear javascript.
**
** Standard Required markup:
** ----
** <a id="mn_lnk_#" href="..."><img id="mn_btn_#"></a>
** ----
**  '#' is a unique number for the page. We may be able to auto generate
**  but no promises.  
**  '...' is your link url.  the href attribute could be replaced by a
**  onClick event, but you'll need to add your own yui click handler.
**
** ----
** <script>
**   rlov.add(#, '/img/over.gif', '/img/out.gif');
** </script>
** ----
**  '#' is the same as the mark up '#' above.
**
** the enable and disable functions are supposed to work with your
** markup to make simple clean and clear menus, or rollover buttons.  To
** make them work better, it's nice to be able to cancel.  Since
** business logic decides canceling much better than we can, we add the
** concept of inteligent enables and disables.  They work off the same
** numbers of existing rollovers, and add a public function which
** business logic can call to take a viable roll over and replace it
** with a cancel, or vice versa.  Business logic must still handle any
** onClick logic themselves.  Esentailly provides object.rlov_enab()
** and object.rlov_dis() functions to enable and disable respectively.
**
** example use of these...
**
** for this setup
** ----
** <script>
** rlov.add(1, 'foo.gif', 'bar.gif', 3); 
** rlov.add(3, 'baz.gif', '', 1); 
** </script>
** ----
**
** then, the business logic hides using one of these 6 options; any of
** which will work the same, by hiding 'foo/bar' and showing 'baz'.
** ----
** <script>
** find_id('mn_lnk_' + 1).rlov_dis();
** find_id('mn_btn_' + 1).parent.rlov_dis();
** rlov.disable(1);
** find_id('mn_lnk_' + 3).rlov_enab(); //	enable the disable one.
** find_id('mn_btn_' + 3).parent.rlov_enab(); //  ditto
** rlov.enable(3); //				  ditto
** </script>
** ----
**
** and also, the business logic shows using one of these 6 options; any
** of which will work the same, by hiding 'baz' and showing 'foo/bar'.
** ----
** <script>
** find_id('mn_lnk_' + 1).rlov_enab();
** find_id('mn_btn_' + 1).parent.rlov_enab();
** rlov.enable(1);
** find_id('mn_lnk_' + 3).rlov_dis(); //	disable the disable one.
** find_id('mn_btn_' + 3).parent.rlov_dis(); //	ditto
** rlov.disable(3); //				ditto
** </script>
** ----
**
*******
**
** TODO: Alternate Required markup:
** ----
** <div id="menu_holder"></div>
**
** <script>
**  rlov.insert('menu_holder', url, '/img/over.gif', '/img/out.gif');
** </script>
** ----
**  'url' is the href data.
**  'menu_holder' is the name of the containing div you wish to auto-
**  insert into.  Each insert will generate a menu item to be inserted.
**  <a id="*gen_lnk_#*" href="*url*"><img id="*gen_btn_#*"></a>
**  
**  THIS DOESN'T EXIST!  -- want to write it? :)
**
*******
** 
*/

/*
** rlov is our global rollover class singlton.
*/
var rlov;

/*
** hooks to yui singltons.
*/
var _evnt = YAHOO.util.Event;
var _doom = YAHOO.util.Dom;
/*
** handy shortcut
*/
_evnt.on = _evnt.addListener;

/*
** The disable function that's smart enough to enable the linked object
** if it exists.  
**
** @return  {*VOID*}		  No value returned.
*/
function rlov_dis()
{
  alert('rlov_dis');
  if (hide_id('mn_btn_' + this.out))
  {
    if (elem.link.link)
    {
      show_id('mn_btn_' + elem.link.link);
      show_id(elem.link.id);
    }
  }
  hide_id(this.id);
}

function rlov_dis2()
{
  alert('rlov_dis2');
  if (this.link)
  {
    rlov.objects[this.link].rlov_dis();
  }
}

/*
** The enable function that's smart enough to disable the linked object
** if it exists.  
**
** @return  {*VOID*}		  No value returned.
*/
function rlov_enab()
{
  alert('rlov_enab');
  if (show_id('mn_btn_' + this.out))
  {
    if (elem.link.link)
    {
      hide_id('mn_btn_' + elem.link.link);
      hide_id(elem.link.id);
    }
  }
  show_id(this.id);
}

function rlov_enab2()
{
  alert('rlov_enab2');
  if (this.lnk)
  {
    rlov.objects[this.link].rlov_enab();
  }
}

/*
** the add function is supposed to work with your markup to make simple
** clean and clear menus.  Adds rollover images to internal array. 
** Function auto extends the rollover image array.  Then ties the Dom
** object to the rollover callbacks, and sets the objects internal data.
** Fails on a duplicate 'num' insert. 
**
** @param   {Integer} num   The number refrenced by both 'A' and 'IMG'.
** @param   {String}  over  pic 'url' to show on 'over' events.
** @param   {String}  out   pic 'url' to show on 'out'  events, if left
**			    blank, then the same url is used.
** @param   {Integer} link  The number of the image to show on disable,
**			    if not provided then enable/disable
**			    functionality limited to just this image.
** @param   {String}  nick  The nickname of the rollover set.
** @return  {Boolean}	    Add worked?
*/
function add(num, over, out, link, nick)
{
  var object;

  if (num < this.btn_img.length)
  {
    alert('Page already contains rollover index of ' + num + ".\n" +
	  'Check your logic or pick a new index.');
    return false;
  }
  for (var i = this.btn_img.length; i <= num + 1; i++)
  {
    this.btn_img[i] = new Image();

    if (i % 2)
    {
      this.objects[i] = object = find_id('mn_lnk_' + num);
    }
    else
    {
      this.objects[i] = null;
    }
  }
  if (nick)
  {
    this.nicknames[nick] = num;
  }
  if (over)
  {
    this.nicknames[over] = num;
  }
  link	= (0 + link) ? link : 0;
  out	= ('' + out) ? out  : over;

  if ((out) && (out != over))
  {
    this.nicknames[out] = num;
  }
  this.btn_img[num    ].src = over;
  this.btn_img[num + 1].src = out;

  if (object)
  {
    object._do_over   = object._do_out = true;
    object.over	      = num + 1;
    object.out	      = num;
    object.img	      = find_id('mn_btn_' + num);
    elem.link	      = object;
    object.img.src    = this.btn_img[object.out].src;
    object.link	      = link;

    if (link)
    {
      if (link < num)
      {
	if (out == over)
	{
	  this.objects[link].rlov_dis   = rlov_dis;
	  this.objects[link].rlov_enab  = rlov_enab;
	  object.rlov_dis		= rlov_dis2;
	  object.rlov_enab		= rlov_enab2;
	  /*
	  ** default disabled: active first, so disable.
	  */
	  object.rlov_dis();
	}
	else
	{
	  object.rlov_dis		= rlov_dis;
	  object.rlov_enab		= rlov_enab;
	  this.objects[link].rlov_dis   = rlov_dis2;
	  this.objects[link].rlov_enab  = rlov_enab2;
	  /*
	  ** default enabled: active last, so enable this.
	  */
	  object.rlov_enab();
	}
      }
    }
    _evnt.on(object, "mouseover", this.rlov_ovcb, object, true);
    _evnt.on(object, "mouseout",  this.rlov_otcb, object, true);
  }
  return true;
}

/*
** call back function to be invoked by the link that wraps the on over.
** @param   {Event}	  event   Event object passed by the yui Event.
** @param   {HTMLElement} object  Effected Link DOM object.
** @return  {*VOID*}		  No value returned.
*/
function rlov_ovcb(event, object)
{
  var target = _evnt.getTarget(event, true); 
  var text = "rlov_ovcb\ntarget:" + target + "\n" +
    'obj._do_over:' + ((object._do_over) ? 'T' : 'F') + "\n" +
    'obj._do_out:' + ((object._do_out) ? 'T' : 'F') + "\n" +
    'obj.img.src:' + object.img.src + "\n" +
    'is_ancestor:' + ((is_ancestor(object,target)) ? 'T' : 'F') + "\n";

  if ((object._do_over) && (is_ancestor(object, target)))
  {
    text = text + "\nso I do it!!!\n\n" + "id:" + object.img.id + "\n";
    object._do_over = false;
    object._do_out  = true;
    find_id(object.img.id);

    if ('SPAN' == elem.tagName)
    {
      text = text + "filter:" + elem.style.filter + "\n";
      elem.style.filter = spanedhandler(rlov.btn_img[object.over].src);
    }
    object.img.src  = rlov.btn_img[object.over].src;
  }
  text = text + "-----------------\n" +
	'obj._do_over:' + ((object._do_over) ? 'T' : 'F') + "\n" +
	'obj._do_out:' + ((object._do_out) ? 'T' : 'F') + "\n" +
	'obj.img.src:' + object.img.src + "\n";
  //alert(text);
}

/*
** call back function to be invoked by the link that wraps the on out.
** @param   {Event}	  event   Event object passed by the yui Event.
** @param   {HTMLElement} object  Effected Link DOM object.
** @return  {*VOID*}		  No value returned.
*/
function rlov_otcb(event, object)
{
  var target = _evnt.getTarget(event, true); 
  var text = "rlov_otcb\ntarget:" + target + "\n" +
    'obj._do_over:' + ((object._do_over) ? 'T' : 'F') + "\n" +
    'obj._do_out:' + ((object._do_out) ? 'T' : 'F') + "\n" +
    'obj.img.src:' + object.img.src + "\n" +
    'is_ancestor:' + ((is_ancestor(object,target)) ? 'T' : 'F') + "\n";

  if ((object._do_out) && (is_ancestor(object, target)))
  {
    text = text + "\nso I do it!!!\n\n" + "id:" + object.img.id + "\n";
    object._do_out  = false;
    object._do_over = true;
    find_id(object.img.id);

    if ('SPAN' == elem.tagName)
    {
      text = text + "filter:" + elem.style.filter + "\n";
      elem.style.filter = spanedhandler(rlov.btn_img[object.out].src);
    }
    object.img.src  = rlov.btn_img[object.out].src;
  }
  text = text + "-----------------\n" +
	'obj._do_over:' + ((object._do_over) ? 'T' : 'F') + "\n" +
	'obj._do_out:' + ((object._do_out) ? 'T' : 'F') + "\n" +
	'obj.img.src:' + object.img.src + "\n";
  //alert(text);
}

function steam_roller()
{
  /*
  ** function extensions.
  */
  this.add	  = add;
  this.rlov_dis	  = rlov_dis;
  this.rlov_enab  = rlov_enab;
  this.rlov_ovcb  = rlov_ovcb;
  this.rlov_otcb  = rlov_otcb;

  /*
  ** this array holds all 'registered' rollover images.
  */
  this.btn_img	  = new Array();
  this.objects	  = new Array();
  this.nicknames  = new Array();
  this.btn_img[0] = '';
  this.objects[0] = '';

  this.by_nick = function (nick) {
    if ((nick) && (this.nicknames[nick]))
    {
      return this.objects[this.nicknames[nick]];
    }
    return null;
  }

  this.disable = function (img) {
    this.objects[img].rlov_dis();
  };

  this.enable = function (img) {
    this.objects[img].rlov_enab();
  };
}

rlov = new steam_roller();
