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

/**
 * Search context widget enumeration
 * This widget is registered for fields of type Ametys.form.WidgetManager#TYPE_STRING
 */
Ext.define('Ametys.web.form.widget.SearchSitemapContext', {
    extend: 'Ametys.form.AbstractFieldsWrapper',
    statics: {
        /**
         * @property {String} CURRENT_SITE value for all pages in the current site
         * @private
         * @readonly
         */
        CURRENT_SITE: 'CURRENT_SITE',
        /**
         * @property {String} CHILD_PAGES values for all child pages
         * @private
         * @readonly
         */
        CHILD_PAGES: 'CHILD_PAGES',
        /**
         * @property {String} DIRECT_CHILD_PAGES values for all direct child pages
         * @private
         * @readonly
         */
        DIRECT_CHILD_PAGES: 'DIRECT_CHILD_PAGES',
        /**
         * @property {String} CHILD_PAGES_OF values for all child pages, with parent page selected by the user
         * @private
         * @readonly
         */
        CHILD_PAGES_OF: 'CHILD_PAGES_OF',
        /**
         * @property {String} DIRECT_CHILD_PAGES_OF values for all direct child pages, with parent page selected by the user
         * @private
         * @readonly
         */
        DIRECT_CHILD_PAGES_OF: 'DIRECT_CHILD_PAGES_OF'
    },
    /**
     * @cfg {String} [sitesField] The relative path to the site field, to allow the status of the search content. The search context can be enabled/disabled depending on the value of the site field.
     */
    /**
     * @private
     * @property {String} _sitesFieldName The property related to {@link #cfg-sitesField}
     */
    /**
     * @private
     * @property {String} _pageValue property related to the select page widget
     */
    initComponent: function()
    {
        var enumeration = [
            [
                "CURRENT_SITE",
                "{{i18n plugin.web:PLUGINS_WEB_SERVICE_FILTERED_PAGES_CURRENT_SITE}}"
            ],
            [
                "CHILD_PAGES",
                "{{i18n plugin.web:PLUGINS_WEB_SERVICE_FILTERED_PAGES_CHILD_PAGES}}"
            ],
            [
                "DIRECT_CHILD_PAGES",
                "{{i18n plugin.web:PLUGINS_WEB_SERVICE_FILTERED_PAGES_DIRECT_CHILD_PAGES}}"
            ],
            [
                "CHILD_PAGES_OF",
                "{{i18n plugin.web:PLUGINS_WEB_SERVICE_FILTERED_PAGES_CHILD_PAGES_OF}}"
            ],
            [
                "DIRECT_CHILD_PAGES_OF",
                "{{i18n plugin.web:PLUGINS_WEB_SERVICE_FILTERED_PAGES_DIRECT_CHILD_PAGES_OF}}"
            ]
        ];
        this._sitesFieldName = this.sitesField || null;
        this.items = [];
        var comboboxConfig = {
            xtype : 'edition.combobox',
            itemId : 'contextComboBox',
            flex : 1,
            enumeration : enumeration,
            querymode : 'local',
            name : this.getInitialConfig('name')
        };

        this.items.push(comboboxConfig);

        var selectPageConfig = {
            xtype : 'edition.select-page',
            itemId : 'selectPageWidget',
            disabled : true,
            allowBlank: this.allowBlank,
            flex : 1,
            form : this.getInitialConfig('form'),
            name : this.getInitialConfig('name') + '-selectPage',
            sitemapContext: Ametys.web.form.widget.SelectPage.SITEMAP_CONTEXT_ALL,
            listeners: {
                    render: {fn: this._onSelectPageRender, scope: this}
                }
        };
        this.items.push(selectPageConfig);

        this.callParent(arguments);

        // remember the desired allowBlank policy
        this._configuredAllowBlank = this.allowBlank;

        if (this._sitesFieldName)
        {
            this.form.onRelativeFieldsChange(this._sitesFieldName, this, this._sitesFieldChange);
        }
        var contextComboBox = this.down('combobox#contextComboBox');
        if (contextComboBox)
        {
            contextComboBox.on("change", this._contexFieldChange, this);
        }
    },

    /**
     * If the value was initialized before the combobox is rendered, set the value now.
     * @private
     * @param {Ametys.web.form.widget.SelectPage} comboBox select page combobox
     */
    _onSelectPageRender: function (comboBox)
    {
        // If the value was initialized before the combobox is rendered, set the value now.
        if (this._pageValue != null)
        {
            comboBox.setValue(this._pageValue);
        }
    },

    /**
     * Listener called when the value of the site field changes
     * @private
     */
    _sitesFieldChange: function()
    {
        var sitesField = this.form.getRelativeField(this._sitesFieldName, this),
            sitesFieldValue = sitesField ? sitesField.getSiteContext() : null,
            siteValues = sitesField ? sitesField.getSiteValues() : null;
        var selectPageWidget = this.down('#selectPageWidget');
        selectPageWidget.siteFieldChanged(sitesFieldValue, siteValues);
        switch (sitesFieldValue)
        {
            case Ametys.web.form.widget.SelectSite.SITE_CONTEXT_CURRENT:
                this._enableWidget(sitesField);
                break;
            case Ametys.web.form.widget.SelectSite.SITE_CONTEXT_SITES_LIST:
                if (Ext.isArray(siteValues) && siteValues.length == 1)
                {
                    this._enableWidget(sitesField);
                }
                else
                {
                    this._disableWidget();
                }
                break;
            case Ametys.web.form.widget.SelectSite.SITE_CONTEXT_ALL:
            case Ametys.web.form.widget.SelectSite.SITE_CONTEXT_OTHERS:
            default:
                this._disableWidget();
                break;
        }
        this._contexFieldChange();
    },

    /**
     * @private
     * disable the widget
     */
    _disableWidget: function()
    {
        this.disable();
        this.allowBlank = true;
        var contextComboBox = this.down('combobox#contextComboBox');
        var selectPageWidget = this.down('#selectPageWidget');
        contextComboBox.allowBlank = this.allowBlank;
        selectPageWidget.allowBlank = this.allowBlank;
        this.setValue(null);
        this.clearInvalid();
    },

    /**
     * @private
     * Enable the widget
     * @param {Ext.form.field.Field} sitesField The site selection field
     */
    _enableWidget: function(sitesField)
    {
        var contextComboBox = this.down('combobox#contextComboBox');
        if (this.isDisabled())
        {
            this.enable();
            this.allowBlank = this._configuredAllowBlank;
            var selectPageWidget = this.down('#selectPageWidget');
            contextComboBox.allowBlank = this.allowBlank;
            selectPageWidget.allowBlank = this.allowBlank;
            this.reset();
        }

        var siteValues = sitesField ? sitesField.getSiteValues() : [];
        var sitesFieldValue = sitesField ? sitesField.getSiteContext() : null;

        if (sitesFieldValue == Ametys.web.form.widget.SelectSite.SITE_CONTEXT_CURRENT)
        {
            //clearFilter
            contextComboBox.getStore().clearFilter();
        }
        else
        {
            var filter = new Ext.util.Filter({
                property: 'value',
                value   : [
                    Ametys.web.form.widget.SearchSitemapContext.CURRENT_SITE,
                    Ametys.web.form.widget.SearchSitemapContext.CHILD_PAGES_OF,
                    Ametys.web.form.widget.SearchSitemapContext.DIRECT_CHILD_PAGES_OF
                ],
                operator : 'in'
            });
            contextComboBox.setFilters(filter);
        }
    },

    /**
     * Listener called when the value of the context field changes
     * @private
     */
    _contexFieldChange: function()
    {
        var contextComboBox = this.down('combobox#contextComboBox');
        var contextValue = contextComboBox ? contextComboBox.getValue() : null;
        var accepted = [
            Ametys.web.form.widget.SearchSitemapContext.CHILD_PAGES_OF,
            Ametys.web.form.widget.SearchSitemapContext.DIRECT_CHILD_PAGES_OF
        ];

        var selectPageWidget = this.down('#selectPageWidget');
        if (Ext.Array.contains(accepted, contextValue))
        {
            if (selectPageWidget)
            {
                selectPageWidget.setDisabled(false);
            }
        }
        else
        {
            if (selectPageWidget)
            {
                selectPageWidget.setDisabled(true);
                selectPageWidget.setValue(null);
                selectPageWidget.clearInvalid();
            }
        }
        this.validate();
    },

    setValue: function (value)
    {
        // retrieves the value object
        value = value || null;
        if (value)
        {
            if (Ext.isString(value))
            {
                value = Ext.JSON.decode(value, true);
            }
            // value should be an object at this point
            if (!Ext.isObject(value))
            {
                value = null;
            }
        }

        if (value)
        {
            this._setPageContext(value.context || null);
            this._setPageValue(value.page || null);
        }
        else
        {
            this._setPageContext(null);
            this._setPageValue(null);
        }
    },

    getValue: function()
    {
        var value = {
            context: this.getPageContext(),
            page: this.getPageValue()
         };

        return Ext.encode(value);
    },

    getErrors: function (value)
    {
        var errors = [];
        var contextComboBox = this.down('combobox#contextComboBox');
        if (!contextComboBox.isDisabled())
        {
            errors = errors.concat(contextComboBox.getErrors());
        }
        var selectPageWidget = this.down('#selectPageWidget');
        if (!selectPageWidget.isDisabled())
        {
            errors = errors.concat(selectPageWidget.getErrors());
        }
        return errors;
    },

    /**
     * @private
     * Set the value of the context field
     * @param {String} context The page context to set. If null the default site context Ametys.web.form.widget.SearchSitemapContext.CURRENT_SITE will be used.
     */
    _setPageContext: function(context)
    {
        var contextValue = context || Ametys.web.form.widget.SearchSitemapContext.CURRENT_SITE;
        var contextComboBox = this.down('combobox#contextComboBox');
        if (contextComboBox)
        {
            contextComboBox.setValue(context);
        }
    },

    /**
     * @private
     * Set the page value
     * @param {String} pageId the id of the page. Can be null to empty the field. 
     */
    _setPageValue: function(pageId)
    {
        this._pageValue = pageId;
        var selectPageWidget = this.down('#selectPageWidget');
        if (selectPageWidget)
        {
            selectPageWidget.setValue(pageId);
        }
    },

    /**
     * Get the context of the search
     * @return {String} search context
     */
    getPageContext: function()
    {
        var contextComboBox = this.down('combobox#contextComboBox');
        if (contextComboBox && !contextComboBox.isDisabled())
        {
            return contextComboBox.getValue();
        }
        else
        {
            return null;
        }
    },

    /**
     * Get the pageId selected
     * @return {String} page id
     */
    getPageValue: function()
    {
        var selectPageWidget = this.down('#selectPageWidget');
        if (selectPageWidget && !selectPageWidget.isDisabled())
        {
            this._pageValue = selectPageWidget.getValue();
            return this._pageValue;
        }
        else
        {
            return null;
        }
    }
});