/*-----------------------------------------------------------------------------------*/
/* Generate Sections Metabox
/*
/* © Kathy Darling http://www.kathyisawesome.com
/* 2016-07-19. */
/*-----------------------------------------------------------------------------------*/

/**
 * @type {Object} JavaScript namespace for our application.
 */
var Generate_Sections = {
    backbone_modal: {
        __instance: undefined
    }
};

(function($, Generate_Sections) {


    // Model
    Generate_Sections.Section = Backbone.Model.extend({
        defaults: {
            "title": "",
            "box_type": "",
            "inner_box_type": "",
            "custom_classes": "",
            "custom_id": "",
            "top_padding": "",
            "bottom_padding": "",
			"top_padding_unit": "",
            "bottom_padding_unit": "",
            "background_color": "",
            "background_image": "",
            "background_image_preview": "",
            "parallax_effect": "",
            "background_color_overlay": "",
            "text_color": "",
            "link_color": "",
            "link_color_hover": "",
            "content": ""
        }
    });


    // Collection
    Generate_Sections.SectionsCollection = Backbone.Collection.extend({
        model: Generate_Sections.Section,
        el: "#generate_sections_container",
        comparator: function(model) {
            return model.get('index');
        }
    });


    /**
     * Primary Modal Application Class
     */
    Generate_Sections.backbone_modal.Application = Backbone.View.extend({

        attributes: {
            id: "generate-sections-modal-dialog",
            class: "generate-sections-modal",
            role: "dialog"
        },

        template: wp.template("generate-sections-modal-window"),

        mediaUploader: null,

        /*-----------------------------------------------------------------------------------*/
        /* tinyMCE settings
        /*-----------------------------------------------------------------------------------*/

        tmc_settings: {},

        /*-----------------------------------------------------------------------------------*/
        /* tinyMCE defaults
        /*-----------------------------------------------------------------------------------*/

        tmc_defaults: {
            theme: "modern",
            menubar: false,
            wpautop: true,
            indent: false,
            toolbar1: "bold,italic,underline,blockquote,strikethrough,bullist,numlist,alignleft,aligncenter,alignright,undo,redo,link,unlink,fullscreen",
            plugins: "fullscreen,image,wordpress,wpeditimage,wplink",
            max_height: 500
        },

        /*-----------------------------------------------------------------------------------*/
        /* quicktags settings
        /*-----------------------------------------------------------------------------------*/

        qt_settings: {},

        /*-----------------------------------------------------------------------------------*/
        /* quicktags defaults
        /*-----------------------------------------------------------------------------------*/

        qt_defaults: {
            buttons: "strong,em,link,block,del,ins,img,ul,ol,li,code,more,close,fullscreen"
        },

        model: Generate_Sections.Section,

        events: {
            "click .media-modal-backdrop, .media-modal-close, .media-button-close": "closeModal",
            "click .media-button-insert": "saveModal",
            "click .media-menu-item": "switchTab",
            "keydown": "keydown",
            "click .generate-sections-upload-button": "openMediaUploader",
            "click .generate-sections-remove-image": "removeImage",
            "click div.media-frame-title h1": "toggleMenu"
        },



        /**
         * Simple object to store any UI elements we need to use over the life of the application.
         */
        ui: {
            nav: undefined,
            content: undefined
        },


        /**
         * Instantiates the Template object and triggers load.
         */
        initialize: function() {
            _.bindAll(this, "render", "closeModal", "saveModal", "switchTab");

            this.focusManager = new wp.media.view.FocusManager({
                el: this.el
            });

            this.changeInsertText();
            this.tinyMCEsettings();
            this.render();
        },

        /**
         * switch the insert button text to "insert section"
         */
        changeInsertText: function(restore) {

            var restore = typeof restore !== 'undefined' && restore == true ? true : false;

            if (restore == false && typeof(wp.media.view.l10n.insertIntoPost) !== "undefined") {
                this.insertIntoPost = wp.media.view.l10n.insertIntoPost;
                wp.media.view.l10n.insertIntoPost = generate_sections_metabox_i18n.insert_into_section;
                // switch the insert button text back
            } else if (restore == true && typeof(this.insertIntoPost) !== "undefined") {
                wp.media.view.l10n.insertIntoPost = this.insertIntoPost;
            }
        },


        /**
         * Merge the default TinyMCE settings
         */
        tinyMCEsettings: function() {
            // get the #content"s tinyMCE settings or use default
            var init_settings = typeof tinyMCEPreInit == "object" && "mceInit" in tinyMCEPreInit && "content" in tinyMCEPreInit.mceInit ? tinyMCEPreInit.mceInit.content : this.tmc_defaults;

            // get the #content"s quicktags settings or use default
            var qt_settings = typeof tinyMCEPreInit == "object" && "qtInit" in tinyMCEPreInit && "content" in tinyMCEPreInit.qtInit ? tinyMCEPreInit.qtInit.content : this.qt_defaults;

            var _this = this;
            var custom_settings = {
                selector: "#generate-sections-editor",
                wp_autoresize_on: false,
                cache_suffix: "",
                min_height: 400,
            }

            // merge our settings with WordPress" and store for later use
            this.tmc_settings = $.extend({}, init_settings, custom_settings);

            this.qt_settings = $.extend({}, qt_settings, {
                id: "generate-sections-editor"
            });
        },


        /**
         * Assembles the UI from loaded template.
         * @internal Obviously, if the template fail to load, our modal never launches.
         */
        render: function() {

            "use strict";

            // Build the base window and backdrop, attaching them to the $el.
            // Setting the tab index allows us to capture focus and redirect it in Application.preserveFocus
            this.$el.attr("tabindex", "0")
                .html(this.template);

            // Handle any attempt to move focus out of the modal.
            //jQuery(document).on("focusin", this.preserveFocus);

            // set overflow to "hidden" on the body so that it ignores any scroll events while the modal is active
            // and append the modal to the body.
            jQuery("body").addClass("generate-modal-open").prepend(this.$el);

            // aria hide the background
            jQuery("#wpwrap").attr("aria-hidden", "true");

            this.renderContent();

            this.renderPreview();

            this.selected();
            this.colorPicker();
            this.startTinyMCE();

            // Set focus on the modal to prevent accidental actions in the underlying page
            this.$el.focus();

            return this;
        },

        /**
         * Make the menu mobile-friendly
         */
        toggleMenu: function() {
            this.$el.find('.media-menu').toggleClass('visible');
        },

        /**
         * Create the nav tabs & panels
         */
        renderContent: function() {

            var model = this.model;

            var menu_item = wp.template("generate-sections-modal-menu-item");

            // Save a reference to the navigation bar"s unordered list and populate it with items.
            this.ui.nav = this.$el.find(".media-menu");

            // reference to content area
            this.ui.panels = this.$el.find(".media-frame-content");

            // loop through the tabs
            if (generate_sections_metabox_i18n.tabs.length) {

                // for...of is nicer, but not supported by minify, so stay with for...in for now
                for (var tab in generate_sections_metabox_i18n.tabs) {

                    if (generate_sections_metabox_i18n.tabs.hasOwnProperty(tab)) {

                        tab = generate_sections_metabox_i18n.tabs[tab];

						var $new_tab = $(menu_item({
							target: tab.target,
							name: tab.title
						}));

						var panel = wp.template("generate-sections-edit-" + tab.target);

                        var $new_panel = $(panel(model.toJSON()));

						if (tab.active == "true") {
                            $new_tab.addClass("active");
                            $new_panel.addClass("active");
                        }

						jQuery( 'body' ).on( 'generate_section_show_settings', function() {
							jQuery( '.generate-sections-modal .media-menu-item' ).removeClass('active');
							jQuery( '.generate-sections-modal .panel' ).removeClass('active');
							jQuery( '.generate-section-item-style' ).addClass('active');
							jQuery( '.generate-section-settings' ).addClass('active');
						});

                        this.ui.nav.append($new_tab);
                        this.ui.panels.append($new_panel);
                    }
                }
            }

        },


        /**
         * Render the background image preview
         */
        renderPreview: function(image_id) {

            var image_id = typeof image_id !== 'undefined' ? image_id : this.model.get("background_image");

            var $preview = $("#generate-section-image-preview");
            $preview.children().remove();

            if (image_id > 0) {
                this.background = new wp.media.model.Attachment.get(image_id);

                this.background.fetch({
                    success: function(att) {
                        if (_.contains(['png', 'jpg', 'gif', 'jpeg'], att.get('subtype'))) {
                            $("<img/>").attr("src", att.attributes.sizes.thumbnail.url).appendTo($preview);
                            $preview.next().find(".generate-sections-remove-image").show();
                        }
                    }
                });
            }

        },


        /**
         * Set the default option for the select boxes
         */
        selected: function() {

            var _this = this;

            this.$el.find("select").each(function(index, select) {

                var attribute = jQuery(select).attr("name");
                var selected = _this.model.get(attribute);
                jQuery(select).val(selected);

            });
        },

        /**
         * Start the colorpicker
         */
        colorPicker: function() {
            this.$el.find(".generate-sections-color").wpColorPicker();
        },

        /**
         * Start TinyMCE on the textarea
         */
        startTinyMCE: function() {

            // set the default editor
            this.ui.panels.find("#wp-generate-sections-editor-wrap").addClass(generate_sections_metabox_i18n.default_editor);

            // remove tool buttons if richedit disabled
            if (!generate_sections_metabox_i18n.user_can_richedit) {
                this.ui.panels.find(".wp-editor-tabs").remove();
            }

            // add our copy to the collection in the tinyMCEPreInit object because switch editors
            if (typeof tinyMCEPreInit == 'object') {
                tinyMCEPreInit.mceInit["generate-sections-editor"] = this.tmc_settings;
                tinyMCEPreInit.qtInit["generate-sections-editor"] = this.qt_settings;
				tinyMCEPreInit.mceInit["generate-sections-editor"].wp_keep_scroll_position = false;
            }

            try {

                var rich = (typeof tinyMCE != "undefined");

                // turn on the quicktags editor
                quicktags(this.qt_settings);

                // attempt to fix problem of quicktags toolbar with no buttons
                QTags._buttonsInit();

                if (rich !== false) {
                    // turn on tinyMCE
					tinyMCE.init(this.tmc_settings);
                }

            } catch (e) {}

        },

        /**
         * Launch Media Uploader
         */
        openMediaUploader: function(e) {

            var _this = this;

            $input = jQuery(e.currentTarget).prev("#generate-sections-background-image");

            e.preventDefault();

            // If the uploader object has already been created, reopen the dialog
            if (this.mediaUploader) {
                this.mediaUploader.open();
                return;
            }
            // Extend the wp.media object
            this.mediaUploader = wp.media.frames.file_frame = wp.media({
                title: generate_sections_metabox_i18n.media_library_title,
                button: {
                    text: generate_sections_metabox_i18n.media_library_button
                },
                multiple: false
            });


            // When a file is selected, grab the URL and set it as the text field"s value
            this.mediaUploader.on("select", function() {

                attachment = _this.mediaUploader.state().get("selection").first().toJSON();

                $input.val(attachment.id);

                _this.renderPreview(attachment.id);
            });
            // Open the uploader dialog
            this.mediaUploader.open();

        },

        /**
         * Remove the background image
         */
        removeImage: function(e) {
            e.preventDefault();
            $("#generate-section-image-preview").children().remove();
            $("#generate-section-image-preview").next().find(".generate-sections-remove-image").hide();
            $("#generate-sections-background-image").val("");
        },


        /**
         * Closes the modal and cleans up after the instance.
         * @param e {object} A jQuery-normalized event object.
         */
        closeModal: function(e) {
            "use strict";

            e.preventDefault();
            this.undelegateEvents();
            jQuery(document).off("focusin");
            jQuery("body").removeClass("generate-modal-open");
            jQuery("body").removeClass("generate-section-content");

            // remove restricted media modal tab focus once it's closed
            this.$el.undelegate('keydown');

			// remove the tinymce editor
			// this needs to be called before the modal is closed or it will fail in Firefox (that was fun to figure out...)
			if (typeof tinyMCE != "undefined") {
				tinymce.EditorManager.execCommand("mceRemoveEditor", true, "generate-sections-editor");
			}

            // remove modal and unset instances
            this.remove();
            Generate_Sections.backbone_modal.__instance = undefined;
            this.mediaUploader = null;
            Generate_Sections.modalOpen = null;

            // switch the insert button text back
            this.changeInsertText(true);

            // send focus back to where it was prior to modal open
            Generate_Sections.lastFocus.focus();

            // aria unhide the background
            jQuery("#wpwrap").attr("aria-hidden", "false");

			// Fix bug where the window scrolls down 50px on close
			var topDistance = jQuery("body").offset().top;
			if ( topDistance >= jQuery("body").scrollTop() ) {
				jQuery("body").scrollTop(0);
			}

        },

        /**
         * Responds to the btn-ok.click event
         * @param e {object} A jQuery-normalized event object.
         * @todo You should make this your own.
         */
        saveModal: function(e) {
            "use strict";

            this.model.get("index");

            var model = this.model;

            // send the tinymce content to the textarea
            if (typeof tinyMCE != "undefined") {
                tinymce.triggerSave();
            }

            var $inputs = this.ui.panels.find("input, select, textarea");

            $inputs.each(function(index, input) {

                var name = $(input).attr("name");

                if (model.attributes.hasOwnProperty(name)) {
                    var value = $(input).val();
                    model.set(name, value);
                }

            });

            this.closeModal(e);
        },

        /**
         * Handles tab clicks and switches to corresponding panel
         * @param e {object} A jQuery-normalized event object.
         */
        switchTab: function(e) {
            "use strict";
            e.preventDefault();

			// close lingering wp link windows
            if (typeof tinyMCE != "undefined" && 'style' == jQuery( e.currentTarget ).data( 'target' ) && this.ui.panels.find( '#wp-generate-sections-editor-wrap' ).hasClass( 'tmce-active' )) {
                tinyMCE.activeEditor.execCommand('wp_link_cancel');
                tinyMCE.activeEditor.execCommand('wp_media_cancel');
            }

            this.ui.nav.children().removeClass("active");
            this.ui.panels.children().removeClass("active");

            var target = jQuery(e.currentTarget).addClass("active").data("target");

            this.ui.panels.find("div[data-id=" + target + "]").addClass("active");
        },

        /**
         * close on keyboard shortcuts
         * @param {Object} event
         */
        keydown: function(e) {
            // Close the modal when escape is pressed.
            if (27 === e.which && this.$el.is(':visible')) {
                this.closeModal(e);
                e.stopImmediatePropagation();
            }
        }

    });


    // Singular View
    Generate_Sections.sectionView = Backbone.View.extend({

        model: Generate_Sections.Section,
        tagName: 'div',

        initialize: function() {
            // re-render on all changes EXCEPT index
            this.listenTo(this.model, "change", this.maybeRender);
        },

        attributes: {
            class: "ui-state-default section"
        },

        // Get the template from the DOM
        template: wp.template("generate-sections-section"),

        events: {
            'click .edit-section': 'editSection',
            'click .section-title > span': 'editSection',
            'click .delete-section': 'removeSection',
            'click .toggle-section': 'toggleSection',
            'reorder': 'reorder',
        },

        maybeRender: function(e) {
            if (this.model.hasChanged('index')) return;
            this.render();
        },

        // Render the single model - include an index.
        render: function() {
            this.model.set('index', this.model.collection.indexOf(this.model));
            this.$el.html(this.template(this.model.toJSON()));

            if (!this.model.get('title')) {
                this.$el.find('h3.section-title > span').text(generate_sections_metabox_i18n.default_title);
            }
            this.$el.find('textarea').val(JSON.stringify(this.model));

            return this;
        },


        // launch the edit modal
        editSection: function(e) {

            // stash the current focus
            Generate_Sections.lastFocus = document.activeElement;
            Generate_Sections.modalOpen = true;

            e.preventDefault();
            if (Generate_Sections.backbone_modal.__instance === undefined) {
                Generate_Sections.backbone_modal.__instance = new Generate_Sections.backbone_modal.Application({
                    model: this.model
                });
            }

        },

        // reorder after sort
        reorder: function(event, index) {
            this.$el.trigger('update-sort', [this.model, index]);
        },

        // remove/destroy a model
        removeSection: function(e) {
            e.preventDefault();
            if (confirm(generate_sections_metabox_i18n.confirm)) {
                this.model.destroy();
                Generate_Sections.sectionList.render(); // manually calling instead of listening since listening interferes with sorting
            }
        },
    });


    // List View
    Generate_Sections.sectionListView = Backbone.View.extend({

        el: "#generate_sections_container",
        events: {
            'update-sort': 'updateSort',
            //     'add-section': 'addOne'
        },

        // callback for clone button
        addSection: function(model) {
            this.collection.add(model);
            this.addOne(model);
        },

        addOne: function(model) {
            var view = new Generate_Sections.sectionView({
                model: model
            });
            this.$el.append(view.render().el);
        },

        render: function() {
            this.$el.children().remove();
            this.collection.each(this.addOne, this);
            return this;
        },

        updateSort: function(event, model, position) {
            this.collection.remove(model);

            // renumber remaining models around missing model
            this.collection.each(function(model, index) {

                var new_index = index;
                if (index >= position) {
                    new_index += 1;
                }
                model.set('index', new_index);
            });

            // set the index of the missing model
            model.set('index', position);

            // add the model back to the collection
            this.collection.add(model, {
                at: position
            });

            this.render();

        },

    });


    // The Buttons & Nonce
    Generate_Sections.ButtonControls = Backbone.View.extend({

        attributes: {
            class: "generate_sections_buttons"
        },

        tagName: 'p',

        el: "#_generate_sections_metabox",

        template: wp.template("generate-sections-buttons"),

        // Attach events
        events: {
            "click .button-primary": "newSection",
            "click #generate-delete-sections": "clearAll",
            'click .edit-section': 'editSection',
        },

        // create new
        newSection: function(e) {
            e.preventDefault();
            var newSection = new Generate_Sections.Section();
            Generate_Sections.sectionList.addSection(newSection);
        },

        // clear all models
        clearAll: function(e) {
            e.preventDefault();
            if (confirm(generate_sections_metabox_i18n.confirm)) {
                Generate_Sections.sectionCollection.reset();
                Generate_Sections.sectionList.render();
            }
        },

        render: function() {
            this.$el.find(".generate_sections_control").append(this.template);
            return this;
        },

    });


    // init
    Generate_Sections.initApplication = function() {

        // Create Collection From Existing Meta
        Generate_Sections.sectionCollection = new Generate_Sections.SectionsCollection(generate_sections_metabox_i18n.sections);

        // Create the List View
        Generate_Sections.sectionList = new Generate_Sections.sectionListView({
            collection: Generate_Sections.sectionCollection
        });
        Generate_Sections.sectionList.render();

        // Buttons
        Generate_Sections.Buttons = new Generate_Sections.ButtonControls({
            collection: Generate_Sections.sectionCollection
        });
        Generate_Sections.Buttons.render();

    };


    /*-----------------------------------------------------------------------------------*/
    /* Execute the above methods in the Generate_Sections object.
    /*-----------------------------------------------------------------------------------*/

    jQuery(document).ready(function($) {

        Generate_Sections.initApplication();

        $( '#generate_sections_container' ).sortable({
            axis: "y",
            opacity: 0.5,
            grid: [20, 10],
            tolerance: "pointer",
            handle: ".move-section",
            update: function(event, ui) {
                ui.item.trigger("reorder", ui.item.index());
            }
        } );

		if ( $( '.use-sections-switch' ).is( ':checked' ) ) {
			setTimeout( function() {
				generateShowSections();
			}, 200 );
		} else {
			generateHideSections();
		}

		$( '.use-sections-switch' ).on( 'change', function( e ) {
			var status = ( $(this).is( ':checked' ) ) ? 'checked' : 'unchecked';

			if ( 'checked' == status ) {
				generateShowSections();
			} else if ( 'unchecked' == status ) {
				generateHideSections();
			}
		} );

        function generateShowSections() {

            // Hide send to editor button
            $('.send-to-editor').css('display', 'none');

            // Hide the editor
            $('#postdivrich').css({
                'opacity': '0',
                'height': '0',
                'overflow': 'hidden'
            });

            // Show the sections
            $('#_generate_sections_metabox').css({
                'opacity': '1',
                'height': 'auto'
            });

			// Remove and add the default editor - this removes any visible toolbars etc..
			// We need to set a timeout for this to work
			// if (typeof tinyMCE != "undefined") {
				// tinyMCE.EditorManager.execCommand("mceRemoveEditor", true, "content");
				// $( '.use-sections-cover' ).css( 'z-index','10000' );
				// setTimeout('tinyMCE.EditorManager.execCommand("mceAddEditor", true, "content");', 1);
				// setTimeout('jQuery( ".use-sections-cover" ).css( "z-index","-1" );', 1000);
			// }

			// Set a trigger
            $('body').trigger('generate_show_sections');

        }

        function generateHideSections() {

            // Show send to editor button
            $('.send-to-editor').css('display', 'inline-block');

            // Show the editor
            $('#postdivrich').css({
                'opacity': '1',
                'height': 'auto'
            });

            // Hide the sections
            $('#_generate_sections_metabox').css({
                'opacity': '0',
                'height': '0',
                'overflow': 'hidden'
            });

            $('body').trigger('generate_hide_sections');

        }

		$( document ).on( 'click', '.edit-section.edit-settings', function() {
			$( 'body' ).trigger( 'generate_section_show_settings' );
		});

    });


})(jQuery, Generate_Sections);
