/*
 * This JavaScript module that implements SelectionList.
 */

// For compatibility with older browsers instantiate a dummy
// selection list, ensures that the prototype of selection list will be correctly
// setup.
new SelectionList();

/**
 * This function returns 'true' if the specified string only consists
 * of whitespaces or '&nbsp;' characters, otherwise it returns 'false'
 *
 * theStr - The string that needs to be checked for emptinness.
 */
function isEmpty(theStr) {

    if (theStr == null || theStr.length == 0) {
        return true;
    }

    whiteSpaceRe1 = /^\s+/g;
    whiteSpaceRe2 = /\s+$/g;
    nbspRe1       = /^(&nbsp;)+/g;
    nbspRe2       = /(&nbsp;)+$/g;

    theStr = theStr.replace(whiteSpaceRe1, '').replace(whiteSpaceRe2, '');
    theStr = theStr.replace(nbspRe1, '').replace(nbspRe2, '');

    return (theStr.length == 0);
}

/**
 * Checks if the specified object is instance of the specified class.
 *
 * theObj   - The object to be checked.
 * theProto - The name of the constructor function for the class of interest.
 */
function isInstanceOf (theObj, theProto) {
    if (document.all) {
        return (eval ("theObj instanceof theProto"));
    }

    while (theObj != null) {
        if (theObj == theProto.prototype) {
	        return true;

	    } else {
	        theObj = theObj.__proto__;
	    }
	}

	return false;
}

/**
 * Returns 'true' if the specified object is an instance of the
 * array.
 *
 * theObj - The object to be checked for being an array.
 */
function isArray(theObj) {
    return isInstanceOf(theObj, Array);
}

/*
 * Construct selection list that will be displayed in a new window
 * containing document at the specified URL.
 *
 * theURL         - URL to be displayed in the selection list window.
 * theDestForm    - Form containing 'theDestElement'
 * theDestElement - Element within 'theDestForm' that will contain value if
 *                  method 'selectValue' is invoked on constructed instance
 *                  of selection list.
 * sourceElement -  Element within 'theDestForm' that will contain value of the field
 *                  the will be used as additional search criteria only
 */
function SelectionList(theURL, theDestForm, theDestElement) {
    this.url          = theURL;
    this.destForm     = theDestForm;
    this.destElement  = theDestElement;
    this.sourceElement= null;
    this.queryParams  = null;
    this.sql          = null;
    this.wildCard     = null;
    this.displayColumnIndex = null;
    this.errorIndex   = null;
    this.parameters   = null;
    this.selectedValues = new Array();
}

/*
 * Construct selection list that will be displayed in a new window
 * containing document at the specified URL.
 *
 * theURL         - URL to be displayed in the selection list window.
 * theDestForm    - Form containing 'theDestElement'
 * theDestElement - Element within 'theDestForm' that will contain value if
 *                  method 'selectValue' is invoked on constructed instance
 *                  of selection list.
 * theSourceElement-Element within 'theDestForm' that will contain value of the field
 *                  the will be used as additional search criteria only
 */
function SelectionList(theURL, theDestForm, theDestElement, theSourceElement) {
    this.url          = theURL;
    this.destForm     = theDestForm;
    this.destElement  = theDestElement;
    this.sourceElement= theSourceElement;
    this.queryParams  = null;
    this.sql          = null;
    this.wildCard     = null;
    this.autoExecuteQuery = null;
    this.displayColumnIndex = null;
    this.errorIndex   = null;
    this.parameters   = null;
    this.selectedValues = new Array();
}

/*
 * Construct selection list that will be displayed in a new window
 * containing document at the specified URL.
 *
 * theURL         - URL to be displayed in the selection list window.
 * theDestForm    - Form containing 'theDestElement'
 * theDestElement - Element within 'theDestForm' that will contain value if
 *                  method 'selectValue' is invoked on constructed instance
 *                  of selection list.
 * theSourceElement-Element within 'theDestForm' that will contain value of the field
 *                  the will be used as additional search criteria only
 */
function SelectionList(theURL, theDestForm, theDestElement, theSourceElement, theSQL, theWildCardSearchFlag, theAutoExecuteQuery, theParameters, theDisplayColumnIndex, theErrorIndex) {
    this.url          = theURL;
    this.destForm     = theDestForm;
    this.destElement  = theDestElement;
    this.sourceElement= theSourceElement;
    this.queryParams  = null;
    this.sql          = theSQL;
    this.wildCard     = theWildCardSearchFlag;
    this.autoExecuteQuery = theAutoExecuteQuery;
    this.parameters   = theParameters;
    this.displayColumnIndex = theDisplayColumnIndex;
    this.errorIndex   = theErrorIndex;
	this.selectedValues = new Array();
}


/**
 * Displays new window containing URL specified when constructing
 * SelectionList.
 */
SelectionList.prototype.show = function showImpl() {
    // Get Initial argument from editor screen
    var element  = (isArray(this.destElement)) ? this.destElement[0] : this.destElement;
    var destArgument  = document.forms[this.destForm].elements[element].value;
    var parameter = "";
    var par="";
    var sourceArguments = "";
    var displayArguments = "";
    var param = "";   

    //if(this.parameters != null) {
    //	parameter = document.forms[this.destForm].elements[this.parameters].value;
    //}
   // alert("element is " + element);
   // alert("parameter value is " + parameter);
   // alert("destArgument " + destArgument);
   // alert(this.url);
   // alert(this.destForm);
   // alert(this.destElement);
   // alert(this.sourceElement);
   // alert(this.sql);
   // alert(this.wildCard);
   // alert(this.parameters);
   // alert(this.displayColumnIndex);
   // alert(this.errorIndex);
      
    if ( this.sourceElement != null) {
        if (isArray(this.sourceElement, Array)) {
            //TO DO: provide funtionality to concat all the elements if the this.sourceElement is an Array
            alert("true");

        } else {
            sourceArguments = sourceArguments.concat("&").concat(escape(this.sourceElement)).concat("=").
                concat(escape(document.forms[this.destForm].elements[this.sourceElement].value));
        }
    }

    if( this.queryParams != null ) {
        sourceArguments = sourceArguments.concat("&").concat(this.queryParams);
    }

  //  alert("length" + this.parameters.length);
	
	if(this.displayColumnIndex != null && this.errorIndex != null) {
		displayArguments = displayArguments.concat("&DISPLAY_COLUMNS=").concat(escape(this.displayColumnIndex)).
							concat("&ERROR_MESSAGE_INDEX=").concat(escape(this.errorIndex));
	}

    if( this.sql != null && this.wildCard != null) {
    	par = "&CUSTOM_SQL_QUERY=".concat(escape(this.sql)).concat("&ALLOW_WILD_CARD_SEARCH=").concat(escape(this.wildCard)).
    	                               concat("&EXECUTE_SEARCH_BY_DEFAULT=").concat(escape(this.autoExecuteQuery));
    }
    if(this.parameters != null) {
    	if(this.parameters.length != 0) {
    		if (isArray(this.parameters, Array)) {
    		
    		var str ="";
				for(i=0;i<this.parameters.length;i++)
				{
			    	   	parameterValue = document.forms[this.destForm].elements[this.parameters[i]].value;
			    	   	str = str.concat("&CUSTOM_SQL_PARAMETER_LIST=").concat(escape(parameterValue));
				}
				param = par.concat(str);
    	   	} else {
    	   	parameter = document.forms[this.destForm].elements[this.parameters].value;
    	   	param = par.concat("&CUSTOM_SQL_PARAMETER_LIST=").concat(escape(parameter));
    	      }
    	   }
    }
    else  {
    	   param = par;
    }
	
	var arguments = '';
	if (document.forms[this.destForm].elements[element].id != '' && document.forms[this.destForm].elements[element].id == document.forms[this.destForm].elements[element].name) {
		var multiSelectedValues = new Array();
    	multiSelectedValues = destArgument.split(',');
    	arguments += "?";
    	for (i=0; i<multiSelectedValues.length; i++) {
    		arguments += "INITIALPRM=".concat(escape(multiSelectedValues[i])).concat(sourceArguments).concat(displayArguments).concat(param).concat('&');
    		if (multiSelectedValues[i] != '') {
    			this.selectedValues.push(multiSelectedValues[i]);
    		}
    	}
    } else {
    	arguments = "?INITIALPRM=".concat(escape(destArgument)).concat(sourceArguments).concat(displayArguments).concat(param);    	    		
    }    

        // Ignore sourceElement if it's value is NULL and Consider only if the value is other than ""
        // If the value of sourceElement is equal to "", then prompt the user to enter a value for Supplier Id
        // Keep track of the opened window
        if (this.sourceElement ==null || document.forms[this.destForm].elements[this.sourceElement].value != "") {

            this.window               = window.open(
                                        this.url.concat(arguments), 'SelectionList',
                                        'height=350,width=550,toolbar=0,menubar=0,scrollbars=1,resizable=1,status=1,location=0,left=30,top=30');

        }
        // If the sourceElement is "" then prompt the user for the SupplierId as it is required attribute to display
        // the ItemId (product Id) selection List from the OrderEditor Screen
        else {
            var message = "Please enter the Manufacturer/Supplier.";
            alert(message);
            return;
        }

   // alert(arguments);

    // Ensure that the opener for the new window is preserved as the original window.
    this.window.opener        = self;

    // Add an attribute to the opener window to reference 'this' selection list
    // so that javascript can be used to select the values is the original
    // window.
    this.window.opener.selectionList = this;

    // Always focus selection list window when show is requested.
    this.window.focus();
}

/**
 * Closes SelectionList window, without assigning any values
 * to 'destForm.destElement'.
 */
SelectionList.prototype.close = function closeImpl() {
    this.window.close();
}

/**
 * Closes SelectionList window, after assigning value to the
 * 'destForm.destElement'.
 */
SelectionList.prototype.selectValue = function selectValueImpl(theVal) {
    // Set specified parameter as the new value for the form element that was
    // specified when selection list was constructed.
    if (isArray(this.destElement)) {
        for (i = 0; i < this.destElement.length; i++) {
            this.selectValueIntoComponent(this.window.opener.document.forms[this.destForm].elements[this.destElement[i]], theVal[i]);
        }
        this.window.opener.document.forms[this.destForm].elements[this.destElement[0]].focus();
    } else {
        this.selectValueIntoComponent(this.window.opener.document.forms[this.destForm].elements[this.destElement], theVal[0]);
        this.window.opener.document.forms[this.destForm].elements[this.destElement].focus();
    }
    this.close();
}

/**
 * This method implements the selection of the values.
 * It simply allows other select methods to handle selections
 * in the manner appropriate fo the specified component.
 */
SelectionList.prototype.selectValueIntoComponent = function selectValueIntoComponentImpl(theComponent, theVal)  {
    this.selectValueIfSelectComponent(theComponent, theVal);
    this.selectValueIfTextComponent(theComponent, theVal);
    return true;
}

/**
 * Ensures that the destination element of the selection list
 * is selection list, and if it is, adds an option to the
 * selection list.
 */
SelectionList.prototype.selectValueIfSelectComponent = function selectValueIfSelectComponentImpl(theComponent, theVal) {

    // Do not try to add empty string.
    if (isEmpty(theVal)) {
        return;
    }


    // Returns immediately if the input is not a valid select.
    var isValidSelect = theComponent.type == "select" || theComponent.type == "select-one" || theComponent.type == "select-multiple";
    if (!isValidSelect) {
        return;
    }
    // Find option with the value equal to the one specified.
    var foundEqualValue = false;
    for (k = 0; k < theComponent.length; k++) {
        if (theComponent.options[k].value == theVal) {
            theComponent.options[k].selected = true;
            foundEqualValue = true;
            break;
        }
    }

    // Quit if duplicate value is in the selection box already.
    if (foundEqualValue) {
        return;
    }

    // Create new option to be added to the select.
    var newOption = new Option();

    newOption.text     = theVal;
    newOption.value    = theVal;
    newOption.selected = theVal;

    // Add the new option to the select
    theComponent.options[theComponent.options.length] = newOption;
    theComponent.focus();
}

/**
 * Ensures that the destination element of the selection list
 * is a text box or something like a text boc, and if it is
 * sets the selected value as the value of the text component.
 */
SelectionList.prototype.selectValueIfTextComponent = function selectValueIfTextComponentImpl(theComponent, theVal) {

    // Make sure that the component is a text component.
    var isValidText = theComponent.type == "text" || theComponent.type == "textarea" || theComponent.type == "hidden";
    if (!isValidText) {
        return;
    }

    theComponent.value = theVal;

    if(theComponent.type != "hidden") {
    	theComponent.focus();
    }
}

/**
 * Closes SelectionList window, after assigning value to the
 * 'destForm.destElement'.
 */
SelectionList.prototype.selectValuewoFocus = function selectValueImplwoFocus(theVal) {
    // Set specified parameter as the new value for the form element that was
    // specified when selection list was constructed.
    if (isArray(this.destElement)) {
        for (i = 0; i < this.destElement.length; i++) {
            this.selectValueIntoComponentwoFocus(this.window.opener.document.forms[this.destForm].elements[this.destElement[i]], theVal[i]);
        }
        this.window.opener.document.forms[this.destForm].elements[this.destElement[0]].focus();
    } else {
        this.selectValueIntoComponentwoFocus(this.window.opener.document.forms[this.destForm].elements[this.destElement], theVal[0]);
        this.window.opener.document.forms[this.destForm].elements[this.destElement].focus();
    }
    this.close();
}
/**
 * This method implements the selection of the values.
 * It simply allows other select methods to handle selections
 * in the manner appropriate fo the specified component.
 */
SelectionList.prototype.selectValueIntoComponentwoFocus = function selectValueIntoComponentImplwoFocus(theComponent, theVal)  {
    this.selectValueIfSelectComponentwoFocus(theComponent, theVal);
    this.selectValueIfTextComponentwoFocus(theComponent, theVal);
}

/**
 * Ensures that the destination element of the selection list
 * is selection list, and if it is, adds an option to the
 * selection list.
 */
SelectionList.prototype.selectValueIfSelectComponentwoFocus = function selectValueIfSelectComponentImplwoFocus(theComponent, theVal) {

    // Do not try to add empty string.
    if (isEmpty(theVal)) {
        return;
    }


    // Returns immediately if the input is not a valid select.
    var isValidSelect = theComponent.type == "select" || theComponent.type == "select-one" || theComponent.type == "select-multiple";
    if (!isValidSelect) {
        return;
    }

    // Find option with the value equal to the one specified.
    var foundEqualValue = false;
    for (i = 0; i < theComponent.length; i++) {
        if (theComponent.options[i].value == theVal) {
            theComponent.options[i].selected = true;
            foundEqualValue = true;
            break;
        }
    }

    // Quit if duplicate value is in the selection box already.
    if (foundEqualValue) {
        return;
    }

    // Create new option to be added to the select.
    var newOption = new Option();

    newOption.text     = theVal;
    newOption.value    = theVal;
    newOption.selected = theVal;

    // Add the new option to the select
    theComponent.options[theComponent.options.length] = newOption;
}

/**
 * Ensures that the destination element of the selection list
 * is a text box or something like a text boc, and if it is
 * sets the selected value as the value of the text component.
 */
SelectionList.prototype.selectValueIfTextComponentwoFocus = function selectValueIfTextComponentImplwoFocus(theComponent, theVal) {

    // Make sure that the component is a text component.
    var isValidText = theComponent.type == "text" || theComponent.type == "textarea" || theComponent.type == "hidden";
    if (!isValidText) {
        return;
    }
    theComponent.value = theVal;
}


/*
 * Displays selection list in a new window containing document with the specified URL.
 *
 * theURL         - URL to be displayed in the selection list window.
 * theDestForm    - Form containing 'theDestElement'
 * theDestElement - Element within 'theDestForm' that will contain value if
 *                  method 'selectValue' is invoked on constructed instance
 *                  of selection list, may be an array of elements within
 *                  dest form.
 */
function showSelectionList(theURL, theDestForm, theDestElement) {
    new SelectionList(theURL, theDestForm, theDestElement).show();
}

/*
 * Displays selection list in a new window containing document with the specified URL.
 *
 * theURL         - URL to be displayed in the selection list window.
 * theDestForm    - Form containing 'theDestElement'
 * theDestElement - Element within 'theDestForm' that will contain value if
 *                  method 'selectValue' is invoked on constructed instance
 *                  of selection list, may be an array of elements within
 *                  dest form.
 * thesourceElement-Element within 'theDestForm' that will contain value of the field
 *                  the will be used as additional search criteria only
 */
function showSelectionList(theURL, theDestForm, theDestElement, theSourceElement) {
    new SelectionList(theURL, theDestForm, theDestElement, theSourceElement).show();
}


/*
 * Displays selection list in a new window containing document with the specified URL.
 *
 * theURL         - URL to be displayed in the selection list window.
 * theDestForm    - Form containing 'theDestElement'
 * theDestElement - Element within 'theDestForm' that will contain value if
 *                  method 'selectValue' is invoked on constructed instance
 *                  of selection list, may be an array of elements within
 *                  dest form.
 * theQueryParams - Additional query params to pass to the selection list
 */
function showSelectionListWithQueryParams(theURL, theDestForm, theDestElement, theQueryParams) {
    sl = new SelectionList(theURL, theDestForm, theDestElement);
    sl.queryParams = theQueryParams;
    sl.show();
}


/*
 * Displays selection list in a new window containing document with the specified URL.
 *
 * theURL         - URL to be displayed in the selection list window.
 * theDestForm    - Form containing 'theDestElement'
 * theDestElement - Element within 'theDestForm' that will contain value if
 *                  method 'selectValue' is invoked on constructed instance
 *                  of selection list, may be an array of elements within
 *                  dest form.
 * thesourceElement-Element within 'theDestForm' that will contain value of the field
 *                  the will be used as additional search criteria only
 */
function showSelectionList(theURL, theDestForm, theDestElement, theSourceElement, theSql, theDoBlindSearch, theAutoExecuteQuery, theParameters){
    new SelectionList(theURL, theDestForm, theDestElement, theSourceElement, theSql, theDoBlindSearch, theAutoExecuteQuery, theParameters).show();
}
