/*
 *  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 that will be enable only if there is a content store into the clipboard.
 * @private
 */
Ext.define('Ametys.plugins.odf.content.controller.PasteODFContentController', {
	extend: 'Ametys.plugins.cms.content.controller.SmartContentController',
	
	constructor: function(config)
	{
		this.callParent(arguments);

		this.disable();
		this.setDescription(this.getInitialConfig("nocopiedcontent-description"));
		
		Ametys.message.MessageBus.on(Ametys.message.Message.MODIFIED, this._onModified, this);
	},
    
    /**
     * Override to force enable if there is no selection, if the copied content is a Program
     * @param {Ametys.message.MessageTarget[]} targets The targets
     */
    _updateMatchingSelectionTargets: function(targets)
    {
        this.setDescription(this.getInitialConfig("description"));
        
        this.callParent(arguments);
        
        var noSelection = Ametys.message.MessageBus.getCurrentSelectionMessage().getTargets().length == 0;
        if (noSelection)
        {
            var clipboardData = Ametys.clipboard.Clipboard.getData();
            if (clipboardData.length > 0 && Ametys.clipboard.Clipboard.getType() == Ametys.message.MessageTarget.CONTENT && this._isContentProgram(clipboardData[0]))
            {
                this.setAdditionalDescription("");
                this.enable();
            }
        }
    },
    
    /**
     * Listener when the clipboard has been modified.
     * Enable/disable the buttons.
     * @param {Ametys.message.Message} message The modified message.
     * @protected
     */
    _onModified: function (message)
    {
        message = message || Ametys.message.MessageBus.getCurrentSelectionMessage();
        
        var target = message.getTarget(Ametys.message.MessageTarget.CLIPBOARD); 
        
        if (target != null)
        {
            if (Ametys.clipboard.Clipboard.getData().length > 0 && Ametys.clipboard.Clipboard.getType() == Ametys.message.MessageTarget.CONTENT)
            {
                this._updateDescription();
            }
            else
            {
                this.setDescription(this.getInitialConfig("nocopiedcontent-description"));
                this.disable();
            }
        }
    },
    
    /**
     * @private
     * Update controller status and description according the current selection and copied content
     */
    _updateDescription: function()
    {
        if (Ametys.clipboard.Clipboard.getData().length > 0 && Ametys.clipboard.Clipboard.getType() == Ametys.message.MessageTarget.CONTENT)
        {
			var clipBoardContent = Ametys.clipboard.Clipboard.getData()[0];
			
            var matchingTargets = this.getMatchingTargets();
			if (this._isContentProgram(clipBoardContent))
			{
				// The content to be copied is program. We don't need parent
				this.setDescription(this.getInitialConfig("description"));
				this.enable();
			}
			else if (matchingTargets.length > 0)
			{
				var targetMessageContent = matchingTargets[0].getParameters().content;
                
                if (targetMessageContent.getId() == clipBoardContent.getId())
                {
                    //This is the same content, can't copy under it
                    var description = Ext.String.format("{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_ERROR_SAME_CONTENT_DESC}}", clipBoardContent.getTitle())
                    this.setDescription(description);
                    this.disable();
                }
                else if (this._isCompatible(clipBoardContent, targetMessageContent))
                {
                    var description = Ext.String.format("{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_WITH_PARENT_DESC}}", clipBoardContent.getTitle(), targetMessageContent.getTitle())
                    this.setDescription(description);
                    this.enable();
                }
                else
                {
                    // Invalid parent
                    var description = Ext.String.format("{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_ERROR_PARENT_INVALID_DESC}}", clipBoardContent.getTitle(), targetMessageContent.getTitle())
                    this.setDescription(description);
                    this.disable();
                }
			}
			else
			{
				// Disable because no parent is selected
				var description = Ext.String.format("{{i18n PLUGINS_ODF_CLIPBOARD_PASTE_ERROR_NO_PARENT_DESC}}", clipBoardContent.getTitle())
				this.setDescription(description);
				this.disable();	
			}
        }
		
	},
    
    /**
     * @private
     * Check if the copied content can be copied under the target content
     * @param {Ametys.cms.content.Content} copiedContent The content in clipboard
     * @param {Ametys.cms.content.Content} targetContent The target content
     * @return {Boolean} true if the copied and target contents are compatible
     */
    _isCompatible: function(copiedContent, targetContent)
    {
        if (this._isContentSubProgram(copiedContent) || this._isContentContainer(copiedContent))
        {
            return this._isContentProgram(targetContent) || this._isContentSubProgram(targetContent) || this._isContentContainer(targetContent);
        }
        else if (this._isContentCourseList(copiedContent))
        {
            return this._isContentProgram(targetContent) || this._isContentSubProgram(targetContent) || this._isContentContainer(targetContent) || this._isContentCourse(targetContent);
        }
        else if (this._isContentCourse(copiedContent))
        {
            return this._isContentCourseList(targetContent);
        }
        return this._isContentProgram(copiedContent) || this._isContentOrgUnit(copiedContent);
    },
	
	/**
	 * @protected
	 * Callback function called after retrieving the lock state of content targets
	 * @param params The JSON result 
	 */
	_getStatusCb: function (params)
	{
        this._contentIds = [];
        
        var description = '';
        
        var allRightContents = params['allright-contents'];
        if (allRightContents.length > 0)
        {
            for (var i=0; i < allRightContents.length; i++)
            {
                this._contentIds.push(allRightContents[i].id)
            }
            this._updateDescription();
        }
        else
        {
            description = this.getInitialConfig("error-description") || '';
            this.disable();
	        this._updateTooltipDescription (description, params);
        }
        
        this.toggle(allRightContents.length > 0 && this.getInitialConfig()["enable-toggle"] == "true");
        
        this._workflowActionId = params['workflowaction-content-actionId'];
	},
	
    /**
     * @private
     * Determines if the content is a orgunit
     * @param {Ametys.cms.content.Content} content The content
     */
    _isContentOrgUnit: function(content)
    {
        return Ext.Array.contains(content.getTypes(), "org.ametys.plugins.odf.Content.orgunit");
    },
    
	/**
	 * @private
	 * Determines if the content is a program
	 * @param {Ametys.cms.content.Content} content The content
	 */
	_isContentProgram: function(content)
	{
		return Ext.Array.contains(content.getTypes(), "org.ametys.plugins.odf.Content.program");
	},
	
	/**
	 * @private
	 * Determines if the content is a subprogram
	 * @param {Ametys.cms.content.Content} content The content
	 */
	_isContentSubProgram: function(content)
	{
		return Ext.Array.contains(content.getTypes(), "org.ametys.plugins.odf.Content.subProgram");
	},
	
	/**
	 * @private
	 * Determines if the content is a container
	 * @param {Ametys.cms.content.Content} content The content
	 */
	_isContentContainer: function(content)
	{
		return Ext.Array.contains(content.getTypes(), "org.ametys.plugins.odf.Content.container");
	},
	
	/**
	 * @private
	 * Determines if the content is a course list
	 * @param {Ametys.cms.content.Content} content The content
	 */
	_isContentCourseList: function(content)
	{
		return Ext.Array.contains(content.getTypes(), "org.ametys.plugins.odf.Content.courseList");
	},
	
	/**
	 * @private
	 * Determines if the content is a course
	 * @param {Ametys.cms.content.Content} content The content
	 */
	_isContentCourse: function(content)
	{
		return Ext.Array.contains(content.getTypes(), "org.ametys.plugins.odf.Content.course");
	}
	
});