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

/**
 * Manager for the skin parameters
 */
Ext.define('Ametys.plugins.skinfactory.SkinParametersManager', {
    singleton: true,
	
	/**
	 * @private
	 * @property _currentParametersValues The current values of skin parameters. Can not be null.
	 */
	_currentParametersValues: {},
	
	/**
	 * @private
	 * @property _currentColorTheme The current color theme. Can be null.
	 */
	_currentColorTheme: null,
	
	/**
	 * @private
	 * @property _themeColors The list of theme colors.
	 */
	_themeColors: [],
	
    /**
     * @private
     * @property _defaultColors The default colors of the site. Can be null.
     */
	_defaultColors: null,
	
    /**
     * @private
     * @property _languages The available languages for the site. Can be null.
     */
	_languages: null,
    
    /**
     * @private
     * @property _currentModel The current model of the site. Can be null.
     */
    _currentModel: null,
    
    /**
     * @private
     * @property _cssStyleItems The css style items of the site. Can be null.
     */
    _cssStyleItems: null,
    
	/**
	 * Get the current value of skin parameter. Can be null.
	 * @param id The parameter's id
	 * @return The current value or null.
	 */
	getParameterValue: function (id)
	{
		if (this._currentParametersValues[id])
		{
			return this._currentParametersValues[id];
		}
		
		return null;
	},
    
    /**
     * Get the current values of skin parameters.
     * @return The current values or null.
     */
    getParametersValues: function ()
    {
        return this._currentParametersValues;
    },
    
    /**
     * Load the parameters values from server side
     * @param {String} [siteName] The site name. Can be null to load the parameters of current site
     * @param {Function} [callback] The callback function to call after loading parameters
     * @param {Object} [scope] The scope of callback function
     */
    loadParametersValues: function(siteName, callback, scope)
    {
        siteName = siteName || Ametys.getAppParameter("siteName");
        
        Ametys.plugins.skinfactory.skin.SkinDAO.getColors([siteName], Ext.bind(this._getColorsCb, this));
        Ametys.plugins.skinfactory.skin.SkinDAO.getParametersValues([siteName, null], Ext.bind(this._getParametersValuesCb, this), {
                arguments: {callback: callback, scope: scope}
        });
    },
    
    /**
     * @private
     * Callback after retrieving the parameters values for the current skin
     * @param {Object} params The skin parameters
     * @param {Object} args The callback arguments
     * @param {Function} [args.callback] The callback function to call after loading parameters
     * @param {Object} [args.scope] The scope of callback function
     */
    _getParametersValuesCb: function (params, args)
    {
        Ametys.plugins.skinfactory.SkinParametersManager.updateParametersValues(params.values);
        
        Ext.create("Ametys.message.Message", {
            type: Ametys.message.Message.LOADED,
            targets: {
                id: Ametys.message.MessageTarget.SKIN,
                parameters: {
                    id: params.skinName
                }
            }
        });
        
        if (Ext.isFunction(args.callback))
        {
            args.callback.call(args.scope, params);
        }
    },
    
    /**
     * Callback after retrieving the colors for the current skin
     * @param {Object} response The colors and theme informations
     * @private
     */
    _getColorsCb: function (response)
    {
        if (response.themeId)
        {
            Ametys.plugins.skinfactory.SkinParametersManager.updateColorTheme(response.themeId, response.themeColors);
        }
    },
    
    /**
     * Update the parameters values
     * @param {Object} values The new parameters
     */
	updateParametersValues: function (values)
	{
		this._currentParametersValues = values;
	},
	
    /**
     * Update the theme and colors' themes
     * @param {String} themeId The theme id
     * @param {Object[]} themeColors The themes colors
     */
	updateColorTheme: function (themeId, themeColors)
	{
		this._currentColorTheme = themeId;
		this._themeColors = themeColors;
	},

	/**
	 * Get the current color theme
	 * @return {Object} The current color theme
	 */
	getCurrentColorTheme: function ()
	{
		return this._currentColorTheme;
	},

	/**
	 * Get the theme colors
	 * @return {Object[]} The theme colors
	 */
	getThemeColors: function ()
	{
		return this._themeColors;
	},

    /**
     * Retrieve the default colors for the siteName
     * @param {Function} callback The callback function
     * @param {Object[]} callback.defaultColors The default colors of the site
     */
	getDefaultColors: function (callback)
	{
		if (this._defaultColors == null)
		{
            Ametys.plugins.skinfactory.skin.SkinDAO.getColors([Ametys.getAppParameter("siteName")], Ext.bind(this._getDefaultColorsCb, this), {
                arguments: {callback: callback}
            });
		}
        else
        {
            callback(this._defaultColors);
        }
	},
    
    /**
     * Callback after retrieve the colors
     * @param {Object} response The response from the server
     * @param {Object} response.colors The colors
     * @param {Object} args The callback arguments
     * @param {Function} args.callback The callback waiting for the default colors
     */
    _getDefaultColorsCb: function (response, args)
    {
        if (response.colors)
        {
            this._defaultColors = response.colors;
        }
        
        args.callback(this._defaultColors);
    },
	
    /**
     * Get the available languages.
     * @param {Function} callback The callback function
     * @param {Object[]} callback.languages The default colors of the site
     */
    getLanguages: function (callback)
    {
    	if (this._languages == null)
    	{
            Ametys.plugins.skinfactory.skin.SkinDAO.getLanguages([Ametys.getAppParameter("siteName")], Ext.bind(this._getLanguagesCb, this), {
                arguments: {callback: callback}
            });
    	}
    	else
        {
            callback(this._languages);
    	}
    },
    
    /**
     * Callback after retrieve the languages
     * @param {Object} languages The list of languages, mapped by code
     * @param {Object} args The callback arguments
     * @param {Function} args.callback The callback waiting for the languages
     */
    _getLanguagesCb: function (languages, args)
    {
        if (languages)
        {
            this._languages = languages;
        }
        
        args.callback(this._languages);
    },

    /**
     * Get the language of given code
     * @param {String} code The language code
     * @return {Object} the language
     */
    getLanguage: function (code)
    {
    	return this._languages[code];
    },

    /**
     * Get the current language code
     * @return {Object} the current language
     */
    getCurrentLanguage: function ()
    {
    	return this._currentLanguage;
    },

    /**
     * Update the current language
     * @param {String} code The current language code
     */
    updateCurrentLanguage: function (code)
    {
    	this._currentLanguage = code;
    },

    /**
     * Get the current model.
     * @return {Object} the current model
     */
    getCurrentModel: function ()
    {
    	return this._currentModel;
    },

    /**
     * Update the current model
     * @param {String} id the current model id
     */
    updateCurrentModel: function (id)
    {
    	this._currentModel = id;
    },
    
    /**
     * Retrieve the css style items
     * @param {String} style The current style
     * @param {Function} callback The callback function
     * @param {Object[]} callback.cssStyleItem The css style item for the specified style
     */
    getCssStyleItems: function (style, callback)
    {
    	if (this._cssStyleItems == null)
    	{
            Ametys.plugins.skinfactory.skin.SkinDAO.getCssStyleItems([Ametys.getAppParameter("siteName")], Ext.bind(this._getCssStyleItemsCb, this), {
                arguments: {style: style, callback: callback}
            });
    	}
        else
        {
            callback(this._cssStyleItems[style] != null ? this._cssStyleItems[style] : []);
        }
    },

    /**
     * Callback after retrieve the css style items
     * @param {Object} cssStyleItems The css style items
     * @param {Object} args The callback arguments
     * @param {String} args.style The requested style
     * @param {Function} args.callback The callback waiting for the css style item
     */
    _getCssStyleItemsCb: function (cssStyleItems, args)
    {
        if (cssStyleItems)
        {
            this._cssStyleItems = cssStyleItems;
        }
        
        args.callback(this._cssStyleItems[args.style] != null ? this._cssStyleItems[args.style] : []);
    }
});