<?php

if (! defined('ABSPATH')) {
    die('No direct access.');
}

/**
 * Vimeo Slide
 */
class MetaVimeoSlide extends MetaSlide
{

    public $identifier = "vimeo"; // should be lowercase, one word (use underscores if needed)
    public $name;
    private $slide_settings;

    /**
     * Register slide type
     */
    public function __construct()
    {
        $this->name = __("Vimeo", 'ml-slider-pro');

        if (is_admin()) {
            add_filter("media_upload_tabs", array($this, 'custom_media_upload_tab_name'), 999, 1);
            add_action("media_upload_{$this->identifier}", array($this, 'get_iframe'));
            add_action("wp_ajax_create_{$this->identifier}_slide", array($this, 'ajax_create_slide'));
            add_action("wp_ajax_update_{$this->identifier}_thumbnail", array($this, 'ajax_update_thumbnail'));
            add_action("wp_ajax_duplicate_{$this->identifier}_slide", array($this, 'ajax_duplicate_slide'));
            add_action("metaslider_register_admin_styles", array($this, 'register_admin_styles'), 10, 1);
            add_action('metaslider_register_admin_components', array($this, 'add_components'));
        }

        add_action("metaslider_save_{$this->identifier}_slide", array($this, 'save_slide'), 5, 3);
        add_action("metaslider_save_{$this->identifier}_slide", array($this, 'update_slide_thumb'), 4, 3);
        add_filter("metaslider_get_{$this->identifier}_slide", array($this, 'get_slide'), 10, 2);
    }

    /**
     * Custom CSS Styling for vimeo slides
     */
    public function register_admin_styles()
    {
        wp_enqueue_style(
            "metasliderpro-{$this->identifier}-style",
            plugins_url('assets/style.css', __FILE__),
            false,
            METASLIDERPRO_VERSION
        );
    }

    /**
     * Add inline styles used by videos
     * 
     * @since 2.37
     */
    public function add_extra_styles()
    {
        $css = '.metaslider .vimeo iframe{opacity:0;transition:opacity 0.5s ease-in-out}.metaslider .vimeo.video-loaded iframe{opacity:1}.metaslider .vimeo .play_button{position:absolute;top:0;left:0;width:100%;height:100%;display:flex;align-items:center;justify-content:center}.metaslider .vimeo .play_button img{width:75px;cursor:pointer;opacity:0.8}.metaslider .vimeo .play_button img:hover{opacity:1}';
        $css = apply_filters('metaslider_vimeo_inline_css', $css, $this->slide, $this->slider->ID);
        wp_add_inline_style('metaslider-public', $css);
    }

    public function add_components()
    {
        wp_enqueue_script(
            "metasliderpro-{$this->identifier}-admin-script",
            plugins_url('assets/admin.js', __FILE__),
            array('jquery'),
            METASLIDERPRO_VERSION
        );
        wp_localize_script(
            "metasliderpro-{$this->identifier}-admin-script",
            'metaslider_vimeo',
            array(
                'nonce' => wp_create_nonce('vimeo-slide-nonce'),
                'duplicate_slide_nonce' => wp_create_nonce( "metaslider_duplicate_{$this->identifier}_nonce" ) 
            )
        );
    }

    /**
     * Saving the new settings
     *
     * @param int $slide_id Slide ID
     * @param int $slider_id Slider ID
     * @param array $fields Fields saved
     *
     * @return void;
     */
    public function update_slide_thumb($slide_id, $slider_id, $fields)
    {
        $vimeo_url = sanitize_url($fields['vimeo_url']);

        $current_url = get_post_meta($slide_id, 'ml-slider_vimeo_url', true);
        if ($vimeo_url === $current_url) {
            return;
        }

        preg_match(
            '%^https?:\/\/(?:www\.|player\.)?vimeo.com\/(?:channels\/(?:\w+\/)?|groups\/([^\/]*)\/videos\/|album\/(\d+)\/video\/|video\/|)(\d+)(?:$|\/|\#?)(?:[?]?.*)$%im',
            $vimeo_url,
            $match
        );
        $video_id = $match[3];

        // Continuing, since the url has changed...
        $media_id = $this->create_slide_thumb($video_id, 999);

        // Set the image to the slide
        set_post_thumbnail($slide_id, $media_id);
    }

    /**
     * Extract the slide setings
     *
     * @param integer $id Slide ID
     */
    public function set_slide($id)
    {
        parent::set_slide($id);
        $this->slide_settings = get_post_meta($id, 'ml-slider_settings', true);
    }

    /**
     * Add extra tabs to the default wordpress Media Manager iframe
     *
     * @param array $tabs existing media manager tabs
     * @return array
     */
    public function custom_media_upload_tab_name($tabs)
    {
        // restrict our tab changes to the MetaSlider plugin page
        if ((isset($_GET['page']) && $_GET['page'] == 'metaslider') ||
            (isset($_GET['tab']) && in_array($_GET['tab'], array($this->identifier)))) {
            $newtabs = array(
                $this->identifier => $this->name
            );

            return array_merge($tabs, $newtabs);
        }

        return $tabs;
    }

    /**
     * Create a new slide and echo the admin HTML
     */
    public function ajax_create_slide()
    {
        if (! isset($_POST['nonce']) || ! wp_verify_nonce(sanitize_key($_POST['nonce']), 'vimeo-slide-nonce')) {
            wp_send_json_error(esc_html__('Invalid nonce', 'ml-slider-pro'), 403);
        }

        if (! isset($_POST['slider_id']) || ! isset($_POST['video_id'])) {
            wp_send_json_error(esc_html__('Bad request', 'ml-slider-pro'), 400);
        }

        $slider_id = intval($_POST['slider_id']);
        $fields['menu_order'] = 9999;
        $fields['video_id'] = sanitize_text_field($_POST['video_id']);
        $fields['settings']['controls'] = "on";
        
        $new_slide_id = $this->create_slide($slider_id, $fields);
        
        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
        $html = $this->get_admin_slide();

        $result = array(
            'slide_id' => $new_slide_id,
            'html' => $html
        );

        if ( is_wp_error( $result ) ) {
            wp_send_json_error( array(
                'message' => $result->get_error_message()
            ), 409 );
        }
        
        wp_send_json_success ( $result, 200 );
    }

    /**
     * Update the slide's thumbnail
     */
    public function ajax_update_thumbnail()
    {
        if (! isset($_POST['nonce']) || ! wp_verify_nonce(sanitize_key($_POST['nonce']), 'vimeo-slide-nonce')) {
            wp_send_json_error(esc_html__('Invalid nonce', 'ml-slider-pro'), 403);
        }

        if (! isset($_POST['video_id']) || ! isset($_POST['slide_id'])) {
            wp_send_json_error(esc_html__('Bad request', 'ml-slider-pro'), 400);
        }

        $slide_id = intval( $_POST['slide_id'] );
        $video_id = sanitize_text_field( $_POST['video_id'] );
        $image_id = $this->create_slide_thumb( $video_id, 999 );

        // Update Vimeo URL
        $this->add_or_update_or_delete_meta( $slide_id, 'vimeo_url', "https://www.vimeo.com/{$video_id}" );

        /*
         * Updates database record and thumbnail if selection changed, 
         * assigns it to the slide, crops the image
         */
        update_post_meta( $slide_id, '_thumbnail_id', $image_id );

        // Get cropped images for srcset attribute
        $thumbnail_url_large    = $this->get_intermediate_image_src( 1024, $image_id );
        $thumbnail_url_medium   = $this->get_intermediate_image_src( 768, $image_id );
        $thumbnail_url_small    = $this->get_intermediate_image_src( 240, $image_id );

        wp_send_json_success([
            'slide_id' => $slide_id,
            'thumbnail_url_small' => $thumbnail_url_small,
            'thumbnail_url_medium' => $thumbnail_url_medium,
            'thumbnail_url_large' => $thumbnail_url_large
        ]);
    }

    /**
     * Media Manager tab
     */
    public function vimeo_tab()
    {
        return $this->get_iframe();
    }

    /**
     * Get the thumbnail URL from the vimeo API
     *
     * @param string $id URL ID
     * @return array|bolean
     */
    private function get_thumb_url($id)
    {
        $thumb = new WP_Http();
        $thumb = $thumb->request("http://vimeo.com/api/v2/video/$id.php");

        if (! is_wp_error($thumb) && isset($thumb['body'])) {
            $body = unserialize($thumb['body']);

            if (isset($body[0]['thumbnail_large'])) {
                return $body[0]['thumbnail_large'];
            }
        }

        return false;
    }

    private function create_slide_thumb($video_id, $menu_order)
    {
        $post_info = array(
            'post_title' => "MetaSlider - Vimeo Thumbnail - {$video_id}",
            'post_mime_type' => 'image/jpeg',
            'post_status' => 'inherit',
            'post_content' => '',
            'guid' => "https://www.vimeo.com/{$video_id}",
            'menu_order' => $menu_order,
            'post_name' => $video_id
        );

        $thumb_url = $this->get_thumb_url($video_id);

        $vimeo_thumb = false;

        if ($thumb_url) {
            $vimeo_thumb = new WP_Http();
            $vimeo_thumb = $vimeo_thumb->request($thumb_url);
        }

        if (
            ! is_wp_error($vimeo_thumb)
            && isset($vimeo_thumb['response']['code'])
            && $vimeo_thumb['response']['code'] == 200
        ) {
            $attachment = wp_upload_bits("vimeo_{$video_id}.jpg", null, $vimeo_thumb['body']);
            $filename = $attachment['file'];
            $media_id = wp_insert_attachment($post_info, $filename);

            if (! function_exists('wp_generate_attachment_metadata')) {
                include( ABSPATH . 'wp-admin/includes/image.php' );
            }

            $attach_data = wp_generate_attachment_metadata($media_id, $filename);
            wp_update_attachment_metadata($media_id, $attach_data);

            return $media_id;
        }

        return wp_insert_attachment($post_info);
    }

    /**
     * Create a new vimeo slide
     *
     * @param integer $slider_id Slider ID
     * @param array $fields Array of slide fields
     * @return integer
     */
    public function create_slide($slider_id, $fields)
    {
        $this->set_slider($slider_id);

        $media_id = $this->create_slide_thumb($fields['video_id'], $fields['menu_order']);
        $slide_id = null;


        if (method_exists($this, 'insert_slide')) {
            $slide_id = $this->insert_slide($media_id, $this->identifier, $slider_id);
            $this->add_or_update_or_delete_meta(
                $slide_id,
                'vimeo_url',
                "https://www.vimeo.com/{$fields['video_id']}"
            );
        } else {
            $this->add_or_update_or_delete_meta($media_id, 'type', $this->identifier);
        }

        $this->set_slide(! is_null($slide_id) ? $slide_id : $media_id);
        $this->tag_slide_to_slider();
        $this->save($fields);
        return ! is_null($slide_id) ? $slide_id : $media_id;
    }

    /**
     * Admin slide html
     *
     * @return string html
     */
    protected function get_admin_slide()
    {
        $thumb = "";

        // only show a thumbnail if we managed to download one when the slide was created
        if (get_post_thumbnail_id($this->slide->ID)) {// new slide format
            $thumb = $this->get_thumb();
        } else {
            if (strlen(get_attached_file($this->slide->ID))) {
                $thumb = $this->get_thumb();
            }
        }

        ob_start();
        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
        echo $this->get_delete_button_html();
        // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
        echo $this->get_update_image_button_html();
        if( method_exists( $this, 'get_duplicate_slide_button_html' ) ) {
            echo $this->get_duplicate_slide_button_html(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
        }
        do_action('metaslider-slide-edit-buttons', $this->identifier, $this->slide->ID);
        $edit_buttons = ob_get_clean();

        $row = "<tr id='slide-" . esc_attr($this->slide->ID) . "' class='slide " . esc_attr($this->identifier) . " flex responsive'>";
        $row .= "    <td class='col-1'>";
        $row .= "       <div class='metaslider-ui-controls ui-sortable-handle'>";
        $row .= "           <h4 class='slide-details'>";
        $row .= "<span class='vimeo'>Vimeo Slide</span> | ID: ". esc_html( $this->slide->ID );
        $row .= "           </h4>";
        if (metaslider_this_is_trash($this->slide)) {
            $row .= '<div class="row-actions trash-btns">';
            $row .= "<span class='untrash'>{$this->get_undelete_button_html()}</span>";
            if( method_exists( $this, 'get_permanent_delete_button_html' ) ) {
                $row .= ' | ';
                $row .= "<span class='delete'>{$this->get_permanent_delete_button_html()}</span>";
            }
            $row .= '</div>';
        } else {
            $row .= $edit_buttons;
        }
        $row .= "       </div>";
        $row .= "    </td>";
        $row .= "    <td class='col-2'>";
        $row .= "       <div class='metaslider-ui-inner flex flex-col h-full'>";

        if (method_exists($this, 'get_admin_slide_tabs_html')) {
            $row .= $this->get_admin_slide_tabs_html();
        } else {
            $row .= "<p>" . esc_html__("Please update to MetaSlider to version 3.2 or above.", "ml-slider-pro") . "</p>";
        }

        $row .= "        <input type='hidden' name='attachment[" . esc_attr($this->slide->ID) . "][type]' value='vimeo' />";
        $row .= "        <input type='hidden' class='menu_order' name='attachment[" . esc_attr($this->slide->ID) . "][menu_order]' value='" . esc_attr($this->slide->menu_order) . "' />";
        $row .= "       </div>";
        $row .= "    </td>";
        $row .= "</tr>";

        return $row;
    }


    /**
     * Build an array of tabs and their titles to use for the admin slide.
     */
    public function get_admin_tabs()
    {
        $path = trailingslashit( plugin_dir_path( __FILE__ ) ) . 'tabs/';
        
        ob_start();
        include $path . 'general.php';
        $general_tab = ob_get_clean();

        $tabs = array(
            'general' => array(
                'title' => __("General", "ml-slider-pro"),
                'content' => $general_tab
            )
        );

        $global_settings = $this->get_global_settings();
        if (
            !isset($global_settings['mobileSettings']) ||
            (isset($global_settings['mobileSettings']) && true == $global_settings['mobileSettings'])
        ) {
            ob_start();
            include $path . 'mobile.php';
            $mobile_tab = ob_get_clean();

            $tabs['mobile'] = array(
                'title' => __("Mobile", "ml-slider"),
                'content' => $mobile_tab
            );
        }
    
        return apply_filters("metaslider_vimeo_slide_tabs", $tabs, $this->slide, $this->slider, $this->settings);
    }

    /**
     * Public slide html
     *
     * @return string html
     */
    protected function get_public_slide()
    {
        wp_enqueue_script(
            'metasliderpro-vimeo-api',
            METASLIDERPRO_BASE_URL . 'node_modules/@vimeo/player/dist/player.js',
            array(),
            METASLIDERPRO_VERSION
        );

        add_action('metaslider_register_public_styles', array($this, 'add_extra_styles'), 10, 2);

        $settings = get_post_meta($this->slider->ID, 'ml-slider_settings', true);

        if (get_post_meta($this->slide->ID, 'ml-slider_vimeo_url', true)) {
            $url = get_post_meta($this->slide->ID, 'ml-slider_vimeo_url', true);
        } else {
            $url = $this->slide->guid;
        }

        sscanf(parse_url($url, PHP_URL_PATH), '/%d', $video_id); // get the video ID

        if (! (int)$this->settings['height'] || ! (int)$this->settings['width']) {
            $ratio = 9 / 16 * 100;
        } else {
            $ratio = $this->settings['height'] / $this->settings['width'] * 100;
        }


        if ($this->settings['type'] == 'responsive') {
            add_filter(
                'metaslider_responsive_slider_parameters',
                array($this, 'get_responsive_slider_parameters'),
                10,
                2
            );
            add_filter(
                'metaslider_responsive_slider_javascript',
                array($this, 'get_responsive_vimeo_javascript'),
                10,
                2
            );

            return $this->get_responsive_slides_markup($video_id, $settings, $ratio);
        }

        if ($this->settings['type'] == 'flex') {
            add_filter('metaslider_flex_slider_parameters', array($this, 'get_flex_slider_parameters'), 10, 2);

            return $this->get_flex_slider_markup($video_id, $settings, $ratio);
        }
    }

    /**
     * Build the Vimeo iFrame URL based on the slide settings
     *
     * @param integer $video_id Video ID
     * @return string
     */
    public function get_vimeo_iframe_url($video_id)
    {
        $url = "https://player.vimeo.com/video/{$video_id}?player_id=vimeo_{$this->slide->ID}";

        foreach (array('byline', 'title', 'portrait', 'loop', 'controls') as $param) {
            // Backward compatibility 2.21 and below
            if( $param == 'controls' ) {
                if( ! isset( $this->slide_settings[$param] ) || $this->slide_settings[$param] == 'on' ) {
                    $param_value = 1;
                } else {
                    $param_value = 0;
                }
            } else {
                $param_value = isset( $this->slide_settings[$param] ) ? $this->slide_settings[$param] : 0;
            }
            $param_value = filter_var($param_value, FILTER_VALIDATE_BOOLEAN) ? '1' : '0';

            $url .= "&{$param}={$param_value}";
        }

        // this filter applied before HTTPS was added directly to the url
        // $url = apply_filters( 'metaslider_vimeo_params', $url, $this->slider->ID, $this->slide->ID );
        $url = apply_filters('metaslider_vimeo_url', $url, $this->slider->ID, $this->slide->ID);

        return $url;
    }

    /**
     * Return the slide HTML
     *
     * @param integer $video_id Video ID
     * @param array $settings Slider settings
     * @param float $ratio Slider ratio
     * @return string
     */
    public function get_responsive_slides_markup($video_id, $settings, $ratio)
    {
        $url = $this->get_vimeo_iframe_url($video_id);
        $autoPlay = isset($this->slide_settings['autoPlay']) && $this->slide_settings['autoPlay'] == 'on' ? '1' : '0';
        $muted = isset($this->slide_settings['mute']) ? (int)filter_var(
            $this->slide_settings['mute'],
            FILTER_VALIDATE_BOOLEAN
        ) : 0;

        $html = sprintf("<div style='position:relative;padding-bottom:%s%%;height:0'>", $ratio);
        $html .= "<iframe class='vimeo' data-muted='{$muted}' data-vimeo-autoplay='{$autoPlay}' id='vimeo_{$this->slide->ID}' data-vimeo-width='{$settings['width']}' data-vimeo-height='{$settings['height']}' src='{$url}' frameborder='0' allowfullscreen></iframe>";
        $html .= "</div>";

        return $html;
    }

    /**
     * Return the slide HTML
     *
     * @param integer $video_id Video ID
     * @param array $settings Slider settings
     * @param float $ratio Slider ratio
     * @return string
     */
    public function get_flex_slider_markup($video_id, $settings, $ratio)
    {
        $url = $this->get_vimeo_iframe_url($video_id);
        $autoPlay = isset($this->slide_settings['autoPlay']) ? (int)filter_var(
            $this->slide_settings['autoPlay'],
            FILTER_VALIDATE_BOOLEAN
        ) : 0;
        $muted = isset($this->slide_settings['mute']) ? (int)filter_var(
            $this->slide_settings['mute'],
            FILTER_VALIDATE_BOOLEAN
        ) : 0;

        $lazyLoad = 0;
        if ( isset( $this->slide_settings['lazyLoad'] ) 
            && filter_var( $this->slide_settings['lazyLoad'], FILTER_VALIDATE_BOOLEAN ) 
        ) {
            $lazyLoad = 1;
        }

        $div_attrs = array(
            'id' => "vimeo_{$this->slide->ID}",
            'class' => 'vimeo',
            'style' => sprintf( "position:relative;padding-bottom:%s%%;height:0", $ratio ),
            'data-id' => $video_id,
            'data-muted' => $muted,
            'data-autoplay' => $autoPlay,
            'data-lazy-load' => $lazyLoad,
            'data-slide-id' => $this->slide->ID,
            'data-url' => $url,
            'data-width' => $settings['width'],
            'data-height' => $settings['height']
        );

        $html = "<div";
        foreach ( $div_attrs as $key => $value ) {
            $html .= " " . $key . '="' . $value . '"';
        }
        $html .= ">";

        if ( $lazyLoad ) {
            $html .= $this->temporary_video_image();
        }
        
        $html .= "</div>";

        // store the slide details
        $attributes = array(
            'class' => "slide-{$this->slide->ID} ms-vimeo {$this->get_mobile_css_class($this->slide->ID)}",
            'style' => "display: none; width: 100%;"
        );

        // Custom delay
        $autoPlay = isset( $this->slide_settings['autoPlay'] ) ? (int)filter_var(
            $this->slide_settings['autoPlay'],
            FILTER_VALIDATE_BOOLEAN
        ) : 0;
        $is_delayed = (bool) get_post_meta( $this->slide->ID, '_meta_slider_slide_is_delayed', true );
        $delay_time = (int) get_post_meta( $this->slide->ID, '_meta_slider_slide_delayed_time', true );
        
        if ( filter_var( $this->settings['autoPlay'], FILTER_VALIDATE_BOOLEAN ) 
            && $is_delayed && $delay_time > 0 && ! $autoPlay 
        ) {
            $attributes['data-custom-delay'] = $delay_time;
        }
        
        $attributes = apply_filters(
            'metaslider_flex_slider_li_attributes',
            $attributes,
            $this->slide->ID,
            $this->slider->ID,
            $this->settings
        );

        $slide = "<li";
        foreach ($attributes as $att => $val) {
            $val = esc_attr($val);
            $slide .= " {$att}='{$val}'";
        }
        $slide .= ">{$html}</li>";

        return $slide;
    }

    /**
     * Get image placeholder with play button
     *
     * @since 2.37
     * 
     * @return string
     */
    public function temporary_video_image()
    {
        $imageHelper = new MetaSliderImageHelper(
            $this->slide->ID,
            $this->settings['width'],
            $this->settings['height'],
            isset($this->settings['smartCrop']) ? $this->settings['smartCrop'] : 'false'
        );
        $url = $imageHelper->get_image_url();

        $image_attributes = array(
            'src' => $url,
            'alt' => '', // @TODO - We need an alt
            'title' => '',
            'class' => 'msDefaultImage',
            'height' => $this->settings['height'],
            'width' => $this->settings['width']
        );

        $html = $this->build_image_tag( $image_attributes );

        $play_button_url = apply_filters(
            'metaslider_vimeo_play_button',
            METASLIDERPRO_BASE_URL . "modules/vimeo/assets/play-button.png",
            $this->slide,
            $this->slider->ID
        );
        $html .= "<span class='play_button'><a tabindex='0' role='button' id='toggle'><img width='75' src='{$play_button_url}'></a></span>";

        return $html;
    }

    /**
     * JavaScript to handle video interaction
     *
     * @deprecated 2.37 - Relevant code moved to get_flex_slider_parameters()
     * 
     * @param string $javascript Video Javascript
     * @param integer $slider_id Slider ID
     * @return string
     */
    public function get_flex_vimeo_javascript($javascript, $slider_id)
    {
        $loopContinuously_pause = "";

        // @since 2.36 - Change animation CSS value when Carousel and Loop Continuously are enabled
        if ( isset( $this->settings['carouselMode'] ) && $this->settings['carouselMode'] == 'true' 
            && isset( $this->settings['infiniteLoop'] ) && $this->settings['infiniteLoop'] == 'true'
        ) {
            $loopContinuously_pause = "$('#metaslider_{$slider_id} .slides').css('animation-play-state', '');";
        }

        // This is for the slideshow autoplay, not the video autoplay.
        // This will play the slideshow when the video is paused
        $autoplay = filter_var($this->settings['autoPlay'], FILTER_VALIDATE_BOOLEAN) ?
            "player.on('ended', function() {
				$('#metaslider_{$slider_id} .slides > li').removeClass('video-playing');
				$('#metaslider_{$slider_id}').data('flexslider').manualPause = false;
            	$('#metaslider_{$slider_id}').flexslider('next');
            	$('#metaslider_{$slider_id}').flexslider('play');
			});
			player.on('pause', function() {
				$('#metaslider_{$slider_id} .slides > li').removeClass('video-playing');
				$('#metaslider_{$slider_id}').data('flexslider').manualPause = false;
				{$loopContinuously_pause}
			})" : '';

        // Pause the slideshow if the options are to autoplay and mute the video,
        // It's paused more liberally later on when play event is fired, but this
        // is more reliable if the Vimeo API is slow. This also mutes the video if needed
        $html = "$('#metaslider_{$slider_id} iframe.vimeo').each(function(i) {

			if ($(this).closest('li').hasClass('flex-active-slide')) {
				if ($(this).data('vimeoAutoplay') && $(this).data('muted')) {
					$('#metaslider_{$slider_id}').flexslider('pause');
				}
			}

			var video = document.getElementById($(this).attr('id'));
			window['player_{$slider_id}_' + $(this).attr('id')] = new Vimeo.Player(video);

			var player = window['player_{$slider_id}_' + $(this).attr('id')];
			$(this).data('muted') && player.setVolume(0);

			{$autoplay}
		});";

        // we don't want this filter hanging around if there's more than one slideshow on the page
        remove_filter('metaslider_flex_slider_javascript', array($this, 'get_flex_vimeo_javascript'));

        return $javascript . $html;
    }

    /**
     * Modify the flex slider parameters when a vimeo slide has been added
     *
     * @param array $options Slider options
     * @param integer $slider_id Slider ID
     * @return array
     */
    public function get_flex_slider_parameters($options, $slider_id)
    {
        $addActiveClass         = "";
        $loopContinuously_play  = "";

        $options['useCSS'] = 'false';

        $loopContinuously_pause = "";

        // @since 2.36 - Change animation CSS value when Carousel and Loop Continuously are enabled
        if ( isset( $this->settings['carouselMode'] ) && $this->settings['carouselMode'] == 'true' 
            && isset( $this->settings['infiniteLoop'] ) && $this->settings['infiniteLoop'] == 'true'
        ) {
            $loopContinuously_pause = "$('#metaslider_{$slider_id} .slides').css('animation-play-state', '');";
        }

        // This is for the slideshow autoplay, not the video autoplay.
        // This will play the slideshow when the video is paused
        $autoplay = filter_var($this->settings['autoPlay'], FILTER_VALIDATE_BOOLEAN) 
            ? "player.on('ended', function() {
				$('#metaslider_{$slider_id} .slides > li').removeClass('video-playing');
                $('#metaslider_{$slider_id}').data('flexslider').manualPause = false;
                $('#metaslider_{$slider_id}').flexslider('next');
            	$('#metaslider_{$slider_id}').flexslider('play');
			});
			player.on('pause', function() {
				$('#metaslider_{$slider_id} .slides > li').removeClass('video-playing');
                $('#metaslider_{$slider_id}').data('flexslider').manualPause = false;
                {$loopContinuously_pause}
			})" 
            // Slideshow Autoplay disabled
            : "player.on('ended', function() {
				$('#metaslider_{$slider_id} .slides > li').removeClass('video-playing');
			});
			player.on('pause', function() {
                $('#metaslider_{$slider_id} .slides > li').removeClass('video-playing');
			})";

        // @since 2.36 - Change animation CSS value when Carousel and Loop Continuously are enabled
        if ( isset( $this->settings['carouselMode'] ) && $this->settings['carouselMode'] == 'true' 
            && isset( $this->settings['infiniteLoop'] ) && $this->settings['infiniteLoop'] == 'true'
        ) {
            $loopContinuously_play  = "$('#metaslider_{$slider_id} .slides').css('animation-play-state', 'paused');";
        }

        // Add active slide class when carousel mode is enabled
        if ( 'true' == $this->settings['carouselMode'] ) {
            $addActiveClass = "$(slider).find('.slides > li').removeClass('flex-active-slide').eq(slider.currentSlide).addClass('flex-active-slide');";
        }

        // Before a slide transitions
        $options['before'] = isset($options['before']) ? $options['before'] : array();
        $options['before'] = array_merge($options['before'], array(
            "$('#metaslider_{$slider_id} .flex-active-slide .vimeo').each(function(index) {
                var id = $(this).attr('id');

                if(typeof window['player_{$slider_id}_' + id] === 'undefined') return;

				var player = window['player_{$slider_id}_' + id];
                console.log('before',player);

                $(this).data('muted') && player.setVolume(0);
				player.pause();
			});"
        ));

        // After a slide transitions
        $options['after'] = isset($options['after']) ? $options['after'] : array();
        $options['after'] = array_merge($options['after'], array(
            "{$addActiveClass}

            $('#metaslider_{$slider_id} .flex-active-slide .vimeo').each(function(index) {
				var id = $(this).attr('id');
                
                if($(this).data('autoplay')) { 
                    $('#metaslider_{$slider_id}').flexslider('pause');

                    if ( $(this).data('lazyLoad') && typeof window['player_{$slider_id}_' + id] === 'undefined') {
                        $(this).trigger('click');
                    } else {
                        var player = window['player_{$slider_id}_' + id];
                        player.setVolume(0);
                        player.play();
                    }
                }
			});"
        ));

        // When the slideshow is loaded
        $options['start'] = isset($options['start']) ? $options['start'] : array();
        $options['start'] = array_merge($options['start'], array(
            "{$addActiveClass}
            $('#metaslider_{$slider_id} .ms-vimeo:not(.clone) .vimeo').each(function() {
                var vimeo = $(this);
                var active = vimeo.parent('.flex-active-slide').length;
                var autoplay = vimeo.data('autoplay') && active ? true : false;
                var lazyload = vimeo.data('lazyLoad');
                var slideId = vimeo.data('slideId');
                var id = vimeo.attr('id');
				
                var eventType = vimeo.data('lazyLoad') ? 'click' : 'metaslider/load-vimeo-video';
                
                vimeo.on(eventType, function() {
                    if(typeof window['player_{$slider_id}_' + id] === 'undefined') {
                        $(this).append(function() {
                            var iframe = $('<iframe>', {
                                frameborder: 0,
                                allowfullscreen: true,
                                src: $(this).data('url')
                            });

                            iframe.attr('width', $(this).data('width'));
                            iframe.attr('height', $(this).data('height'));
                        
                            return iframe;
                        });

                        window['player_{$slider_id}_' + id] = new Vimeo.Player($('#vimeo_' + slideId + ' iframe'));
                        var player = window['player_{$slider_id}_' + id];

                        vimeo.data('muted') && player.setVolume(0);

                        if (active && autoplay) {
                            $('#metaslider_{$slider_id}').flexslider('pause');
                            player.setVolume(0);
                            player.play();
                        }

                        player.on('loaded', function() {
                            vimeo.addClass('video-loaded');
                            if (eventType === 'click') player.play();
                        });

                        player.on('play', function() {
                            $('#metaslider_{$slider_id} .flex-active-slide').addClass('video-playing');
                            $('#metaslider_{$slider_id}').flexslider('pause');
                            $('#metaslider_{$slider_id}').data('flexslider').manualPause = true;
                            $('#metaslider_{$slider_id}').data('flexslider').manualPlay = false;
                            {$loopContinuously_play}
                        });

                        {$autoplay}
                    }
                });
                if (lazyload && autoplay) $(this).trigger(eventType);
                lazyload || $(this).trigger('metaslider/load-vimeo-video');
			});"
        ));

        // We don't want this filter hanging around if there's more than one slideshow on the page
        remove_filter('metaslider_flex_slider_parameters', array($this, 'get_flex_slider_parameters'));
        return $options;
    }

    /**
     * JavaScript to handle video interaction
     *
     * @param string $javascript Vimeo Javascript
     * @param integer $slider_id Slider ID
     * @return string
     */
    public function get_responsive_vimeo_javascript($javascript, $slider_id)
    {
        $autoplay = filter_var($this->settings['autoPlay'], FILTER_VALIDATE_BOOLEAN) ? 'true' : 'false';

        $html = "$('#metaslider_{$slider_id} iframe.vimeo').each(function() {
				var autoplay = false;
				var vimeo = $(this);
				var video = document.getElementById(vimeo.attr('id'));
				window['player_{$slider_id}_' + vimeo.attr('id')] = new Vimeo.Player(video);
				var player = window['player_{$slider_id}_' + vimeo.attr('id')];

				/* Set to mute */
				vimeo.data('muted') && player.setVolume(0);

				if ({$autoplay}) {
					if (vimeo.parents('.rslides1_on').length) {

						/* When video loads */
						player.on('loaded', function () {
							player.play();
						});

						/* When video ends */
						player.on('ended', function() {
							vimeo.trigger('mouseleave');
						});

						/* When video is paused manually  */
						player.on('pause', function() {
							/* I think the best approach is to just do nothing */
							/* The slideshow will autoplay if the mouse leaves */
							/* If more functionality is needed, use FlexSlider */
						});

						/* If first slide, pause slideshow before loaded event
						if (vimeo.closest('li').hasClass('rslides1_on')) {

							/* ... only if muted & autoplay */
							if (vimeo.data('vimeoAutoplay') && vimeo.data('muted')) {
								vimeo.trigger('mouseenter');
							}
						}

						/* Pause the slideshow */
						player.on('play', function () {
							vimeo.trigger('mouseenter');
						});
				}
			});";

        // we don't want this filter hanging around if there's more than one slideshow on the page
        remove_filter('metaslider_responsive_slider_javascript', array($this, 'get_responsive_vimeo_javascript'));

        return $javascript . $html;
    }

    /**
     * Modify the reponsive slider parameters when a vimeo slide has been added
     *
     * @param array $options Slider options
     * @param string $slider_id Slider ID
     * @return array
     */
    public function get_responsive_slider_parameters($options, $slider_id)
    {
        // If autoslide is true for the slideshow, we have to fake it
        // trigger('mouseenter') and trigger('mouseleave')
        if (filter_var($this->settings['autoPlay'], FILTER_VALIDATE_BOOLEAN)) {
            $options["pause"] = 'true';
        }

        $options['before'] = isset($options['before']) ? $options['before'] : array();
        $options['before'] = array_merge($options['before'], array(
            "$('#metaslider_{$slider_id} iframe.vimeo').each(function(index) {
				var player = window['player_{$slider_id}_' + $(this).attr('id')];
				player.pause();
			});"
        ));

        $options['after'] = isset($options['after']) ? $options['after'] : array();
        $options['after'] = array_merge($options['after'], array(
            "$('#metaslider_{$slider_id} .rslides1_on iframe.vimeo[data-vimeo-autoplay=1]').each(function(index) {
				var player = window['player_{$slider_id}_' + $(this).attr('id')];
				$(this).data('vimeoAutoplay') && player.play();
			});"
        ));

        // We don't want this filter hanging around if there's more than one slideshow on the page
        remove_filter('metaslider_responsive_slider_parameters', array($this, 'get_responsive_slider_parameters'));
        return $options;
    }

    /**
     * Return wp_iframe
     */
    public function get_iframe()
    {
        return wp_iframe(array($this, 'iframe'));
    }

    /**
     * Media Manager iframe HTML
     */
    public function iframe()
    {
        do_action("metaslider_vimeo_iframe");

        wp_enqueue_style('media-views');
        wp_enqueue_style(
            "metasliderpro-{$this->identifier}-styles",
            plugins_url('assets/style.css', __FILE__),
            false,
            METASLIDERPRO_VERSION
        );
        wp_enqueue_script(
            "metasliderpro-{$this->identifier}-script",
            plugins_url('assets/script.js', __FILE__),
            array('jquery'),
            METASLIDERPRO_VERSION
        );
        wp_localize_script("metasliderpro-{$this->identifier}-script", 'metaslider_custom_slide_type', array(
            'identifier' => $this->identifier,
            'name' => $this->name,
            'nonce' => wp_create_nonce('vimeo-slide-nonce'),
        ));

        echo "<div class='metaslider'>
                <div class='vimeo'>
                    <div class='media-embed'>
                        <label class='embed-url'>
                            <span>" . 
                                esc_html__( 'Enter the URL of a Vimeo video:', 'ml-slider-pro' ) . 
                            "</span>
                            <input type='text' placeholder='https://vimeo.com/475593351' class='vimeo_url ms-super-wide'>
                            <span class='spinner' style='display:none'></span>
                        </label>
                        <div class='embed-link-settings'></div>
                    </div>
                </div>
            </div>
            <div class='media-frame-toolbar'>
                <div class='media-toolbar'>
                    <div class='media-toolbar-primary'>
                        <a href='#' class='button media-button button-primary button-large' disabled='disabled'>" . esc_html__(
                "Add to slideshow",
                "ml-slider-pro"
            ) . "</a>
                    </div>
                </div>
            </div>";
    }

    /**
     * Save
     *
     * @param array $fields Fields for adding to menu
     */
    protected function save($fields)
    {
        // Save the url in case it was updated
        if (isset($fields['vimeo_url']) && ! empty($fields['vimeo_url'])) {
            update_post_meta($this->slide->ID, 'ml-slider_vimeo_url', $fields['vimeo_url']);
        }

        // Update the order
        wp_update_post(array(
            'ID' => $this->slide->ID,
            'menu_order' => $fields['menu_order']
        ));
        
        foreach (array('lazyLoad', 'title', 'byline', 'autoPlay', 'portrait', 'controls', 'mute', 'loop') as $setting) {
            if (! isset($fields['settings'][$setting])) {
                $fields['settings'][$setting] = 'off';
            }
        }

        // Save all the settings fields serialized
        if (isset($fields['settings'])) {
            $this->add_or_update_or_delete_meta($this->slide->ID, 'settings', $fields['settings']);
        }

        $this->add_or_update_or_delete_meta(
            $this->slide->ID,
            'hide_slide_smartphone',
            isset($fields['hide_slide_smartphone']) && $fields['hide_slide_smartphone'] === 'on'
        );

        $this->add_or_update_or_delete_meta(
            $this->slide->ID,
            'hide_slide_tablet',
            isset($fields['hide_slide_tablet']) && $fields['hide_slide_tablet'] === 'on'
        );

        $this->add_or_update_or_delete_meta(
            $this->slide->ID,
            'hide_slide_laptop',
            isset($fields['hide_slide_laptop']) && $fields['hide_slide_laptop'] === 'on'
        );

        $this->add_or_update_or_delete_meta(
            $this->slide->ID,
            'hide_slide_desktop',
            isset($fields['hide_slide_desktop']) && $fields['hide_slide_desktop'] === 'on'
        );
    }

    public function duplicate_slide($slideshow_id, $slide_id)
    {
        $old_slide = get_post($slide_id);
        if (!$old_slide) {
            return 0;
        }
        $title = $old_slide->post_title;
        $post_excerpt = '';
        if(isset($old_slide->post_excerpt)){
            $post_excerpt = $old_slide->post_excerpt;
        }
        $new_slide = [
            'post_title'  => $title,
            'post_name'   => sanitize_title($title),
            'post_status' => 'publish',
            'post_type'   => $old_slide->post_type,
            'post_excerpt'   => $post_excerpt
        ];
        $new_slide_id = wp_insert_post($new_slide);
        $slide_meta = get_post_custom($slide_id);
        foreach ($slide_meta as $key => $values) {
            foreach ($values as $value) {
                add_post_meta($new_slide_id, $key, maybe_unserialize($value));
            }
        }
        $taxonomies = get_post_taxonomies($slide_id);
        foreach ($taxonomies as $taxonomy) {
            $term_ids = wp_get_object_terms($slide_id, $taxonomy, ['fields' => 'ids']);
            wp_set_object_terms($new_slide_id, $term_ids, $taxonomy);
        }

        $this->set_slide($new_slide_id);
        $this->set_slider($slideshow_id);

        return array('slide_id' => $new_slide_id, 'html' => $this->get_admin_slide());
    }

    public function ajax_duplicate_slide()
    {
        if ( ! isset( $_POST['nonce'] ) 
            || ! wp_verify_nonce( sanitize_key( $_POST['nonce']), "metaslider_duplicate_{$this->identifier}_nonce" ) 
        ) {
            wp_send_json_error( esc_html__( 'Invalid nonce', 'ml-slider-pro' ), 403 );
        }

        $capability = apply_filters('metaslider_capability', MetaSliderPlugin::DEFAULT_CAPABILITY_EDIT_SLIDES);
        if (! current_user_can($capability)) {
            wp_send_json_error(
                [
                    'message' => __('Access denied', 'ml-slider')
                ],
                403
            );
        }

        if (! isset($_POST['slide_id']) || ! isset($_POST['slider_id'])) {
            wp_send_json_error(
                [
                    'message' => __('Bad request', 'ml-slider'),
                ],
                400
            );
        }

        $result = $this->duplicate_slide(
            absint($_POST['slider_id']),
            absint($_POST['slide_id'])
        );

        wp_send_json_success($result, 200);
    }
}
