/*
 *  Copyright 2015 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.
 */

/**
 * @private
 * This helper is used to generate a skin from another skin or from a model. See #open method.
 */
Ext.define("Ametys.plugins.web.skin.helper.GenerateSkinUI", {
    singleton: true,

    /**
     * @private
     * @property {Function} _cbFn Callback function to execute after generating the skin
     */

    /**
     * @private
     * @property {Ametys.window.DialogBox} _box The dialog box
     */

    /**
     * @private
     * @property {Ext.form.FormPanel} _formPanel The form of the dialog box
     */


    /**
     * Open the dialog box for generating the skin
     * @param {String} [skinId] The id of skin used to generate the new skin. If omited, this helper will let the user choose from a combobox.
     * @param {Function} [callback] The function to call when successful
     */
    open: function (skinId, callback)
    {
        this._cbFn = callback;

        this._delayedInitialize();

        this._box.show();
        this._initForm (skinId);
    },

    /**
     * Creates the dialog box
     * @private
     */
    _delayedInitialize: function ()
    {
        if (this._initialized)
        {
            return;
        }

        this._formPanel = this._createFormPanel();

        this._box = Ext.create('Ametys.window.DialogBox', {
            iconCls: 'ametysicon-three115',
            title: "{{i18n PLUGINS_SKINFACTORY_SKIN_MODEL_GENERATE_SKIN_LABEL}}",
            width: 520,
            scrollable: false,
            layout: "fit",

            items: [this._formPanel],

            closeAction: 'hide',
            defaultFocus: 'originalModelId',
            
            referenceHolder: true,
            defaultButton: 'validate',
            
            buttons: [{
            	reference: 'validate',
                text: "{{i18n PLUGINS_SKINFACTORY_ADMINISTRATOR_DIALOG_OK}}",
                handler: Ext.bind(this._validate, this)
            }, {
                text: "{{i18n PLUGINS_SKINFACTORY_ADMINISTRATOR_DIALOG_CANCEL}}",
                handler: Ext.bind(this._cancel, this)
            }]
        });

        this._initialized = true;
    },

    /**
     * Create the form panel
     * @return {Ext.form.FormPanel} the form panel
     * @private
     */
    _createFormPanel: function()
    {
        var formPanel = new Ext.form.FormPanel( {
            defaultType: 'textfield',
            border: false,

            defaults: {
                cls: 'ametys',
                labelAlign: 'right',
                labelSeparator: '',
                labelWidth: 80,
                width: 470,
                msgTarget: 'side'
            },

            items: [
                {
                    xtype: 'container',
                    html: "{{i18n PLUGINS_SKINFACTORY_SKIN_MODEL_GENERATE_SKIN_HINT}}",
                    cls: 'text'
                },
                {
                    xtype: 'combobox',
                    name: 'originalModelId',
                    itemId: 'originalModelId',
                    fieldLabel: "{{i18n PLUGINS_SKINFACTORY_SKIN_MODEL_GENERATE_SKIN_MODEL}} *",
                    hidden: true,
                    store: Ext.create('Ext.data.Store', {
                        model: "Ametys.plugins.skinfactory.skin.SkinModel"
                    }),
                    displayField: 'fullLabel',
                    valueField: 'id',
                    validator: function (val) {
                        return (this.isHidden() || val.length > 0) ? true : "{{i18n plugin.core-ui:PLUGINS_CORE_UI_DEFAULT_VALIDATOR_MANDATORY}}";
                    }
                },
                {
                    xtype: 'textfield',
                    name: 'skinId',
                    fieldLabel: "{{i18n PLUGINS_SKINFACTORY_SKIN_MODEL_GENERATE_SKIN_SKIN_NAME}} *",
                    allowBlank: false,
                    emptyText: "{{i18n PLUGINS_SKINFACTORY_SKIN_MODEL_GENERATE_SKIN_SKIN_NAME_DESC}}",
                    invalidText: "{{i18n PLUGINS_SKINFACTORY_SKIN_MODEL_GENERATE_SKIN_SKIN_NAME_INVALID}}",
                    regex: /^[0-9a-z_-]+$/
                }
                
            ],

            scrollable: false
        });

        return formPanel;
    },

    /**
     * Initialize the form
     * @param {String} [modelId] The id of model used to generate the new skin. If omitted, this helper will let the user choose his model from a combobox.
     * @private
     */
    _initForm: function (modelId)
    {
    	var form = this._formPanel.getForm();
        form.findField('skinId').setValue("");

        form.findField('originalModelId').setVisible(modelId == null);
        form.findField('originalModelId').setValue(modelId);
        
        form.clearInvalid();
        
        if (modelId == null)
        {
            // There is no pre-selected model, let the user choose the model in a combo box
        	Ametys.plugins.skinfactory.model.SkinModelDAO.getSkinsAndModels([false], Ext.bind(this._getModelsCb, this), {
                waitMessage: {
                    target: this._box
                }
            });
        }
    },

    /**
     * Callback invoked after loading available models.
     * Load store of combo box for models.
     * @param {Object} response The server response.
     * @param {Object[]} response.models The list of available models
     * @param {Object[]} response.skins The list of available skins
     * @private
     */
    _getModelsCb: function(response)
    {
    	var form = this._formPanel.getForm();
    	form.findField('originalModelId').getStore().loadData (response.models || []);
    },

   /**
    * Handler for the 'Ok' button of the dialog box.
    * Generate a new skin from selected model.
    * @private
    */
    _validate: function ()
    {
        var form = this._formPanel.getForm();
        if (!form.isValid())
        {
            return;
        }

        var skinId = form.findField('skinId').getValue();

        var originalModelId = form.findField('originalModelId').getValue();
        Ametys.plugins.skinfactory.model.SkinModelDAO.generateSkin([skinId, originalModelId], Ext.bind(this._generateSkinCb, this), {
            waitMessage: {
                target: this._box
            }
        });
    },

    /**
     * Callback for the "cancel" button of the dialog. Close the dialog.
     * @private
     */
    _cancel: function ()
    {
        this._box.hide();
    },

    /**
     * Callback after the new skin was generated successfully.
     * @param {String} error The error code. Null if it was successful.
     * @private
     */
    _generateSkinCb: function (error)
    {
        if (!error)
        {
            this._box.hide();
            if (Ext.isFunction(this._cbFn))
            {
                this._cbFn (skinName);
            }
        }
        else if (error == "already-exists")
        {
            Ametys.Msg.show({
                title: "{{i18n plugin.web:PLUGINS_WEB_ADMINISTRATOR_SKINS_ALREADY_EXIST_TITLE}}",
                msg: "{{i18n plugin.web:PLUGINS_WEB_ADMINISTRATOR_SKINS_ALREADY_EXIST}}",
                buttons: Ext.Msg.OK,
                icon: Ext.MessageBox.ERROR
            });
        }
    }

});