(function($) {
    var isClicked = false;

    $.fn.constructorToolTip = function(opt) {
        return this.each(function() {
            var $this = $(this),
                body = $(document.body),
                container, arrow, wrapper, msg,
                tooltipSize, elPos, elSize, arrowSize = { width: 0, height: 0 },
                top, left, containerPosition = { top: 0, left: 0 },
                options = {
                    margin: 15,
                    content: 'Constructor tool tip',
                    container: body,
                    position: 'bottom', // top left right bottom
                    additionalClass: '',
                    timer: 7000,
                    arrow: true
                };

            $.extend(options, opt);

            container = $('<div>');
            container.addClass('magic-tooltip');
            container.addClass(options.additionalClass);

            wrapper = $('<div>');
            wrapper.addClass('mtt-wrapper');

            msg = $('<div>');
            msg.addClass('mtt-message');

            msg[0].innerHTML = options.content;

            wrapper.append(msg[0]);

            if (options.arrow) {
                arrow = $('<div>');
                arrow.addClass('mtt-arrow');
                arrow.addClass('mtt-arrow-' + options.position);
                wrapper.append(arrow[0]);
            }

            container.append(wrapper);

            container.css('top', '-10000px');
            body.append(container[0]);

            tooltipSize = {
                width: container.width(),
                height: container.height()
            };

            if (options.arrow) {
                arrowSize = {
                    width: arrow.outerWidth(true),
                    height: arrow.outerHeight(true)
                };

                if ('top' === options.position || 'bottom' === options.position) {
                    arrow.css('left', tooltipSize.width / 2 - arrowSize.width / 2);
                } else {
                    arrow.css('top', tooltipSize.height / 2 - arrowSize.height / 2);
                }
            }

            elPos = $this.offset();

            if (body !== options.container) {
                containerPosition = $(options.container).offset();
                elPos.top -= containerPosition.top;
                elPos.left -= containerPosition.left;
            }

            elSize = {
                width: $this.outerWidth(true),
                height: $this.outerHeight(true)
            };

            if ('top' === options.position || 'bottom' === options.position) {
                if ('top' === options.position) {
                    top = elPos.top - (arrowSize.height || options.margin) - elSize.height;
                } else {
                    top = elPos.top + elSize.height + (arrowSize.height || options.margin);
                }
                left = (elPos.left + (elSize.width / 2)) - tooltipSize.width / 2;
            } else {
                if ('left' === options.position) {
                    left = elPos.left - (arrowSize.width || options.margin) - elSize.width;
                } else {
                    left = elPos.left + elSize.width + (arrowSize.width || options.margin);
                }
                top = (elPos.top + (elSize.height / 2)) - tooltipSize.height / 2;
            }

            $(options.container).append(container[0]);

            container.css({
                'top': top + 'px',
                'left': left + 'px'
            });

            setTimeout(function() {
                container.on('transitionend', function() {
                    container.remove();
                });
                container.addClass('mtt-hide');
            }, options.timer);

            return $this;
        });
    };


    function NameEditor(node_, id_) {
        var node = $(node_),
            id = id_,
            input, cont,
            updating = false,
            active = false,
            oldname = node[0].innerHTML,
            nameTimer;

        function verification(str) {
            var result = false,
                valid_characters = /^[A-Za-z0-9 \-_]+$/gi;

            if (valid_characters.test(str)) {
                result = true;
            }

            return result;
        }

        function checkUniqueName(name) {
            var unique = true;
            $('.tool-cell').each(function(i, n) {
                n = $(n);
                var toolId = n.attr('tool-id');
                if (toolId && ('null' === id || toolId !== id)) {
                    if (n.find('span')[0].innerHTML === name) {
                        unique = false;
                    }
                }
            });
            return unique;
        }

        function set(force) {
            var _m,
                name = $.trim(input.attr('value')),
                v = verification(name),
                un = checkUniqueName(name);

            if (!v || !un) {
                if (!v) {
                    _m = 'Shortcode name must be maximum 50 characters. It can only contain letters, numbers, spaces, underscores and dashes.';
                } else {
                    _m = '"' + name + '" is not the unique name';
                }
                input.css('color', 'red');
                input.parent().constructorToolTip({
                    content: _m,
                    additionalClass: 'warning'
                });
                input.focus();
                if (undefined === force) {
                    return;
                }
            }

            input.attr('value', '');
            input.off('blur');
            input.remove();


            active = false;
            // node.addClass('inactive');

            node[0].innerHTML = name;

            if (force) {
                node[0].innerHTML = oldname;
                return;
            }

            if (name !== oldname) {
                nameTimer = setTimeout(function() {
                    node.addClass('loading');
                }, 250);
                updating = true;
                $.post(magictoolbox_WordPress_MagicSlideshow_admin_modal_object.ajax, {
                    action: "WordPress_MagicSlideshow_rename",
                    nonce: magictoolbox_WordPress_MagicSlideshow_admin_modal_object.nonce,
                    id: id,
                    name: name
                })
                .success(function(data) {
                    if ('verification failed' === data || 'error' === data) {
                        node[0].innerHTML = oldname;
                    } else {
                        oldname = name;
                    }
                    clearTimeout(nameTimer);
                    node.removeClass('loading');
                    updating = false;
                })
                .error(function() {
                    node[0].innerHTML = oldname;
                    clearTimeout(nameTimer);
                    node.removeClass('loading');
                    updating = false;
                });
            } else {
                node[0].innerHTML = oldname;
            }
        };

        node.on('click', function(e) {
            var inner;
            e.preventDefault();
            // return false;
            if (!active && !updating) {
                input = $('<input>');
                input.attr('maxlength','20');
                input.on('keydown', function(e) {
                    if (13 === e.keyCode) {
                        set();
                    } else {
                        input.css('color', '');
                    }
                });
                input.on('blur', function(e) {
                    var n = $.trim(input.attr('value')),
                        v = verification(n),
                        un = checkUniqueName(n);
                    set(!v || !un);
                });

                active = true;
                // node.removeClass('inactive');
                node[0].blur();

                inner = node[0].innerHTML;
                node[0].innerHTML = '';

                input.attr('value', inner);

                node.append(input[0]);
                cont = input.parent();
                input[0].focus();
            }
            return false;
        });
    }

    function setActions(ifm) {
        $(ifm).on('load', function() {
            var ready = false;

            isClicked = false;

            var msg = function(e) {
                /**
                 *  e.data = {
                 *      type: 'mssc-ready' | 'mssc-save' | 'mssc-get',
                 *      data: {} - obj
                 *  }
                 */

                var params,
                    data = e.data.data;

                switch(e.data.type) {
                    case 'mssc-ready':
                        /**
                         *  data = {}
                         */
                        ready = true;
                        break;

                    case 'mssc-save':
                        /**
                         *  data = {
                         *      id: number,
                         *      data: {
                         *          json: [{},{}], - obj
                         *          html: '<div>...</div>' - string
                         *      }
                         *  }
                         */
                        if (!ready) return;

                        $.post(magictoolbox_WordPress_MagicSlideshow_admin_modal_object.ajax, {
                            action: "WordPress_MagicSlideshow_save",
                            nonce: magictoolbox_WordPress_MagicSlideshow_admin_modal_object.nonce,
                            data: data.data.json,
                            // data: JSON.parse(data.data.json),
                            id: data.id,
                            html: JSON.parse(data.data.html)
                        })
                        .success(function(_data) {
                            _data = JSON.parse(_data);
                            var cell, br, bc, face, n, url = _data.url, text, tmp, i, j;
                            if ('' === url) {
                                tmp = JSON.parse(data.data.json)[0];
                                text = '';
                                for (i = 0; i < tmp.length; i++) {
                                    for (j = 0; j < tmp[i].blocks.length; j++) {
                                        text += ' ';
                                        text += tmp[i].blocks[j].content;
                                    }
                                }
                                text = text.replace(/<\s*\/?\s*[^>]*>/g, '');
                                text = text.replace(/&#39/g, '"');
                                text = text.replace(/&#34/g, '\'');
                            }

                            if (null === data.id) {
                                cell =  $('<div>');
                                cell.addClass('tool-cell');
                                cell.attr('tool-id', _data.id);

                                bc = $('<button>');
                                bc.addClass('copy-magic-tool');
                                bc.addClass('magic-button');
                                bc.addClass('dashicons');
                                bc.addClass('dashicons-admin-page');
                                bc.attr('title', 'Copy');

                                br = $('<button>');
                                br.addClass('remove-magic-tool');
                                br.addClass('magic-button');
                                br.addClass('dashicons');
                                br.addClass('dashicons-no-alt');
                                bc.attr('title', 'Remove');

                                face = $('<div>');
                                face.addClass('tool-face');
                                if (text) {
                                    face.attr('data-face-text', text);
                                }
                                face.css('background-image', 'url(' + url + ')');

                                n = $('<span>');
                                n.addClass('tool-name');
                                n[0].innerHTML = 'magicslideshow-' + _data.id;

                                cell.append($('<div class="label">advanced</div>'));

                                cell.append(bc[0]);
                                cell.append(br[0]);
                                cell.append(face[0]);
                                cell.append(n[0]);

                                $('.magic-starts-here').append(cell[0]);

                                bc.on('click', copyTool);
                                br.on('click', removeTool);
                                cell.on('click', openConstructor);
                                new NameEditor(n, _data.id);
                                if (text) {
                                    tagСloud(face);
                                }
                            } else {
                                cell = $('div[tool-id="' + _data.id + '"]');
                                face = cell.find('.tool-face');
                                if ('' === url) {
                                    face.attr('data-face-text', text);
                                    tagСloud(face);
                                } else {
                                    face.removeAttr('data-face-text');
                                    face.css('background-image', 'url(' + url + ')');
                                }
                            }

                            ifm[0].contentWindow.postMessage({data: _data, mssConstructorMessage: 'mssc-data-saved'}, document.location);
                        })
                        .error(function() {
                            ifm[0].contentWindow.postMessage({mssConstructorMessage: 'mssc-data-saved-fail'}, document.location);
                        });
                        break;

                    case 'mssc-get-json':
                        /**
                         *  data = {
                         *      id: number
                         * }
                         */
                        if (!ready) return;

                        $.post(magictoolbox_WordPress_MagicSlideshow_admin_modal_object.ajax, {
                            action: "WordPress_MagicSlideshow_load",
                            nonce: magictoolbox_WordPress_MagicSlideshow_admin_modal_object.nonce,
                            id: data.id
                        })
                        .success(function(_data) {
                            _data = '"' + $.trim(_data) + '"';

                            _data = JSON.parse(JSON.parse(_data));

                            function rightType(value) {
                                if (Array.isArray(value) || !(value instanceof window.Function) && value instanceof window.Object) {
                                    for(var i in value) {
                                        rightType(value[i]);
                                        if (!Array.isArray(value) && !value.hasOwnProperty(i)) { continue; }
                                        if ('true' === value[i]) {
                                            value[i] = true;
                                        } else if ('false' === value[i]) {
                                            value[i] = false;
                                        } else if ('null' === value[i]) {
                                            value[i] = null;
                                        } else {
                                            rightType(value[i]);
                                        }
                                    }
                                }
                            }

                            function getImg(callback) {
                                var s = _data[0];
                                function step(slideIndex, blockIndex) {
                                    if (slideIndex <= s.length - 1) {
                                        if (blockIndex <= s[slideIndex].blocks.length - 1) {
                                            if (null !== s[slideIndex].blocks[blockIndex].imgId && undefined !== s[slideIndex].blocks[blockIndex].imgId) {
                                                $.post(magictoolbox_WordPress_MagicSlideshow_admin_modal_object.ajax, {
                                                    action: "WordPress_MagicSlideshow_get_image",
                                                    nonce: magictoolbox_WordPress_MagicSlideshow_admin_modal_object.nonce,
                                                    imgid: s[slideIndex].blocks[blockIndex].imgId,
                                                })
                                                .success(function(url) {
                                                    url = $.trim(url);

                                                    if ('error' !== url || 'verification failed' !== url) {
                                                        s[slideIndex].blocks[blockIndex].url = url;
                                                    }
                                                    step(slideIndex, blockIndex + 1);
                                                })
                                                .error(function() {
                                                    step(slideIndex, blockIndex + 1);
                                                });
                                            } else {
                                                step(slideIndex, blockIndex + 1);
                                            }
                                        } else {
                                            step(slideIndex + 1, 0);
                                        }
                                    } else {
                                        callback();
                                    }
                                }
                                step(0, 0);
                            }

                            rightType(_data);

                            getImg(function() {
                                ifm[0].contentWindow.postMessage({data: _data, mssConstructorMessage: 'mssc-json'}, document.location);
                            });
                        })
                        .error(function() {
                            ifm[0].contentWindow.postMessage({mssConstructorMessage: 'mssc-json-fail'}, document.location);
                        });
                        break;

                    case 'mssc-get-img':
                        if (!ready) return;

                        var win = wp.media({
                            title: 'Insert a media',
                            library: {type: 'image'},
                            multiple: false,
                            button: {text: 'Insert'}
                        });

                        win.on('select', function() {
                            var first = win.state().get('selection').first().toJSON();
                            ifm[0].contentWindow.postMessage({data: {url: first.url, imgId: first.id}, mssConstructorMessage: 'mssc-data-img'}, document.location);
                        });

                        win.open();
                        break;
                    case 'mssc-close':
                        if (!ready) return;

                        ifm.off('load');
                        ifm.removeAttr('src');
                        window.removeEventListener('message', msg);
                        $(ifm[0].parentNode).remove();
                        // checkLength();
                        break;
                }
            };
            window.addEventListener('message', msg, false);
        });
    }

    function removeTool(e) {
        e.preventDefault();
        var self = this, rTimer;

        if (!isClicked) {
            var curtain = $('<div class="magic-tool-curtain"></div>'),
                parent = $(e.target).parent(),
                _id = parent.attr('tool-id');

            isClicked = true;
            parent.append(curtain[0]);

            rTimer = setTimeout(function () {
                $(self).addClass('loading');
            }, 250);

            $.post(magictoolbox_WordPress_MagicSlideshow_admin_modal_object.ajax, {
                action: "WordPress_MagicSlideshow_delete",
                nonce: magictoolbox_WordPress_MagicSlideshow_admin_modal_object.nonce,
                id: _id
            })
            .success(function(data) {
                isClicked = false;
                if ('verification failed' === data || 'error' === data) {
                    curtain.remove();
                } else {
                    parent.on('transitionend', function() {
                        parent.remove();
                    });

                    parent.css({
                        'transition': 'opacity 0.5s linear',
                        'opacity': 0
                    });
                }
                clearTimeout(rTimer);
                $(self).removeClass('loading');
            })
            .error(function(e) {
                isClicked = false;
                curtain.remove();
                clearTimeout(rTimer);
                $(self).removeClass('loading');
            });
        }
        return false;
    }

    function copyTool(e) {
        e.preventDefault();
        if (!isClicked) {
            isClicked = true;
            var clone, span, self = this, cTimer,
                parent = $(e.target).parent(),
                _id = parent.attr('tool-id');

            e.preventDefault();

            cTimer = setTimeout(function () {
                $(self).addClass('loading');
            }, 250);

            $.post(magictoolbox_WordPress_MagicSlideshow_admin_modal_object.ajax, {
                action: "WordPress_MagicSlideshow_copy",
                nonce: magictoolbox_WordPress_MagicSlideshow_admin_modal_object.nonce,
                id: _id
            })
            .success(function(_data) {
                if ('error' !== _data && 'verification failed' !== _data) {
                    clone = parent.clone(true);
                    clone.attr('tool-id', _data);
                    span = clone.find('span');
                    span[0].innerHTML = 'magicslideshow-' + _data;
                    span.off('click');
                    clone.find('button').removeClass('loading');
                    new NameEditor(span, _data);
                    parent.parent().append(clone[0]);
                }
                isClicked = false;
                clearTimeout(cTimer);
                $(self).removeClass('loading');
            })
            .error(function() {
                isClicked = false;
                // console.log('error');
                clearTimeout(cTimer);
                $(self).removeClass('loading');
            });

        }
        return false;
    }

    function openConstructor(e) {
        if (!isClicked) {
            isClicked = true;

            var w = $(document.createElement('div')),
                ifm = $(document.createElement('iframe')),
                iframeUrl = magictoolbox_WordPress_MagicSlideshow_admin_modal_object.iframe,
                _id, node;

            e.preventDefault();

            node = $(e.target);

            while(!node.hasClass('tool-cell')) {
                if ('body' === node[0].tagName) {
                    return false;
                }
                node = node.parent();
            }

            _id = node.attr('tool-id');

            if (node.hasClass('simple')) {
                var href = window.location.href;
                href = href.split('?')[0];
                href = href.split('wp-admin')[0];
                href = href + 'wp-admin/admin.php?page=WordPressMagicSlideshow-shortcodes-page&id='+_id;
                window.location.href = href;
                return false;
            }

            w.css({
                'top': '0px',
                'left': '0px',
                'width': '100%',
                'height': '100%',
                'position': 'fixed',
                'z-index': 100000,
                'opacity': 0,
                'transition': 'opacity .7s linear'
            });

            // ifm.css({
            //     'top': '0px',
            //     'left': '0px',
            //     'width': '100%',
            //     'height': '100%',
            //     'position': 'relative'
            // });

            ifm.css({
                'top': '50%',
                'left': '50%',
                'width': '97%',
                'height': '97%',
                'position': 'relative',
                'border': '1px solid #cecece',
                'box-shadow': '1px 1px 5px 1px rgba(0,0,0,0.5)',
                'transform': 'translate(-50%, -50%)',
                'background-color': 'white'
            });

            if (undefined !== _id) {
                iframeUrl += ('#/ss_l?id=' + _id);
            }

            ifm.attr('src', iframeUrl);
            w.append(ifm);

            setActions(ifm);
            $(document.body).append(w);
            w.width();
            w.css('opacity', 1);
        }
        return false;
    }

    function tagСloud(tag_) {
        var faces, attr,
            CreateUrl = function(text, tag) {
                var i, j, l = [],
                    canvas,
                    scheme = {};

                text = $.trim(text);
                text = text.replace(/\.|,|!|\-|_|\?|\*|;/g, '');
                // text = text.replace(/[^\w\s]|_/g, '');
                if ('' == text) {
                    text = 'magictoolbox any device magic amazing enjoy simplicity responsive design easy magicslideshow support automatically scale slide block effect fade responsive cube flip friendly bars3d blinds3d';
                }

                text = text.split(" ");
                canvas =  document.createElement('canvas');

                for (i = 0 ; i < text.length; i++) {
                    if (text[i] in scheme) {
                        scheme[text[i]] += 1;
                    } else {
                        scheme[text[i]] = 1;
                    }
                    // l.push([text[i], parseInt(Math.random() * (max - min) + min)]);
                }

                for (i in scheme) {
                    if (!scheme.hasOwnProperty(i)) continue;
                    l.push([i, scheme[i]]);
                }

                WordCloud(canvas, {
                    list: l,
                    gridSize: 5,
                    weightFactor: 10,
                    fontFamily: '\"comic sans ms\", sans-serif, Times, serif',
                    shuffle: true,
                    // rotateRatio: 1
                });
                canvas.addEventListener('wordcloudstop', function wordcloudstopped() {
                    var url;
                    canvas.removeEventListener('wordcloudstop', wordcloudstopped);
                    url = canvas.toDataURL('image/jpeg');
                    tag.css('background-image', 'url(' + url + ')');
                });
            };
        if (tag_) {
            tag_ = $(tag_);
            attr = tag_.attr('data-face-text');
            if (attr && '' !== attr) {
                new CreateUrl(attr, tag_);
            }
        } else {
            faces = $('.tool-face');
            faces.each(function(i, n) {
                attr = null;
                n = $(n);
                attr = n.attr('data-face-text');
                // attr = 'magictoolbox any device magic amazing enjoy simplicity responsive design easy magicslideshow support automatically scale slide block effect fade responsive cube flip friendly bars3d blinds3d';
                if (attr && '' !== attr) {
                    new CreateUrl(attr, n);
                }
            });
        }
    }

    $(document).ready(function() {
        var
            openButtons = $('.tool-cell'),
            removeMagicTool = $('.remove-magic-tool'),
            copyMagicTool = $('.copy-magic-tool');

        copyMagicTool.on('click', copyTool);
        removeMagicTool.on('click', removeTool);
        openButtons.filter(':not(.new-magic-tool)').on('click', openConstructor);

        $('.new-magic-tool').find('.pro').on('click', openConstructor);

        openButtons.each(function(index, node) {
            node = $(node);
            if (!node.hasClass('new-magic-tool')) {
                new NameEditor(node.find('span'), node.attr('tool-id'));
            }
        });
        tagСloud();
    });
})(jQuery);
