var $dom = YAHOO.util.Dom;
var $ = $dom.get;
var $class = $dom.getElementsByClassName;

var highlight_auto = {
    init: function() {
	    this.highlight_items = [];
	    var highlight_lists = $class('highlight-holder', 'div');
	    for(var i=0, item; item=highlight_lists[i]; i++) {
	        this.highlight_items[i] = new Highlight(item);

	    }
    }
};

Highlight = function(highlight_holder) {
    if (highlight_holder) {
        this.init(highlight_holder); 
    }
};

Highlight.prototype = {  
    init: function(highlight_holder) {
        if (highlight_holder) {
            this.highlight_list = $class('highlight-list', 'ul', highlight_holder)[0];
    	    this.highlight_bg = $class('highlight', 'div', highlight_holder)[0];
            this.highlight_bg_spacer = $class('spacer', 'div', this.highlight_bg)[0];
            // Used to offset the left image size for centering the text within the highlight
            // For details on the effect used go here: http://alistapart.com/articles/slidingdoors
       	    this.highlight_left_img_width = parseInt($dom.getStyle(this.highlight_bg_spacer, 'margin-left'));
    	    
    	    // How to display the item initially and for resetting if an item isn't selected
    	    // the options are "slide" or "fade"
    	    this.initial_display_method = 'fade'
    	    // Should the position reset on mouse out or stay over the current highlighted option.
    	    this.reset_on_mouseout = true;
    	    // This is how long of a pause should be taken on mouse out before the highlight resets.
    	    this.exit_pause = 250;
    	    
    	    // Looking to see if an item is highlighted by default and get the appropriate values
    	    // if not set default values
    	    // These values are used for moving the highlight back once the menu/item have been moved off of.
            var highlighted_item = $class('highlight', 'li', this.highlight_list)[0];
    	    if (highlighted_item) {
    	        var region = $dom.getRegion(highlighted_item);
    	        this.reset_width = (region.right - region.left - this.highlight_left_img_width);
                this.reset_x = $dom.getX(highlighted_item);
                this.reset_y = $dom.getY(highlighted_item);
                this.current_highlighted_item = highlighted_item;
                this.hide_on_reset = false;
    	    } else {
    	        this.reset_width = 0;
                this.reset_x = -10;
                this.reset_y = -10;
                this.current_highlighted_item = null;
                this.hide_on_reset = true;
    	    }
                    
            var obj = this;
            var highlight_items = this.highlight_list.childNodes;
    	    for(var i=0, item; item=highlight_items[i]; i++) {
    	        if (item.nodeName=="LI") {
        	        YAHOO.util.Event.addListener(item, 'mouseover', this.hover, obj);
                }
    	    }
    	    if (this.reset_on_mouseout) {
                YAHOO.util.Event.addListener(this.highlight_list, 'mouseout', this.mouseout, obj);
            }
            
            
            this.set_position(this.reset_x, this.reset_y, this.reset_width)
            this.in_highlight_area = false;
            this.highlight_visible = false;
            if (highlighted_item) {
                this.display_highlight();   
            }
        }
    },

    set_position: function(x, y, width) {
        $dom.setX(this.highlight_bg, x);
        $dom.setY(this.highlight_bg, y);
        $dom.setStyle(this.highlight_bg_spacer, 'width',width+'px');   
    },

    display_highlight: function() {
        if (this.initial_display_method == 'slide') {
            $dom.setStyle(this.highlight_bg, 'visibility', 'visible');
        } else if (this.initial_display_method == 'fade') {
            $dom.setStyle(this.highlight_bg, 'opacity', 0);
            $dom.setStyle(this.highlight_bg, 'visibility', 'visible');
            var fade_in_anim = new YAHOO.util.Anim(this.highlight_bg, { opacity: { to: 1 } }, .5, YAHOO.util.Easing.easeBoth);
            fade_in_anim.animate();
        }
        this.highlight_visible = true;
        
    },
    
    hide_highlight: function() {
        if (this.initial_display_method == 'slide') {
            $dom.setStyle(this.highlight_bg, 'visibility', 'hidden');
        } else if (this.initial_display_method == 'fade') {
            var fade_out_anim = new YAHOO.util.Anim(this.highlight_bg, { opacity: { to: 0 } }, .7, YAHOO.util.Easing.easeBoth);
            fade_out_anim.animate();
        }
        this.highlight_visible = false;

    },

    get_item_positioning: function(item) {
        var region = $dom.getRegion(item);
        var positioning = {};
        positioning['width'] = (region.right - region.left - this.highlight_left_img_width);
        positioning['x'] = region.left;
        positioning['y'] = region.top; 
        
        return positioning;   
    },

    move_to_item: function(item) {
        item = this.get_parent_li(item);
        var positioning = this.get_item_positioning(item);
        this.move_highlight(positioning['x'], positioning['y'], positioning['width']);
        this.current_highlighted_item = item;        
    },
    
    move_highlight: function(x, y, width) {
        var move_anim = new YAHOO.util.Motion(this.highlight_bg, {points: { to: [x, y] }}, 0.7, YAHOO.util.Easing.easeIn ); 
        var width_anim = new YAHOO.util.Anim(this.highlight_bg_spacer, {width: {to: width}}, 0.7, YAHOO.util.Easing.easeIn);
        if (this.hide_on_reset && !this.in_highlight_area) {
            var obj = this;
            move_anim.onComplete.subscribe(this.hide_highlight, obj, true);
        } 
        move_anim.animate();
        width_anim.animate();
    },

    get_parent_li: function(item) {
        while (item.nodeName != 'LI') {
            item = item.parentNode;   
        }
        return item;  
    },

    hover: function(e, obj) {
        var item = YAHOO.util.Event.getTarget(e, true);
        if (item.nodeName != "LI") {
            item = obj.get_parent_li(item);
        }
        if(obj.current_highlighted_item != item) {
            obj.in_highlight_area = true; 
            if(!obj.highlight_visible && obj.initial_display_method=='fade') {
                var positioning = obj.get_item_positioning(item);
                obj.set_position(positioning['x'], positioning['y'], positioning['width']);
                obj.display_highlight();
            } else {
                if (!obj.highlight_visible) {
                    obj.display_highlight();   
                }
                obj.move_to_item(item);
            }           
        }
    },
  
    mouseout: function(e, obj) {
        var item = YAHOO.util.Event.getRelatedTarget(e, true);
        if(!$dom.isAncestor(obj.highlight_list, item)) {
            obj.in_highlight_area = false;
            setTimeout(function(){ obj.reset_position() }, obj.exit_pause);
        }    
    },
    
    reset_position: function() {
        if (!this.in_highlight_area) {
            if (this.initial_display_method=='fade' && this.hide_on_reset) {
                this.hide_highlight();
            } else {
                this.move_highlight(this.reset_x, this.reset_y, this.reset_width);
            }
            this.current_highlighted_item = null;
        }
    }
};

//Un comment the below line or add it to your own html/javascript files to start the highlighting
YAHOO.util.Event.addListener(window, 'load', highlight_auto.init);
