﻿var Highlight = Class.create();
Highlight.prototype = {
    // ------------------------------------------------------------------------
    // constructor:
    //      container: defines the starting location of our search
    // ------------------------------------------------------------------------
    initialize: function(container) {
        // define the default options used and extend it with the ones passed in
		this._options = Object.extend({
            searchTags: ["tr"],
            className: "Highlight",
            onDoubleClick: Prototype.emptyFunction,
            onDelete: Prototype.emptyFunction,
            onSelect: Prototype.emptyFunction,
            onDeSelect: Prototype.emptyFunction
        }, arguments[1] || {});
        
        this._container = $(container);
        this._itemList = [];
        
        this._selectedIndex = null;
        this._selectedItem = null;
        
        this._itemClicked = false;

        // fill item list
        this._fillItemList();

        // bindAsEventListener returns a different hash so it can't be used in stopObserving()
		this._eventContainerClick = this._clear.bindAsEventListener(this);
        this._eventKeyPress = this._keyPress.bindAsEventListener(this);

    },
    
    // ------------------------------------------------------------------------
    // return the selected Item
    // ------------------------------------------------------------------------
    getSelectedItem: function(){
        return this._selectedItem;
    },
    
    // ------------------------------------------------------------------------
    // Highlight the item
    // ------------------------------------------------------------------------
    setSelectedItem: function(item){
        if(this._itemList.indexOf(item) < 0){
            this._select(null, item);
        }
    },

    // ------------------------------------------------------------------------
    // unselect the item 
    // ------------------------------------------------------------------------
    clearSelectedItem: function(){
        if(this._selectedItem){
            Element.removeClassName(this._selectedItem, this._options.className + "_Selected");
            this._selectedIndex = null;
            this._selectedItem = null;
        }
    },
            
    
    // ------------------------------------------------------------------------
    // all registering item after class is created
    // ------------------------------------------------------------------------
    registerItem: function(item){
        // add item only if it isn't already register
        if(this._itemList.indexOf(item) < 0){
            if(!Element.hasClassName(item, this._options.className)){
                Element.addClassName(item, this._options.className);
            }
            this._registerItem(item);
        }
    },
        
    // ------------------------------------------------------------------------
    // all unregistering item after class is created
    // ------------------------------------------------------------------------
    unregisterItem: function(item){
        var index = this._itemList.indexOf(item);
        if(index >= 0){
			if(index == this._selectedIndex){
				this.clearSelectedItem()
			}

			Event.stopObserving(item, "click", item._onClick);
			Event.stopObserving(item, "dblclick", this._options.onDoubleClick);

			Event.stopObserving(this._container, "click", this._eventContainerClick);
			Event.stopObserving(document, "keypress", this._eventKeyPress);               

			this._itemList.splice(index, 1);
			
			// reset and clear the itemClicked indicator
			this._itemClicked = false;
        }
    },
    
        
    // ------------------------------------------------------------------------
    // Fill _itemList by searching container for all item matching our tag
    // ------------------------------------------------------------------------
    _fillItemList: function(){
        // loop though all the search tags and items matching search tag
         for (var i = 0; i < this._options.searchTags.length; i++){
            var items = this._container.getElementsByTagName(this._options.searchTags[i]);
            for( var j = 0; j < items.length; j++){
            	if(Element.hasClassName(items[j], this._options.className)){
                    this._registerItem(items[j]);
                    
                    // change mouse pointer on hoverable items
                    items[j].style.cursor = "pointer";                    
                }
            }
         }
    },
    
    _registerItem: function(item){
        // add item to itemList
        this._itemList.push(item);
            
        // attach the click event for selecting
        item._onClick = this._select.bindAsEventListener(this, item);
        
        Event.observe(item, "click", item._onClick);
        Event.observe(item, "dblclick", this._options.onDoubleClick);
    },
    
    // ------------------------------------------------------------------------
    // handles the event when the item is clicked
    // ------------------------------------------------------------------------
    _select: function(evt, item){
        if(!this._selectedItem){
            Event.observe(this._container, "click", this._eventContainerClick);
            Event.observe(document, "keypress", this._eventKeyPress);               
        }
    
        if(this._selectedItem != item){
            // unselect pervious item
            this.clearSelectedItem();
            
            // save index of selected item and highlight row
            this._selectedIndex = this._itemList.indexOf(item);
            this._selectedItem = item;
            
            Element.addClassName(item, this._options.className + "_Selected");
          }
          
          // set indicator 
           this._itemClicked = true;
           
           this._options.onSelect();
    },    


    // ------------------------------------------------------------------------
    // clear any selected item if container is clicked
    // ------------------------------------------------------------------------
    _clear: function(event, item){
        // run this only if selectEvent didn't run
        if(!this._itemClicked){
            Event.stopObserving(this._container, "click", this._eventContainerClick);
			Event.stopObserving(document, "keypress", this._eventKeyPress);
            this.clearSelectedItem();
            
            this._options.onDeSelect();
        }
          
        // reset and clear the itemClicked indicator
        this._itemClicked = false;
    },
    
    _keyPress: function(evt){

		var target = Event.element(evt);
        if(target.nodeName == "SELECT" || target.nodeName == "INPUT" || target.nodeName == "TEXTAREA" || $('overlay_modal')){
            return;
        }
           
        switch(evt.keyCode) {
            case Event.KEY_UP:
                // selected previous item
                if((this._selectedIndex != null) && (this._selectedIndex - 1 >= 0)){
                    this._select(null, this._itemList[this._selectedIndex -1]);
                    // set indicator 
					this._itemClicked = false;
					
                    Event.stop(evt);
                    
                    // get distance from page top
                    var offsetTop = Position.cumulativeOffset(this._selectedItem)[1];
                    
                    // if we are not in the viewable range the scroll there
					if(offsetTop < document.documentElement.scrollTop)
					{		
						document.documentElement.scrollTop = offsetTop;
					}
                }
                break;
            case Event.KEY_DOWN:
                // selecte next item
                if((this._selectedIndex != null) && (this._selectedIndex + 1 < this._itemList.length)){
                    this._select(null, this._itemList[this._selectedIndex + 1]);
                    // set indicator 
					this._itemClicked = false;
					
                    Event.stop(evt);
                    
                    // get distance from page top
                    var offsetTop = Position.cumulativeOffset(this._selectedItem)[1] + this._selectedItem.offsetHeight;
                    
                    // if we are not in the viewable range then scroll there
					if(offsetTop > (document.documentElement.clientHeight + document.documentElement.scrollTop))
					{		
						document.documentElement.scrollTop = (offsetTop - document.documentElement.clientHeight);
					}
                }
                break;
            case Event.KEY_RETURN:
                this._options.onDoubleClick();
                break;
            case Event.KEY_DELETE:
                //this._options.onDelete();
                break;
        }    
    }
  
}    