/**
 * Makes a multi-select box that does not occupy screen space.
 * Essentially it is a layer with a grid panel on top of it.
 *
 * A hidden field id is passed whose value is set as a CSV of ids. The jsonData
 * is currently local and of the form "id: name: ".
 *
 * Further configurations
 * 1) Take grid data store options from the user.
 * 2)
 * @author Ravindra Wankar
 *
 * Notes:
 * 1. Container created outside.
 * Currently the container and the picker are created outside. We only create the textarea
 * and render it to the div specified.
 * 2. If container is to be created by us
 * In this case we must create the container and then we can simply use applyToMarkup on
 * the text area.
 * 3. Grow/Hide
 * All Grow/Hide is managed by the text area. If we want to manage it we must uncomment
 * the code for height manipulation. Also set grow to false on the textarea
 */

CELOXIS.MultiSelectBox = function(config) {
    config = config || {};
    config = Ext.applyIf(config, {
        pickerId: '',
        displayId: '',
        //renderTo: '',
        hiddenName: '',
        jsonData: '',
        labelName: 'name',
        valueName: 'id',
        selected: '',
        emptyText: '< Any >',
        scrollAfter: 4,
        width: 180,
        listWidth: 200,
        onePerLine: true,
        height: 250,
        oneLineSeparator: ', ',
        growMax: 60 /* applicable only when onePerLine is false */,
        moreConfig: ''
    });

    Ext.applyIf(this, config);
    Ext.apply(this, config.moreConfig);

    /*
     * Use this block if at we decide to handle the container ourselves.
    this.displayId = this.hiddenName + 'disp';
    this.pickerId = this.hiddenName + 'pick';
    Ext.DomHelper.insertFirst(this.renderTo, {
        tag: 'div', cls: 'x-form-field-wrap', children: [
                                                         {tag: 'textarea', id: this.displayId},
                                                         {tag: 'img', id: this.pickerId, cls: 'x-form-trigger x-form-arrow-trigger'}
                                                         ]
    });
    */

    //this.growMin = Ext.isSafari ? 16 : 22;
    this.growMin = 22;
    this.grow = true;
    this.separator = '\n';
    if (!this.onePerLine)
    {
        this.separator = this.oneLineSeparator;
        this.displayArea = new Ext.form.TextField({
            renderTo: this.displayId,
            emptyText: this.emptyText,
            readOnly: true,
            width: this.width - 16,
            grow: false,
            //height: this.growMin,
            // grow: this.grow,
            // growMin: this.growMin,
            // growMax: this.growMax,
            //growPad: Ext.isSafari ? -14 : -10, /* hack from forum */
            // growPad: -10,
            // growAppend: '',
            cls: 'multisel'
            //style: 'border: 1px solid #999999; overflow:auto;'
        });

    }
    else
    {
        this.displayArea = new Ext.form.TextArea({
            renderTo: this.displayId,
            emptyText: this.emptyText,
            readOnly: true,
            width: this.width - 16,
            //height: this.growMin,
            grow: this.grow,
            growMin: this.growMin,
            growMax: this.growMax,
            //growPad: Ext.isSafari ? -14 : -10, /* hack from forum */
            growPad: -8,
            growAppend: '',
            cls: 'multisel',
            //style: 'border: 1px solid #999999; overflow:auto;'
            style: 'overflow:auto;'
        });

        this.growMax = this.growMin * this.scrollAfter;
    }

    // Foll is we create the container ourselves
    //this.displayArea.applyToMarkup(Ext.get(this.displayId));

    this.form = function() { return this.displayArea.getEl().dom.form };

    /*
     * Create a layer that will hold our multi-select
     */
    this.layer = new Ext.Layer({
        shadow: false,
        zindex: 1000
    });

    this.picker = Ext.get(this.pickerId);
    this.picker.layer = this.layer;

    this.onClick = function(e) {
        this.layer.anchorTo(this.id, 'tr');
        this.layer.show(false);
    };

    this.picker.on('click', this.onClick, this.picker);
    this.displayArea.on('focus', this.onClick, this.picker);

    this.hiddenFields = new Array();
    this.selectedRecords = new Array();

    /*
     * A convenient method to clear the form hidden fields.
     */
    this.clearHiddenFields = function () {
        for (var i = 0; i < this.hiddenFields.length; i++)
        {
            this.hiddenFields[i].remove();
        }
        this.hiddenFields.length = 0;
    }

    /*
     * Cancels selections made by user
     */
    this.cancelSelections = function() {
        this.sm.clearSelections();
        this.sm.selectRecords(this.selectedRecords);
    }

    /*
     * Sets the selections based on the selected values passed.
     */
    this.setOriginalSelections = function () {
        this.sm.clearSelections();
        if (this.selected != '')
        {
            for (var i = 0; i < this.selected.length; i++)
            {
                this.sm.selectRow(this.grid.store.indexOfId(this.selected[i]), true);
            }
        }
        this.setSelections();
    }

    /*
     * Sets the display and form hidden field based on selections made
     */
    this.setSelections = function () {
        var items = this.sm.getSelections();
        var selNames = '';
        this.clearHiddenFields();
        this.selectedRecords.length = 0; // this is for the cancel op
        for (var i = 0; i < items.length; i++)
        {
            //var h = new Ext.form.Hidden({name: this.hiddenName, value: items[i].get('id')});
            //this.form.add(h);
            //var h = Ext.get(this.form()).createChild({tag:'input', type:'hidden', name:this.hiddenName, value: items[i].get('id')});
            var h = this.picker.insertSibling({tag:'input', type:'hidden', name:this.hiddenName, value: items[i].get('id')});
            //var h = addHiddenInputField(this.form, this.hiddenName, items[i].get('id'));
            this.hiddenFields.push(h);
            selNames += items[i].get('name');
            if (i < items.length - 1)
            {
                selNames += this.separator;
            }
            this.selectedRecords.push(items[i]);
        }
        if (items.length == 0)
        {
            selNames = this.emptyText;
            var h = this.picker.insertSibling({tag:'input', type:'hidden', name:this.hiddenName, value: ''});
            this.hiddenFields.push(h);
        }
        this.displayArea.setValue(selNames);
        /*
        if (this.onePerLine)
        {
            height = this.growMin;
            if (items.length > 1 && items.length < this.scrollAfter) { height = items.length * 20; }
            if (items.length >= this.scrollAfter) { height = this.scrollAfter * 20; }
            this.displayArea.setHeight(height);
        }
        */
    }

    this.sm = new Ext.grid.CheckboxSelectionModel();
    id = Ext.id();

    /*
     * The grid panel that holds the main data
     */
    this.grid = new Ext.grid.GridPanel({
        store: new Ext.data.JsonStore({
            fields: [this.valueName, this.labelName],
            id: this.valueName,
            data : this.jsonData
            /*
            listeners: {
                load: {
                    scope: this, single:true, fn:function() {
                        var view = this.grid.getView()
                        if(true === view.forceFit) {
                            view.fitColumns.defer(500, view);
                        }
                    }
                }
            }
            */
        }),
        cm: new Ext.grid.ColumnModel([
            this.sm,
            {id:id, header: "Name", width: this.listWidth, sortable: false, resizable: false, fixed: true, dataIndex: 'name'}
        ]),
        sm: this.sm,
        width: this.listWidth + 52,
        autoScroll: true,
        //autoExpandColumn: id,
        height:this.height,
        frame:true,
        //title:'Select Users',
        iconCls:'icon-grid',
        layout: 'fit',
        /* Seems to autoexpand the grid to the width
        viewConfig: {
            forceFit:true
        },
        */
        buttons: [
                  new Ext.Button({
                      text: 'OK',
                      minWidth: 60,
                      multiselect: this,
                      listeners: {
                          click: function (e, target) {
                              this.multiselect.setSelections();
                              this.multiselect.layer.hide(false);
                          }
                      }
                  }),
                  new Ext.Button({
                      text: 'Cancel',
                      minWidth: 60,
                      multiselect: this,
                      listeners: {
                          click: function (e, target) {
                              this.multiselect.cancelSelections();
                              this.multiselect.layer.hide(false);
                          }
                      }
                  })
                  /*
                  new Ext.Button({
                      text: 'Reset',
                      multiselect: this,
                      listeners: {
                          click: function (e, target) {
                              this.multiselect.setOriginalSelections();
                              this.multiselect.layer.hide(false);
                          }
                      }
                  })
                  */
                  ],
        buttonAlign:'center'
    });

    /*
     * We must have something inside the layer to which we can render the grid panel.
     */
    var panelId = Ext.id();
    this.layer.createChild({tag: 'div', id: panelId});
    this.grid.render(panelId);

    this.setOriginalSelections();
};
