


//defines an object that simplifies grid data handling
//-----------------------------------------------------

var GridData=function(oOptions) { //GridData Object
  var _gr_reader;
  var _gr_fields;
  var _gr_oEDRC;
  var _gr_plugins=[];
  
  if (typeof oOptions=='undefined')
    oOptions={};

  var normalSearch=1; //search window is used for search
  var normalReset=1; //search window is used for search
  var uType='';
  if (oOptions.searchWindow) {
    if (typeof oOptions.searchWindow.button_search_action!='undefined')
       normalSearch=0; //special function (like filtering on addcampaign)
    if (typeof oOptions.searchWindow.button_reset_action!='undefined')
       normalReset=0; //special function (like filtering on addcampaign)
    if (typeof oOptions.searchWindow.uType!='undefined')
      uType=oOptions.searchWindow.uType;
  }

  var buttonSearchText='Search';
  if (uType=='filter') buttonSearchText='Set filter';

  //define search window -- init -->
  //search window  
  var oSearchWindowOptions={};
  var oSearchWindowOptions_defaults={
    width:540,height:500,autoHeight:true,closeAction:'hide',plain:true,
    title:_LANG.searchWindow.title,bodyBorder:false,border:false,
    modal:true,resizable:false,
    buttons: [
      {text:buttonSearchText,disabled:false,handler: 
        function() {
          
          //inspect all fields and raise errors for improper search
          var formy=_gr_searchWindow.oForm.form;
          var gridy=_gr_searchWindow.grid;
          var filterParams=_gr_searchWindow.oForm.form.getValues();
          var aFilterss=new Array();
          var aContentss=new Array();
          for (var z in filterParams) {
            if (z.indexOf('searchcontent_')==0) {
              var sidx=z.replace('searchcontent_','');
              if (filterParams[z])
                aContentss[sidx]=filterParams[z];
              else
                aContentss[sidx]='';
            }  
            if (z.indexOf('searchfilter_')==0) {
              var sidx=z.replace('searchfilter_','');
              if (filterParams[z])
                aFilterss[sidx]=filterParams[z];
              else  
                aFilterss[sidx]='';
            }  
          }
          var allNull=1;
          for (var z in filterParams) {
            if (filterParams[z]!='' && z!='search_condition')
              allNull=0;
          }
          if (uType=='filter') { //in filter mode null filters are allowed -> this mean we want to mail the entire list
            allNull=0;
          }
          if (allNull) {
            Ext.Msg.alert('Error','Please enter your search criteria for one or more of the available fields');  
          } else {
            //console.log(aContentss);
            var someIncompletes=0; 
            for (var z in aContentss) {
              //alert(z+' '+typeof aContentss[z])
              if (typeof aContentss[z]=='string') { //skip Ext array prototype added functions like 'the remove' method
                //alert('looping z:'+z+' acontent: "'+aContentss[z]+'" afilter: seba'+aFilterss[z]+'seba');
                if (aContentss[z]!='' && aFilterss[z]=='') {
                  //alert(z+' '+filterParams[aContentss[z]]+' '+filterParams[aFilterss[z]])
                  formy.findField('searchfilter_'+z).markInvalid('Please specify a search criteria');
                  someIncompletes=1;
                }  
                if (aContentss[z]=='' && aFilterss[z]!='')  {
                  //alert(z+' '+filterParams[aContentss[z]]+' '+filterParams[aFilterss[z]])
                  //alert(z);                
                  formy.findField('searchcontent_'+z).markInvalid('Please specify the search content');
                  someIncompletes=1;
                }
              }  
            }

            if (!someIncompletes) {
              if (normalSearch) {
                var ds=_gr_searchWindow.parentGrid.Store;
                var filterParams=_gr_searchWindow.oForm.form.getValues();
                filterParams.filter=1;
                ds.load( {params:_gr_searchWindow.parentGrid.getParams(filterParams)} );
                _gr_searchWindow.hide(); //hide the search window
              } else {
                var filterParams=_gr_searchWindow.oForm.form.getValues();
                oOptions.searchWindow.button_search_action(filterParams);
                _gr_searchWindow.hide(); //hide the search window
              }  
            }  
          }  
        }
      },
      
      {text:'Reset',disabled:false,handler:
        function(){
          //reset all fields
          var filterParams=_gr_searchWindow.oForm.form.getValues();
          for (var z in filterParams) {
            try {
              effe=_gr_searchWindow.oForm.form.findField(z);
              //console.log(effe);
              effe.setValue(''); //make sure al combo boxes are reset (the null element is selected)
              effe.setRawValue(''); //then set null values for every field
              effe.clearInvalid();
            } catch(er) {
            }  
          }
          if (normalReset) {
            //reload data without filters
            var ds=_gr_searchWindow.parentGrid.Store;
            ds.load({params:_gr_searchWindow.parentGrid.getParams()});
            _gr_searchWindow.hide(); //hide the search window
          } else {
            oOptions.searchWindow.button_reset_action();
            _gr_searchWindow.hide(); //hide the search window
          }  
        }
      },
      {text:'Cancel',disabled:false,handler:function(){_gr_searchWindow.hide()}}
    ]
    
  };
  if (typeof oOptions.searchWindow=='undefined') oOptions.searchWindow={};
  Ext.apply(oSearchWindowOptions,oOptions.searchWindow,oSearchWindowOptions_defaults)
  var _gr_searchWindow=new Ext.Window(oSearchWindowOptions);

  //search form
  var oSearchFormOptions={};
  var oSearchFormOptions_defaults={
    autoHeight:false,autoScroll:true,frame:true,
    width:650,
    bodyStyle:'padding:10px 10px 10px',
    items:[{
        layout:'column',
        labelWidth:150,
        items:[
          {columnWidth:.33,layout:'form',items:[{checked:true,autoHeight:true,style:'margin-top:9px',width:20,xtype:'radio',name:'search_condition',inputValue:'search_and',fieldLabel:_LANG.searchWindow.radioAnd}] },
          {columnWidth:.4,layout:'form',items:[{autoHeight:true,style:'margin-top:9px',width:20,xtype:'radio',name:'search_condition',inputValue:'search_or',fieldLabel:_LANG.searchWindow.radioOr}] }
        ]
    }]
  };
  
  if (typeof oOptions.searchForm=='undefined') oOptions.searchForm={};
  Ext.apply(oSearchFormOptions,oOptions.searchForm,oSearchFormOptions_defaults) 
  var _gr_searchForm = new Ext.FormPanel(oSearchFormOptions);
  
  _gr_searchWindow.add(_gr_searchForm);
  _gr_searchWindow.oForm=_gr_searchForm;
  //define searchForm property fot the GridData object
  this.searchWindow=_gr_searchWindow;
  //<-- define search window -- end
  
  getExtRecordData=function() {
    var a=[];
    var zEnd=_gr_fields.length;
    for (var z=0;z<zEnd;z++) {
      a[a.length]=_gr_fields[z].dataIndex;
    }
    return a;
  }
  
  this.setReader=function(oR) {
      _gr_reader=oR;
   };
  this.getPlugins=function() {
    return _gr_plugins;
  }

  this.getFields=function() {
    return _gr_fields;
  }  

  this.getField=function(id) {
    return _gr_fields[id]; //id=integer
  }  

  this.getFieldById=function(sId) {
        for (var z=0,zEnd=_gr_fields.length;z<zEnd;z++) {
      if (_gr_fields[z].dataIndex) {
        if (_gr_fields[z].dataIndex==sId)
          return _gr_fields[z];
        }  
    }
    return null;
  }  
    
  this.setFields=function(oF) {
      _gr_fields=oF;
      var a=[];
      var wichFilterStore,typ,labell;
      if (oF) {
        var zEnd=oF.length;
        //mem fields and auto build search form
        for (var z=0;z<zEnd;z++) {
          var iddo=a.length;
          a[a.length]=_gr_fields[z];
          var summaryType='';
          //console.log(_gr_fields[z]);
          if (typeof _gr_fields[z].summaryType!='undefined')
            summaryType=_gr_fields[z].summaryType;
          a[iddo].summaryType=summaryType;
          a[iddo].grandTotal=_gr_fields[z].grandTotal;
          if (typeof oF[z].name!='undefined' && (typeof oF[z].publish=='undefined' || oF[z].publish) && oF[z].name!='hh_status') {
//            alert(oF[z].header);
            if (typeof oF[z].header!='undefined')                  
              labell=oF[z].header;
            else
              labell='';
            labell=labell.replace(/<[^>]+>/,'');//strip html for search label
            typ=oF[z].searchType;
            if (typeof typ=='undefined') { //v1.5 user defined type added
              if (typeof oF[z].userType!='undefined' && oF[z].userType!='')
                typ=oF[z].userType;
            }
            //console.log(typ);
            
            switch (typ) {
              case 'number':wichFilterStore=_APP.store_searchFilterNumber;break;
              case 'date':wichFilterStore=_APP.store_searchFilterDate;break;
              case 'fixed':wichFilterStore=_APP.store_searchFilterFixed;break;
              case 'boolean':wichFilterStore=_APP.store_searchFilterFixed;break;
              default:wichFilterStore=_APP.store_searchFilterText;break;
            }
            var osF= new Ext.form.ComboBox({
              width:180,
              store:wichFilterStore,//listWidth:300,
              valueField:'value',displayField:'text',editable:false,mode:'local',triggerAction: 'all',selectOnFocus:true,
              hiddenName:'searchfilter_'+oF[z].name, //attach value field to a dynamically generated hidden input 
              fieldLabel:labell,
              tpl:'<tpl for="."><div class="x-combo-list-item"><tpl if="value==\'\'">&nbsp;</tpl><tpl if="value!=\'\'">{[values.text]}</tpl></div></tpl>'
            });
            /*
             //discontinued - use tpl instead
            //use a little trick to set a null value 
            osF.on('select',
              function(oCombo,oRecord,iIndex) {
                if (iIndex==0)
                  oCombo.setRawValue('');
                return false;
              }      
            )
            */
            //no searchValues, use a standard text box
            if (typeof oF[z].searchValues=='undefined' || oF[z].searchValues=='') { //per tutti i campi che non hanno un search value...
              switch (typ) {
                case 'number':
                  var oI=new Ext.form.NumberField({
                     hideLabel:true,
                     width:180,
                     name:'searchcontent_'+oF[z].name,
                  });
                break;
                case 'date':
                  var oI=new Ext.form.DateField({
                     format:'Y-m-d',
                     hideLabel:true,
                     width:180,
                     name:'searchcontent_'+oF[z].name,
                  });
                break;
                default:
                  var oI=new Ext.form.TextField({
                     hideLabel:true,
                     width:180,
                     name:'searchcontent_'+oF[z].name,
                  });
                break;  
              }  
            } else { //build a combo and set all specified options
              var aaa=oF[z].searchValues;
              if (typeof aaa=='string') { //evaluate values if coming direclty from php
                try{
                    aaa=eval(oF[z].searchValues);
                  } catch(er){
                    console.log('this.setFields searchValues ERROR: searchValues');
                    console.log(er);
                    console.log(oF[z].searchValues);
                  };
              }  
              var dynamic_store = new Ext.data.SimpleStore({
                fields:['value','text'],
                data:aaa
              });
              var oI=new Ext.form.ComboBox({
                width:180,
                hideLabel:true,
                store:dynamic_store,//listWidth:300,
                valueField:'value',displayField:'text',editable:false,mode:'local',triggerAction:'all',selectOnFocus:true,
                hiddenName:'searchcontent_'+oF[z].name, //attach value field to a dynamically generated hidden input
                tpl:'<tpl for="."><div class="x-combo-list-item"><tpl if="value==\'\'">&nbsp;</tpl><tpl if="value!=\'\'">{[values.text]}</tpl></div></tpl>'
              });
              /*
              oI.on('select',
                function(oCombo,oRecord,iIndex) {
                  if (iIndex==0)
                    oCombo.setRawValue('');
                  return false;
                }      
              );
              */
            }
            this.searchWindow.oForm.add(
              {labelAlign:'left',labelWidth:100,layout:'column',items:[{layout:'form',columnWidth:.5,items:[osF]},{layout:'form',columnWidth:.5,items:[oI]} ]}
            );
          }  
        }
      }  
      _gr_oEDRC=Ext.data.Record.create(a);
  }

  this.getReader=function() {
      return new Ext.data.JsonReader(_gr_reader,getExtRecordData());
    }

  this.getDefaults=function() {
      var o={};
      var zEnd=_gr_fields.length;
      for (var z=0;z<zEnd;z++) {
        if (_gr_fields[z].publish!=false)          
          o[_gr_fields[z].dataIndex]=_gr_fields[z].defaultValue?_gr_fields[z].defaultValue:'';
      }
      var p=new _gr_oEDRC(o);
      return p; 
    }  

  this.getArrayReader=function() {
    /*
    crea un array reader tenendo correttamente conto di eventuali
    colonne aventi publish=0
    [
      {name: 'company'},
      {name: 'price', type: 'float'},
      {name: 'change', type: 'float'},
      {name: 'pctChange', type: 'float'},
      {name: 'lastChange', type: 'date', dateFormat: 'n/j h:ia'}
     ]
    */
    var o={};
    var retArray=[];
    if (_gr_fields) {
      var zEnd=_gr_fields.length;
      for (var z=0;z<zEnd;z++) {
        if (_gr_fields[z].publish!=false) { //i campi non pubblicati non devono essere inclusi nell'array reader
          var o={};
          o.name=_gr_fields[z].name;
          if (typeof _gr_fields[z].type!='undefined')
            o.type=_gr_fields[z].type;
          o.mapping=z;  
          retArray[retArray.length]=o;
          //console.log(retArray[retArray.length-1]);
        }                   
      }
     //console.log(retArray);
     return new Ext.data.ArrayReader({},retArray);
   } else {
     return null;
   }  
  }

  this.getExtGridColumModel=function() {
      var a=[];
      var zEnd=_gr_fields.length;
      for (var z=0;z<zEnd;z++) {
        if (typeof _gr_fields[z].publish=='undefined' || _gr_fields[z].publish) {
          /*
          since getExtGridColumModel can be builded from json we create some special fields
          - sJS - by setting this param you can pass a new object (like new Ext.grid.RowNumberer() ) or function to this field
          - sUJS - javascript user-defined che viene eseguito prima della creazione del componente - può contenere un codice qualsiasi
                   window_fileupload ne fa uso per creare un editor di tipo combo che esegue delle azione in base al valore selezionato 
          //usable functions if you are building the grid trough php                   
          - sEditor   - contains jscript code for the editor paramenter - result is assigned to editor property
          - sRenderer - contains jscript (function name or function content) code for renderer param - result is assigned to renderer property
          - sHeader   - contains jscript code for header param - - result is assigned to header property (see page_adv_campaign_addnew)
          php scripts that defines fields (see window_fileupload ad page_lists_list) must use this
          special properties..
          see utils_buildGloGridFields for more info
          */
          for (var xz in _gr_fields[z]) {
            switch (xz) {
              case 'sUJS':
                try{
                    eval(_gr_fields[z][xz]);
                  }catch(er){
                    console.log('getExtGridColumModel editor ERROR: sUJS');
                    console.log(er);
                    console.log(_gr_fields[z][xz])
                  };
              break;
              case 'sJS':
                try{
                    _gr_fields[z]=eval(_gr_fields[z][xz]);
                  }catch(er){
                    console.log('getExtGridColumModel editor ERROR: sJS');
                    console.log(er);
                    console.log(_gr_fields[z][xz])
                  };
              break;
              case 'sEditor':
                try{
                    _gr_fields[z].editor=eval(_gr_fields[z][xz]);
                  }catch(er){
                    console.log('getExtGridColumModel editor ERROR: sEditor');
                    console.log(er);
                    console.log(_gr_fields[z][xz]);
                    console.log(_gr_fields);
                  };
              break;
              case 'sRenderer':
                try{
                    _gr_fields[z].renderer=eval(_gr_fields[z][xz]);
                  }catch(er){
                    console.log('getExtGridColumModel renderer ERROR: sRenderer');
                    console.log(er);
                    console.log(_gr_fields[z][xz])
                  };
              break;
              case 'sHeader':
                try{
                    _gr_fields[z].header=eval(_gr_fields[z][xz]);
                  }catch(er){
                    console.log('getExtGridColumModel renderer ERROR: sHeader');
                    console.log(er);
                    console.log(_gr_fields[z][xz])
                  };
              break;
            }
          }
          a[a.length]=_gr_fields[z];
        }     
      }
      return a;
    }

  this.getExtDataConnectionRequestParams=function(oData,oAddtionalData) {
      var o={};
      var zEnd=_gr_fields.length;
      for (var z=0;z<zEnd;z++) {
        o[_gr_fields[z].dataIndex]=oData[_gr_fields[z].dataIndex];
      }
      for (var z in oAddtionalData) {
        o[z]=oAddtionalData[z];
        //alert(z+' '+oAddtionalData[z]);                   
      }
      //console.log(o);
      return o;
  }
  
  return this;
} //end of gridData object

//griddata object end
/*
===============================================================================================================================
===============================================================================================================================
===============================================================================================================================
*/

//add a new check column type for ExtGridDataEditor
//-----------------------------------------------------
Ext.grid.CheckColumn = function(config){
    Ext.apply(this, config);
    if(!this.id){
        this.id = Ext.id();
    }
    this.renderer = this.renderer.createDelegate(this);
};

Ext.grid.CheckColumn.prototype ={
    init : function(grid){
        this.grid = grid;
        this.grid.on('render', function(){
            var view = this.grid.getView();
            view.mainBody.on('mousedown', this.onMouseDown, this);
        }, this);
    },

    onMouseDown : function(e, t){
        if(t.className && t.className.indexOf('x-grid3-cc-'+this.id) != -1){
            e.stopEvent();
            var index = this.grid.getView().findRowIndex(t);
            var record = this.grid.store.getAt(index);
            record.set(this.dataIndex, !record.data[this.dataIndex]);
            if (this.onafteredit) {
              /* 
              * grid - This grid
              * record - The record being edited
              * field - The field name being edited
              * value - The value being set
              * originalValue - The original value for the field, before the edit.
              * row - The grid row index (starting from 0)
              * column - The grid column index (starting from 0)
              */
              this.onafteredit({grid:this.grid,record:record,field:this.dataIndex,originalValue:!record.data[this.dataIndex],value:record.data[this.dataIndex]});
            }
        }
    },

    renderer : function(v, p, record){
      //console.log('v:',v,'p:',p,'record:',record);
      p.css += ' x-grid3-check-col-td'; 
      return '<div class="x-grid3-check-col'+(v?'-on':'')+' x-grid3-cc-'+this.id+'">&#160;</div>';
    }
};



//defines an extended editorGridPanel Ext object
//------------------------------------------------
//************************************************
//------------------------------------------------

var glo_editorGridPanel=function(oO) {
  this.gridData=oO.gridData;
  var that=this;
  var searchWindow=oO.gridData.searchWindow;
  
  // shorthand alias
  var PAGE_SIZE=20;
  var fm = Ext.form;
  var grid=null; //private global grid object
  var ds=null; //private global data store
  var oEDConnectionRead=null; //global read/write data connection objects
  var oEDConnectionSave=null;
  
  //use a fixed data reader
  //json data returned by our script must always include this fixed fields
  that.gridData.setReader({
    root:'data',
    totalProperty:'totalCount',
    id:'id'    
  });
  
  
  // create the Main Grid
  function glo_initGrid(oO) {
      
      //elements per page
      PAGE_SIZE=parseInt(mainPanel.getInnerHeight()/24); //auto calc page size based on current page height
      that.config=oO;

      //v1.3 20080713
      var add_hdl=btnAddClick;
      if (typeof oO.button_add_handler!='undefined') {
        add_hdl=function() {
           if (oO.button_add_handler())
             btnAddClick();
        }
      }

      var toolbarButtonHash=[];
      if (uIsDefined(oO.autoToolbarIdx)) {
      //search add,modify and delete standard buttons
      //and add auto button ordering basing on declaration order
        if (oO.tbar) { //user defined tbar
          for (var z=0,zEnd=oO.tbar.length;z<zEnd;z++) {
            if (!isUndefined(oO.tbar[z].buttonType)) {
              var tipo=oO.tbar[z].buttonType;
              switch(tipo) {
                case 'add'   : oO.addButton=oO.button_add=oO.tbar[z];oO.tbar[z].alreadyPushed=1;break;
                case 'modify':case 'edit': oO.modifyButton=oO.button_modify=oO.tbar[z];oO.tbar[z].alreadyPushed=1;break;
                case 'delete': case 'del': oO.delButton=oO.button_delete=oO.tbar[z];oO.tbar[z].alreadyPushed=1;break;
              }
              toolbarButtonHash[tipo]=z;
            }
            oO.tbar[z].positionIdx=z; //auto set toolbar ordering
          }  
        }
      }  

          
      var btn_addButton={ positionIdx:0,text:'Add',tooltip:{title:'Add',text:'Add a new item'},iconCls:'btn-add',handler:add_hdl }
      var btn_modButton={ disableIfNorowIsSelected:true,positionIdx:1,text:'Edit',tooltip:{title:'Edit',text:'Edit the selected item'},iconCls:'btn-add',handler:btnModClick }
      var btn_delButton={ disableIfNorowIsSelected:true,positionIdx:2,text:'Delete',tooltip:{title:'Delete',text:'Delete the selected item'},iconCls:'btn-remove',handler:btnDelClick }
  
      if (typeof oO.button_add!='undefined') //user defined add button
        btn_addButton=u_objAppend(btn_addButton,oO.button_add); // 'paste' user properties

      if (typeof oO.button_modify!='undefined') //user defined modify button
        btn_modButton=u_objAppend(btn_modButton,oO.button_modify); // 'paste' user properties

      if (typeof oO.button_delete!='undefined') //user defined delete button
        btn_delButton=u_objAppend(btn_delButton,oO.button_delete); // 'paste' user properties

/*
      if (!isUndefined(oO.modifyButton.disableIfNorowIsSelected))
        btn_modButton.disableIfNorowIsSelected=oO.modifyButton.disableIfNorowIsSelected;
      if (!isUndefined(oO.delButton.disableIfNorowIsSelected))
        btn_delButton.disableIfNorowIsSelected=oO.delButton.disableIfNorowIsSelected;
*/

      /*  
      if (typeof oO.button_modify!='undefined') //user defined modify button
        btn_modButton=oO.button_modify;
      if (typeof btn_modButton.handler=='undefined')
        btn_modButton.handler=btnModClick;
      */  

      var grid_tbar_default_Buttons=[];

      if (typeof oO.addButtonDisabled!='undefined' && oO.addButtonDisabled)
         btn_addButton.disabled=true;
      if (typeof oO.modButtonDisabled!='undefined' && oO.modButtonDisabled)
         btn_modButton.disabled=true;
      if (typeof oO.delButtonDisabled!='undefined' && oO.delButtonDisabled)
         btn_delButton.disabled=true;

      if (typeof oO.addButton=='undefined' || oO.addButton)
        grid_tbar_default_Buttons.push(btn_addButton);
      if (typeof oO.modifyButton=='undefined' || oO.modifyButton)
        grid_tbar_default_Buttons.push(btn_modButton);
      if (typeof oO.delButton=='undefined' || oO.delButton)
        grid_tbar_default_Buttons.push(btn_delButton);
        
      if (oO.tbar) { //user defined tbar
        var initidx=grid_tbar_default_Buttons.length;
        for (var z=0,zEnd=oO.tbar.length;z<zEnd;z++) {
          if (isUndefined(oO.tbar[z].alreadyPushed)) {
            if (typeof oO.tbar[z]=='string') {
              oO.tbar[z]={insertAsString:oO.tbar[z]};
            }
            grid_tbar_default_Buttons.push(oO.tbar[z]);
            if (typeof oO.tbar[z].positionIdx=='undefined') {
              oO.tbar[z].positionIdx=initidx+z;
            }
          }  
        }  
      }
      
      //now order the tbar buttons basing on the positionIdx index
      var tempTbar=[];
      var tempTbar2=[];
      for (var z=0,zEnd=grid_tbar_default_Buttons.length;z<zEnd;z++) {
        tempTbar[grid_tbar_default_Buttons[z].positionIdx]=grid_tbar_default_Buttons[z];
        //alert(grid_tbar_default_Buttons[z].positionIdx+' '+grid_tbar_default_Buttons[z].buttonType);
      }
      //discard null items and set final topbar
      for (var z=0,zEnd=tempTbar.length;z<zEnd;z++) {
        if (tempTbar[z]) {
          if (typeof tempTbar[z].insertAsString!='undefined')
            tempTbar2.push(tempTbar[z].insertAsString)
          else  
            tempTbar2.push(tempTbar[z]);
        }  
      }
      grid_tbar_default_Buttons=tempTbar2;
      
      //define default values for special button types
      var obtn_search_def={
        text:_LANG.searchButton.text,tooltip:{title:_LANG.searchButton.text,text:_LANG.searchButton.tip},iconCls:_LANG.searchButton.iconCls,
        handler:function() {searchWindow.parentGrid=grid;grid.searchWindow.show()}
      };
      
      //search for special buttons and build auto actions
      var disableIfNorowIsSelectedList=[];
      for (var z=0,zEnd=grid_tbar_default_Buttons.length;z<zEnd;z++) {
        if (isTrue(grid_tbar_default_Buttons[z].disableIfNorowIsSelected)) {
          disableIfNorowIsSelectedList.push(z);
        }
        switch (grid_tbar_default_Buttons[z].buttonType) {
          case 'search':
            var oOo={};
            Ext.apply(oOo,grid_tbar_default_Buttons[z],obtn_search_def);
            grid_tbar_default_Buttons[z]=oOo;
          break;
        }
      }
      //text:_LANG.searchButton.text,tooltip:{title:_LANG.searchButton.text,text:_LANG.searchButton.tip},iconCls:_LANG.searchButton.iconCls
      

      var oExtraparamsRead={mode:'read',s:HR_SRC};
      var oExtraparamsSave={mode:'save',s:HR_SRC};

      if (typeof oO.params!='undefined') {
        for (z in oO.params) {
          oExtraparamsRead[z]=oO.params[z];
          oExtraparamsSave[z]=oO.params[z];
        }
      } 

      var script=oO.script;
      var plugins=oO.plugins;
      oEDConnectionRead=new Ext.data.Connection({ url:script,extraParams:oExtraparamsRead});
      oEDConnectionSave=new Ext.data.Connection({ url:script,extraParams:oExtraparamsSave});

      if (typeof oO.ds=='undefined') {
        ds = new Ext.data.Store({
            proxy: new Ext.data.HttpProxy(oEDConnectionRead), // create reader
            reader:that.gridData.getReader(),
            remoteSort: true // turn on remote sorting
        });
      } else {
        if (oO.ds!='groupingStore')
          ds=oO.ds;
        else {
          //grouping code.. not working...
          var cfgg={
            proxy: new Ext.data.HttpProxy(oEDConnectionRead), // create reader
            reader:that.gridData.getReader(),
            remoteSort:true, // turn on remote sorting
            sortInfo:{field:'id',direction: "ASC"} //SORTINFO is MANDATORY!!!
          }
          if (typeof oO.groupField!='undefined')
            cfgg.groupField=oO.groupField;
          if (typeof oO.defaultSort!='undefined')
            cfgg.sortInfo=oO.defaultSort;
          console.log(cfgg);  
          ds=new Ext.data.GroupingStore(cfgg);
        }  
      }  

      ds.on('load',function(o){
                    try {
                      if (typeof grid.ge_config.userOnLoad!='undefined')
                        grid.ge_config.userOnLoad();
                      if (typeof grid.ge_config.disableButtonsAfterAdd!='undefined') {
                        var eleele=grid.ge_config.disableButtonsAfterAdd;
                        for (var z=0,zEnd=eleele.length;z<zEnd;z++) {
                         grid.topToolbar.items.items[eleele[z]].enable();
                        }      
                      }
                    } catch(er) {
                    }
                  }    
          );
      
      // the column model has information about grid columns
      // dataIndex maps the column to the specific data field in
      // the data store
      if (typeof oO.cm=='undefined')
        cm = new Ext.grid.ColumnModel(that.gridData.getExtGridColumModel());
      else
        cm=oO.cm;
      //console.log('CM',cm);                                                            
      
      var clicksToEdit=oO.clicksToEdit?oO.clicksToEdit:2;
      var width=oO.width?oO.width:700;
      var height=oO.height?oO.height:500;
      var bbar=new Ext.PagingToolbar({
                 pageSize: PAGE_SIZE,
                 store: ds,
                 displayInfo: true,
                 displayMsg: 'Displaying elements {0} - {1} of {2}',
                 emptyMsg: "No elements to display"
                  /*
                  ,items:[
                      '-', {
                      pressed: true,
                      enableToggle:true,
                      text: 'Show Preview',
                      cls: 'x-btn-text-icon details',
                      //toggleHandler: toggleDetails
                  }]
                  */
                })
      if (oO.bbar===false)
        bbar=''; 
      
      // by default columns are sortable
      cm.defaultSortable = true;
      
      var sm = new Ext.grid.CheckboxSelectionModel();

      var doLoadMask=0;
      if (typeof oO.ds!='undefined')
        doLoadMask=1;

      var _TBAR=null;
      if (typeof oO.doTBar=='undefined' || oO.doTBar==1)
        _TBAR=grid_tbar_default_Buttons;

      //editor grid configuration
      var EGP_config={
          //el:'topic-grid',
          plugins:plugins,
          /*title:'notitle',,*/
          cls:'gridgrid',
          //baseCls:'gridgrid',
          store: ds,
          cm: cm,
          //trackMouseOver:true, //exeption bug if enabled
          sm:sm,
          //sm: new Ext.grid.RowSelectionModel({selectRow:Ext.emptyFn}),
          //sm: new Ext.grid.CheckboxSelectionModel(),
          loadMask:doLoadMask, //we want the loadmask displayed even on first load so we manually create it (see below), in case a static ds is defined for this grid the loadmask handling is done by the user function
          clicksToEdit:clicksToEdit,
          viewConfig: {
            forceFit:true
          },
          
          /*
          // inline buttons
          buttons: [{text:'Save',handler:btnSave},{text:'Cancel'}],
          buttonAlign:'right',
          */        
          
          // inline toolbars
          tbar:_TBAR,
          //bottom bar
          bbar:bbar
      };
/*      
      if (typeof oO.width!='undefined')
        EGP_config.width=oO.width;

      if (typeof oO.height!='undefined')
        EGP_config.height=oO.height;
*/

    //add new config options HERE
    if (typeof oO.view!='undefined')
      EGP_config.view=oO.view;    

    if (typeof oO.buttons!='undefined')
      EGP_config.buttons=oO.buttons;    

    if (typeof oO.buttonAlign!='undefined')
      EGP_config.buttonAlign=oO.buttonAlign;    

    if (typeof oO.region!='undefined')
      EGP_config.region=oO.region;

    if (typeof oO.layout!='undefined')
      EGP_config.layout=oO.layout;
      
    if (typeof oO.border!='undefined')
      EGP_config.border=oO.border;

      if (typeof oO.el!='undefined')
        EGP_config.el=oO.el;
        
      if (typeof oO.autoWidth!='undefined')
        EGP_config.autoWidth=oO.autoWidth
      else  
        EGP_config.width=width;

      if (typeof oO.autoHeight!='undefined')
        EGP_config.autoHeight=oO.autoHeight
      else  
        EGP_config.height=height;

      if (typeof oO.el=='undefined')  
        if (oO.autoEl || typeof oO.autoEl=='undefined')
          EGP_config.el='topic-grid';
      
      if (EGP_config.layout=='fit') {
        EGP_config.width='';
        EGP_config.height='10';
      }
      grid = new Ext.grid.EditorGridPanel(EGP_config);
    
      grid.priv_autoSaveAfterEdit=true;
      if (oO.autoSaveAfterEdit || typeof oO.autoSaveAfterEdit=='undefined')
        grid.on('afteredit',gridAfteredit); //fire this after every cell edit
      else
        grid.priv_autoSaveAfterEdit=false;
    /*
      function saveComplete(oConn,oResponse,oOptions) {
        alert('done');
      }
    */
    
    //DEFINE SOME GRID METHODS and PROPERTIES
    grid.defaultDelAction=btnDelClick;
    grid.modifyButton=btn_modButton;  //save the modify button object as a property of the grid
    grid.searchWindow=searchWindow;  //add the searchWindow object to the propery list
    grid.Store=ds;
    grid.getParams=geg_getGridStateParams;
    grid.openTab=function (oTab) { //allow to open a new tab with specified otab params
      btnModClick(null,null,oTab); //same as modify action but with a tab obj as param
    }  
    grid.reloadData=function(fCallback) {
      ds.load( {params:geg_getGridStateParams(),callback:fCallback} ); // trigger the data store load, passing some parameters
    };
    grid.load=function() {
      ds.load( {params:geg_getGridStateParams()} );     
    }
    grid.getToolbarButton=function(sIdx) {
      return toolbarButtonHash[sIdx];      
    };
    grid.topToolbarAutoEnable=function(sIdx) {
      for (var z=0,zEnd=disableIfNorowIsSelectedList.length;z<zEnd;z++) {
        grid.topToolbar.items.items[disableIfNorowIsSelectedList[z]].enable()
      }
    }; 
    grid.topToolbarAutoDisable=function(sIdx) {
      for (var z=0,zEnd=disableIfNorowIsSelectedList.length;z<zEnd;z++) {
        grid.topToolbar.items.items[disableIfNorowIsSelectedList[z]].disable()
      }  
    };
    grid.internal_rowIndex=null;
    grid.getSelectedRow=function() { //restituisce la 
      return grid.internal_rowIndex;  
    }
    grid.reselectCurrentRow=function() { //reseleziona ultima riga correntemente selezionata
      //deselect rows
      //var selectionModel = grid.getSelectionModel();
      //selectionModel.clearSelections();
      //select last row
      grid.fireEvent('rowclick',grid,grid.internal_rowIndex,grid.internal_event);
    }  
    //auto add grid events
    grid.on('rowclick',
      function(oGrid,rowIndex,event) {
        grid.internal_rowIndex=rowIndex;
        grid.internal_event=event;
        /*
        var selectionModel = grid.getSelectionModel();
        var records=selectionModel.getSelections();
        if (records.length>0) {
          if (records[0].data.weight==0)
        */  
      }
    );  
    
    /*     
    grid.on('render',
      function() {
        console.log(grid.loadMask);//grid.loadMask.show();
      }
    );
    */
    if (grid.hasSummary) {      
      PAGE_SIZE-=2; //auto calc page size based on current page height
      if (grid.hasTwoSummaryRows)
        PAGE_SIZE-=1; //auto calc page size based on current page height
      grid.getBottomToolbar().pageSize=PAGE_SIZE;
    }
          
    
    return grid;
  }    

  function geg_getGridStateParams(oO) {
     //obtain an optional object and add
     //current grid paging and ordering info
     if (typeof oO=='undefined') 
       oO={};
     var gss=grid.store.getSortState();
     //console.log(grid.store);
     oO.start=0;
     oO.limit=PAGE_SIZE;
     if (gss) {
       oO.dir=gss.direction;
       oO.sort=gss.field;
     }
     return oO;
  }
  
  function gridAfteredit(oO) {    
    /* 
    Fires after a cell is edited.
    
        * grid - This grid
        * record - The record being edited
        * field - The field name being edited
        * value - The value being set
        * originalValue - The original value for the field, before the edit.
        * row - The grid row index (starting from 0)
        * column - The grid column index (starting from 0)
    
    Listeners will be called with the following arguments:
    
        * e : Object
          An edit event (see above for description)
    */

    function saveComplete(oOptions,bSuccess,oHTTPResponse) { //called after grid edit
      if (bSuccess) {

        var rText=oHTTPResponse.responseText;
        if (rText) {
          //decode server response
          var jsonData=Ext.decode(rText); //instead of Ext.util.JSON.decode(oHTTPResponse.text);
          if (jsonData.success) {
            //reenable previously disabled buttons after add has been pressed
            if (typeof grid.ge_config.disableButtonsAfterAdd!='undefined') {
              var eleele=grid.ge_config.disableButtonsAfterAdd;
              for (var z=0,zEnd=eleele.length;z<zEnd;z++) {
               grid.topToolbar.items.items[eleele[z]].enable();
              }      
            }
            //if all is ok -> set new entered user value
            if (!grid.ge_config.autoReloadAfterSave) { 
              oO.record.set(oO.field,oO.value);
              if (jsonData.action) {
                switch (jsonData.action) {
                  case 'getServerData':
                    //set record id
                    oO.record.set(oO.id,jsonData.id); //visually set the result
                    oO.record.data['id']=jsonData.id; //update the recordset
                    if (jsonData.list_table)
                      oO.record.data['list_table']=jsonData.list_table; //update the recordset
                    //refresh fields  
                    if (jsonData.refreshFields) {
                      for (var zz in jsonData.refreshFields) {
                        oO.record.data[zz]=jsonData.refreshFields[zz];
                        oO.record.set(oO[zz],jsonData.refreshFields[zz]);
                      }
                    }  
                  break;
                }
              }
            } else {  
              //force reload of grid after editing
              grid.store.load( {params:geg_getGridStateParams()} ); // trigger the data store load, passing some parameters
            }  
          } else {
            //disable buttons again since we have errors
            if (typeof grid.ge_config.disableButtonsAfterAdd!='undefined') {
              var eleele=grid.ge_config.disableButtonsAfterAdd;
              for (var z=0,zEnd=eleele.length;z<zEnd;z++) {
               grid.topToolbar.items.items[eleele[z]].disable();
              }      
            }
            //and now inspect the current error from the server

            switch(jsonData.errorType) { //errors from server (server checking)
              case 'DUPLICATE_KEY':u_showErrorPopUp('"'+jsonData.value+'" is already present.');return 0;
              case 'NO_NEWSLETTER_NAME':u_showErrorPopUp('You need to specify a newsletter name before proceeding.');return 0;               case 'NO_LIST_NAME':u_showErrorPopUp('You need to specify a list name before proceeding.');return 0;               case 'NO_CLIENT_ID':u_showErrorPopUp('You need to specify a client ID.');return 0;               case 'BAD_CLIENT':u_showErrorPopUp('The specified user id is incorrect.');return 0;               case 'NO_EMAIL':u_showErrorPopUp('The email field is required.<br>Please, specify an email address before including other fields.');return 0;
              case 'DATA_TRUNCATED':u_showErrorPopUp('The value you have specified for the "'+jsonData.field+'" is too long.');return 0;
              case 'BAD_NUMBER':u_showErrorPopUp('The "'+jsonData.field+'" field requires a number.');return 0;
              case 'SYNTAX_ERROR_ABORT':
                u_showErrorPopUp(jsonData.errors.name);
                oO.record.set(oO.field,oO.originalValue);               return 0;
            }

/*
            switch(jsonData.errorType) { //errors from server (server checking)
              case 'DUPLICATE_KEY':Ext.Msg.alert('Error','"'+jsonData.value+'" is already present.');return 0;
              case 'NO_NEWSLETTER_NAME':Ext.Msg.alert('Error','You need to specify a newsletter name before proceeding.');return 0;               case 'NO_LIST_NAME':Ext.Msg.alert('Error','You need to specify a list name before proceeding.');return 0;               case 'NO_CLIENT_ID':Ext.Msg.alert('Error','You need to specify a client ID.');return 0;               case 'BAD_CLIENT':Ext.Msg.alert('Error','The specified user id is incorrect.');return 0;               case 'NO_EMAIL':Ext.Msg.alert('Error','The email field is required.<br>Please, specify an email address before including other fields.');return 0;
              case 'DATA_TRUNCATED':Ext.Msg.alert('Error','The value you have specified for the "'+jsonData.field+'" is too long.');return 0;
              case 'BAD_NUMBER':Ext.Msg.alert('Error','The "'+jsonData.field+'" field requires a number.');return 0;
              case 'SYNTAX_ERROR_ABORT':Ext.Msg.alert('Error',jsonData.errors.name);return 0;
            }
*/            
            
          }    
        }  
      }  
    }
    
    if (typeof oO.value=='object') {
      try {
        if (oO.value.getDate)
          oO.value=typeDateRenderer(oO.value)
      } catch(er) {
        console.log('gridAfteredit error - unknow oO.value object type');
      }
    }
    
    if (oO.originalValue != oO.value) { //if something has been changed -> CHECK IT -> SAVE IT
            var f=that.gridData.getFieldById(oO.field);
      var syntaxError=0;
      var errorMessage='';
      var fieldValue=oO.value;
      var error_msg='Syntax error';
      
      //console.log('effe:',f);
      //>field name > header
      
      //client checking
      //check syntax for the current value
      fieldValue=fieldValue+''; //convert field value to string so we can apply our special checkings
      if (f) {
        if (f.ftype) {
          alert(f.ftype);
        }
        if (f.type) {
          switch(f.type) {
            case 'email':
              if (!fieldValue.match(/\b[A-Z0-9\.\_\-\+]+@[A-Z0-9\.\-]+\.[A-Z]{2,4}\b/i)) {
                syntaxError=1;
                error_msg=u_buildErrorMessage("<b>Syntax error</b><br />%1 field should be a valid e-mail address in the format<br />&quot;user@domain.com&quot;",f.header,"");
                //error_msg="";
              }
            break;
            case 'weekly_usage_limit':
              if (fieldValue.match(/[^0-9]/)) {
                syntaxError=1;
                error_msg="Syntax error.<br>Please specify a valid weekly usage limit value.<br>A value of 0 means no limits will be applied.";
              }
            break;
            case 'string':
            case 'text':
              if (fieldValue.match(/[^a-zA-Z0-9\.\-\_\s]/)) {
                syntaxError=1;
                error_msg=u_buildErrorMessage("<b>Syntax error</b><br />%1 field can only contain<br />%2",f.header,"a-z A-Z 0-9 . - _ [space]");//"";
              }
            break;
            case 'richtext':
              if (fieldValue.match(/[^a-zA-Z0-9\.\-\_\s'àèìòù\%\?\!]/)) {
                syntaxError=1;
                error_msg=u_buildErrorMessage("<b>Syntax error</b><br />%1 field can only contain<br />%2",f.header,"a-z &agrave;-&ugrave; A-Z 0-9 . - _ ? ! [space]");//"";
              }
            break;
            case 'textarea':
              if (fieldValue.match(/[^\n\r\:\;\,'\a-zA-Z0-9\.\-\_\s'àèìòù]/)) {
                syntaxError=1;
                error_msg=u_buildErrorMessage("<b>Syntax error</b><br />%1 field can only contain<br />%2",f.header,"a-z &agrave;-&ugrave; A-Z 0-9 ' : , ; [space] [enter]");
                //error_msg="";
              }
            break;
            case 'unsigned_integer':
            case 'integer':
              if (fieldValue.match(/[^0-9]/)) {
                syntaxError=1;
                error_msg=u_buildErrorMessage("<b>Syntax error</b><br />Please specify a valid integer numeric value for %1.",f.header,"0-9");
                //error_msg="";
              }
            break;
/*
            case 'email':if (!fieldValue.match(/\b[A-Z0-9\.\_\-\+]+@[A-Z0-9\.\-]+\.[A-Z]{2,4}\b/i)){syntaxError=1;error_msg="";};break;
            case 'weekly_usage_limit':if (fieldValue.match(/[^0-9]/)){syntaxError=1;error_msg="Syntax error.<br>Please specify a valid weekly usage limit value.<br>A value of 0 means no limits will be applied.";};break;
            case 'string':
            case 'text':if (fieldValue.match(/[^a-zA-Z0-9\.\-\_\s]/)){syntaxError=1;error_msg="";};break;
            case 'textarea':if (fieldValue.match(/[^\n\r\:\;\,'\a-zA-Z0-9\.\-\_\s'àèìòù]/)){syntaxError=1;error_msg="";};break;
            case 'unsigned_integer':
            case 'integer':
              if (fieldValue.match(/[^0-9]/)){syntaxError=1;error_msg="";}
            ;break;
*/
          }        
        }
      }  

      if (!syntaxError) {
        oEDConnectionSave.request({
          callback:saveComplete,
          params: that.gridData.getExtDataConnectionRequestParams(oO.record.data,{id:oO.record.data['id'],field:oO.field,value:oO.value,originalValue:oO.originalValue})
        })
      } else {
        u_showErrorPopUp(error_msg);
        oO.record.set(oO.field,oO.originalValue);       
        //Ext.Msg.alert('Error',error_msg);
      }  
  
      //oO.record.set(oO.field,oO.originalValue);       return false;
    } 

  } 
  
  

  /*function btnSave() {
  }*/

  function btnDelClick() {
    var selectionModel = grid.getSelectionModel();
    var records = selectionModel.getSelections();
    if (records.length>0) {
      Ext.Msg.confirm('Message', 'Do you really want to delete it?',btnDelClick_confirm);
    } else { 	
      Ext.Msg.alert('Message', 'Please select at least one item to delete');
    }  
    return false;  
  }

  function btnDelClick_confirm(btn) {
    if (btn=='yes') {
			var m=grid.getSelections();

			var jsonData = "[";
      var readOnly;
	    for(var i=0, len=m.length;i<len;i++){
        //check the row numberer id > some codes specify special types of records
        //since the row numberer does not have a dataIndex associated to it it is referenced with
        //undefined
        readOnly=0;
        switch (m[i].data['undefined']) { //doppio check > la griglia ci pensa in automatico a disabilitare il tasto remove se abbiamo il 999 > ma cmq meglio farlo anche qui
          case 999:readOnly=1;break; //999 means read only record
        }
        if (!readOnly) {      		
  			  var ss = "{'id':'"+m[i].data['id']+"'}";
  			  if(i==0)
  	        jsonData = jsonData + ss ;
  			  else
  			    jsonData = jsonData + "," + ss;	
  			  ds.remove(m[i]);
        }   								
	    }	
			jsonData=jsonData + "]";
      if (grid.priv_autoSaveAfterEdit)
        ds.load( {params:geg_getGridStateParams({delData:jsonData})} );		
    }
  }
  
  
  function geg_update_Bbar_Info() {
  /*
 	    updateInfo : function(){
 	        if(this.displayEl){
 	            var count = this.store.getCount();
 	            var msg = count == 0 ?
 	                this.emptyMsg :
 	                String.format(
 	                    this.displayMsg,
 	                    this.cursor+1, this.cursor+count, this.store.getTotalCount()
 	                );
 	            this.displayEl.update(msg);
 	        }
 	    },
   */     
  }
  
  function btnAddClick() {
    //console.log(_gridData.getDefaults());

    if (typeof grid.ge_config.disableButtonsAfterAdd!='undefined') {
      var eleele=grid.ge_config.disableButtonsAfterAdd;
      for (var z=0,zEnd=eleele.length;z<zEnd;z++) {
       grid.topToolbar.items.items[eleele[z]].disable();
      }      
    }
    
    grid.stopEditing();
    var selectionModel = grid.getSelectionModel();
    //var records = selectionModel.getSelections();
    var record = selectionModel.getSelected();
    var insertId=0;
    if (!grid.ge_config.addNewRecordsAlwaysOnTop && !grid.ge_config.addNewRecordsAlwaysOnBottom) { 
      if (record) {
        var jsonData=[];
        var recordRowIndex=-1;
        //obtain row index
        for (var z=0,len=grid.store.data.items.length;z<len;z++) {
          if (grid.store.data.items[z].id==record.id)
            recordRowIndex=z;
        }
        insertId=recordRowIndex+1; //if there is a selection insert the new field just after it
      }
    }    

    if (grid.ge_config.addNewRecordsAlwaysOnBottom)
      insertId=grid.store.data.items.length;

    grid.store.insert(insertId,that.gridData.getDefaults());
    grid.startEditing(insertId,1); //startEditing( Number rowIndex, Number colIndex )
    grid.getView().refresh(); //update rownumberer displaying info
//    console.log(grid);
//    grid.bottomToolbar.updateInfo();  
  }

  function geg_loadGridData() {
    ds.load({params:geg_getGridStateParams()});    
  }

//----------

  function btnModClick(oThisButto,oEvent,oTabParam) {
  
    var doCheck=true;
  
    if (typeof oTabParam!='undefined')
      if (typeof oTabParam.allowNorecordSelected!='undefined' || oTabParam.allowNorecordSelected==true)
        doCheck=false;
    
    if (doCheck) {    
      var selectionModel = grid.getSelectionModel();
      var records = selectionModel.getSelections();
      if (!records.length) {
        Ext.Msg.alert('Message', 'Please select at least one item');
        return false;
      }
    }  

    //var selectionModel = grid.getSelectionModel();
    var record = selectionModel.getSelected(); //if multiselection always returns the first selected record
    var selectedId=record.data['id'];
    /*
    var rowSelected = grid.getSelections(); 
    if ( rowSelected.length > 1 ) {
      grid.getSelectionModel().clearSelections(); 
    }
    */      
    //console.log(grid);

    var tabParams={
      id:'list_'+selectedId,
      closable:true,
      title:record.data['name'],
      tabTip:'<b>E-mail list</b><br />'+record.data['name'],
      callBack:'',
      url:_CFG.path('page_lists_list.html.php'),
      params:{
        lid:record.data['id'],
        tid:record.data['list_table'],
        s:HR_SRC
      }
    }
    
    //inspect user-defined newTab object
    var oUDTab=grid.modifyButton.newTab;
    if (typeof oTabParam!='undefined') 
      oUDTab=oTabParam;
    
    for (var z in oUDTab) {
      if (z!='params') {
        if (oUDTab[z].needEval)
          tabParams[z]=eval(oUDTab[z].data);
        else  
          tabParams[z]=oUDTab[z];
      } else {
        for (var w in oUDTab.params) {
          if (oUDTab.params[w]==null) {  
            delete(tabParams.params[w])
          } else {    
            if (oUDTab.params[w].needEval)
              tabParams.params[w]=eval(oUDTab.params[w].data);
            else {
              tabParams.params[w]=oUDTab.params[w];
            }
          }    
        }
      }  
    }
    
    var t1=mainPanel.createTab(tabParams);
    t1.helpId='edit-list'; //force help id
    //but if there is any into the newTab config, use it instead
    if (typeof oUDTab!='undefined')
      if (oUDTab.helpId)
        t1.helpId=oUDTab.helpId;
    mainPanel.setActiveTab(t1); //auto enable first tab
  }
  
  //Methods for the
  //glo_editor_gridpanel object
  
  this.reloadCurrentPage=function(oO) {
   // console.log(that.activePage);
   // console.log(this.activePage);
   // mainPanel.setActiveTab(this.activePage);
  }
  
  this.onAfterEdit=function(oO) {
    gridAfteredit(oO);
    //alert(this.)
  };
  
  this.getJsonData=function() {
   // console.log(grid);
  //obtain current grid state as json data
    //console.log(grid.store.data.items);
    var jsonData=[];
    for (var z=0,len=grid.store.data.items.length;z<len;z++) {
      jsonData.push(Ext.encode(grid.store.data.items[z].data));
    }
    var sJsonData='['+jsonData.join(',')+']';
    //console.log(sJsonData);
    return sJsonData;
  }
  
  this.create=function(oO) {
    var grid=glo_initGrid(oO);
    grid.ge_config=oO;
    grid.gloParent=this;
    //console.log(grid);
    if (oO.defaultSort)
      ds.setDefaultSort(oO.defaultSort.field,oO.defaultSort.direction);
    if (oO.autoRender || typeof oO.autoRender=='undefined') 
      grid.render(); // render the grid
    if (typeof oO.ds=='undefined')  {//auto load data store after rendering
      var loadMask=new Ext.LoadMask(grid.getEl(),{store:grid.store});
      loadMask.el.setHeight('100%');
      loadMask.show();
      grid.loadMask=loadMask;
      geg_loadGridData();
    }  
    return grid;
  }

  return this;
};