/*
 *  Copyright 2013 Anyware Services
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */

/**
 * This class provides a widget to query and select one or more groups.
 * 
 * This widget is registered for fields of type Ametys.form.WidgetManager#TYPE_STRING.<br>
 */
Ext.define('Ametys.form.widget.Group', {
    extend: 'Ametys.form.AbstractQueryableComboBox',
	
	valueField: 'value',
	displayField: 'displayName',
	
    getStore: function()
    {
        if (!Ext.data.schema.Schema.get('default').hasEntity('Ametys.form.widget.Group.Groups')) {
            Ext.define("Ametys.form.widget.Group.Groups", {
                extend: 'Ext.data.Model',
                
                idProperty: 'value',
                
                fields: [
                     {name: 'label', mapping: 'label', type: 'string'},
                     {name: 'groupId', mapping: 'id'},
                     {name: 'groupDirectory', mapping: 'groupDirectory'},
                     {name: 'groupDirectoryLabel', mapping: 'groupDirectoryLabel', type: 'string'},
                     {
                        name: 'value', 
                        type: 'string',
                        calculate: function(data)
                        {
                            return data.groupId + '#' + data.groupDirectory;
                        }
                     },
                     {
                         name: 'displayName',
                         type: 'string',
                         calculate: function(data)
                         {
                            return Ext.String.escapeHtml(data.label) + ' (' + data.groupId + ', ' + data.groupDirectoryLabel + ')';
                         }
                     }
                ]
            });
        }

        return Ext.create('Ext.data.Store', {
            model: 'Ametys.form.widget.Group.Groups',
            proxy: {
                type: 'ametys',
                role:"org.ametys.plugins.core.group.GroupDAO",
                methodName: "searchGroupsByContexts",
                methodArguments: ['contexts', 'limit', 'offset', 'searchCriteria'],
                reader: {
                    type: 'json',
                    rootProperty: 'groups'
                }
            },
            
            pageSize: this.maxResult,
            sortOnLoad: true,
            sorters: [{property: 'label', direction:'ASC'}],
            
            listeners: {
                beforeload: {fn: this._onStoreBeforeLoad, scope: this}
            }
        });
    },
    
    /**
     * Set the request parameters before loading the store.
     * @param {Ext.data.Store} store The store.
     * @param {Ext.data.operation.Operation} operation The Ext.data.Operation object that will be passed to the Proxy to load the Store.
     * @private
     */
    _onStoreBeforeLoad: function(store, operation)
    {
        var proxy = operation.getProxy();
        
        proxy.setExtraParam('contexts', Ametys.getAppParameter('populationContexts'));
        proxy.setExtraParam('limit', this.maxResult);
        proxy.setExtraParam('offset', 0);
        proxy.setExtraParam('searchCriteria', operation.getParams().query);
    },
    
    
    _convertToComparableValue: function(item)
    {
        if (!item)
        {
            return "";
        }
        else if (Ext.isString(item))
        {
            if (!item.startsWith('{'))
            {
                return item;
            }
            item = JSON.parse(item)
        }

        return item.groupId + '#' + item.groupDirectory;
    },
    
    getValue: function ()
    {
    	var value = this.callParent(arguments),
    		convertedValues = [];
    	
    	value = Ext.Array.from(value);
    	
    	Ext.Array.forEach (value, function (val) {
            var index = val.lastIndexOf("#");
    		convertedValues.push({
    			groupId: val.substring(0, index),
    			groupDirectory: val.substring(index + 1)
    		});
    	});
    	
    	return this.multiple ? convertedValues : convertedValues[0];
    },
    
    getJsonValue: function()
    {
        var convertedValues = Ext.Array.from(this.getValue());
        var jsonValues = [];
        
        Ext.Array.forEach (convertedValues, function (convertedValue) {
            jsonValues.push(Ext.JSON.encode(convertedValue));
        });
        
        return this.multiple ? jsonValues : jsonValues[0];
    },
    
    setValue: function(value)
    {
    	value = value ? Ext.Array.from(value) : [];
    	
    	var convertedValues = [];
    	Ext.Array.forEach(value, function(item) {
    		if (Ext.isObject(item))
    		{
    			convertedValues.push(item.groupId + '#' + item.groupDirectory);
    		}
    		else
    		{
                var groupJson = Ext.JSON.decode(item, true /*safe to return null if it fails*/);
    			if (groupJson == null)
    			{
                    // was not a JSON but a raw value
    				convertedValues.push(item);
    			}
    			else
    			{
    				convertedValues.push(groupJson.groupId + '#' + groupJson.groupDirectory);
    			}
    		}
    	});
    	
    	this.callParent([convertedValues]);
    },
    
    getSubmitValue: function ()
    {
    	var value = this.getValue();
    	return value != null ? Ext.encode(this.getValue()) : null;
    },
    
    getLabelTpl: function ()
    {
    	var tpl = [];
    	tpl.push('<span class="x-tagfield-glyph ametysicon-multiple25"></span>');
    	tpl.push('{' + this.displayField + '}');
    	return tpl;
    }
});