/**
 * An autosuggest textbox control.
 * @class
 * @scope public
 */
function AutoSuggestControl(oTextbox /*:HTMLInputElement*/, 
                            oProvider /*:SuggestionProvider*/) {
       
    /**
     * Suggestion provider for the autosuggest feature.
     * @scope private.
     */
    this.provider /*:SuggestionProvider*/ = oProvider;
    
    /**
     * The textbox to capture.
     * @scope private
     */
    this.textbox /*:HTMLInputElement*/ = oTextbox;
    
    //initialize the control
    this.init();
    
}

/**
 * Autosuggests one or more suggestions for what the user has typed.
 * If no suggestions are passed in, then no autosuggest occurs.
 * @scope private
 * @param aSuggestions An array of suggestion strings.
 */
AutoSuggestControl.prototype.autosuggest = function (aSuggestions /*:Array*/) {
    
    //make sure there's at least one suggestion
    if (aSuggestions.length > 0) {
        this.typeAhead(aSuggestions[0]);
    }
};


/**
 * Handles keyup events.
 * @scope private
 * @param oEvent The event object for the keyup event.
 */
AutoSuggestControl.prototype.handleKeyUp = function (oEvent /*:Event*/) {

    var iKeyCode = oEvent.keyCode;

    //make sure not to interfere with non-character keys
    if (iKeyCode < 32 || (iKeyCode >= 33 && iKeyCode <= 46) || (iKeyCode >= 112 && iKeyCode <= 123)) {
        //ignore
    } else {
        //request suggestions from the suggestion provider
        this.provider.requestSuggestions(this);
    }
};

/**
 * Initializes the textbox with event handlers for
 * auto suggest functionality.
 * @scope private
 */
AutoSuggestControl.prototype.init = function () {

    //save a reference to this object
    var oThis = this;
    
    //assign the onkeyup event handler
    this.textbox.onkeyup = function (oEvent) {
    
        //check for the proper location of the event object
        if (!oEvent) {
            oEvent = window.event;
        }    
        
        //call the handleKeyUp() method with the event object
        oThis.handleKeyUp(oEvent);
    };
    
};

/**
 * Selects a range of text in the textbox.
 * @scope public
 * @param iStart The start index (base 0) of the selection.
 * @param iLength The number of characters to select.
 */
AutoSuggestControl.prototype.selectRange = function (iStart /*:int*/, iLength /*:int*/) {

    //use text ranges for Internet Explorer
    if (this.textbox.createTextRange) {
        var oRange = this.textbox.createTextRange(); 
        oRange.moveStart("character", iStart); 
        oRange.moveEnd("character", iLength - this.textbox.value.length);      
        oRange.select();
        
    //use setSelectionRange() for Mozilla
    } else if (this.textbox.setSelectionRange) {
        this.textbox.setSelectionRange(iStart, iLength);
    }     

    //set focus back to the textbox
    this.textbox.focus();      
}; 

/**
 * Inserts a suggestion into the textbox, highlighting the 
 * suggested part of the text.
 * @scope private
 * @param sSuggestion The suggestion for the textbox.
 */
AutoSuggestControl.prototype.typeAhead = function (sSuggestion /*:String*/) {

    //check for support of typeahead functionality
    if (this.textbox.createTextRange || this.textbox.setSelectionRange){
        var iLen = this.textbox.value.length; 
        this.textbox.value = sSuggestion; 
        this.selectRange(iLen, sSuggestion.length);
    }
};

/**
 * Provides suggestions for hints.
 * @class
 * @scope public
 */
function HintSuggestions() {
    this.hints = [
	  "amateria", "amateria tusk", "amateria screenshots", "atrus",
	  "ball on track, amateria tusk", "balls in tusks", "bird, edanna", "blimp, voltaic", "contact us",
	  "d'ni", "edanna", "edanna bird", "edanna elevator plant", "edanna level explanation",
	  "edanna tusk", "edanna screenshots", "electric fish, edanna", "electromagnet, voltaic",
	  "elevator, amateria", "elevator, j'nanin", "email exile-hints", "endings",
	  "fish, edanna", "help using exile-hints", "hexagon maze, amateria", "instructions for using exile-hints",
	  "j'nanin", "jnanin", "jnanin amateria tusk", "jnanin edanna tusk",
	  "jnanin squee", "jnanin voltaic tusk", "jnanin viewers", "jnanin balls",
	  "j'nanin amateria tusk", "j'nanin edanna tusk", "j'nanin screenshots", 
	  "j'nanin voltaic tusk", "j'nanin viewers", "j'nanin balls", "journal", "lava room, voltaic",
	  "level 1, edanna", "level 2, edanna", "level 3, edanna", "level 4, edanna", "level 5, edanna",
	  "level 6, edanna", "level 7, edanna", "level 8, edanna", "level 9, edanna", "level 10, edanna",
	  "links", "main tusk", "missing journal pages", "moths", "multiple endings", "myst series",
	  "narayan", "news 'n' updates", "north puzzle in amateria",
	  "pagoda puzzles in amateria", "plot, exile", "plot, myst", "plot, myst series",
	  "plot, riven", "privacy policy", "releeshahn",
	  "saavedro", "saavedro\'s missing journal pages", "screenshots",
	  "spiral elevator plant, edanna", "spoiler section", "sound flower, j'nanin",
	  "south puzzle in amateria", "squee", "sunflower", "swing vine",
	  "tree in edanna", "tusk", "tusk code", "tomanah", "user's guide", "updates",
	  "viewer, j'nanin", "voltaic", "voltaic tusk", "voltaic screenshots",
	  "waterwheel, voltaic", "weights", "west puzzle in amateria",
	  "andy", "adam"
    ];
}

/**
 * Request suggestions for the given autosuggest control. 
 * @scope protected
 * @param oAutoSuggestControl The autosuggest control to provide suggestions for.
 */
HintSuggestions.prototype.requestSuggestions = function (oAutoSuggestControl /*:AutoSuggestControl*/) {
    var aSuggestions = [];
    var sTextboxValue = oAutoSuggestControl.textbox.value;
    
    if (sTextboxValue.length > 0){
    
        //search for matching hints
        for (var i=0; i < this.hints.length; i++) { 
            if (this.hints[i].indexOf(sTextboxValue) == 0) {
                aSuggestions.push(this.hints[i]);
            } 
        }
    }

    //provide suggestions to the control
    oAutoSuggestControl.autosuggest(aSuggestions);
};
            window.onload = function () {
                var oTextbox = new AutoSuggestControl(document.getElementById("txt1"), new HintSuggestions());        
            }