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

/**
 * Convertor for TableOfContents
 * @private
 */
Ext.define('Ametys.plugins.cms.editor.tableofcontents.TableOfContentsConvertorAndValidator', {
    statics: {
        /**
         * Create the html for the TOC image in the editor.
         * @param {String} id The identifier to set on the created html tag
         * @param {String} code The "table of content" code to set
         * @param {String} [pellet] The pellet to use
         * @param {boolean} [ribbonselect=false] When true, will force selection of the ribbon tab associated with the table of contents. 
         */
        createHTML: function(id, code, pellet, ribbonselect)
        {
            var classes = ['toc', 'mceItemNoResize'];
            if (pellet)
            {
                classes.push(pellet);
            }
            
            var idAttr = id ? 'id="' + id + '" ' : '';
            var ribbonAttr = ribbonselect ? '_mce_ribbon_select="1" ' : '';
            var pelletAttr = pellet ? 'pellet="' + pellet + '" ' : '';
            var classAttr = 'class="' + classes.join(' ') + '" ';
            var srcAttr = 'src="' + Ametys.getPluginResourcesPrefix('cms') + '/img/content/edition/htmlexpert/trans.gif"';
            
            return '<img ' + idAttr + 'toc="-' + code + '" marker="marker" ' + ribbonAttr + pelletAttr + classAttr + srcAttr + '/>';
        },        
    },
    
    /**
     * @private
     * @readonly
     * @property {RegExp} _REGEXP_GET_CONTENT A regexp to search for content to replace during a getContent
     */
    _REGEXP_GET_CONTENT: /<img[^>]* toc="-([^"]*)"[^>]*>/g,
    /**
     * @private
     * @readonly
     * @property {RegExp} _REGEXP_SET_CONTENT A regexp to search for content to replace during a setContent
     */
    _REGEXP_SET_CONTENT: /<!-- toc(:([^ ]+))? ([^-]*) -->/g,
    
    /**
     * Registered to intercept getContent on richtext
     * @param {Ametys.form.field.RichText} field The richtext to convert
     * @param {tinymce.Editor} editor The current richtext editor
     * @param {Object} object The object of value to be modified
     */
    onGetContent: function(field, editor, object)
    {
        var me = this;
        
        if (object.content)
        {
            object.content = object.content.replace(
                me._REGEXP_GET_CONTENT,
                function (s, m1) {
                    var toc = m1;
                    var pellet = / pellet="([^"]+)"/.test(s) ? RegExp.$1 : null;
                    return "<!-- toc" + (pellet != null ? ':' + pellet : '') + ' ' + toc.replace(/-/g, "%2D") + " -->";
                }
            );
        }        
    },
    
    /**
     * Registered to intercept setContent on richtext
     * @param {Ametys.form.field.RichText} field The richtext to convert
     * @param {tinymce.Editor} editor The current richtext editor
     * @param {Object} object The object of value to be modified
     */
    onSetContent: function(field, editor, object)
    {
        var me = this;
        
        if (object.content)
        {
            object.content = object.content.replace(
                me._REGEXP_SET_CONTENT, 
                function(s, m1, m2, m3) {
                    var pellet = m2;
                    var toc = m3;
                    return Ametys.plugins.cms.editor.tableofcontents.TableOfContentsConvertorAndValidator.createHTML(null, toc.replace(/%2D/g, "-"), pellet, false);
                }
            );
        }        
    },
    
    /**
     * Validates if the current richtext value is valid or not
     * @param {String} value The current field value
     * @return {Boolean/String} true if value valid. The error message in other cases;     
     */
    validates: function(value)
    {
        function _endsWithBeginingPara(s)
        {
            return /<p( |\/)?[^>]*>\s*$/i.test(s);
        }
        
        function _startsWithEndingParam(s)
        {
            return /^\s*<\/p>/i.test(s);
        }
        
        var STARTING_TOC = "<!-- toc"; 
        var ENDING_TOC = "-->"; 
        
        var index;
        while (value && (index = value.indexOf(STARTING_TOC)) != -1)
        {
            var index2 = value.indexOf(ENDING_TOC, index + STARTING_TOC.length);
            
            if (index2 == -1 || !_endsWithBeginingPara(value.substring(0, index)))
            {
                return "{{i18n WIDGET_RICH_TEXT_TOC_ERROR}}";
            }
            
            value = value.substring(index2 + ENDING_TOC.length);
            
            if (!_startsWithEndingParam(value))
            {
                return "{{i18n WIDGET_RICH_TEXT_TOC_ERROR}}";
            }
        }
        
        return true;
    }
});