/*
 *  Copyright 2022 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 add a rule to a question
 */
Ext.define('Ametys.plugins.forms.widget.QuestionRules', {
    extend : 'Ametys.form.AbstractField',
    
    xtype: 'edition.question-rules',
    
    constructor: function(config)
    {
    	this.callParent(arguments);
    },
    
    initComponent: function()
    {
    	var tool = Ametys.tool.ToolsManager.getFocusedTool();
    	this._formId = tool._formId;
		this._questionId = this.config.form.additionalWidgetsConf.questionId;
		
		//init option store
    	this._optionStore = Ext.create('Ext.data.Store', {
		     proxy: {
			     	type: 'ametys',
			     	role: 'org.ametys.plugins.forms.helper.QuestionRuleHelper',
	                methodName: 'getSourceOptions',
	                methodArguments: ['questionId'],
	                reader: {
	                    type: 'json',
						rootProperty :'data'
	                }
			     },
			     listeners: {
	                'beforeload': Ext.bind(this._onBeforeLoadOptionStore, this),
	                'load': Ext.bind(this._onLoadOptionStore, this),
	            }
			 });
    	
    	// init action store
        this._actionStore = Ext.create('Ext.data.Store', {
		     proxy: {
			     	type: 'ametys',
			     	role: 'org.ametys.plugins.forms.helper.QuestionRuleHelper',
	                methodName: 'getRuleActions',
	                methodArguments: [],
	                reader: {
	                    type: 'json',
						rootProperty :'data'
	                }
			     },
			     autoLoad: true
			 });
        
    	this._rulePanel = this._createPanel()
        this.items = [this._rulePanel];
        this.layout = 'fit';
        this.cls = this.emptyCls;
        
        this.callParent(arguments);
    },
    
    getValue: function ()
    {
        var values = {};
        
        //Question
        var question = this._comboQuestions.getValue();
        
        //Option
        var option = this._comboOptions.getValue();
        
        //Action
        var action = this._comboActions.getValue();
        
        if (question != null && option != null && action != null)
        {
        	values.question = question;
            values.option = option;
            values.action = action;
        }
        
        return Ext.JSON.encode(values);
    },
    
    setValue: function(value) 
    {   
		this.callParent(arguments);
		if (value != null)
		{
			this._comboQuestions.setValue(value.sourceId);
			this._comboOptions.setValue(value.option);
			this._comboActions.setValue(value.action);
		}
    },
    
	/**
	/* @private 
	 * Create the rule panel
	 */
	_createPanel : function()
	{
		//combobox questions
		this._comboQuestions = Ext.create('Ext.form.ComboBox', {
		    name: 'questions',
			store: this._getQuestionStore(),
		    queryMode: 'local',
		    displayField: 'label',
		    width: 300,
		    valueField: 'id',
		    editable: false,
            listeners: {
                'change': Ext.bind(this._onQuestionChange, this)
            }
		});
		
		//combobox options
		this._comboOptions = Ext.create('Ext.form.ComboBox', {
		    name: 'options',
		    store: this._optionStore,
		    queryMode: 'local',
		    displayField: 'label',
		    editable: false,
            width: 200,
            valueField: 'value',
            listeners: {
                'change': Ext.bind(this._onOptionStoreChange, this)
            }
		});
		
		//combobox actions 
		this._comboActions = Ext.create('Ext.form.ComboBox', {
			name: 'actions',
		    store: this._actionStore,
		    queryMode: 'local',
		    displayField: 'label',
		    valueField: 'value',
		    value: 'SHOW',
		    editable: false,
		    width: 100,
		});
		
		
		
		var panel = Ext.create('Ext.form.Panel', {
		    items: [{
                xtype: 'container',
                flex: 1,
                layout: {
                    type: 'hbox',
                    align: 'center'
                },
                style: {
                    padding: '5px'
                },
                itemId: 'items',
                items: [
                    {
                        xtype: 'container',
                        html: '{{i18n PLUGINS_FORMS_WIDGET_QUESTION_RULES_QUESTION_LABEL}}',
                        style: {
                            margin: '0 10px'
                        }
                    },
                    this._comboQuestions,
                    {
                        xtype: 'container',
                        html: '{{i18n PLUGINS_FORMS_WIDGET_QUESTION_RULES_OPTIONS_LABEL}}',
                        style: {
                            margin: '0 10px'
                        }
                    },
                    this._comboOptions,
                    {
                        xtype: 'container',
                        html: '{{i18n PLUGINS_FORMS_WIDGET_QUESTION_RULES_ACTIONS_LABEL}}',
                        style: {
                            margin: '0 10px'
                        }
                    },
                    this._comboActions
                ]
            }],
		});
		
		return panel;
	},
    
	/**
	 * Get the question store 
	 * @private 
	 */
	_getQuestionStore : function()
	{
		return Ext.create('Ext.data.Store', {
		     proxy: {
		     	type: 'ametys',
		     	role: 'org.ametys.plugins.forms.helper.QuestionRuleHelper',
                methodName: 'getSourceQuestions',
                methodArguments: ['formId', 'questionId'],
                reader: {
                    type: 'json',
					rootProperty :'data'
                }
		     },
		     autoLoad: true,
		     listeners: {
	                'beforeload': Ext.bind(this._onBeforeLoadQuestionStore, this)
            }
		 });
	},
	
	/**
     * Listens before loading the question store. 
     * The load action will be canceled if it returns false 
     * @param {Ext.data.Store} store The store.
     * @param {Ext.data.operation.Operation} operation The Ext.data.operation.Operation object that will be passed to the Proxy to load the Store.
     * @param {Object} eOpts The options object passed to Ext.util.Observable.addListener.
     * @return {Boolean} False if the load action will be canceled.
     * @private
     */
	_onBeforeLoadQuestionStore: function(store, operation, eOpts)
    {
        operation.setParams( Ext.apply(operation.getParams() || {}, {
            formId: this._formId,
			questionId : this._questionId
        }));
    },
	
	/**
     * Listens before loading the option store. 
     * The load action will be canceled if it returns false 
     * @param {Ext.data.Store} store The store.
     * @param {Ext.data.operation.Operation} operation The Ext.data.operation.Operation object that will be passed to the Proxy to load the Store.
     * @param {Object} eOpts The options object passed to Ext.util.Observable.addListener.
     * @return {Boolean} False if the load action will be canceled.
     * @private
     */
    _onBeforeLoadOptionStore: function(store, operation, eOpts)
    {
        operation.setParams( Ext.apply(operation.getParams() || {}, {
            questionId: this._comboQuestions.value
        }));
    },
    
    /**
     * Listens before loading the option store. 
     * The load action will be canceled if it returns false 
     * @param {Ext.data.Store} store The store.
     * @private
     */
    _onLoadOptionStore: function(store)
    {
        var value = this._comboOptions.getValue();
        if (!store.getData().items.find(function(e) {return e.data.value == value;}))
        {
            this._comboOptions.clearValue()
        }
    },
	
	/**
	 * Reload optionStore depending on selected value in comboQuestion
	 * @private 
	 */
	_onQuestionChange : function()
	{
		this._optionStore.load();
	},
	
	/**
     * Check the rule fields
     * @private 
     */
	_onOptionStoreChange: function()
	{
        if (this.form.isValid())
        {
            this.clearInvalid();
        }
    },
	
	getErrors: function(value)
    {
        var errors = this.callParent(arguments);
        
        var question = this._comboQuestions.getValue();
        if (question == null)
        {
            errors.push("{{i18n PLUGINS_FORMS_QUESTION_RULES_OPTION_ERROR}}");
        }
        
        var option = this._comboOptions.getValue();
        if (option == null)
        {
            errors.push("{{i18n PLUGINS_FORMS_QUESTION_RULES_FIELD_ERROR}}");
        }
        
        return errors;
    }
});