/*
 *  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 class controls a ribbon button representing the lock state of a content
 * @private
 */
Ext.define('Ametys.plugins.cms.content.controller.LockController', {
	extend: 'Ametys.ribbon.element.ui.ButtonController',
	
	/**
	 * @cfg {String} locked-content-icon-glyph The CSS class for glyph when the selected contents are locked.
	 */
	/**
	 * @property {String} _lockedIconGlyph See #cfg-locked-content-icon-glyph
	 * @private
	 */
	
	/**
	 * @cfg {String} locked-owner-content-icon-glyph The CSS class for glyph when the selected contents are locked and the locker owner is the current user.
	 */
	/**
	 * @property {String} _lockedOwnerIconGlyph See #cfg-locked-owner-content-icon-glyph
	 * @private
	 */
	
	/**
	 * @cfg {String} mixed-locked-content-icon-glyph The CSS class for glyph when some contents of the current selection are locked by the current AND some others are locked by other users.
	 */
	/**
	 * @property {String} _mixedLockedIconGlyph See #cfg-mixed-locked-content-icon-glyph
	 * @private
	 */
	
	/**
	 * @property {String[]} [_currentLockedContentsId=[]] List of identifiers of locked contents among the current selection
	 * @private
	 */
	/**
	 * @property {String[]} [_currentUnlockedContentsId=[]] List of identifiers of unlocked contents among the current selection
	 * @private
	 */
	/**
	 * @property {String[]} [_currentLockedOwnerContentsId=[]] List of identifiers of locked contents by the current user among the current selection
	 * @private
	 */
	
	constructor: function(config)
	{
        config['toggle-enabled'] = true;

        this.callParent(arguments);
		
		this._unlockIconGlyph = this.getInitialConfig("icon-glyph");
		this._unlockIconDecorator = null;
	
		this._lockedIconGlyph = this.getInitialConfig("locked-content-icon-glyph");
		this._lockedIconDecorator = this.getInitialConfig("locked-content-icon-decorator");
		
		this._lockedOwnerIconGlyph = this.getInitialConfig("locked-owner-content-icon-glyph");
		this._lockedOwnerIconDecorator = this.getInitialConfig("locked-owner-content-icon-decorator");
		
		this._mixedLockedIconGlyph = this.getInitialConfig("mixed-locked-content-icon-glyph");
		this._mixedLockedIconDecorator = this.getInitialConfig("mixed-locked-content-icon-decorator");
		
		this._currentLockedContentsId = [];
		this._currentUnlockedContentsId = [];
		this._currentLockedOwnerContentsId = [];
        
        this._canUnlockAll = this.getInitialConfig("canUnlockAll");
		
		Ametys.message.MessageBus.on(Ametys.message.Message.LOCK_CHANGED, this.refreshIfMatchingMessage, this);
	},

	updateState: function()
	{
		this._getLockState(this.getMatchingTargets());
	},
	
	/**
	 * Get the lock state of given targets
	 * @param targets The content targets
	 * @private
	 */
	_getLockState: function (targets)
	{
        var result = this._calculateStatus(targets);
        this._getLockStateCb(result);
	},

    /**
     * Simulation of getStatus server side, done only client-side.
     * @param {Object[]} contentTargets content targets see Ametys.ribbon.element.ui.CommonController#getMatchingTargets
     * @return {Object} a map of arrays representing contents in different states that will be sent to _getLockStateCb
     */
    _calculateStatus: function (contentTargets)
    {
        var result = {};
        result["locked-contents"] = [];
        result["unlocked-contents"] = [];
        result["locked-owner-contents"] = [];
        result["locked-notowner-contents"] = [];
         Ext.Array.each(contentTargets, function(contentTarget)
            {
                var parameters = contentTarget.getParameters();
                if (parameters && parameters.content)
                {
                    var content = parameters.content;

                    if (content != null)
                    {
                        if (!content.getLocked())
                        {
                            var i18nStr = this.getConfig("unlocked-content-description");
                            var description = Ext.String.format(i18nStr, content.getTitle());
                            var contentParam = this._getContentDefaultParameters(content);
                            contentParam["description"] = description;
                            result["unlocked-contents"].push(contentParam);
                        }
                        else if (this._canUnlockAll || this._isLockOwner(content))
                        {
                            var i18nStr = this.getConfig("locked-owner-content-description");
                            var lockOwner = content.getLockOwner();
                            var fullName = lockOwner != null ? lockOwner.fullname : "";
                            var login = lockOwner != null ? lockOwner.login : "Anonymous";
                            var description = Ext.String.format(i18nStr, content.getTitle(), fullName, login);
                            var contentParam = this._getContentDefaultParameters(content);
                            contentParam["description"] = description;
                            if (!this._isLockOwner(content))
                            {
                                result["locked-notowner-contents"].push(contentParam);
                            }
                            result["locked-owner-contents"].push(contentParam);
                        }
                        else
                        {
                            var i18nStr = this.getConfig("locked-content-description");
                            var lockOwner = content.getLockOwner();
                            var fullName = lockOwner != null ? lockOwner.fullname : "";
                            var login = lockOwner != null ? lockOwner.login : "Anonymous";
                            var description = Ext.String.format(i18nStr, content.getTitle(), fullName, login);
                            var contentParam = this._getContentDefaultParameters(content);
                            contentParam["description"] = description;
                            result["locked-contents"].push(contentParam);
                        }
                    }
                }
            }, this);
        
        return result;
    },
    
    /**
     * Test if the current user is the lock owner of the content
     * @param {Ametys.cms.content.Content} content
     * @return {boolean} containing id and title
     */
    _isLockOwner: function (content)
    {
        var currentUser = Ametys.getAppParameter('user');
        var lockOwner = content.getLockOwner();
        return currentUser.login === lockOwner.login && currentUser.population === lockOwner.populationId;
    },

	/**
     * create a json object representing a content
     * @private
     * @param {Ametys.cms.content.Content} content The content
     * @return {Object} containing id and title
     */
    _getContentDefaultParameters : function(content)
    {
        var contentParams = {};
        contentParams["id"] = content.getId();
        contentParams["title"] = content.getTitle();
        return contentParams;
    },

	/**
	 * @private
	 * Callback function called after retrieving the lock state of content targets
	 * @param params The JSON result 
	 */
	_getLockStateCb: function (params)
	{
		this._currentLockedContentsId = [];
		this._currentUnlockedContentsId = [];
		this._currentLockedOwnerContentsId = [];
		
		// Update tooltip description and icons
		this._updateTooltipDescription("", params);
		this._updateIcon (params);
		
		// Toggle element if at least one content is locked
		this.toggle (this._currentLockedContentsId.length > 0 || this._currentLockedOwnerContentsId.length > 0);
		
		this._currentLockedOwnerContentsId.length == 0 ? this.disable() : this.enable();
		
		// TODO
		/*if (this._currentEdition)
		{
			this.disable();
			this.setDescription(this.getInitialConfig('editing-description'));
		}*/
		
		// this.enable();
	},
	
	/**
	 * @private
	 * Update the tooltip description according to lock state of the current selection
	 * @param {String} description The initial description
	 * @param {Object} params The JSON result object
	 */
	_updateTooltipDescription: function (description, params)
	{
		var lockedOwnerContents = params["locked-owner-contents"];
		if (lockedOwnerContents.length > 0)
		{
			if (description != "")
			{
				description += "<br/><br/>";
			}
			
			description += this.getInitialConfig("locked-owner-content-start-description");
			for (var i=0; i < lockedOwnerContents.length; i++)
			{
				if (i != 0) 
				{
					description += ", ";
				}
				description += lockedOwnerContents[i].description;
				this._currentLockedOwnerContentsId.push(lockedOwnerContents[i].id);
			}
			description += this.getInitialConfig("locked-owner-content-end-description");
		}
		
		var lockedContents = params["locked-contents"];
		if (lockedContents.length > 0)
		{
			if (description != "")
			{
				description += "<br/><br/>";
			}
			
			description += this.getInitialConfig("locked-content-start-description");
			for (var i=0; i < lockedContents.length; i++)
			{
				if (i != 0) 
				{
					description += ", ";
				}
				description += lockedContents[i].description;
				this._currentLockedContentsId.push(lockedContents[i].id);
			}
			description += this.getInitialConfig("locked-content-end-description");
		}
		
		var unLockedContents = params["unlocked-contents"];
		if (unLockedContents.length > 0)
		{
			if (description != "")
			{
				description += "<br/><br/>";
			}
			
			description += this.getInitialConfig("unlocked-content-start-description");
			for (var i=0; i < unLockedContents.length; i++)
			{
				if (i != 0) 
				{
					description += ", ";
				}
				description += unLockedContents[i].description;
				this._currentUnlockedContentsId.push(unLockedContents[i].id);
			}
			description += this.getInitialConfig("unlocked-content-end-description");
		}
		
		this.setDescription (description);
	},
	
	/**
	 * @private
	 * Update the controller icons according to lock state of the current selection
	 * @param {Object} params The JSON result object
	 */
	_updateIcon: function (params)
	{
		var nbLocked = params["locked-contents"].length;
		var nbLockedOwner = params["locked-owner-contents"].length;
		var nbLockedNotOwner = params["locked-notowner-contents"].length;
		var nbUnlocked = params["unlocked-contents"].length;
		
		nbLocked += nbLockedNotOwner;
		nbLockedOwner -= nbLockedNotOwner;
		
		if (nbUnlocked > 0 && nbLocked == 0 && nbLockedOwner == 0)
		{
			this.setGlyphIcon (this._unlockIconGlyph);
			this.setIconDecorator (null);
		}
		else if (nbLocked > 0 && nbLockedOwner == 0)
		{
			this.setGlyphIcon (this._lockedIconGlyph);
			this.setIconDecorator (null);
		}
		else if (nbLocked > 0 && nbLockedOwner > 0)
		{
			this.setGlyphIcon (this._mixedLockedIconGlyph);
			this.setIconDecorator (null);
		}
		else if (nbLocked == 0 && nbLockedOwner > 0)
		{
			this.setGlyphIcon (this._lockedOwnerIconGlyph);
			this.setIconDecorator (this._lockedOwnerIconDecorator);
		}
	}
});