<?php
/**
 * Lottie element.
 *
 * @package BricksExtras
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit; // Exit if accessed directly.
}

/**
 * Lottie element class.
 */
class X_Lottie extends \Bricks\Element {

	/**
	 * Element category.
	 *
	 * @var string
	 */
	public $category = 'extras';
	/**
	 * Element name.
	 *
	 * @var string
	 */
	public $name = 'xlottie';
	/**
	 * Element icon.
	 *
	 * @var string
	 */
	public $icon = 'ti-image';
	/**
	 * CSS selector.
	 *
	 * @var string
	 */
	public $css_selector = '';
	/**
	 * Required scripts.
	 *
	 * @var array
	 */
	public $scripts = array( 'xLottie' );
	/**
	 * Script localized flag.
	 *
	 * @var bool
	 */
	private static $script_localized = false;


	/**
	 * Get element label.
	 */
	public function get_label() {
		return esc_html__( 'Lottie', 'bricksextras' );
	}

	/**
	 * Get element keywords.
	 */
	public function get_keywords() {
		return array( 'lottie' );
	}

	/**
	 * Set control groups.
	 */
	public function set_control_groups() {
	}

	/**
	 * Set element controls.
	 */
	public function set_controls() {

		$this->controls['lottieURL'] = array(
			'tab'         => 'content',
			'label'       => 'URL',
			'type'        => 'text',
			'placeholder' => 'https://assets8.lottiefiles.com/packages/lf20_8qDRX7nBln.json',
		);

		$this->controls['width'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Width', 'bricks' ),
			'inline'      => true,
			'type'        => 'number',
			'units'       => true,
			'css'         => array(
				array(
					'selector' => '',
					'property' => 'width',
				),
			),
			'placeholder' => '300px',
		);

		$this->controls['frameStart'] = array(
			'tab'         => 'content',
			'inline'      => true,
			'label'       => esc_html__( 'Start frame', 'bricksextras' ),
			'type'        => 'number',
			'units'       => false,
			'placeholder' => esc_html__( '0', 'bricks' ),
		);

		$this->controls['frameEnd'] = array(
			'tab'         => 'content',
			'inline'      => true,
			'label'       => esc_html__( 'End frame', 'bricksextras' ),
			'type'        => 'number',
			'units'       => false,
			'placeholder' => esc_html__( '60', 'bricks' ),
		);

		$this->controls['speed'] = array(
			'tab'         => 'content',
			'inline'      => true,
			'label'       => esc_html__( 'Speed', 'bricks' ),
			'type'        => 'number',
			'units'       => false,
			'placeholder' => esc_html__( '1', 'bricks' ),
			'required'    => array( 'trigger', '!=', array( 'scroll', 'scrollSelector', 'cursor' ) ),
		);

		$this->controls['interactivitySep'] = array(
			'tab'   => 'content',
			'type'  => 'separator',
			'label' => esc_html__( 'Interactivity', 'bricksextras' ),
		);

		$this->controls['trigger'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Trigger', 'bricks' ),
			'type'        => 'select',
			'options'     => array(
				'viewport'       => esc_html__( 'When visible in viewport', 'bricksextras' ),
				'scroll'         => esc_html__( 'Scroll', 'bricks' ) . ' (' . esc_html__( 'Relative to this element', 'bricksextras' ) . ')',
				'scrollSelector' => esc_html__( 'Scroll', 'bricks' ) . ' (' . esc_html__( 'Relative to another element', 'bricksextras' ) . ')',
				'click'          => esc_html__( 'Click on this element', 'bricksextras' ),
				'clickSelector'  => esc_html__( 'Click on another element', 'bricksextras' ),
				'hover'          => esc_html__( 'Hover over this element', 'bricksextras' ),
				'hoverSelector'  => esc_html__( 'Hover over another element', 'bricksextras' ),
				'cursor'         => esc_html__( 'Cursor position', 'bricksextras' ),
			),
			'default'     => 'click',
			'placeholder' => esc_html__( 'None', 'bricks' ),
		);

		$this->controls['clickElementSelector'] = array(
			'tab'         => 'content',
			'inline'      => true,
			'label'       => esc_html__( 'Selector', 'bricks' ) . ' (' . esc_html__( 'Element', 'bricks' ) . ')',
			'type'        => 'text',
			'placeholder' => '.element-class',
			'required'    => array( 'trigger', '=', 'clickSelector' ),
		);

		$this->controls['reverseClick'] = array(
			'tab'      => 'content',
			'inline'   => true,
			'small'    => true,
			'label'    => esc_html__( 'Reverse on second click', 'bricksextras' ),
			'type'     => 'checkbox',
			'required' => array( 'trigger', '=', array( 'click', 'clickSelector' ) ),
		);

		$this->controls['scrollElementSelector'] = array(
			'tab'         => 'content',
			'inline'      => true,
			'label'       => esc_html__( 'Selector', 'bricks' ) . ' (' . esc_html__( 'Element', 'bricks' ) . ')',
			'type'        => 'text',
			'placeholder' => '.container-class',
			'required'    => array( 'trigger', '=', 'scrollSelector' ),
		);

		$this->controls['hoverSelector'] = array(
			'tab'         => 'content',
			'inline'      => true,
			'label'       => esc_html__( 'Selector', 'bricks' ) . ' (' . esc_html__( 'Element', 'bricks' ) . ')',
			'type'        => 'text',
			'placeholder' => '.container-class',
			'required'    => array( 'trigger', '=', 'hoverSelector' ),
		);

		$this->controls['hoverReverse'] = array(
			'tab'      => 'content',
			'inline'   => true,
			'small'    => true,
			'label'    => esc_html__( 'Reverse on mouseout', 'bricksextras' ),
			'type'     => 'checkbox',
			'required' => array( 'trigger', '=', array( 'hover', 'hoverSelector' ) ),
		);

		$this->controls['offsetTop'] = array(
			'tab'         => 'content',
			'inline'      => true,
			'label'       => esc_html__( 'Offset', 'bricks' ) . ' (' . esc_html__( 'Top', 'bricks' ) . ')',
			'description' => esc_html__( 'Percentage distance from the top of viewport for animation to start', 'bricksextras' ),
			'type'        => 'number',
			'units'       => false,
			'placeholder' => esc_html__( '0', 'bricks' ),
			'required'    => array( 'trigger', '=', array( 'scroll', 'scrollSelector' ) ),
		);

		$this->controls['offsetBottom'] = array(
			'tab'         => 'content',
			'inline'      => true,
			'label'       => esc_html__( 'Offset', 'bricks' ) . ' (' . esc_html__( 'Bottom', 'bricks' ) . ')',
			'description' => esc_html__( 'Percentage distance from the bottom of viewport for animation to start', 'bricksextras' ),
			'type'        => 'number',
			'units'       => false,
			'placeholder' => esc_html__( '0', 'bricks' ),
			'required'    => array( 'trigger', '=', array( 'scroll', 'scrollSelector' ) ),
		);

		$this->controls['autoPlay'] = array(
			'tab'      => 'content',
			'inline'   => true,
			'small'    => true,
			'label'    => esc_html__( 'Autoplay', 'bricks' ),
			'type'     => 'checkbox',
			'required' => array( 'trigger', '=', array( 'none', 'viewport' ) ),
		);

		$this->controls['loop'] = array(
			'tab'      => 'content',
			'inline'   => true,
			'small'    => true,
			'label'    => esc_html__( 'Loop', 'bricks' ),
			'type'     => 'checkbox',
			'required' => array( 'trigger', '=', array( 'none', 'viewport' ) ),
		);

		$this->controls['perfSep'] = array(
			'tab'   => 'content',
			'type'  => 'separator',
			'label' => esc_html__( 'Performance', 'bricks' ),
		);

		$this->controls['lottieVersion'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Lottie version', 'bricksextras' ),
			'type'        => 'select',
			'inline'      => true,
			'options'     => array(
				'light' => esc_html__( 'Light', 'bricks' ),
				'full'  => esc_html__( 'Full', 'bricks' ),
			),
			'default'     => 'light',
			'placeholder' => esc_html__( 'Light', 'bricks' ),
			'description' => esc_html__( "Lottie light is ~39% lighter version of Lottie that doesn't support expressions or effects. Use light unless your chosen animation needs those supported", 'bricksextras' ),
		);
	}


	/**
	 * Enqueue scripts.
	 */
	public function enqueue_scripts() {

		if ( ! \BricksExtras\Helpers::element_css_added( $this->name ) ) {
			wp_enqueue_style( 'x-lottie', BRICKSEXTRAS_URL . 'components/assets/css/lottie.css', array(), \BricksExtras\Plugin::VERSION );
		}
	}

	/**
	 * Render element output.
	 */
	public function render() {

		$trigger        = isset( $this->settings['trigger'] ) ? $this->settings['trigger'] : 'none';
		$lottie_url     = isset( $this->settings['lottieURL'] ) ? esc_url( $this->render_dynamic_data( $this->settings['lottieURL'] ) ) : 'https://assets8.lottiefiles.com/packages/lf20_8qDRX7nBln.json';
		$lottie_version = isset( $this->settings['lottieVersion'] ) ? $this->settings['lottieVersion'] : 'light';

		$config = array(
			'url'     => $lottie_url,
			'trigger' => $trigger,
			'start'   => isset( $this->settings['frameStart'] ) ? intval( $this->settings['frameStart'] ) : 0,
			'end'     => isset( $this->settings['frameEnd'] ) ? intval( $this->settings['frameEnd'] ) : 60,
			'speed'   => isset( $this->settings['speed'] ) ? floatval( $this->settings['speed'] ) : 1,
		);

		if ( 'scroll' === $trigger || 'scrollSelector' === $trigger || 'viewport' === $trigger ) {
			$config += array(
				'offsetB'        => isset( $this->settings['offsetBottom'] ) ? intval( $this->settings['offsetBottom'] ) : 0,
				'offsetT'        => isset( $this->settings['offsetTop'] ) ? intval( $this->settings['offsetTop'] ) : 0,
				'scrollSelector' => isset( $this->settings['scrollElementSelector'] ) ? bricks_render_dynamic_data( $this->settings['scrollElementSelector'] ) : '',
			);
		}

		if ( 'none' === $trigger || 'viewport' === $trigger ) {
			$config += array(
				'autoPlay' => isset( $this->settings['autoPlay'] ) ? $this->settings['autoPlay'] : false,
				'loop'     => isset( $this->settings['loop'] ) ? $this->settings['loop'] : false,
			);
		}

		if ( 'click' === $trigger || 'clickSelector' === $trigger ) {
			$config += array(
				'rev'           => isset( $this->settings['reverseClick'] ),
				'clickSelector' => isset( $this->settings['clickElementSelector'] ) ? bricks_render_dynamic_data( $this->settings['clickElementSelector'] ) : '.element-class',
			);
		}

		if ( 'hoverSelector' === $trigger ) {
			$config += array(
				'hoverReverse'  => isset( $this->settings['hoverReverse'] ),
				'hoverSelector' => isset( $this->settings['hoverSelector'] ) ? bricks_render_dynamic_data( $this->settings['hoverSelector'] ) : '.container-class',
			);
		}

		if ( 'hover' === $trigger ) {
			$config += array(
				'hoverReverse' => isset( $this->settings['hoverReverse'] ),
			);
		}

		$this->set_attribute( '_root', 'data-x-lottie', wp_json_encode( $config ) );

		// Generate and set a unique identifier for this instance.
		$indentifier = \BricksExtras\Helpers::set_identifier_attribute( $this );

		echo "<div {$this->render_attributes( '_root' )}></div>";

		if ( ! bricks_is_builder_main() ) {

			if ( 'light' === $lottie_version ) {
				wp_enqueue_script( 'x-lottie-light', BRICKSEXTRAS_URL . 'components/assets/js/lottielight.min.js', array( 'bricks-scripts' ), '5.13.0', true );
			} else {
				wp_enqueue_script( 'x-lottie', BRICKSEXTRAS_URL . 'components/assets/js/lottie.min.js', array( 'bricks-scripts' ), '5.13.0', true );
			}

			if ( 'none' !== $trigger && 'viewport' !== $trigger && 'hoverSelector' !== $trigger ) {
				wp_enqueue_script( 'x-lottie-interactivity', BRICKSEXTRAS_URL . 'components/assets/js/lottieinteractivity.min.js', array( 'bricks-scripts' ), '1.6.1', true );
			}

			wp_enqueue_script( 'x-lottie-init', BRICKSEXTRAS_URL . 'components/assets/js/' . \BricksExtras\Helpers::maybe_minify_scripts( 'lotties' ) . '.js', array( 'bricks-scripts' ), \BricksExtras\Plugin::VERSION, true );

			$lazy_lottie = '200px';
			$lazy_lottie = apply_filters( 'bricksextras/lottie/lazy', $lazy_lottie );

			if ( ! self::$script_localized ) {

				wp_localize_script(
					'x-lottie-init',
					'xLottieAnimation',
					array(
						'Instances' => array(),
						'Lazy'      => $lazy_lottie,
					)
				);

				self::$script_localized = true;

			}
		}
	}
}
