﻿/** <description><![CDATA[Définit le format de colonne de imageButton</BR>
Ce format permet d'ajouter une colonne qui contient une dont l'url est définie par la propriété image.</BR>
Cette image peut être maintenue masquée et n'aparaître lorsque la ligne est over en mettant la propriété hideWhenMouseOut à vrai</BR>
La propriété onClick définit le handler qui se déclenche sur le click sur l'image.
]]></description>
*<fullName>AJAXImageButtonFormat</fullName>
*<type>class</type>
*/
var AJAXImageButtonFormat = Class.create({
    initialize: function(params) {
        this.typeOf = 'AJAXImageButtonFormat'
        this.image = params.editor.image
        this.onClick = params.editor.onClick
        this.hideWhenMouseOut = params.editor.hideWhenMouseOut
        this.alternateText = params.editor.alternateText
        this.name = params.editor.name
        this.params = params
    },
    
    
    /** <description>Initialisation du controle</description>
    * <fullName>AJAXImageButtonFormat.init</fullName>
    * <type>method</type>
    * <param name="parent">AJAXColumn qui genère ce format</param>
    */
    init: function(parent) {
        this.parent = parent
        this.column = this.parent.column
    },
    
    /** <description><![CDATA[Revoie le controle à afficher</BR>
    Dans le cadre spécifique de ce controle l'apparence et l'éditeur ne font qu'un.]]></description>
    * <fullName>AJAXImageButtonFormat.getDisplayControl</fullName>
    * <type>function</type>
    * <param name="el">Valeurs au format JSON</param>
    * <param name="parentCell">AJAXTableauCell dans laquelle se trouve le controle.</param>
    * <return>AJAXImageButtonDisplayControl généré.</return>
    */
    getDisplayControl: function(el, parentCell) {
        var c = new AJAXImageButtonDisplayControl(this.params.editor, parentCell, this)
        return c.render(el)
    }
})

var AJAXImageButtonDisplayControl = Class.create({
    initialize: function(params, parentCell, parentFormat) {
        this.typeOf = 'AJAXImageButtonDisplayControl'
        this.parentCell = parentCell /**<description>AJAXTableauCell qui a contient le controle</description><fullName>AJAXImageButtonDisplayControl.parentCell</fullName><type>property</type> */
        this.parentColumn = this.parentCell.column /**<description>AJAXColumn de la cellule dans laquelle se trouve le controle.</description><fullName>AJAXImageButtonDisplayControl.parentColumn</fullName><type>property</type> */
        this.parentTable = this.parentColumn.parent.parent /**<description>AJAXTableau</description><fullName>AJAXImageButtonDisplayControl.parentTable</fullName><type>property</type> */
        this.parent = parentFormat/**<description>Format qui a généré ce controle</description><fullName>AJAXImageButtonDisplayControl.parent</fullName><type>property</type> */
        this.imageElement /** <description>Element HTML généré</description><fullName>AJAXImageButtonDisplayControl.imageElement</fullName><type>property</type> */
        this.onClick = null /** <description>Handler se produisant au click sur l'image. Fait référence à une fonction définie par ailleurs</description><type>AJAXImageButtonDisplayControl.onClick</type><param name="AJAXImageButtonDisplayControl">Objet qui a généré le click</params><param name="AJAXTableauRow">AJAXTableauRow à la quelle appartien l'objet qui a généré le click</params><param name="AJAXTableau">AJAXTableau de référence</params><param name="e">event</params><type>property</type> */
        this.setParams(params)
    },

    render: function(el) {
    
        if (this.parentCell.parentRow.isFooter == true) return

        this.element = new Element('IMG', { src: this.image })
        if (this.name) this.element.name = this.name
        if (this.alternateText) { this.element.alt = this.alternateText; this.element.title = this.alternateText }
        if (this.parentCell.parentRow.isGroup) return
        this.parentCell.element.update(this.element)

        this.element.observe('click', function(e) {
            var pos = { top: e.pointerY(), left: e.pointerX()}
            if (Object.isFunction(this.onClick)) {
                this.onClick(this.element, this.parentCell.parentRow,  this.parentCell.parentTable, pos)
            }
        } .bindAsEventListener(this))

        if (this.hideWhenMouseOut == true) {
            this.element.hide()
            this.parentCell.parentRow.element.observe('mouseout', function() { this.element.hide() } .bindAsEventListener(this))
            this.parentCell.parentRow.element.observe('mouseover', function() {
                this.element.show()
            } .bindAsEventListener(this))
        }

        return this
    },

    setParams: function(params) {
        if (!params) return
        for (var property in params) this[property] = params[property];
        if (!params.parameters) return
        this.parameters = new Hash()

        for (var i = 0; i < params.parameters.length; i++) {
            this.parameters.set(params.parameters[i], '')
        }
    }
})




/** <description><![CDATA[Définit le format de colonne de type selector.</BR>
Ce format permet d'ajouter une colonne qui va contenir une case à cocher et qui va permettre de faciliter la sélction des lignes.</BR>
Une case à cocher est étalement ajoutée dans l'entete afin de sélectionner toutes les lignes du tableau.</BR>
Dans ce cas, la valeur du paramètre de clé primaire transmise au serveur est égal à 'all']]></description>
*<fullName>AJAXSelectorFormat</fullName>
*<type>class</type>
*/
var AJAXSelectorFormat = Class.create({
    initialize: function(params) {
        this.typeOf = 'AJAXSelectorFormat'
        this.imageOn = params.editor.imageOn
        this.imageOff = params.editor.imageOff
        this.params = params
        this.isChecked = false
    },


    /** <description>Initialisation du controle</description>
    * <fullName>AJAXSelectorFormat.init</fullName>
    * <type>method</type>
    * <param name="parent">AJAXColumn qui genère ce format</param>
    */
    init: function(parent) {
        this.parent = parent
        this.column = this.parent.column
    },

    /** <description><![CDATA[Revoie le controle à afficher</BR>
    Dans le cadre spécifique de ce controle l'apparence et l'éditeur ne font qu'un.]]></description>
    * <fullName>AJAXSelectorFormat.getDisplayControl</fullName>
    * <type>function</type>
    * <param name="el">Valeurs au format JSON</param>
    * <param name="parentCell">AJAXTableauCell dans laquelle se trouve le controle.</param>
    * <return>AJAXSelectorControl généré.</return>
    */
    getDisplayControl: function(el, parentCell) {
        var c = new AJAXSelectorControl(this.params.editor, parentCell, this)
        return c.render(el)
    },

    /** <description>Construit et renvoie la case à cocher qui va se trouver dans la ligne d'entete.</description>
    * <fullName>AJAXSelectorFormat.getHeaderElement</fullName>
    * <type>function</type>
    * <param name="col">AJAXColumn qui genère ce format</param>
    * <return>HTMLElement de type IMG</return>
    */
    getHeaderElement: function(col) {
        var src = this.imageOff
        var img = new Element('IMG', { src: src, name: '__selector__' })
        var tab = col.parent.parent
        
        img.observe('click', function(e) {
            if (src == this.imageOff) {
                src = this.imageOn
                this.isChecked = true
                tab.body.selectedRows.setSelectAll(true)
            } else {
                src = this.imageOff
                tab.body.selectedRows.setSelectAll(false)
                this.isChecked = false
            }
            img.src = src
        }.bindAsEventListener(this))
        
        return img
    }
})

var AJAXSelectorControl = Class.create({
    initialize: function(params, parentCell, parentFormat) {
        this.typeOf = 'AJAXSelectorControl'
        this.parentCell = parentCell /**<description>AJAXTableauCell qui a contient le controle</description><fullName>AJAXSelectorControl.parentCell</fullName><type>property</type> */
        this.parentColumn = this.parentCell.column /**<description>AJAXColumn de la cellule dans laquelle se trouve le controle.</description><fullName>AJAXSelectorControl.parentColumn</fullName><type>property</type> */
        this.parentTable = this.parentColumn.parent.parent /**<description>AJAXTableau</description><fullName>AJAXSelectorControl.parentTable</fullName><type>property</type> */
        this.parent = parentFormat/**<description>Format qui a généré ce controle</description><fullName>AJAXSelectorControl.parent</fullName><type>property</type> */
        this.isChecked = false /**<description>Indidique si la l'élément est coché</description><fullName>AJAXSelectorControl.isChecked</fullName><type>property</type> */
        this.setParams(params)
    },

    render: function(el) {
        
        this.element = new Element('IMG', { src: this.imageOff, name:'__selector__' })
        if (this.parentCell.parentRow.isGroup) return
        this.setValue(el)

        this.element.observe('click', function(e) {
            if (this.isChecked == false) {
                this.setCheck(true)
            } else {
                this.setCheck(false)
            }
        } .bindAsEventListener(this))

        return this
    },

    setParams: function(params) {
        if (!params) return
        for (var property in params) this[property] = params[property];
        if (!params.parameters) return
        this.parameters = new Hash()

        for (var i = 0; i < params.parameters.length; i++) {
            this.parameters.set(params.parameters[i], '')
        }
    },

    setValue: function(el) {
        this.parentCell.element.update(this.element)
        this.element.show()
    },

    setCheck: function(bChecked) {
        if (bChecked == true) {
            this.isChecked = true
            this.element.src = this.imageOn
        } else {
            this.isChecked = false
            this.element.src = this.imageOff  
        }
    }
})

/** <description><![CDATA[Définit le format de colonne de type OnOff.</BR>
                Ce format s'applique sur des valeurs de type boolean. La valeur renvoyées est 'True' ou 'False'.</BR>
                Une image s'applique pour chacun des deux états.</BR>
                Contrairement aux formtas habituels, il n'y a pas de EditorControl.]]></description>
*<fullName>AJAXOnOffFormat</fullName>
*<type>class</type>
*/
var AJAXOnOffFormat = Class.create({
initialize: function(params) { /**<description>Constructeur</description><fullName>AJAXOnOffFormat.initialize</fullName><type>Method</type><param name="params">Paramètres du format (JSON)</param> */
        this.typeOf = 'AJAXOnOffFormat' 
        this.parent = null //column
        this.column = null // column
        this.value = null
        this.params = params
    },

/** <description>Initialisation du controle</description>
* <fullName>AJAXOnOffFormat.init</fullName>
* <type>method</type>
* <param name="parent">AJAXColumn qui genère ce format</param>
*/
    init: function(parent) {
        this.parent = parent;
        this.column = this.parent;
        this.onAfterSaving = (this.params.onAfterSaving)?this.params.onAfterSaving:undefined
        this.onBeforeSaving = (this.params.onBeforeSaving)?this.params.onBeforeSaving:undefined
        this.onAfterEdit = (this.params.onAfterEdit)?this.params.onAfterEdit:undefined
        this.onBeforeEdit = (this.params.onBeforeEdit)?this.params.onBeforeEdit:undefined
        
    },

    /** <description><![CDATA[Revoie le controle à afficher</BR>
        Dans le cadre spécifique de ce controle l'apparence et l'éditeur ne font qu'un.]]></description>
    * <fullName>AJAXOnOffFormat.getDisplayControl</fullName>
    * <type>function</type>
    * <param name="el">Valeurs au format JSON</param>
    * <param name="parentCell">AJAXTableauCell dans laquelle se trouve le controle.</param>
    * <return>AJAXOnOffDisplayControl généré.</return>
    */
    getDisplayControl:function(el, parentCell){
        var c = new AJAXOnOffDisplayControl(this.params.editor, parentCell, this)
        return c.render(el)
    }
})
/** <description><![CDATA[Fournit le controle HTML de type OnOff.</BR>
Cet objet gère l'affichage ET l'édition. Il n'y pas de permutation comme dans les autres formats.</BR>
Au clic, l'image change d'aspect et la valeur est envoyée sur le serveur pour sauvegarde.]]></description>
*<fullName>AJAXOnOffDisplayControl</fullName>
*<type>class</type>
*/
var AJAXOnOffDisplayControl = Class.create({
    initialize: function(params, parentCell, parentFormat) { /**<description>Constructeur</description><fullName>AJAXOnOffFormat.initialize</fullName><type>Method</type><param name="params">Paramètres du format (JSON)</param><param name="parentCell">AJAXTableauCell dans laquelle va se trouver le controle</param><param name="parentFormat">Format qui a généré ce controle.</param> */
        this.typeOf = 'AJAXOnOffDisplayControl'
        this.parentCell = parentCell /**<description>AJAXTableauCell qui a contient le controle</description><fullName>AJAXOnOffFormat.parentCell</fullName><type>property</type> */
        this.parentColumn = this.parentCell.column /**<description>AJAXColumn de la cellule dans laquelle se trouve le controle.</description><fullName>AJAXOnOffFormat.parentColumn</fullName><type>property</type> */
        this.parentTable = this.parentColumn.parent.parent /**<description>AJAXTableau</description><fullName>AJAXOnOffFormat.parentTable</fullName><type>property</type> */
        this.parent = parentFormat/**<description>Format qui a généré ce controle</description><fullName>AJAXOnOffFormat.parent</fullName><type>property</type> */
        this.setParams(params)
    },

    /** <description><![CDATA[Crée le controle et le renvoie vers la cellule]]></description>
    *<fullName>AJAXOnOffDisplayControl.render</fullName>
    *<type>function</type>
    *<return>AJAXOnOffDisplayControl</return>
    */
    render: function(el) {
        this.element = new Element('IMG')
        this.setValue(el)

        this.element.observe('click', function(e) {
            var r = this.parentCell.parentRow
            if (Object.isFunction(this.parent.onBeforeEdit)) this.parent.onBeforeEdit(this.parentTable, this.parent, this.parentColumn.getIndex())
            r.activate()
            this.toggle()
            if (Object.isFunction(this.parent.onAfterEdit)) this.parent.onAfterEdit(this.parentTable, this.ajaxCell, this.parentColumn.getIndex())
            this.save()
            this.parentCell.values = this.values
            this.parentCell.syncWithGroupe() 
            // affectation de la valeur sur la cellule
        } .bindAsEventListener(this))

        return this
    },
    
    /** <description><![CDATA[Affecte la valeur au controle, change son état et lance la sauvegarde]]></description>
    *<fullName>AJAXOnOffDisplayControl.setValue</fullName>
    *<type>mehtod</type>
    */
    setValue: function(el) {
        this.values = el
        if (this.values.get('value') == 'True') {
            this.src = this.imageOn
            this.element.src = this.src
        } else {
            this.src = this.imageOff
            this.element.src = this.src
        }
        this.parentCell.element.update(this.element)
        this.element.show()
    },

    /** <description><![CDATA[Affecte la paramètres du controle.]]></description>
    *<fullName>AJAXOnOffDisplayControl.setParams</fullName>
    *<type>mehtod</type>
    *<param name="params">Paramètres à affecter</param>
    */
    setParams: function(params) {
        if (!params) return
        if (!params.parameters) return
        for (var property in params) this[property] = params[property];
        this.parameters = new Hash()

        for (var i = 0; i < params.parameters.length; i++) {
            this.parameters.set(params.parameters[i], '')
        }
    },

    /** <description><![CDATA[Intervertit l'état et la valeur du controle]]></description>
    *<fullName>AJAXOnOffDisplayControl.toggle</fullName>
    *<type>mehtod</type>
    */
    toggle: function() {
        if (this.src == this.imageOff) {
            this.src = this.imageOn
            this.element.src = this.src
            this.values.set('value', 'True')
        } else {
            this.src = this.imageOff
            this.element.src = this.src
            this.values.set('value', 'False')
        }
    },
    
    /** <description><![CDATA[Sauvegarde la valeur du controle]]></description>
    *<fullName>AJAXOnOffDisplayControl.save</fullName>
    *<type>mehtod</type>
    */
    save: function(SQLDatas, AjaxHandler) {
        var params = 'action=5&fr=' + this.parentTable.fileRessource + '&pp=' + this.parentTable.pagePath + '&cid=' + this.parentTable.controlId
        if (SQLDatas) params += '&' + SQLDatas
        if (!AjaxHandler) AjaxHandler = 'ajaxtableau.ajax'

        var colIndex = this.parentColumn.parent.indexOf(this.parentColumn)

        params += '&colIndex=' + colIndex

        if (Object.isFunction(this.parent.onBeforeSaving)) { if (this.parent.onBeforeSaving(this.parentTable, this, this.parentColumn.getIndex()) == true) return }

        params += '&' + this.parameters.toQueryString()

        var a = new Ajax.Request(AjaxHandler, {
            method: 'post',
            asychronous: false,
            postBody: params,
            onLoading: function() { this.parentTable.statusBar.setChargement('updading Datas') } .bind(this),
            onComplete: function(e) {
                var r = e.responseJSON
                this.parentTable.statusBar.setChargement('Idle')
                if (Object.isFunction(this.parent.onAfterSaving)) this.parent.onAfterSaving(this.parent.parentTable, this, this.parentColumn.getIndex())
            } .bind(this)
        })
    }
})

var AJAXTextFormat=Class.create()
AJAXTextFormat.prototype = {
    initialize:function(params){
        this.typeOf = 'AJAXTextFormat' 
        this.parent = null //column
        this.column = null // column
        this.value = null
        this.params = params
    },
    
    init:function(parent){
        this.parent = parent;
        this.column = this.parent;
        this.onAfterSaving = (this.params.onAfterSaving)?this.params.onAfterSaving:undefined
        this.onBeforeSaving = (this.params.onBeforeSaving)?this.params.onBeforeSaving:undefined
        this.onAfterEdit = (this.params.onAfterEdit)?this.params.onAfterEdit:undefined
        this.onBeforeEdit = (this.params.onBeforeEdit)?this.params.onBeforeEdit:undefined
        
        this.editor = new AJAXTextEditorControl(this.params.editor, this)
    },
    
    
    getDisplayControl:function(el, parentCell){
        var c = new AJAXTextDisplayControl(this.params.display, parentCell)
        return c.render(el)
    },
    
    setValue:function(el, ajaxCell){
       ajaxCell.values = el   
    }   
}

var AJAXTextDisplayControl = Class.create()
AJAXTextDisplayControl.prototype = {
   initialize:function(params, parentCell){
        this.typeOf = 'AJAXTextDisplayControl' 
        this.parentCell = parentCell //AJAXCell
        this.parentColumn = this.parentCell.column // --> Column
        this.bodyWrap = this.parentColumn.bodyWrap
        this.setParams(params)
          
    },
    
    render:function(el){
        if (this.bodyWrap == false){
            var nobr = new Element('NOBR')
            this.element = nobr
            this.setValue(el)
            this.parentCell.element.insert(this.element)
            this.element.title = (el.get('text'))
        } else {
            var span = new Element('SPAN').update(el.get('text'))
            this.element = span
            this.parentCell.element.appendChild(span)
        } 
        
        return this  
    },
    
    setValue:function(el){
        this.values = el
        this.element.update(el.get('text'))
        this.element.show()
    },
    
    setParams:function(params){if (params) for (var property in params) this[property]=params[property];}

}

var AJAXTextEditorControl = Class.create()
AJAXTextEditorControl.prototype = {
   initialize:function(params, parent){
        this.typeOf = 'AJAXTextEditorControl'
        this.parent = parent //AJAXTextFormat
        this.parentColumn = this.parent.parent // --> Column
        this.parentColumns = this.parentColumn.parent
        this.parentTable = this.parentColumns.parent
        this.ajaxCell = null
        
        this.setParams(params)  
    },
    
    render:function(ajaxCell){
        // ajaxCell = cellule ajax en cours d'édition
        if (ajaxCell.column.isReadOnly == true) return
        this.ajaxCell = ajaxCell
        var t = new Element('INPUT', {value:ajaxCell.values.get('value')})
        t.setStyle({width:'100%', border:'none', height:'100%', margin:'0', padding:'0'}) // Ajouter style pour sélection.
        ajaxCell.displayControl.element.hide()
        if (Object.isFunction(this.parent.onBeforeEdit)) this.parent.onBeforeEdit(this.parentTable, this.parent, this.parent.column.getIndex())
        ajaxCell.element.insert(t)
        this.ajaxCell.editMode = true // cellule placée en mode edit
        this.element = t
        this.setEvents()
        
        // enable selection
        this.element.style.MozUserSelect =''
        this.element.style.KhtmlUserSelect = '';
        if (Prototype.Browser.IE) this.element.onselectstart=function(){return true}
        this.element.focus()
        return this
    },
    
    setEvents:function(){
    
       this.element.onblur = function(e){
            if (!e) e = window.event
            var tg = (e.target) ? e.target : e.srcElement
            var val = this.ajaxCell.values
            val.set('value', this.element.value); val.set('text', this.element.value) 
            this.ajaxCell.setValue(val)
            this.remove()
            return false
       }.bind(this)
       
       
       this.element.onkeydown = function(e){
            __postForm = false
            if (!e) e = window.event
            var tg = (e.target) ? e.target : e.srcElement
            
            var kc = (e.keyCode)?e.keyCode:e.which
            
           
            
            if (kc==13){
                var val = this.ajaxCell.values
                val.set('value', this.element.value); val.set('text', this.element.value) 
                this.ajaxCell.setValue(val)
                this.save()
                this.remove()
                return false
            }
            
            if (kc == 27){
                var val = this.ajaxCell.values
                this.ajaxCell.setValue(val)
                this.remove()
                return false  
            }
            
            if (kc == 9){
            
              var c = this.ajaxCell.getNextEditableCell()
              if (c) {window.setTimeout(function(){c.column.format.editor.render(c)}.bind(this), 1)}
              this.element.blur()
              return  false

            }

       }.bind(this)
       

       this.element.onchange = function(e){
           var val = this.ajaxCell.values
           val.set('value', this.element.value); val.set('text', this.element.value)
           this.values = val
           this.ajaxCell.setValue(val)
           this.ajaxCell.syncWithGroupe() 
           this.save()
       }.bind(this)

    },
    
    save:function(SQLDatas, AjaxHandler){
       
        var params = 'action=5&fr='+ this.parentTable.fileRessource + '&pp=' + this.parentTable.pagePath + '&cid=' + this.parentTable.controlId
        if (SQLDatas) params += '&' + SQLDatas
        if (!AjaxHandler) AjaxHandler = 'ajaxtableau.ajax'
        
        var colIndex = this.parentColumn.parent.indexOf(this.parentColumn)
        
        params += '&colIndex=' + colIndex
        
        if (Object.isFunction(this.parent.onBeforeSaving)) {if(this.parent.onBeforeSaving(this.parentTable, this, this.parentColumn.getIndex()) == true ) return}
        
        params += '&' + this.parameters.toQueryString()

        var a = new Ajax.Request(AjaxHandler, {
            method:'post',
            asychronous:false,
            postBody:params,
            onLoading:function(){this.parentTable.statusBar.setChargement('updading Datas')}.bind(this),
            onComplete:function(e){
                var r = e.responseJSON
                this.parentTable.statusBar.setChargement('Idle')
                if (Object.isFunction(this.parent.onAfterSaving)) this.parent.onAfterSaving(this.parent.parentTable, this, this.parentColumn.getIndex())
            }.bind(this)
        })
    },
    
    remove:function(){
        if (!this.element) return
        this.element.hide()
        if (Object.isFunction(this.parent.onAfterEdit)) this.parent.onAfterEdit(this.parentTable, this.ajaxCell, this.parent.column.getIndex())
        window.setTimeout(function(){this.element.remove()}.bind(this), 100)
        
    },
    
    setParams:function(params){
        if (!params) return
        if (!params.parameters) return
        for (var property in params) this[property]=params[property];
        this.parameters = new Hash()
        
        for (var i=0;i<params.parameters.length;i++){
            this.parameters.set(params.parameters[i], '')
        }
    }
}

// --> TextArea

var AJAXTextAreaFormat=Class.create()
AJAXTextAreaFormat.prototype = {
    initialize:function(params){
        this.typeOf = 'AJAXTextAreaFormat' 
        this.parent = null //column
        this.column = null // column
        this.value = null
        this.params = params
    },
    
    init:function(parent){
        this.parent = parent; 
        this.column = this.parent;
        this.onAfterSaving = (this.params.onAfterSaving)?this.params.onAfterSaving:undefined
        this.onBeforeSaving = (this.params.onBeforeSaving)?this.params.onBeforeSaving:undefined
        this.onAfterEdit = (this.params.onAfterEdit)?this.params.onAfterEdit:undefined
        this.onBeforeEdit = (this.params.onBeforeEdit)?this.params.onBeforeEdit:undefined
        
        this.editor = new AJAXTextAreaEditorControl(this.params.editor, this)
    },
    
    
    getDisplayControl:function(el, parentCell){
        var c = new AJAXTextDisplayControl(this.params.display, parentCell)
        return c.render(el)
    },
    
    setValue:function(el, ajaxCell){
       ajaxCell.values = el   
    }   
}

var AJAXTextAreaDisplayControl = Class.create()
AJAXTextAreaDisplayControl.prototype = {
   initialize:function(params, parentCell){
        this.typeOf = 'AJAXTextAreaDisplayControl' 
        this.parentCell = parentCell //AJAXCell
        this.parentColumn = this.parentCell.column // --> Column
        this.bodyWrap = this.parentColumn.bodyWrap
        this.setParams(params)
          
    },
    
    render:function(el){
        this.element = new Element('DIV')
        this.setValue(el)
        return this  
    },
    
    setValue:function(el){
        this.values = el
        this.element.update(el.get('text'))
        this.element.show()
    },
    
    setParams:function(params){if (params) for (var property in params) this[property]=params[property];}
}

var AJAXTextAreaEditorControl = Class.create()
AJAXTextAreaEditorControl.prototype = {
   initialize:function(params, parent){
        this.typeOf = 'AJAXTextAreaEditorControl'
        this.parent = parent //AJAXTextAreaFormat
        this.parentColumn = this.parent.parent // --> Column
        this.parentColumns = this.parentColumn.parent
        this.parentTable = this.parentColumns.parent
        this.ajaxCell = null
        
        this.setParams(params)  
    },
    
    render:function(ajaxCell){
        // ajaxCell = cellule ajax en cours d'édition
        if (ajaxCell.column.isReadOnly == true) return
        this.ajaxCell = ajaxCell
        var t = new Element('TEXTAREA')
        var v = ajaxCell.values.get('value')
        v = v.replace(new RegExp("(<BR/>)", "g"), '\n')
        t.update(v)
        t.setStyle({width:'100%', border:'none', margin:'0', padding:'0', fontFamily:ajaxCell.element.getStyle('fontFamily'), fontSize:ajaxCell.element.getStyle('fontSize')}) // Ajouter style pour sélection.
        t.rows = this.nbRows
        ajaxCell.displayControl.element.hide()
        if (Object.isFunction(this.parent.onBeforeEdit)) this.parent.onBeforeEdit(this.parentTable, this.parent, this.parent.column.getIndex())
        ajaxCell.element.insert(t)
        this.ajaxCell.editMode = true // cellule placée en mode edit
        this.element = t
        this.setEvents()
        
        // enable selection
        this.element.style.MozUserSelect =''
        this.element.style.KhtmlUserSelect = '';
        if (Prototype.Browser.IE) this.element.onselectstart=function(){return true}
        this.element.focus()
        return this
    },
    
    setEvents:function(){
    
       this.element.onblur = function(e){
            if (!e) e = window.event
            var tg = (e.target) ? e.target : e.srcElement
            var val = this.ajaxCell.values
            var t = this.element.value.replace(new RegExp("(\n)", "g"), '<BR/>')
            val.set('value', t); val.set('text', t) 
            this.ajaxCell.setValue(val)
            this.remove()
            return false
       }.bind(this)
       
       
       this.element.onkeydown = function(e){
            __postForm = false
            if (!e) e = window.event
            var tg = (e.target) ? e.target : e.srcElement
            
            var kc = (e.keyCode)?e.keyCode:e.which

            if (kc == 27){
                var val = this.ajaxCell.values
                this.ajaxCell.setValue(val)
                this.remove()  
            }
            
            if (kc == 9){
            
              var c = this.ajaxCell.getNextEditableCell()
              if (c) {window.setTimeout(function(){c.column.format.editor.render(c)}.bind(this), 1)}
              this.element.blur()
              return  false

            }

       }.bind(this)
       

       this.element.onchange = function(e){
           var val = this.ajaxCell.values
           val.set('value', this.element.value); val.set('text', this.element.value)
           this.values = val
           this.ajaxCell.setValue(val)
           this.ajaxCell.syncWithGroupe() 
           this.save()
       }.bind(this)

    },
    
    save:function(SQLDatas, AjaxHandler){
       
        var params = 'action=5&fr='+ this.parentTable.fileRessource + '&pp=' + this.parentTable.pagePath + '&cid=' + this.parentTable.controlId
        if (SQLDatas) params += '&' + SQLDatas
        if (!AjaxHandler) AjaxHandler = 'ajaxtableau.ajax'
        
        var colIndex = this.parentColumn.parent.indexOf(this.parentColumn) - 1
        
        params += '&colIndex=' + colIndex
        
        if (Object.isFunction(this.parent.onBeforeSaving)) {if(this.parent.onBeforeSaving(this.parentTable, this, this.parentColumn.getIndex()) == true ) return}
        
        params += '&' + this.parameters.toQueryString()
        
        var a = new Ajax.Request(AjaxHandler, {
            method:'post',
            asychronous:false,
            postBody:params,
            onLoading:function(){this.parentTable.statusBar.setChargement('updading Datas')}.bind(this),
            onComplete:function(e){
                var r = e.responseJSON
                this.parentTable.statusBar.setChargement('Idle')
                if (Object.isFunction(this.parent.onAfterSaving)) this.parent.onAfterSaving(this.parent.parentTable, this, this.parentColumn.getIndex())
            }.bind(this)
        })
    },
    
    remove:function(){
        if (!this.element) return
        this.element.hide()
        if (Object.isFunction(this.parent.onAfterEdit)) this.parent.onAfterEdit(this.parentTable, this.ajaxCell, this.parent.column.getIndex())
        window.setTimeout(function(){this.element.remove()}.bind(this), 100)
        
    },
    
    setParams:function(params){
        if (!params) return
        if (!params.parameters) return
        for (var property in params) this[property]=params[property];
        this.parameters = new Hash()
        
        for (var i=0;i<params.parameters.length;i++){
            this.parameters.set(params.parameters[i], '')
        }
    }
}




// --> Number

var AJAXNumberFormat=Class.create()
AJAXNumberFormat.prototype = {
    initialize:function(params, parent){
        this.typeOf = 'AJAXDecimalFormat' 
        this.parent = parent //column
        this.column = null // column
        this.value = null
        this.params = params
       
    },
    
 init:function(parent){
        this.parent = parent; 
        this.column = this.parent;
        this.onAfterSaving = (this.params.onAfterSaving)?this.params.onAfterSaving:undefined
        this.onBeforeSaving = (this.params.onBeforeSaving)?this.params.onBeforeSaving:undefined
        this.onAfterEdit = (this.params.onAfterEdit)?this.params.onAfterEdit:undefined
        this.onBeforeEdit = (this.params.onBeforeEdit)?this.params.onBeforeEdit:undefined
        
        this.editor = new AJAXTextEditorControl(this.params.editor, this)
    },
    
    getDisplayControl:function(el, parentCell){
        var c = new AJAXNumberDisplayControl(this.params.display, parentCell)
        return c.render(el)
    },
    
    setValue:function(el, ajaxCell){
        ajaxCell.values = el     
    }   
}

var AJAXNumberDisplayControl = Class.create()
AJAXNumberDisplayControl.prototype = {
   initialize:function(params, parentCell){
        this.typeOf = 'AJAXNumberDisplayControl' 
        this.parentCell = parentCell //AJAXCell
        this.parentColumn = this.parentCell.column // --> Column
        this.bodyWrap = null
        this.setParams(params)
          
    },
    
    render:function(el){
        var span = new Element('SPAN')
        this.element = span
        this.setValue(el)
        this.parentCell.element.appendChild(span)
        return this 
         
    },
    
    setValue:function(el){
        this.values = el
        var val = __formatNumber(this.values.get('value'), this.nbDecimal)
        var t
        
        if (val == 'NaN' || val == ''){
            if (this.nanReplacementChar) val = this.nanReplacementChar
            t = this.values.set('text', val)
            this.values.set('value', 0)
        } else {
            t = this.values.set('text', __formatNumber(this.values.get('value'), this.nbDecimal))
            this.values.set('value', this.values.get('value').replace(',', '.'))
            if (this.suffix) t += this.suffix
            if (this.prefix) t = this.prefix + t
        }
        
        this.values.set('text', t)
        this.element.update(t)
        this.element.show()
    },
    
    setParams:function(params){ if (params) for (var property in params) this[property]=params[property];}

}


// --> Combo
var AJAXComboFormat=Class.create()
AJAXComboFormat.prototype = {
    initialize:function(params){
        this.typeOf = 'AJAXComboFormat' 
        this.parent = parent //column   
        this.column = null // column
        this.value = null
        this.params = params
        
    },
    
   init:function(parent){
        this.parent = parent; 
        this.column = this.parent;
        this.onAfterSaving = (this.params.onAfterSaving)?this.params.onAfterSaving:undefined
        this.onBeforeSaving = (this.params.onBeforeSaving)?this.params.onBeforeSaving:undefined
        this.onAfterEdit = (this.params.onAfterEdit)?this.params.onAfterEdit:undefined
        this.onBeforeEdit = (this.params.onBeforeEdit)?this.params.onBeforeEdit:undefined
        
        this.editor = new AJAXComboEditor(this.params.editor, this)
    },
    
    getDisplayControl:function(el, parentCell){
        var c = new AJAXTextDisplayControl(this.params.display, parentCell)
        return c.render(el)
    }
}

var AJAXComboEditor = Class.create()
AJAXComboEditor.prototype = {
    initialize:function(params, parent){
        this.parent = parent // --> AJAXComboFormat
        this.column = this.parent
        this.typeOf = 'AJAXComboEditor'
        this.parentColumn = this.parent.parent // --> Column
        this.parentColumns = this.parentColumn.parent
        this.parentTable = this.parentColumns.parent
        this.ajaxCell = null
        this.options = undefined
        
        this.setParams(params)
    }, 
    
    render:function(ajaxCell){
        this.ajaxCell = ajaxCell
        var t = new Element('SELECT')
        t.setStyle({width:'100%', border:'none', height:'18px', margin:'0', padding:'0'})
        this.element = t
        this.setEvents()
        this.setOptions()
        this.element.value = ajaxCell.values.get('value')
        ajaxCell.displayControl.element.hide()
        if (Object.isFunction(this.parent.onBeforeEdit)) this.parent.onBeforeEdit(this.parentTable, this.parent, this.parent.column.getIndex())
        ajaxCell.element.insert(t)
        this.ajaxCell.editMode = true
       
        
         // enable selection
        this.element.style.MozUserSelect =''
        this.element.style.KhtmlUserSelect = '';
        if (Prototype.Browser.IE) this.element.onselectstart=function(){return true}
        this.element.focus()
        return this 
        
    },
    
    setOptions:function(options){
        if (!options && !this.options) return
        if (options) this.options = options
        
        this.element.length=0
        
        for (var i=0; i<this.options.length; i++){
            var op = this.options[i]
            this.element.insert(new Element('OPTION', {value:op.value}).update(op.text))
        }
    },
 
    setParams:function(params){
        if (!params) return
        for (var property in params) this[property]=params[property];
        this.parameters = new Hash()
        
        for (var i=0;i<params.parameters.length;i++){
            this.parameters.set(params.parameters[i], '')
        }
    },
    
     setEvents:function(){
    
       this.element.onblur = function(e){
          writeLog('blur')
            if (!e) e = window.event
            var tg = (e.target) ? e.target : e.srcElement

            var val = this.ajaxCell.values
            val.set('value', this.element.value); val.set('text', this.element.options[this.element.selectedIndex].text) 
             
            this.ajaxCell.setValue(val)
            this.remove()
       }.bind(this)
       
       
       this.element.onkeydown = function(e){
             __postForm = false
           if (!e) e = window.event
            var tg = (e.target) ? e.target : e.srcElement
            
            var kc = (e.keyCode)?e.keyCode:e.which
            
            if (kc==13){
                var val = this.ajaxCell.values
                val.set('value', this.element.value); val.set('text', this.element.options[this.element.selectedIndex].text)
                this.ajaxCell.setValue(val)
                this.remove()
            }
            
            if (kc == 27){
                var val = this.ajaxCell.values
                this.ajaxCell.setValue(val)
                this.remove()  
            }
            
            if (kc == 9){
                var c = this.ajaxCell.getNextEditableCell()
                if (c) {window.setTimeout(function(){c.column.format.editor.render(c)}.bind(this), 1)}
                this.element.blur()
                return false  
            }
            
            
       }.bind(this)
       
       this.element.onchange = function(e){
           this.ajaxCell.syncWithGroupe()
           this.save()
       }.bind(this)

    },
    
    
     save:function(SQLDatas, AjaxHandler){
       
        var params = 'action=5&fr='+ this.parentTable.fileRessource + '&pp=' + this.parentTable.pagePath + '&cid=' + this.parentTable.controlId
        if (SQLDatas) params += '&' + SQLDatas
        if (!AjaxHandler) AjaxHandler = 'ajaxtableau.ajax'
        
        var colIndex = this.parentColumn.parent.indexOf(this.parentColumn)
        
        params += '&colIndex=' + colIndex
        
        if (Object.isFunction(this.parent.onBeforeSaving)) this.parent.onBeforeSaving(this.parentTable, this, this.parentColumn.getIndex())
        
        params += '&' + this.parameters.toQueryString()
        
        var a = new Ajax.Request(AjaxHandler, {
            method:'post',
            asychronous:false,
            postBody:params,
            onLoading:function(){this.parentTable.statusBar.setChargement('updading Datas')}.bind(this),
            onComplete:function(e){
                var r = e.responseJSON
                this.parentTable.statusBar.setChargement('Idle')
                // After binding
            }.bind(this)
        })
    },
    
     remove:function(){
        writeLog('Remove')
        this.element.hide()
        if (!this.element) return
        if (Object.isFunction(this.parent.onAfterEdit)) this.parent.onAfterEdit(this.parentTable, this.ajaxCell, this.parent.column.getIndex())
        window.setTimeout(function(){this.element.parentNode.removeChild(this.element)}.bind(this), 100)
       
        
    }

}

