// Version 2; use object prototypes instead of function pointers
extend(ligoForm, ligoDSVisualiser);

function ligoForm (paramsObj) {
    //Constructor

    //all parameters are passed in JSON notation

    //Attributes
    this.instanceName;  //The name of the variable that is used for this object (I know this is horrible)
    this.Dataset;       //Instance of a ligoDataset
    this.div;           //The name of the target div
    this.inNew;         //flag to let us know that we are doing a new record

    //Finish the init by applying the passed in values
    ligoForm.superclass.call(this, paramsObj);
}

//#####################################################################################################################

/*
ligoForm.prototype._init = function (paramsObj) {

    if (paramsObj.instanceName) { this.instanceName = paramsObj.instanceName; }
    if (paramsObj.Dataset) { this.Dataset = paramsObj.Dataset; }
    if (paramsObj.div) { this.div = paramsObj.div; }

    this.Dataset.addDependant(this);

}
*/
//#####################################################################################################################

ligoForm.prototype.render = function () {

   this._set_values();

}

//#####################################################################################################################

ligoForm.prototype.Save = function () {

    var record = this._get_values();

    if (this.inNew) {   //new record
        this.Dataset.Save(record, true);
    }
    else {  //Updated record
        this.Dataset.Save(record, false);
    }

    return false; // return false to stop buttons accidentally submitting form when clicked
                    // (they should be set to type="button" though instead of relying on this)
}

//#####################################################################################################################

ligoForm.prototype.Delete = function () {

    var record = this._get_values();

    if (confirm("Really delete this data?")) {
        this.Dataset.Delete(record);
    }

    return false;
}

//#####################################################################################################################

ligoForm.prototype.StartNew = function () {

    this._clear_all_values();
    this.inNew = true;

    return false;
}

//#####################################################################################################################

ligoForm.prototype._get_values = function () {

    return this.action_on_fieldset('get');

}

//#####################################################################################################################

ligoForm.prototype._set_values = function () {

    this.action_on_fieldset('set');

}

//#####################################################################################################################

ligoForm.prototype._clear_all_values = function () {

    this.action_on_fieldset('clear');

}

//#####################################################################################################################

ligoForm.prototype.action_on_fieldset = function (action) {
    //action can be  get, set or clear

    var elements_in_div = this._get_div_elements();

    var formdata = {};

    //apparently looping without evaluating elements_in_div is faster because getElementsByTagName()
    //returns a dynamic object that has to be reevaluated every itteration to check the length
    for (var i = elements_in_div.length - 1; i > -1; i-- ) {
        var field = elements_in_div[i];
                        
        var field_exists = false;
        if (this.Dataset.nameIndex[field.name] != undefined) {
            field_exists = true;
        }
        
        //clear the value out of a field
        if ( field.tagName.match(/^(?:input|textarea)$/i) ) {
            if (action == 'set') {
                if (field.type != 'button') {
                    field.value="";
                }
            }
        }
        
        // Don't try to set something if it's not in the dataset
        if ( action == 'set' &&  ! field_exists ) {
            continue;   //this is the equivelent to perls next;
        }

        //Text type elements
        if ( field.tagName.match(/^(?:input|textarea)$/i) ) {

            if (field.type != 'button') {
                if (action == 'get') {
                    formdata[field.name] = field.value;
                }
                else if (action == 'set') {
                    //field.value = "xxxx";
                    field.value = this.Dataset.currentRow[this.Dataset.nameIndex[field.name]];
                }
                else if (action == 'clear') {
                    field.value = '';
                }
            }

        }

        //Select elements
        else if ( field.tagName.match(/^select$/i) ) {

            if (action == 'get') {
                // Handle selects with multiple options or ones set to submit all options
                // At the moment this relies on having select.name == ligoselectvarname which is messy
                var submit_all = ( window[field.name] && window[field.name].display
                                   && window[field.name].display.submitAllVisible );

                if (field.multiple || submit_all) {
                    formdata[field.name] = new Array();

                    for (var j=0; j < field.options.length; j++) {
                        if (field.options[j].selected == true || submit_all) {
                            formdata[field.name].push(field.options[j].value);
                        }
                    }
                }
                // Only do something if this selectbox has something selected
                else if (field.selectedIndex > -1) {
                    formdata[field.name] = field.value;
                }

            }
            else if (action == 'set') {
                field.selectedIndex = -1; // start by clearing any selection

                var value = this.Dataset.currentRow[this.Dataset.nameIndex[field.name]];

                if (value instanceof Array) { // the Dataset code can't do this, but it's here just in case
                    for (var j=0; j < field.options.length; j++) {
                        field.options[j].selected = (value.indexOf(field.options[j].value) != -1);
                    }
                }
                else {
                    for (var j=0; j < field.options.length; j++) {
                        if (value == field.options[j].value) {
                            field.options[j].selected = true;
                            break;
                        }
                    }
                }
            }
            else if (action == 'clear') {
                //select the first element
                field.selectedIndex = 0;
            }

        }

    }

    return formdata;
}

//#####################################################################################################################

//Standard callback handlers follow
ligoForm.prototype.onDS_dataLoaded = function (source) {
    //Sent by a dataset to tell us that the data has been loaded
    //Standard action is for us to render
    
    
    //FIXME: this method should be inherited, see the parent for more info
    this._init_display_formats();
    
    this.Dataset.setCurrentRow(0);
    this.render();
}

//#####################################################################################################################

ligoForm.prototype.onDS_newData = function (source) {

    this.render();

}

//#####################################################################################################################

ligoForm.prototype.onDS_currentRowChange = function (source) {
    //Selected row has changed, so we want to highlight the current row

    this.inNew = false;

    this.render();

}

//#####################################################################################################################

ligoForm.prototype._get_div_elements = function () {
    var elements = new Array();
    var form = document.getElementById(this.div);
    var element_types = ['SELECT', 'INPUT', 'TEXTAREA'];

    for (var i = element_types.length - 1; i >= 0; i--) {
        var these_elements = form.getElementsByTagName(element_types[i]);

        for (var j = these_elements.length - 1; j >= 0; j--) {
            //alert ("Pushing: " + these_elements[j]);
            elements.push( these_elements[j] );
        }
    }

    return elements;
}

//#####################################################################################################################
