var MyUtils = {
  clean_href: function( element ) {
    if( !element.href )
      return "";
    return new String(element.href).sub(/.*NoJs.aspx#/, "");
  },
  up_inclusive: function( element, expression ) {
    if( element.match(expression) )
      return element;
    return element.up(expression);
  },
  any_sib: function( element, expression ) {
    return element.siblings().find(function( sib ) {
      return sib.match( expression );
    });
  },
  saveInnerHTML: function( element, value ) {
    element.savedInnerHTML = value ? value : element.innerHTML;
  },
  restoreInnerHTML: function( element ) {
    element.innerHTML = element.savedInnerHTML;
  },
  toggleInnerHTML: function( element ) {
    var temp = element.innerHTML;
    element.innerHTML = element.savedInnerHTML;
    element.savedInnerHTML = temp;
  }
}
Element.addMethods(MyUtils);

// Provides hover functionality to make IE6 easier to deal with.
// Adds a hover class to any elements that are 'hovered' and match.
var Hover = Class.create();
Hover.prototype = {
  options: null,
  listener: null,
  initialize: function( options ) {
    options.counter = 0;
    this.options = options;
    options.class_name = options.class_name || 'hover';
    this.listener = this._listener.curry( options );
    Event.observe( options.element, 'mouseover', this.listener );
    Event.observe( options.element, 'mouseout', this.listener );
  },
  stop: function() {
    Event.stopObserving( this.options.element, 'mouseover', this.listener );
    Event.stopObserving( this.options.element, 'mousout', this.listener );
  },
  // this routine is longer than you'd expect, because some browsers seem to drop events (sometimes).
  // (namely opera and safari)
  // thus, when we get any event, don't assume we will get the oposite event.
  // additionally, we keep track of the last element we added the hover class to, and make sure we
  // remove that element's class on every event too.
  _listener: function( options, e ) {
    var element = $(e.target).up_inclusive( options.match );
    var relatedElement = e.relatedTarget ? e.relatedTarget.up_inclusive( options.match ) : null;
    
    if( e.type == 'mouseover' ) {
      if( relatedElement && relatedElement != element )
        relatedElement.removeClassName( options.class_name );
      
      if( element ) 
        element.addClassName( options.class_name );
        
      if( options.last && options.last != element )
        options.last.removeClassName(  options.class_name );
        
      if( element )
        options.last = element;
    } else if( e.type == 'mouseout' ) {
      if( element && element != relatedElement )
        element.removeClassName(options.class_name);

      if( relatedElement )
        relatedElement.addClassName(options.class_name);
      
      if( options.last && options.last != relatedElement )
        options.last.removeClassName( options.class_name );
      
      if( relatedElement )
        options.last = relatedElement;
    }
  }
}
Element.addMethods({
  hover: function( element, match, class_name ) {
    if( !element._hovers )
      element._hovers = [];
    element._hovers.push( [ match, new Hover({ element: element, match: match, class_name: class_name }) ] );
  },
  stopHover: function( element, match ) {
    element._hovers = element._hovers.select(function( pair ) {
      if( match && pair[0] != match )
        return true;
      pair[1].stop();
      return false;
    });
  }
});
