// Original:  Anand Raman (anand_raman@poboxes.com) 
// Web Site:  http://www.angelfire.com/ar/diduknow 

// This file now depends on GC_BROWSER_SNIFFER.js being included first.
// Since GC_TOP includes GC_BROWSER_SNIFFER.js, this should always be the case.

// !!! These should be removed when safari tests are added to GC_BROWSER_SNIFFER.
var comboagent = navigator.userAgent.toLowerCase();
var using_safari = ((comboagent.indexOf('safari')!=-1)&&(comboagent.indexOf('mac')!=-1))?true:false;

var ENTRY_DIVIDER = ";;"
var VALUE_DIVIDER = "||"

var browser_does_outer_html = is_ie5_5up;
var browser_does_inner_html = using_safari;

// The support for NS4 has probably been broken since it was last tested, but
// we'll keep the NS4 tests in place for now.

// The constructor for option objects doesn't properly initialize selected and defaultSelected  in Netscape 4
var browser_doesnt_initialize_option_fields = is_nav4;
// Under some circumstances, adding elements to an array in NS4 doesn't set its length properly
var browser_doesnt_set_array_length = is_nav4;
// NS4 can't skip some initialization steps after search box is cleared.
var browser_needs_full_reinit = is_nav4;

var SelObjList = new Array();

function SelObj(formname,selname,textname,wildcard,str) {
    SelObjList[SelObjList.length] = this;
    this.formname = formname;
    if (document.forms[this.formname] == null) 
        alert("SelObj: Form " + this.formname + " not found.");
    this.selname = selname;
    if (document.forms[this.formname][this.selname] == null) 
        alert("SelObj: SELECT control " + this.selname + " not found.");
    this.textname = textname;
    this.wildcard = wildcard;
    this.select_str = str || '';

    // Optional 6th argument is value of initially selected item
    this.initialvalue = null;
    if (arguments.length > 5 && arguments[5] != null) {
        this.initialvalue = arguments[5];
    }
    
    // Optional 7th argument is max width of select box in pixels
    this.width = null;
    if (arguments.length > 6 && arguments[6] != null) {
        this.width = arguments[6];
    }
    
    this.builtFromHTML = (this.select_str == '');
    this.selectArr = new Array();
    this.initialize = initialize;
    this.reinitialize = reinitialize;
    this.bldInitial = bldInitial;
    this.bldList = bldList;
    this.bldListFromHtml = bldListFromHtml;
    this.bldListFromOptions = bldListFromOptions;
    if (browser_does_outer_html) {
        this.selectTag = document.forms[this.formname][this.selname].outerHTML;
        this.selectTag = this.selectTag.replace(/>.*$/, '>');
    }

    this.initialSelection = -1;
	this.lastSearchString = "";
	this.buildTime = 0;
	this.initTime = 0;
    this.initialized = false;
}

function initialize() {
    if (!browser_needs_full_reinit) {
        // Not sure why this causes problems in NS, but it makes the whole browser
        // abort. selectArr is messed up when we get here after search box is cleared.
        if (this.initialized)
            return;
		// If no max length, set style width to current width
		if (this.width == null)
			this.width = document.forms[this.formname][this.selname].offsetWidth;
		// Shorten element's style width if it's greater than specified max
		if (document.forms[this.formname][this.selname].offsetWidth < this.width)
			this.width = document.forms[this.formname][this.selname].offsetWidth;
		document.forms[this.formname][this.selname].style.width = this.width;

		// Javascript code in pages can't rely on the value of defaultSelected in
		// this select control's options, since the select control can shrink and
		// expand and the originally selected option may not currently be in the
		// select control.  So we create an origValue property that can be used
		// instead.
		if (document.forms[this.formname][this.selname].selectedIndex >= 0) {
			if (document.forms[this.formname][this.selname].origValue == document.undefinedproperty) {
				var defaultSelectedIndex = 0;
				for(var j=0;j<document.forms[this.formname][this.selname].options.length;j++) {
					if (document.forms[this.formname][this.selname].options[j].defaultSelected) {
						defaultSelectedIndex = j;
						break;
					}
				}
				
				document.forms[this.formname][this.selname].origValue = 
					document.forms[this.formname][this.selname].options[defaultSelectedIndex].value;
			}
			// !!! Commented out to fix bug 2004-18.  This line erroneously clears 
			// origValue when ResetSelObjs is called.  Need to watch for any
			// problems this may introduce.  This fix may need to be
			// ported to CAE.

			// else document.forms[this.formname][this.selname].origValue = "";
		}
    }

    var StartTime = new Date();
    this.initialized = true;
    var selectControl = document.forms[this.formname][this.selname];

    if (this.select_str =='') {
        for(var i=0;i<selectControl.options.length;i++) {
            if (i != 0)
                this.select_str += ENTRY_DIVIDER;
            this.select_str += selectControl.options[i].value + VALUE_DIVIDER
                + selectControl.options[i].text;
            if (selectControl.options[i].selected) {
                this.initialSelection = i;
            }
        }
    }

    var tempArr = this.select_str.split(ENTRY_DIVIDER);

    for(var i=0;i<tempArr.length;i++) {
        var prop = tempArr[i].split(VALUE_DIVIDER);
        var value = prop[0];
        var text = prop[1];
        this.selectArr[i] = new Option(text,value, false, false);
        if (browser_doesnt_initialize_option_fields) {
            this.selectArr[i].defaultSelected = false;
            this.selectArr[i].selected = false;
        }
        if (value == this.initialvalue) {
            this.initialSelection = i;
        }
    }
    if (browser_doesnt_set_array_length)
        this.selectArr.length = tempArr.length;

    if (this.initialSelection != -1) {
        this.selectArr[this.initialSelection].defaultSelected = true;
        this.selectArr[this.initialSelection].selected = true;
    }
	this.initTime = (new Date()).valueOf() - StartTime.valueOf();
}

function reinitialize(s) {
    this.select_str = s;
    this.initialized = false;
    this.bldList();
}

function bldInitial(LOVNum) {
    if (this.builtFromHTML) {
        this.initialize();
    }
    else {
        this.bldList();
    }

    // Call bldInitial for the next LOV in the list of LOVs.
    // See comments in InitSelObjs.
    ++LOVNum;
    if (LOVNum < SelObjList.length) {
        setTimeout("SelObjList[" + LOVNum + "].bldInitial(" + LOVNum + ");", 1);
    }
}

function bldList() {
    this.initialize();

    var StartTime = new Date();

    var searchstr;
    if (document.forms[this.formname] == document.undefinedProperty)
        searchstr = "";
    else searchstr = document.forms[this.formname][this.textname].value;
    searchstr = searchstr.toUpperCase();
	this.lastSearchString = searchstr;

    if (browser_does_inner_html || browser_does_outer_html) {
        this.bldListFromHtml(searchstr);
    }
    else {
        this.bldListFromOptions(searchstr);
    }
	this.buildTime = (new Date()).valueOf() - StartTime.valueOf();

	// Safari (as of 1.2) loses keyboard input events for characters that are typed into
	// the search box while the processing of the previous characters is still going on.
	// So we do another check in 100 msec to see if keyboard events were missed that
	// would have caused bldList to be called again.  If so, a call to bldList is forced.
	if (is_safari)
		setTimeout("if (" + this.selname + "_SelObj.lastSearchString != document.forms." + this.formname + "." + this.textname + ".value.toUpperCase()) " + this.selname + "_SelObj.bldList();", 100);
}

function bldListFromHtml(searchstr) {
	// Replacing the contents of the select element using innerHTML or outerHTML 
	// is many times faster than rebuilding the select element's options array.
    var selection = -1;
    if (searchstr == '')
        selection = this.initialSelection;
    var j = 0;
	var innerHTML = "";

    for(var i = 0; i < this.selectArr.length; i++) {
        var match = (searchstr == '');
        if (!match && this.selectArr[i].value != "") {
            var index = this.selectArr[i].text.toUpperCase().indexOf(searchstr);
            if (index == 0 || (this.wildcard && index >= 0))
                match = true;
        }
        if (match) {
            if (searchstr != '' && selection == -1)
                selection = j;
            var selectedAttr = ""
            if (j == selection)
                selectedAttr = ' selected';
            innerHTML += '<option value="' +  this.selectArr[i].value + '"' + selectedAttr + '>' + this.selectArr[i].text + '</option>';
            ++j;
        }
    }

	if (browser_does_inner_html) {
		document.forms[this.formname][this.selname].innerHTML = innerHTML;
	}
	else {
		var outerHTML = this.selectTag;
		outerHTML = outerHTML.replace('>', ' style="width:' + this.width + '">');
		outerHTML += innerHTML;
		outerHTML += '</select>';

		// Replacing outerHTML creates a new element, which will have no event handlers.
		// Save copies of the existing handlers to put in the new element.
		var handlers = new Object();
		for (var name in document.forms[this.formname][this.selname]) {
			if (name.substr(0,2) == "on" && document.forms[this.formname][this.selname][name] != null)
				handlers[name] = document.forms[this.formname][this.selname][name];
		}
		// Save the origValue property.
		var origValue = document.forms[this.formname][this.selname].origValue;

		// Replace the select tag
		document.forms[this.formname][this.selname].outerHTML = outerHTML;
		
		// Restore origValue
		document.forms[this.formname][this.selname].origValue = origValue;
		
		// Restore the old handlers
		for (name in handlers) {
			document.forms[this.formname][this.selname][name] = handlers[name];
		}
	}
}

function bldListFromOptions(searchstr) {
    var selection = -1;
    if (searchstr == '')
        selection = this.initialSelection;
    var j = 0;
    var padentry = -1;

    for(var i=0;i<this.selectArr.length;i++) {
        var match = (searchstr == '');
        if (!match && this.selectArr[i].value != "") {
            var index = this.selectArr[i].text.toUpperCase().indexOf(searchstr);
            if (index == 0 || (this.wildcard && index >= 0))
                match = true;
        }
        if (match) {
            if (searchstr != '' && selection == -1)
                selection = j;
            document.forms[this.formname][this.selname].options[j] = null;
            document.forms[this.formname][this.selname].options[j] = this.selectArr[i];
            document.forms[this.formname][this.selname].options[j].selected = false;
            ++j;
        }
    }

    document.forms[this.formname][this.selname].options.length = j;
    if (selection != -1)
        document.forms[this.formname][this.selname].options[selection].selected = true;

}

function ResetSelObjs() {
    for (var i = 0; i < SelObjList.length; ++i) {
        if (document.forms[SelObjList[i].formname][SelObjList[i].selname + '_filter'].value != "") {
			document.forms[SelObjList[i].formname][SelObjList[i].selname + '_filter'].value = "";
            SelObjList[i].bldList();
		}
    }
}

function InitSelObjs() {
    // Initialize all the LOVs in sequence, with a pause in between them 
    // to allow a redisplay.  Without the pause, the LOVs disappear until all
    // the initializations are done.
    // Call bldInitial on the first LOV. Use setTimeout so that the page finishes 
    // displaying before the initialization ties things up.  The first LOV's
    // bldInitial will call the second LOV's bldInitial, which will call the third, etc.
    if (SelObjList.length >= 0) {
        setTimeout("SelObjList[0].bldInitial(0)", 100);
	}
}
