//
//  Class:
//      VdfGrid
//
//  Extends the DbList to an edit-in-place grid lookalike of the VDF grid.
//  
//  Since:      
//      24-10-2005
//  Changed:
//      --
//  Version:    
//      0.9
//  Creator:    
//      Data Access Europe (Harm Wibier)
//

//
//  Constructor of the DbGrid object. Calls the parent (DbList) constructor 
//  and initializes the attributes.
//
//  Params:
//      oTable      HTML DOM element of list table
//      oVdfForm    Parent form object
//
function VdfGrid(oTable, oVdfForm){
    //  Parent initialisation
    this.base = VdfList;
    this.base(oTable, oVdfForm);
    
    //  Settings (may overide list defaults)
    this.sServerTable       = browser.dom.getVdfAttribute(this.oTable, "sServerTable", null);
    
    this.bReturnCurrent     = browser.dom.getVdfAttribute(this.oTable, "bReturnCurrent", false);
    this.bJumpIntoList      = browser.dom.getVdfAttribute(this.oTable, "bJumpIntoList", false);
    this.bDisplayNewRow     = browser.dom.getVdfAttribute(this.oTable, "bDisplayNewRow", true);
    this.bFocus             = browser.dom.getVdfAttribute(this.oTable, "bFocus", false);
    
    this.sCssOrigEditRow    = "";
    
    //  Data structures
    this.oEditRow           = null;
    this.oOrigRow           = null;
    this.aEditFields        = new Array();
    this.oLastEditField     = null;
    this.oFirstEditField    = null;

    this.oLastFocus         = null;
    this.bRowChanged        = false;    
    
    if(this.sServerTable != null){
        this.sServerTable = this.sServerTable.toLowerCase();
    }
}

//  Extend DbList
VdfGrid.prototype = new VdfList;


//  Rename origional init method so it can be extended
VdfGrid.prototype.origInit = VdfGrid.prototype.init;

//
//  Initializes the grid by searching the edit row prototype and scanning for 
//  fields. Calls initField for each editfield found. When finished origInit is
//  called for the list initialisation part.
//
VdfGrid.prototype.init = function(){
    var iRow, oRow, aChilds, iChild, sColumn, oCurrentElement;

    //  Scan rows for header & display
    for(iRow = 0; iRow < this.oTable.rows.length && this.oEditRow == null; iRow++){
        oRow = this.oTable.rows[iRow];
        
        if(browser.dom.getVdfAttribute(oRow, "sRowType") == "edit"){
            this.oEditRow = oRow;
            this.sCssOrigEditRow = oRow.className;
        }
    }    
    if(this.oEditRow == null) alert("Edit row not found!");
    
    //  Scan for fields
    aChilds = browser.dom.getAllChildElements(this.oEditRow);
    for(iChild = 0; iChild < aChilds.length; iChild++){
        oCurrentElement = aChilds[iChild];
        if(oCurrentElement.oVdfField != null){
            this.initField(oCurrentElement.oVdfField);
        }
    }
    
    //  Call origional initialisation method
    this.origInit();
}

//
//  Initialises the given field by attaching events, adding it to the 
//  administration structure and giving it the focus if needed.
//
//  Params:
//      oVdfField   VdfField object
//
VdfGrid.prototype.initField = function(oVdfField){
    this.oLastEditField = oVdfField;

    //  Attach listeners
    oVdfField.addKeyListener(this.onFieldKeyPress);
    oVdfField.addGenericListener('focus', this.onFieldFocus);
    
    //  Add to administration
    this.aEditFields[oVdfField.getName()] = oVdfField;
    if(this.oFirstEditField == null){
        this.oFirstEditField = oVdfField;
    }
    
    //  Set datatype class for alignment (if no css class is set)
    if(oVdfField.getCSSClass() == null || oVdfField.getCSSClass() == ""){
        oVdfField.setCSSClass(this.oVdfForm.getVdfFieldAttribute(oVdfField, "sDataType") + "_data");
    }
    
    //  Give focus if needed
    if(this.bFocus){
        if(this.oLastFocus == null || oVdfField.getAttribute("bFocus", false) == true){
            oVdfField.focusSelect();
            this.oLastFocus = oVdfField;
        }
    }
    
    //  Set server table
    if(this.sServerTable != null){
        oVdfField.setServerTable(this.sServerTable, false);
    }
}



//
//  Selects an record by replacing its row with the editrow (filled with the 
//  record values). It tries to reselect the last edited field (column) in the
//  grid.
//
//  Parameters
//      oRecord             The record that should be selected
//
VdfGrid.prototype.selectRecord = function(oRecord){
    var oOrigRow, oEditRow;
    
    //  Fetch row objects
    oEditRow = this.oEditRow;
    oOrigRow = oRecord.oRow;
    
    //  Set values
    this.bRowChanged = false;
    
    //  Attach css style
    if(oRecord == this.oNewRecord && this.sCssNewRow != ""){
        oEditRow.className = this.sCssNewRow;
    }else if(this.sCssFilledRow != ""){
        oEditRow.className = this.sCssFilledRow;
    }else{
        oEditRow.className = this.sCssOrigEditRow;
    }
    
    //  Place row
    browser.dom.swapNodes(oOrigRow, oEditRow);
    
    //  Reselect field
    if(this.oVdfForm.oVdfActiveObject == this){
        this.catchFocus();
    }
    
    this.oOrigRow = oOrigRow;
}

//
//  Selects a record by removing the css class
//
//  Params:
//      bNoSave     If true the record will not be saved
//  Returns:
//      True if succesfull
//
VdfGrid.prototype.deSelectRecord = function(bNoSave){
    var oRecord = this.oSelectedRecord;
    
    //  Save if needed
    if(bNoSave || !this.isRowChanged() || this.save(true)){
        
        //  Replace row with orrigional
        browser.dom.swapNodes(this.oEditRow, this.oOrigRow);
		
        this.oOrigRow = null;
        
        return true;
    }else{
        //  Return false if save failed
        return false;
    }
}

VdfGrid.prototype.save = function(){
    return this.oVdfForm.doSave();
}

//
//  The clear of the grid is special regarding to the find / save / delete 
//  methods. It puts the orrigional buffered values of the selected record back
//  after user confirmation.
//
//  Params:
//      sClearTable Name of the table on which the action should be applied
//  Returns:
//      True if the clear is handled (only handles clear when on maintable of
//      the grid.)
//
VdfGrid.prototype.doClear = function(sClearTable){
    if(this.sMainTable == sClearTable && this.oSelectedRecord != null){
        if(confirm("Do you really wan't to undo the changes?")){
            this.oVdfForm.aTables[this.sMainTable].setValues(this.oSelectedRecord, true, false);
        }
        return true;
    }else{
        return false;
    }
}

//
//  Used to fetch a field input element from the grid
//
//  Params:
//      sName   Name of the field
//  Returns:
//      Field input element or null if not found
//
VdfGrid.prototype.getField = function(sName){
    return this.aEditFields[sName];
}

//
//  Checks if the constrain table of the mainfile (if it has one) has an 
//  record loaded. If not it sends an globalerror and returns false.
//
//  Returns:
//      True if access is alowed
//
VdfGrid.prototype.checkAccessAlowed = function(){
    var sConstrainFile, bResult = true;
    
    //  Check constrain file
    sConstrainFile = this.oVdfForm.aTables[this.sMainTable].sConstrainedTo;
    if(sConstrainFile != null){
        if(!this.oVdfForm.aTables[sConstrainFile].hasRecord()){
            if(this.oVdfForm.aTables[sConstrainFile].hasData() && confirm("Save the NEW header?")){
                bResult = this.oVdfForm.doSave(sConstrainFile, false);
            }else{
                bResult = false;
                if(this.oVdfForm.oVdfErrorHandler != null){
                    this.oVdfForm.oVdfErrorHandler.showGlobalError("Header table should be saved / found first", 4401);
                }
                
                if(this.oVdfForm.oPreviousFocus != null){
                    this.oVdfForm.oPreviousFocus.focusSelect();
                }
            }
        }
    }
    
    return bResult;
}

//
//  Returns:
//      True if the selected row is changed (by find or direct input)
//
VdfGrid.prototype.isRowChanged = function(){
    return this.oVdfForm.aTables[this.sMainTable].isDataChanged(this.oSelectedRecord, true, false);
}

//
//  (Overloads origional VdfList catchFocus) Puts the focus back to the last 
//  selected field or gives focus to the first field if none selected.
//
VdfGrid.prototype.catchFocus = function(){
    //  Focus last selected field (or first)
    if(this.oLastFocus != null){
        this.oLastFocus.focusSelect();
    }else{
        this.catchFocusFirstField();
    }
}

//
//  Returns focus to the first field (if has been set)
//
VdfGrid.prototype.catchFocusFirstField = function(){
    if(this.oFirstEditField != null){
        this.oFirstEditField.focusSelect();
    }
}


//
//  Fetches the keypress event of a grid field in a editeable row. It calls
//  the keyAction function to let the list do its actions.
//
//  Params:
//      e   Event object
// 
VdfGrid.prototype.onFieldKeyPress = function(e){
    var oInput, oTable, oVdfList, iKey;
    
    if(!browser.events.canceled(e)){
        //  Get needed objects and information
        oInput = browser.events.getTarget(e);

        oTable = browser.dom.searchParent(oInput, 'table');
        if(oTable == null)
            return false;
                    
        oVdfList = oTable.oVdfList;
        if(oVdfList == null)
            return false;
            
            
            
            
    	iKey = browser.events.getKeyCode(e);

        //  Call global list key handling method
        if(oVdfList.keyAction(iKey, browser.events.getCharCode(e), e.ctrlKey, e.shiftKey, e.altKey)){
            browser.events.stop(e);
            return false;
        }else if(iKey == 9 && !e.shiftKey){
            //  If tab in last field select next record
            if(oVdfList.aEditFields[oInput.name] == oVdfList.oLastEditField){ 
                // If tabbing out the last field select the next
                if(oVdfList.oSelectedRecord == oVdfList.oNewRecord){
                    oVdfList.save();
                    oVdfList.scroll(true);
                }else{
                    oVdfList.scroll(true);
                }
                oVdfList.oFirstEditField.focusSelect();
                browser.events.stop(e);
    			return false;
            }
    	}
    }

	return true;	
}

//
//  Called when an input element is selected. It stops the event and saves id 
//  of the selected column.
//
//  Param:
//      e   Event object (on some browsers)
//
VdfGrid.prototype.onFieldFocus = function(e){
    var oInput, oTable, oVdfList;

    if(!browser.events.canceled(e)){
    
        //  Get needed objects and information
        oInput = browser.events.getTarget(e);

        oTable = browser.dom.searchParent(oInput, 'table');
        if(oTable == null)
            return false;
                
        
        oVdfList = oTable.oVdfList;
        if(oVdfList == null)
            return false;

        //  Check if parents loaded
        if(!oVdfList.checkAccessAlowed()){
            browser.events.stop(e);
        }else{
            //  Save information about the selected object
            if(oVdfList.aEditFields[oInput.name] != null){
                oVdfList.oVdfForm.oVdfActiveObject = oVdfList;
                oVdfList.oLastFocus = oVdfList.aEditFields[oInput.name];
                
                if(oVdfList.oVdfForm.oPreviousFocus != oVdfList.oVdfForm.oLastFocus){
                    oVdfList.oVdfForm.oPreviousFocus = oVdfList.oVdfFormoLastFocus;
                }                                   
                oVdfList.oVdfForm.oLastFocus = oVdfList.aEditFields[oInput.name];
            }
        }
    }
}
