<?php
/**
 * Editor class
 * 
 * @package Page_Generator_Pro
 * @author  Tim Carr
 * @version 1.0.0
 */
class Page_Generator_Pro_Editor {

    /**
     * Holds the base object.
     *
     * @since 1.2.1
     *
     * @var     object
     */
    public $base;

    /**
     * Holds the screen and section the user is viewing
     *
     * @since   2.6.2
     *
     * @var     array
     */
    public $screen = array(
        'screen'    => false,
        'section'   => false,
    );

    /**
     * Holds the shortcodes to register as TinyMCE Plugins
     *
     * @since   2.6.2
     *
     * @var     array
     */
    public $shortcodes = array();

    /**
     * Constructor
     * 
     * @since   1.0.0
     *
     * @param   object $base    Base Plugin Class
     */
    public function __construct( $base ) {

        // Store base class
        $this->base = $base;

        // Add filters to register QuickTag Plugins
        add_action( 'admin_enqueue_scripts', array( $this, 'register_quicktags' ) ); // WordPress Admin
        add_action( 'wp_enqueue_scripts', array( $this, 'register_quicktags' ) ); // Frontend Editors

        // Add filters to register TinyMCE Plugins
        // Low priority ensures this works with Frontend Page Builders
        add_filter( 'mce_external_plugins', array( $this, 'register_tinymce_plugins' ), 99999 );
        add_filter( 'mce_buttons', array( $this, 'register_tinymce_buttons' ), 99999 );

    }

    /**
     * Register QuickTags JS for the TinyMCE Text (non-Visual) Editor
     *
     * @since   3.0.0
     */
    public function register_quicktags() {

        // Determine the screen that we're on
        $screen = $this->base->get_class( 'screen' )->get_current_screen();

        // Bail if we're not registering TinyMCE Plugins
        if ( ! $this->should_register_tinymce_plugins( $screen ) ) {
            return;
        }

        // If SCRIPT_DEBUG is enabled, load unminified versions
        $minified = ( ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? false : true );

        // Depending on the screen we're on, define the shortcodes to register as TinyMCE Plugins
        switch ( $screen['screen'] ) {
            case 'post':
                $shortcodes = $this->base->get_class( 'shortcode' )->get_shortcode_supported_outside_of_content_groups();
                break;

            case 'content_groups':
                // Get shortcodes
                $shortcodes = $this->base->get_class( 'shortcode' )->get_shortcodes();

                // Get Plugins that aren't shortcodes, registering their JS scripts
                foreach ( $this->get_tinymce_plugins( $minified ) as $plugin_name => $plugin_attributes ) {
                    $plugins[ $plugin_name ] = $plugin_attributes['js'];
                }
                break;

            case 'content_terms':
                // Get Plugins that aren't shortcodes, registering their JS scripts
                foreach ( $this->get_tinymce_plugins( $minified ) as $plugin_name => $plugin_attributes ) {
                    $plugins[ $plugin_name ] = $plugin_attributes['js'];
                }
                break;
        }

        // If no shortcodes require registration, bail
        if ( ! isset( $shortcodes ) ) {
            return;
        }

        // Enqueue Quicktag JS
        wp_enqueue_script( $this->base->plugin->name . '-quicktags', $this->base->plugin->url . 'assets/js/' . ( $minified ? 'min/' : '' ) . 'quicktags' . ( $minified ? '-min' : '' ) . '.js', array( 'jquery', 'quicktags' ), $this->base->plugin->version, true );
        wp_localize_script( $this->base->plugin->name . '-quicktags', 'page_generator_pro_quicktags', $shortcodes );

        // Output Backbone View Template
        ?>
        <script type="text/template" id="tmpl-wpzinc-quicktags-modal"><div id="wpzinc-quicktags-modal"></div></script>
        <?php

    }

    /**
     * Register JS plugins for the TinyMCE Editor
     *
     * @since   1.0.0
     *
     * @param   array   $plugins    JS Plugins
     * @return  array 		        JS Plugins
     */
    public function register_tinymce_plugins( $plugins ) {

        // Determine the screen that we're on
        $screen = $this->base->get_class( 'screen' )->get_current_screen();

        // Bail if we're not registering TinyMCE Plugins
        if ( ! $this->should_register_tinymce_plugins( $screen ) ) {
            return $plugins;
        }

        // If SCRIPT_DEBUG is enabled, load unminified versions
        $minified = ( ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) ? false : true );

        // Depending on the screen we're on, define the shortcodes to register as TinyMCE Plugins
        switch ( $screen['screen'] ) {
            case 'post':
                $shortcodes = $this->base->get_class( 'shortcode' )->get_shortcode_supported_outside_of_content_groups();
                break;

            case 'content_groups':
                // Get shortcodes
                $shortcodes = $this->base->get_class( 'shortcode' )->get_shortcodes();

                // Get Plugins that aren't shortcodes, registering their JS scripts
                foreach ( $this->get_tinymce_plugins( $minified ) as $plugin_name => $plugin_attributes ) {
                    $plugins[ $plugin_name ] = $plugin_attributes['js'];
                }
                break;

            case 'content_terms':
                // Get Plugins that aren't shortcodes, registering their JS scripts
                foreach ( $this->get_tinymce_plugins( $minified ) as $plugin_name => $plugin_attributes ) {
                    $plugins[ $plugin_name ] = $plugin_attributes['js'];
                }
                break;
        }

        // If no shortcodes require registration, bail
        if ( ! isset( $shortcodes ) ) {
            return $plugins;
        }

        // Register TinyMCE Plugins
        foreach ( $shortcodes as $shortcode => $properties ) {
            $plugins['page_generator_pro_' . str_replace( '-', '_', $shortcode ) ] = $this->base->plugin->url . 'assets/js/' . ( $minified ? 'min/' : '' ) . 'tinymce-' . $shortcode . ( $minified ? '-min' : '' ) . '.js';
        }

        /**
         * Defines the TinyMCE Plugins to register
         *
         * @since   1.0.0
         *
         * @param   array   $plugins    TinyMCE Plugins
         * @param   array   $screen     Screen and Section
         * @param   array   $shortcodes Shortcodes
         */
	    $plugins = apply_filters( 'page_generator_pro_editor_register_tinymce_plugins', $plugins, $screen, $shortcodes );

        // Return filtered results
        return $plugins;

    }

    /**
     * Registers buttons in the TinyMCE Editor
     *
     * @since   1.0.0
     *
     * @param   array   $buttons    Buttons
     * @return  array 		        Buttons
     */
    public function register_tinymce_buttons( $buttons ) {

        // Determine the screen that we're on
        $screen = $this->base->get_class( 'screen' )->get_current_screen();

        // Bail if we're not registering TinyMCE Plugins
        if ( ! $this->should_register_tinymce_plugins( $screen ) ) {
            return $buttons;
        }

        // Deliniate buttons before we add this Plugin's buttons
        $buttons[] = "|";

        // Depending on the screen we're on, define the shortcodes to register as TinyMCE Plugins
        switch ( $screen['screen'] ) {
            case 'post':
                $shortcodes = $this->base->get_class( 'shortcode' )->get_shortcode_supported_outside_of_content_groups();
                break;

            case 'content_groups':
            case 'content_terms':
                $shortcodes = $this->base->get_class( 'shortcode' )->get_shortcodes();

                // Get Plugins that aren't shortcodes, registering their buttons
                foreach ( $this->get_tinymce_plugins() as $plugin_name => $plugin_attributes ) {
                    // Don't register a button if this TinyMCE Plugin doesn't have one
                    if ( ! isset( $plugin_attributes['has_button'] ) ) {
                        continue;
                    }
                    if ( ! $plugin_attributes['has_button'] ) {
                        continue;
                    }

                    // Add Button
                    $buttons[] = $plugin_name;
                }
                break;
        }

        // Register TinyMCE Buttons
        foreach ( $shortcodes as $shortcode => $properties ) {
            $buttons[] = 'page_generator_pro_' . str_replace( '-', '_', $shortcode );
        }

        /**
         * Defines the TinyMCE Buttons to register
         *
         * @since   1.0.0
         *
         * @param   array   $plugins    TinyMCE Plugins
         * @param   array   $screen     Screen and Section
         * @param   array   $shortcodes Shortcodes
         */
    	$buttons = apply_filters( 'page_generator_pro_editor_register_tinymce_buttons', $buttons, $screen, $shortcodes );

        // Return filtered results
        return $buttons;

    }

    /**
     * Returns an array of TinyMCE Plugins that aren't shortcodes/blocks,
     * such as Autocomplete and Generate Spintax from Selected Text
     *
     * @since   2.8.9
     *
     * @param   bool    $minified           Whether to load minified versions
     * @return  array                       TinyMCE Plugins
     */
    private function get_tinymce_plugins( $minified = true ) {

        // Define Plugins
        $plugins = array(
            'page_generator_pro_autocomplete'       => array(
                'js'        => $this->base->plugin->url . 'assets/js/' . ( $minified ? 'min/' : '' ) . 'tinymce-autocomplete' . ( $minified ? '-min' : '' ) . '.js',
                'has_button'=> false,
            ),
            'page_generator_pro_research'   => array(
                'js'        => $this->base->plugin->url . 'assets/js/' . ( $minified ? 'min/' : '' ) . 'tinymce-research' . ( $minified ? '-min' : '' ) . '.js',
                'has_button'=> true,
            ),
            'page_generator_pro_spintax_generate'   => array(
                'js'        => $this->base->plugin->url . 'assets/js/' . ( $minified ? 'min/' : '' ) . 'tinymce-spintax-generate' . ( $minified ? '-min' : '' ) . '.js',
                'has_button'=> true,
            ),
        );

        /**
         * Returns an array of TinyMCE Plugins that aren't shortcodes/blocks,
         * such as Autocomplete and Generate Spintax from Selected Text
         *
         * @since   2.8.9
         *
         * @param  array   $plugins     TinyMCE Plugins
         */
        $plugins = apply_filters( 'page_generator_pro_editor_get_tinymce_plugins', $plugins );

        // Return
        return $plugins;

    }

    /**
     * Determines whether TinyMCE Plugins should be registered, by checking if the
     * user is editing a Content Group in the WordPress Admin or a Frontend Page Builder
     *
     * @since   2.5.7
     *
     * @param   array   $screen     Screen and Section
     * @return  mixed               false
     */
    private function should_register_tinymce_plugins( $screen ) {

        // Set a flag to denote whether we should register TinyMCE Plugins
        $should_register_tinymce_plugins = false;

        // Depending on the screen we're on, define the Plugins that we should register
        if ( $screen['screen'] == 'post' && $screen['section'] == 'edit' ) {
            // Only register Shortcodes where register_on_generation_only = false
            $should_register_tinymce_plugins = true;
        } elseif ( $screen['screen'] == 'content_groups' && $screen['section'] == 'edit' ) {
            // Register all Shortcodes
            $should_register_tinymce_plugins = true;
        } elseif ( $screen['screen'] == 'content_terms' && $screen['section'] == 'edit' ) {
            // Register all Shortcodes
            $should_register_tinymce_plugins = true;
        }

        /**
         * Set a flag to denote whether we should register TinyMCE Plugins
         *
         * @since   2.2.4
         *
         * @param   bool   $should_register_tinymce_plugins    Should Register TinyMCE Plugins
         */
        $should_register_tinymce_plugins = apply_filters( 'page_generator_pro_editor_should_register_tinymce_plugins', $should_register_tinymce_plugins );

        // Return
        return $should_register_tinymce_plugins;

    }

    /**
     * Returns the singleton instance of the class.
     *
     * @since       1.1.6
     * @deprecated  1.9.8
     *
     * @return      object Class.
     */
    public static function get_instance() {

        // Define class name
        $name = 'editor';

        // Warn the developer that they shouldn't use this function.
        _deprecated_function( __FUNCTION__, '1.9.8', 'Page_Generator_Pro()->get_class( \'' . $name . '\' )' );

        // Return the class
        return Page_Generator_Pro()->get_class( $name );

    }

}