/*
 *  Copyright 2021 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.
 */
 
/**
 * Helper for creating or editing a question.
 */
Ext.define('Ametys.plugins.forms.helper.QuestionEditDialogHelper', {
    singleton: true,
    
    /**
     * Open the dialog to edit a question
     * @param {Object} config The configuration object
     * @param {Ametys.message.MessageTarget} config.target The target to edit.
     */
    open: function (config){
        Ametys.data.ServerComm.callMethod({
            role: "org.ametys.plugins.forms.dao.FormQuestionDAO",
            methodName: "getQuestionParametersDefinitions",
            parameters: [config.questionType, config.formId],
            callback: {
                handler: this._configureCB,
                scope: this,
                arguments: {
                    config: config
                }
            },
            waitMessage: true,
            errorMessage: true
        });         
    },
    
    /**
     * @private
     * Callback function after retrieving question parameters.<br/>
     * Draw the forms.
     * @param {Object} response the server response
     * @param {Object[]} args the callback arguments.
     */
    _configureCB: function(response, args)
    {
       var cfpConfig = {
            hideDisabledFields: true,
            tabPosition: 'left',
            layout: 'fit',
            itemsLayout: 'fit',
            tabItemsLayout: 'anchor',
            scrollable: false,
            tabBar: {defaults: {width: 180}},
            spacingCls: false,
            
            additionalWidgetsConf: {
                standaloneEdition: true, // standalone edition (use case: a popup without ribbon (for example richtext buttons) or FO edition)  
                category: "forms", // category for richtext
                questionId: args.config.id // the question id for rules widget
            }
        };
        
        this._form = Ext.create('Ametys.form.ConfigurableFormPanel', cfpConfig);
        this._form.configure(response.parameters.elements);
        
        this._createDialogBox(args.config);
        this._box.add(this._form);
        this._questionNames = response["questionNames"];
         
        Ametys.data.ServerComm.callMethod({
            role: "org.ametys.plugins.forms.dao.FormQuestionDAO",
            methodName: "getQuestionParametersValues",
            parameters: [args.config.id],
            callback: {
                handler: this._initFormCb,
                scope: this,
                arguments: {
                    hasRule: args.config.hasRule
                }
            },
            waitMessage: true,
            errorMessage: true
        });
    },
    
    /**
     * @private
     * Initialize form values
     * @param {Object} response The values of question attributes
     * @param {Object[]} args the callback arguments.
     */
    _initFormCb: function (response, args)
    {
        this._form.setValues(response);
        
        var dateFormat = this._form.getField("date-format");
        if (dateFormat)
        {
        	dateFormat.addListener("change", function(field, value)
            	{
            		this._transferDateValues(value);
            	}, this);	
        }
        var numberType = this._form.getField("number-type");
        if (numberType)
        {
        	numberType.addListener("change", function(field, value)
            	{
            		this._transferNumberValues(value);
            	}, this);	
        }
        
        var writingComboBox = this._form.getField("writing");
        if (writingComboBox && writingComboBox.getStore().getData().length == 0)
        {
            var writingCheckBoxField = this._form.getField("writingCheckbox");
            writingCheckBoxField.disable(true);
            writingCheckBoxField.ametysDescription = writingCheckBoxField.ametysDescription + "<br/><br/>" + "{{i18n PLUGINS_FORMS_QUESTIONS_DIALOG_QUESTION_RESTRICTION_NO_WRITABLE_DESC}}";
            writingComboBox.disable(true);
        }
        
        if (args.hasRule)
        {
            var writingCheckBoxField = this._form.getField("writingCheckbox");
            if (writingCheckBoxField)
            {
                writingCheckBoxField.disable(true);
                this._form.getField("writing").disable(true);
            }
        }
        
        var repeaters = this._form.getRepeaters();
        var fieldNames = response.fieldToDisable;
        for (var i in fieldNames)
        {
            var field = this._form.getField(fieldNames[i]);
            if (field)
            {
                field.disable();
                field.ametysDescription = field.ametysDescription + "<br/><br/>" + "{{i18n PLUGINS_FORMS_QUESTIONS_DIALOG_QUESTION_NO_WRITABLE_DESC}}";
            }
            else
            {
                for (var j in repeaters)
                {
                    if (repeaters[j].name == fieldNames[i])
                    {
                        repeaters[j].disable();
                    }
                }
            }
        }
        
        this._box.show();
        this._form.focus();
    },
    
	/**
	 * @private 
	 * On date format change, set min and max dates values to the new format
	 * @param {String} format The format's name, can be 'date' or 'datetime'
	 */
	_transferDateValues : function(format)
	{
		if (format == "datetime")
		{
            var minDate = this._form.getField('min-date').getValue();
            var maxDate = this._form.getField('max-date').getValue();
            if (minDate != null)
            {
                this._form.getField('min-datetime').setValue(new Date(minDate));
            }
            
            if (maxDate != null)
            {
                this._form.getField('max-datetime').setValue(new Date(maxDate));
            }
		}
		else
		{
            var minDateTime = this._form.getField('min-datetime').getValue();
			var maxDateTime = this._form.getField('max-datetime').getValue();
			if (minDateTime != null)
			{
    			this._form.getField('min-date').setValue(new Date(minDateTime));
            }
            
            if (maxDateTime != null)
            {
                this._form.getField('max-date').setValue(new Date(maxDateTime));
            }
		}
	},
	
	
	/**
	 * @private 
	 * On number format change, set min and max values to the new format
	 * @param {String} format the number's format, can be 'double' or 'integer'
	 */
	_transferNumberValues : function(format)
	{
		if (format == "double")
		{
			var minDouble = this._form.getField('min-int').getValue();
			var maxDouble = this._form.getField('max-int').getValue();
			this._form.getField('min-double').setValue(minDouble);
			this._form.getField('max-double').setValue(maxDouble);
		}
		else
		{
			var minInt = this._form.getField('min-double').getValue();
			var maxInt = this._form.getField('max-double').getValue();
			this._form.getField('min-int').setValue(minInt);
			this._form.getField('max-int').setValue(maxInt);
		}
	},
	
    /**
     * @private
     * Create the question dialog box
     * @param {Object} config The configuration object
     */
    _createDialogBox: function(config)
    {
        var ratio = 0.80,
        maxHeight = window.innerHeight * ratio,
        maxWidth = window.innerWidth * ratio;
        
        var title = config.questionType == "form.Computed"
            ? "{{i18n PLUGINS_FORMS_PARAMETERS_DIALOG_BOX_WITHOUT_FIELD_LABEL}} " + config.dialogTitle.toLowerCase()
            : "{{i18n PLUGINS_FORMS_PARAMETERS_DIALOG_BOX_LABEL}} " + config.dialogTitle.toLowerCase();

        this._box = Ext.create('Ametys.window.DialogBox', {
            title : title,
            iconCls : config.iconGlyph,
            
            layout: 'fit',
            bodyPadding: '0',
            maxHeight: maxHeight,
            maxWidth: maxWidth,
            width: 1300,
            minHeight: 350,
            freezeHeight: true,
            
            items: [],
            
            closeAction: 'destroy',
            closeToolText: "{{i18n PLUGINS_FORMS_QUESTIONS_DIALOG_BUTTON_CANCEL}}",
            
            referenceHolder: true,
            defaultButton: 'validate',
            
            buttons : [
                {
                    reference: 'validate',
                    itemId: 'button-ok',
                    text :"{{i18n PLUGINS_FORMS_QUESTIONS_DIALOG_BUTTON_OK}}",
                    handler:Ext.bind(this._validate, this, [config]),
                    scope: this
                }, {
                    text :"{{i18n PLUGINS_FORMS_QUESTIONS_DIALOG_BUTTON_CANCEL}}",
                    handler: function() { this._box.close(); },
                    scope: this
            }]
        });
    },
    
    /**
     * @private
     * Validate the dialog box and create the service.
     * @param {Object} config The configuration object
     */
    _validate: function (config)
    {
        var invalidFields = this._form.getInvalidFields();
        var values = this._form.getJsonValues();
        if (invalidFields.length > 0)
        {
            Ametys.Msg.show({
                   title: "{{i18n PLUGINS_FORMS_QUESTIONS_DIALOG_BOX_SAVE_ERROR}}",
                   msg: "{{i18n PLUGINS_FORMS_QUESTIONS_DIALOG_BOX_SAVE_ERROR_INVALIDFIELDS}}" + Ametys.form.SaveHelper.getInvalidFieldsAsReadableList(invalidFields),
                   buttons: Ext.Msg.OK,
                   icon: Ext.MessageBox.ERROR
            });
            return;
        }
        
        Ametys.plugins.forms.dao.FormQuestionDAO.editQuestion([config.id, values], this._validateCb, {scope: this} );
    },
    
    /**
     * @private
     * Callback function called after creation or edition process
     * @param {Object} response The server response
     */
    _validateCb: function (response)
    {
        if (response && !response['errors'])
        {
            this._box.close();
        }
        else if (response && response['errors'])
        {
            var fieldsInError = response['errors'];
            for (var i in fieldsInError)
            {
                var fd = this._form.getField(i);
                if (fd != null)
                {
                    fd.markInvalid(fieldsInError[i]);
                }
            }
        }
        else
        {
            Ametys.Msg.show({
                title: "{{i18n PLUGINS_FORMS_QUESTIONS_PROCESS_ERROR_HEADER}}",
                msg: "{{i18n PLUGINS_FORMS_QUESTIONS_PROCESS_ERROR}}",
                buttons: Ext.Msg.OK,
                icon: Ext.Msg.ERROR
            });
        }
    }
    
});