/*
 *  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 UI helper provides a dialog box to upload a file from hard drive
 * See #open method.
 * @private
 */
Ext.define('Ametys.plugins.inlinemedia.InsertMediaHelper',
{
    singleton: true,

    /**
     * @property {Boolean} _initialized True if the dialog box has been initialized.
     * @private
     */
    /**
     * @property {Ext.form.Basic} _formPanel The inner basic form.
     * @private
     */
    /**
     * @property {Ametys.window.DialogBox} _box The dialog box
     * @private
     */
    /**
     * @property {String[]} _urlPatterns The url patterns to retrieve the video id
     * @private
     */
    /**
     * @property {String} _videoType The type of video to be inserted.
     * @private
     */
    /**
     * @property {tinymce.Editor} _currentEditor The last used tinymce editor
     * @private
     */

     /**
      * Allow the user to upload a file from local hard drive
      * @param {tinymce.Editor} editor The richtext editor
      * @param {String} title The title of the dialog
      * @param {String} iconCls The CSS class for icon
      * @param {String} hintText The hint text
      * @param {String} videoType The type of video. 
      * @param {String[]} urlPatterns RegExp Strings to retrieve the video id from its url
      * @param {Number} defaultWidth The default width set in the dialog
      * @param {Number} defaultHeight The default height set in the dialog
      */
    open: function (editor, title, iconCls, hintText, videoType, urlPatterns, defaultWidth, defaultHeight)
    {
        this._delayedInitialize(editor);

        this._videoType = videoType;
        this._urlPatterns = urlPatterns || [];

        this._initForm(title, iconCls, hintText, defaultWidth, defaultHeight);
        this._box.show();
    },

    /**
     * Initialize the dialog box
     * @param {tinymce.Editor} editor The richtext editor
     * @return {Boolean} true if the box has been initialized (or if it was already initialized).
     * @private
     */
    _delayedInitialize: function (editor)
    {
        this._currentEditor = editor;
        
        if (this._initialized)
        {
            return true;
        }

        var formPanel = Ext.create('Ext.form.Panel',
        {
            border: false,
            // bodyStyle: 'padding:5px',
            scrollable: true,
            defaults:
            {
                cls: 'ametys',
                anchor: '95%'
            },
            fieldDefaults:
            {
                labelAlign: 'right',
                labelSeparator: '',
                labelWidth: 100,
                msgTarget: 'side'
            },

            items: [
                {
                    xtype: 'component',
                    html: '',
                    name: 'hint',
                    cls: 'a-text'
                },
                {
                    // The real tag tree will be inserted later here
                    itemId: 'url-field',
                    xtype: 'component'
                },
                {
                    xtype: 'numberfield',
                    allowDecimals: false,
                    name: 'width',
                    fieldLabel: "{{i18n PLUGINS_INLINEMEDIA_DIALOG_WIDTH}}",
                    ametysDescription: "{{i18n PLUGINS_INLINEMEDIA_DIALOG_WIDTH_DESC}}"
                },
                {
                    xtype: 'numberfield',
                    allowDecimals: false,
                    name: 'height',
                    fieldLabel: "{{i18n PLUGINS_INLINEMEDIA_DIALOG_HEIGHT}}",
                    ametysDescription: "{{i18n PLUGINS_INLINEMEDIA_DIALOG_HEIGHT_DESC}}"
                }
            ]
        });

        this._formPanel = formPanel;

        this._box = Ext.create('Ametys.window.DialogBox',
        {
            title: "",
            iconCls: "",

            layout: 'fit',
            width: 520,

            items: formPanel,

            closeAction: 'hide',
            defaultFocus: 'url-field',
            
            referenceHolder: true,
            defaultButton: 'validate',
            
            buttons: [{
            	reference: 'validate',
            	text: "{{i18n PLUGINS_INLINEMEDIA_DIALOG_OK}}",
                handler: Ext.bind(this._ok, this)
            }, {
                text: "{{i18n PLUGINS_INLINEMEDIA_DIALOG_CANCEL}}",
                handler: Ext.bind(this._cancel, this)
            }]
        });

        this._initialized = true;
        return true;
    },

    /**
     * Initialize or reinitialize the form with the appropriate values.
     * @param {String} title The title of the dialog
     * @param {String} iconCls The CSS class for icon
     * @param {String} hintText The hint text
     * @param {Number} defaultWidth The default width set in the dialog
     * @param {Number} defaultHeight The default height set in the dialog
     * @private
     */
    _initForm: function (title, iconCls, hintText, defaultWidth, defaultHeight)
    {
        this._box.setTitle(title);
        this._box.setIconCls(iconCls);

        this._formPanel.items.get(0).update(hintText);

        var currentUrlField = this._formPanel.getComponent('url-field');
        var position = this._formPanel.items.indexOf(currentUrlField);
        
        // remove current field
        currentUrlField.destroy();
        
        // because regex config cannot be changed on the fly, the url field is recreated every time
        var urlField = Ext.create('Ext.form.field.Text', {
            xtype: 'textfield',
            name: 'url',
            itemId: 'url-field',
            fieldLabel: "{{i18n PLUGINS_INLINEMEDIA_DIALOG_URL}}",
            ametysDescription: "{{i18n PLUGINS_INLINEMEDIA_DIALOG_URL_DESC}}",
            allowBlank: false,
            regex: new RegExp(this._urlPatterns.join("|")),
            regexText: "{{i18n PLUGINS_INLINEMEDIA_REGEXP_DIALOG_ERROR}}" 
        });
        
        this._formPanel.insert(position, urlField);
        
        var form = this._formPanel.getForm();
        form.setValues({
            "url": "",
            "width": defaultWidth,
            "height": defaultHeight
        });
        form.clearInvalid();
    },

    /**
     * This function is called when the 'Ok' button of the dialog box #_box is pressed
     * Validate the form and insert the video into the rich text
     * @private
     */
    _ok: function ()
    {
        if (!this._formPanel.getForm().isValid())
        {
            return;
        }

        var values = this._formPanel.getForm().getValues();

        var videoId = this._getVideoId(values.url);

        if (videoId == '')
        {
            Ametys.Msg.show({
                title: this._box.getTitle(),
                msg: "{{i18n PLUGINS_INLINEMEDIA_REGEXP_DIALOG_ERROR}}",
                buttons: Ext.Msg.OK,
                icon: Ext.MessageBox.ERROR
             });
            return;
        }

        this._box.hide();

        var width = values.width || '480';
        var height = values.height || '385';
        
        this._currentEditor.execCommand('mceBeginUndoLevel');
        this._currentEditor.execCommand('mceInsertContent', false, '<img class="' + this._videoType + '" _mce_ribbon_select="1" marker="marker" media="' + this._videoType + '" width="' + width + '" height="' + height + '" src="' + Ametys.getPluginResourcesPrefix('inlinemedia') + '/img/trans.gif" data-ametys-type="' + this._videoType + '" data-ametys-src="' + videoId + '"/>');
        this._currentEditor.execCommand('mceEndUndoLevel');
        this._currentEditor.focus();
        this._currentEditor = null;
    },

    /**
     * Get the id of the video from its url
     * @param {String} videoUrl The url
     * @return {String} The id
     */
    _getVideoId: function(videoUrl)
    {
        for (var i = 0; i < this._urlPatterns.length; i++) 
        {
            var regexp = new RegExp(this._urlPatterns[i]);

            if (regexp.test(videoUrl))
            {
                return RegExp.$1;
            }
        }

        return '';
    },

    /**
     * This function is called when the 'Cancel' button of the dialog box #_box is pressed
     * Close the dialog
     * @private
     */
    _cancel: function ()
    {
        this._box.hide();
        
        this._currentEditor.focus();
        this._currentEditor = null;
    }

});