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

/**
 * This tool displays a preview of the skin currently modified
 * @private
 */
Ext.define('Ametys.plugins.skinfactory.tool.SkinFactoryTool', {
    extend : 'Ametys.tool.Tool',
	
	/**
	 * @private
	 * @property _ribbonLoaded True if the ribbon has been loaded once already.
	 */
	_ribbonLoaded: false,
	
	/**
	 * @private
	 * @property _skinId The id of the current skin.
	 */
	 _skinId: null,
	
     /**
	  * @private
	  * @property _scrollTop The scroll offset from the top, used when reloading the iframe.
	  */
	_scrollTop: 0,
	
    /**
     * @private
     * @property _previewUri The preview uri for the skin.
     */
   _previewUri: null,
   
	constructor : function(config)
	{
		this.callParent(arguments);
		
		Ametys.message.MessageBus.on(Ametys.message.Message.MODIFIED, this._onModified, this);
	},
	
	createPanel : function()
	{
		this._iframe = Ext.create("Ext.ux.IFrame", {}); 
        this._iframe.on ('load', this._onIframeLoad, this);
        
		this._panel = Ext.create('Ext.panel.Panel', {
            scrollable : false,
			cls: 'skinfactory-tool',
			layout: { 
                type: 'card', 
                deferredRender: false 
            },
            activeItem: 1,

            items: [
                {
                    xtype: 'component',
    				html: "<div class='info'>{{i18n PLUGINS_SKINFACTORY_TOOL_NO_PREVIEW_AVAILABLE}}</div>"
    			},
    			this._iframe
            ]
        });
		
		return this._panel;
	},
	
    getMBSelectionInteraction : function()
    {
        return Ametys.tool.Tool.MB_TYPE_ACTIVE;
    },
	
    sendCurrentSelection: function ()
    {
		Ext.create("Ametys.message.Message", {
            type: Ametys.message.Message.SELECTION_CHANGED,
            targets: []
        });
    },
	
    setParams: function (params)
    {
    	if (!params.checksDone)
    	{
    		// If checksDone is null, the tool was open directly without the necessary checks (temp, work, lock, etc ..) => close the tool.
    		// This could append when reloading application with the tool previously opened 
    		this.close();
    		return;
    	}
    	
    	// Do not save checksDone parameter
    	delete params.checksDone;
    	
    	this.callParent(arguments);
		
        this._skinId = params.skinId;
        
		var lang = Ametys.cms.language.LanguageDAO.getCurrentLanguage();
		Ametys.plugins.skinfactory.SkinParametersManager.updateCurrentLanguage(lang);
		
		Ametys.plugins.skincommons.helper.SkinHelper.getSkinModel(Ametys.plugins.skinfactory.skin.SkinDAO.SERVER_ROLE, null, this._skinId, "temp", Ext.bind(this._getSkinModelCb, this));
	},
    
    /**
     * Callback after retrieving the model name of the skin
     * @param  {string} skinName The current skin name
     * @param  {string} modelName The model name
     * @private
     */
    _getSkinModelCb: function (skinName, modelName)
    {
    	if (modelName == null)
    	{
    		// There is no model for this skin, close the tool (this should never append)
    		Ametys.log.ErrorDialog.display({
                title: "{{i18n PLUGINS_SKINFACTORY_TOOL_LABEL}}",
                text: "{{i18n PLUGINS_SKINFACTORY_TOOL_NO_MODEL_FOUND}}",
                details: details,
                category: this.self.getName()
            });
    		this.close();
    		return;
    	}
    	
        Ametys.plugins.skinfactory.SkinParametersManager.updateCurrentModel(modelName);
        
        Ametys.plugins.skinfactory.SkinParametersManager.loadParametersValues(Ametys.getAppParameter("siteName"), this.refresh, this);
    },
	
	refresh: function ()
	{
		this.showRefreshing();

		var iframe = this._iframe;
		if (iframe)
		{
			// Register scroll top position
			var window = iframe.getWin();
            if (window)
            {
                this._scrollTop = window.pageYOffset ? window.pageYOffset : (window.document.documentElement ? window.document.documentElement.scrollTop : 0);
            }
            else
            {
                this._scrollTop = 0;    
            }
		}
        
        if (this._previewUri == null)
        {
    		Ametys.data.ServerComm.callMethod({
    			role: Ametys.plugins.skinfactory.skin.SkinDAO.SERVER_ROLE,
    			methodName: "getPreviewURI",
    			parameters: [Ametys.getAppParameter("siteName"), Ametys.plugins.skinfactory.SkinParametersManager.getCurrentLanguage()],
    			callback: {
    				handler: this._loadPreviewUri,
    				scope: this
    			},
    			waitMessage: true
    		});
        }
        else
        {
            this._loadPreviewUri();
        }
	},
	
    /**
     * Load the preview with the uri received
     * @param {String} uri The preview URI
     * @private
     */
	_loadPreviewUri: function (uri)
	{
        if (this._previewUri)
        {
        	this._iframe.load(this._previewUri);
            this._panel.getLayout().setActiveItem(1);
        }
		else if (uri)
		{
            var previewUri = Ametys.getPluginDirectPrefix('skincommons') + '/preview/' + Ametys.getAppParameter("siteName") + '/' + uri;
			this._iframe.load(previewUri);
            this._panel.getLayout().setActiveItem(1);
		}
		else
		{
			// No preview is available
            this._panel.getLayout().setActiveItem(0);
		}
		
        this.showRefreshed();
	},
	
    /**
     * Listener on the iframe load event.
     * @private
     */
	_onIframeLoad: function (iframe)
	{
		var iframe = this._iframe;
		if (iframe)
		{
            var win = iframe.getWin();
			win.scrollTo(0, this._scrollTop);
			this._previewUri = win.location.pathname && win.location.pathname != 'blank' ? win.location.pathname : null;
		}
	},
	
    /**
     * Listener when a Ametys.message.Message.MODIFIED message is received
     * @param {Ametys.message.Message} message The message
     * @private
     */
	_onModified: function (message)
	{
        var target = message.getTarget(Ametys.message.MessageTarget.SKIN_PARAMETER);
        if (target)
        {
            this.showOutOfDate();
        }
        
        target = message.getTarget(Ametys.message.MessageTarget.SKIN_COLOR_THEME);
        if (target)
        {
            this.showOutOfDate();
        }
        
        target = message.getTarget(Ametys.message.MessageTarget.SKIN_LANGUAGE);
        if (target)
        {
            // force preview URI reloading
            var lang = target.getParameters().lang;
            Ametys.plugins.skinfactory.SkinParametersManager.updateCurrentLanguage(lang);
            this._previewUri = null;
            
            this.showOutOfDate();
        }
	},
	
	/**
	 * Retrieve the skin name
	 * @return {String} The skin name
	 */
	getSkinName: function ()
	{
		return this._skinId;
	},
    
    close: function (manual)
    {
    	if (manual)
    	{
            Ametys.plugins.skincommons.helper.SkinHelper.checkUnsaveModification(Ametys.plugins.skinfactory.skin.SkinDAO.SERVER_ROLE, this._skinId, Ext.bind(this._beforeCloseCb, this));
    	}
    	else
    	{
    		this.callParent(manual);
    	}
    	
    },

    /**
     * Callback after checking for unsaved modification
     * @param {boolean} success True if the check was successful
     * @param {boolean} close True to close the tool
     */
    _beforeCloseCb: function (success, close)
    {
    	if (success && close)
    	{
    		this.superclass.close.call(this, true);
    	}
    }
});

Ext.define("Ametys.message.SkinFactoryMessageTarget",
{
    override: "Ametys.message.MessageTarget",

    statics: 
    {
        /**
         * @member Ametys.message.MessageTarget
         * @readonly
         * @property {String} SKIN_PARAMETER The target type is a skin parameter. 
         */
        SKIN_PARAMETER: "skin-parameter",

        /**
         * @member Ametys.message.MessageTarget
         * @readonly
         * @property {String} SKIN_LANGUAGE The target type is a skin language. 
         */
        SKIN_LANGUAGE: "skin-language",

        /**
         * @member Ametys.message.MessageTarget
         * @readonly
         * @property {String} SKIN_COLOR_THEME The target type is a skin color theme. 
         */
        SKIN_COLOR_THEME: "skin-color-theme"
    }
});