/**********************************************************
ProgressSpinner
Author:		 Dan Brochu
Create date: 8/1/2007
Description: A small class useful for implementing graphical progress meters 
Dependencies: prototype.js v 1.5
Parameters:
    progressImg = ID or DOM element of <img> to use
    progressOnSrc =  URL of image to use when ProgressSpinner is on (spinning)
    progressOffSrc = URL of image to use when ProgressSpinner is off (inactive)
Methods:
    start()
    stop()
**********************************************************/
var ProgressSpinner = Class.create();
ProgressSpinner.prototype = {
    initialize: function(progressImg, progressOnSrc, progressOffSrc) {
        this.progressImg = $(progressImg);
        this.progressOn = new Image();
        this.progressOn.src = progressOnSrc;
        this.progressOff = new Image();
        this.progressOff.src = progressOffSrc;
        //this.src = this.progressOn.src;
    },
    
    start: function() {
        this.progressImg.src = this.progressOn.src;
    },
    
    stop: function() {
        this.progressImg.src = this.progressOff.src;
    }
}

/**********************************************************
DynamicDropdown
Author:		 Dan Brochu
Create date: 8/1/2007
Description: A class that enables the creation of dropdown lists populated by ajax requests
    triggerd by the change in value of a second field
Dependencies: prototype.js v 1.5
Parameters:
    targetField = ID or DOM element of <select> field to populate
    dataURL = URL of script that will provide a javascript array of select options
    postPars = Optional parameter list to pass to dataURL in the format of x=1&y=2, etc.
    progressImg = ID or DOM element of <img> to use as a ProgressSpinner
    progressOnSrc = URL of image to use when ProgressSpinner is on (spinning)
    progressOffSrc = URL of image to use when ProgressSpinner is off (inactive)
    callbackError = a function to handle errors that occur in DynamicDropdown methods. 
        The function will be passed one parameter, a string error description.
    formfieldsToPass = Optional 2D array of formfield element names and corresponding ID or DOM elements to evaluate and
        pass to the dataURL in addition to the postPars
Methods:
    sendRequest(element, value) 
        element = ID of DOM element of triggering field
        value = value of element field
**********************************************************/
var DynamicDropdown = Class.create();
DynamicDropdown.prototype = {

    initialize: function(targetField, dataURL, postPars, progressImg, progressOnSrc, progressOffSrc, callbackError, formfieldsToPass) {
	    this.targetField = $(targetField);
		this.dataURL = dataURL;
		this.postPars = postPars;
		this.errorOccurred = false;
		this.errorDescription = "";
		this.progressSpinner = new ProgressSpinner(progressImg, progressOnSrc, progressOffSrc);		
		this.callbackError = callbackError;	
		this.formfieldsToPass = formfieldsToPass;
    },
    
    getFormfieldValues: function() {
        if(typeof(this.formfieldsToPass) != 'undefined') {
            var retval = '';
            for(var j=0; j<this.formfieldsToPass.length; j++) {
                retval += '&' + this.formfieldsToPass[j][0] + '=' + $F(this.formfieldsToPass[j][1]);
            }
            return retval;
        }
        else {
            return '';
        }
    },
    
    sendRequest: function(element, value) {
        this.progressSpinner.start();
        this.clear();
        var requestPars = this.postPars;
        requestPars += "&triggerValue=" + value;
        requestPars += this.getFormfieldValues();
        var myAjax = new Ajax.Request(this.dataURL, {method: 'post', postBody: requestPars, onSuccess: this.loadData.bind(this), onFailure: this.catchFailure.bind(this), onException: this.catchException.bind(this) });
    },
    
    loadData: function(originalRequest) {
        // fill dropdown with results from ajax request
        try {
            //eval newOptions array contained in ajax response
            eval(originalRequest.responseText);
            this.fill(newOptions);
            this.progressSpinner.stop();
        }
        catch(err) {
            this.reportError(err.description);
        }
    },
    
    fill: function(optionsArray) {
        try {
            for(var i = 0; i<optionsArray.length; i++)
            {
                this.targetField.options[i+1] = new Option(optionsArray[i][1],optionsArray[i][0]);
            }
            this.targetField.options[0].selected = true;
            this.targetField.disabled = false; 
            this.progressSpinner.stop();
        }
        catch(err) {
            this.reportError(err.description);
        }
    },
    
    clear: function() {
        try {    
            this.targetField.options.length = 0;
            this.targetField.options[0] = new Option('-SELECT ONE-','');
            this.targetField.disabled = true;
        }
        catch(err) {
            this.reportError(err.description);
        }
    },
    
    catchException: function(t, e) {
        this.reportError(e);
    },
    
    catchFailure: function(req) {
        this.reportError(req.responseText);
    },    
    
    reportError: function(errorDesc) {
        this.progressSpinner.stop();
        this.callbackError(errorDesc);
    }
    
};	

/**********************************************************
AjaxRequester
Author:		 Dan Brochu
Create date: 12/4/2007
Description: A class to simplify the process of making an ajax request
Dependencies: prototype.js v 1.5
Parameters:
    ajaxUrl = Url of script that will accept the Ajax POST 
    postPars = Optional parameter list to pass to ajaxUrl in the format of x=1&y=2, etc.
    progressImg = ID or DOM element of <img> to use as a ProgressSpinner
    progressOnSrc = URL of image to use when ProgressSpinner is on (spinning)
    progressOffSrc = URL of image to use when ProgressSpinner is off (inactive)
    callbackSuccess = a function to handle successful completion of ajax POST opertation
        The function will be passed one parameter, the XMLHttpRequest object
    callbackError = a function to handle errors that occur in during processing. 
        The function will be passed one parameter, a string error description.
    formfieldsToPass = Optional 2D array of formfield element names and corresponding ID or DOM elements to evaluate and
        pass to the dataURL in addition to the postPars
Methods:
    sendRequest() 
**********************************************************/
var AjaxRequester = Class.create();
AjaxRequester.prototype = {

    initialize: function(ajaxURL, postPars, progressImg, progressOnSrc, progressOffSrc, callbackSuccess, callbackError, formfieldsToPass) {
		this.ajaxURL = ajaxURL;
		this.postPars = postPars;
		this.errorOccurred = false;
		this.errorDescription = "";
		this.progressSpinner = new ProgressSpinner(progressImg, progressOnSrc, progressOffSrc);		
		this.callbackError = callbackError;	
		this.callbackSuccess = callbackSuccess;
		this.formfieldsToPass = formfieldsToPass;
    },
    
    getFormfieldValues: function() {
        if(typeof(this.formfieldsToPass) != 'undefined') {
            var retval = '';
            for(var j=0; j<this.formfieldsToPass.length; j++) {
                retval += '&' + this.formfieldsToPass[j][0] + '=' + $F(this.formfieldsToPass[j][1]);
            }
            return retval;
        }
        else {
            return '';
        }
    },
    
    sendRequest: function() {
        this.progressSpinner.start();
        var requestPars = this.postPars;
        requestPars += this.getFormfieldValues();
        var myAjax = new Ajax.Request(this.ajaxURL, {method: 'post', postBody: requestPars, onSuccess: this.loadSuccess.bind(this), onFailure: this.catchFailure.bind(this), onException: this.catchException.bind(this) });
    },
    
    loadSuccess: function(originalRequest) {
        try {
            this.callbackSuccess(originalRequest);
            this.progressSpinner.stop();
        }
        catch(err) {
            this.reportError(err.description);
        }
    },
    
    catchException: function(originalRequest, exception) {
        this.reportError('Exception: ' + exception);
    },
    
    catchFailure: function(req) {
        this.reportError('Error: ' + req.status + ' -- ' + req.statusText);
    },    
    
    reportError: function(errorDesc) {
        this.progressSpinner.stop();
        this.callbackError(errorDesc);
    }
    
};	