/*
 *  Copyright 2013 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 is a DAO handling a local store of available languages.<br/>
 * Call #getStore to get the store.<br/>
 * Call #getCurrentLanguage to get the current active language.<br/>
 * Call #setCurrentLanguage to change the current active language.
 */
Ext.define('Ametys.cms.language.LanguageDAO', {
	singleton: true,

	/**
	 * @private
	 * @property {String} _currentLanguage The current active language
	 */
	_currentLanguage: null,
	
	/**
	 * @private
	 * @property {Ext.data.Store} _store The local store for available languages
	 */
	_store: Ext.create('Ext.data.Store', {
		model: 'Ametys.cms.language.Language',
		
        sorters: [ { property: 'label', direction: "ASC" }],
	}),
	
	/**
	 * Determines if language is supported
	 * @param {String} code the language code such as 'fr', 'en', 'es', ...
	 * @return {Boolean} true if the language is supported
	 */
	hasLanguage: function (code)
	{
		return this._store.find('name', lang) != -1;
	},
	
	/**
	 * Get the current active language
	 * @return {String} the current language
	 */
	getCurrentLanguage: function ()
	{
		return this._currentLanguage;
	},
	
	/**
	 * Set the current language.
	 * This fires a {@link Ametys.message.Message#MODIFIED} event for target {@link Ametys.message.MessageTarget#LANGUAGE} the on bus message
	 * @param {String} lang The language code to set as current language
	 */
	setCurrentLanguage: function (lang)
	{
		if (this._store.find('name', lang) != -1)
		{
			var alreadyInitialized = this._currentLanguage != null;
			var hasChanges = this._currentLanguage != lang;
			
			this._currentLanguage = lang;
			
			if (alreadyInitialized && hasChanges)
			{
				Ext.create('Ametys.message.Message', {
					type: Ametys.message.Message.MODIFIED,
					targets: {
						id: Ametys.message.MessageTarget.LANGUAGE,
						parameters: {
							name: this._currentLanguage
						}
					}
				});
			}
		}
		else
		{
			throw new Error("The current language can not be set to '" + lang + "': this language is not supported by local language store");
		}
	},
	
	/**
	 * Get the local stores handling available languages
	 * @return {Ext.data.Store} the store handling languages
	 */
	getStore: function ()
	{
		return this._store;
	},
	
	/**
	 * Creates a combo box mapped on local language store #getStore
	 * @param {Object} config The optional additional or personalized configuration object.
	 * @param {Boolean} [config.synchronize=false] Set to `true`to synchronize this combo box field with the current active language handle by LanguageDAO.
	 * @return {Ext.form.field.ComboBox} the combo box for languages.
	 */
	createComboBox: function (config)
	{
	    var cfg = config || {};
		var combo = Ext.create('Ext.form.field.ComboBox', Ext.applyIf(cfg, {
			
			cls: 'ametys',
			forceSelection: true,
	    	editable: false,
	    	triggerAction: 'all',
	    	queryMode: 'local',
	    	
	    	store: this._store,
	    	
	    	valueField: 'name',
	        displayField: 'fulllabel',
	        value: this._currentLanguage,
	    	
	        tpl: Ext.create('Ext.XTemplate',
	        		 '<ul class="x-list-plain">',
	        		 	'<tpl for=".">',
	        		 		'<li role="option" class="x-boundlist-item lang-item">{label} <em>({name})</em></li>',
	        		 	'</tpl>',
	        		 '</ul>')
		}));
		
		if (cfg.synchronize)
		{
			combo.on('change', function (combo, newValue, oldValue) {
                if (newValue)
                {
    				this.setCurrentLanguage (newValue);
                }
			}, this);
			
			function onLangModified (message)
			{
				var langTarget = message.getTarget(Ametys.message.MessageTarget.LANGUAGE);
				if (langTarget != null)
				{
					this.setValue(langTarget.getParameters().name);
				}
			}
			
			Ametys.message.MessageBus.on (Ametys.message.Message.MODIFIED, onLangModified, combo);
			
			combo.on('destroy', function (combo) {Ametys.message.MessageBus.unAll(combo);});
		}
		
		return combo;
	}
});

Ext.define("Ametys.message.LanguageMessageTarget",
        {
            override: "Ametys.message.MessageTarget",
            
            statics: 
            {
                /**
                 * @member Ametys.message.MessageTarget
                 * @readonly
                 * @property {String} LANGUAGE The target type is the main language.
                 */
                LANGUAGE: "language"
            }
        }
);