<?php
/**
 * BricksExtras Interactive Effects
 *
 * @package BricksExtras
 */

namespace BricksExtras;

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

if ( class_exists( 'BricksExtrasInteractive' ) ) {
	return;
}

/**
 * Class for managing interactive effects like parallax, floating, tilt, and tooltips.
 */
class BricksExtrasInteractive {

	/**
	 * Initialize interactive effects.
	 *
	 * @return void
	 */
	public static function init() {

			/* apply interactive effects to container element. */
			$interactive_elements = array(
				'container',
				'div',
				'block',
			);

			$native_elements = array(
				// Layout.
				'container',
				'section',
				'block',
				'div',

				// Basic.
				'heading',
				'text-basic',
				'text',
				'button',
				'icon',
				'image',
				'video',

				// General.
				'divider',
				'icon-box',
				'social-icons',
				'list',
				'accordion',
				'accordion-nested',
				'tabs',
				'tabs-nested',
				'form',
				'map',
				'alert',
				'animated-typing',
				'countdown',
				'counter',
				'pricing-tables',
				'progress-bar',
				'pie-chart',
				'team-members',
				'testimonials',
				'html',
				'code',
				'template',
				'logo',
				'facebook-page',

				// Media.
				'image-gallery',
				'audio',
				'carousel',
				'slider',
				'slider-nested',
				'svg',

				// WordPress.
				'wordpress',
				'posts',
				'pagination',
				'nav-menu',
				'sidebar',
				'search',
				'shortcode',

				// Single.
				'post-title',
				'post-excerpt',
				'post-meta',
				'post-content',
				'post-sharing',
				'related-posts',
				'post-author',
				'post-comments',
				'post-taxonomy',
				'post-navigation',
			);

			foreach ( $native_elements as $native_element ) {
					add_filter( "bricks/elements/$native_element/control_groups", array( __CLASS__, 'interactive_effects_group' ) );
					add_filter( "bricks/elements/$native_element/controls", array( __CLASS__, 'interactive_effects_controls' ) );
			}

			foreach ( $native_elements as $native_element ) {
				add_filter( "bricks/elements/$native_element/control_groups", array( __CLASS__, 'tooltip_group' ) );
				add_filter( "bricks/elements/$native_element/controls", array( __CLASS__, 'tooltip_controls' ) );
			}

			add_filter( 'bricks/element/render_attributes', array( __CLASS__, 'render_attributes' ), 10, 3 );
	}

	/**
	 * Add interactive effects control group.
	 *
	 * @param array $control_groups Existing control groups.
	 * @return array Modified control groups.
	 */
	public static function interactive_effects_group( $control_groups ) {
			$control_groups['x_interactive'] = array(
				'tab'   => 'style',
				'title' => esc_html__( 'Interactive', 'bricksextras' ),
			);
			return $control_groups;
	}

	/**
	 * Add tooltip control group.
	 *
	 * @param array $control_groups Existing control groups.
	 * @return array Modified control groups.
	 */
	public static function tooltip_group( $control_groups ) {
		$control_groups['x_tooltip_group'] = array(
			'tab'   => 'style',
			'title' => esc_html__( 'Tooltip', 'bricks' ),
		);
		return $control_groups;
	}

	/**
	 * Add interactive effects controls.
	 *
	 * @param array $controls Existing controls.
	 * @return array Modified controls.
	 */
	public static function interactive_effects_controls( $controls ) {

			$controls['x_interactive_sep'] = array(
				'tab'         => 'content',
				'group'       => 'x_interactive',
				'type'        => 'info',
				'description' => esc_html__( 'Interactions are not visible when editing in the builder', 'bricksextras' ),
			);

			/* Parallax effect controls. */

			$controls['x_parallax'] = array(
				'tab'   => 'content',
				'group' => 'x_interactive',
				'label' => esc_html__( 'Parallax scroll effect', 'bricksextras' ),
				'type'  => 'checkbox',
			);

			$controls['x_parallax_content'] = array(
				'tab'         => 'content',
				'group'       => 'x_interactive',
				'type'        => 'separator',
				'label'       => esc_html__( 'Scroll speeds', 'bricksextras' ),
				'required'    => array( 'x_parallax', '=', true ),
				'description' => esc_html__( 'We recommend keeping the speed between -5 and +5', 'bricksextras' ),
			);

			$controls['scrollSpeedDefault'] = array(
				'tab'      => 'content',
				'label'    => esc_html__( 'Default', 'bricks' ),
				'group'    => 'x_interactive',
				'type'     => 'number',
				'min'      => -10,
				'max'      => 10,
				'inline'   => true,
				'required' => array( 'x_parallax', '=', true ),
			);

			$controls['scrollSpeedDesktop'] = array(
				'tab'      => 'content',
				'label'    => esc_html__( 'Desktop', 'bricks' ) . ' ( >= 992px )',
				'group'    => 'x_interactive',
				'type'     => 'number',
				'min'      => -10,
				'max'      => 10,
				'inline'   => true,
				'required' => array( 'x_parallax', '=', true ),
			);

				$controls['scrollSpeedTablet'] = array(
					'tab'      => 'content',
					'label'    => esc_html__( 'Tablet', 'bricks' ) . ' (768px - 991px)',
					'group'    => 'x_interactive',
					'type'     => 'number',
					'min'      => -10,
					'max'      => 10,
					'inline'   => true,
					'required' => array( 'x_parallax', '=', true ),
				);

				$controls['scrollSpeedMobile'] = array(
					'tab'      => 'content',
					'label'    => esc_html__( 'Mobile landscape', 'bricks' ) . ' (479px - 767px)',
					'group'    => 'x_interactive',
					'type'     => 'number',
					'min'      => -10,
					'max'      => 10,
					'inline'   => true,
					'required' => array( 'x_parallax', '=', true ),
				);

				$controls['scrollSpeedMobilePortrait'] = array(
					'tab'         => 'content',
					'label'       => esc_html__( 'Mobile portrait', 'bricks' ) . ' ( <= 478px)',
					'group'       => 'x_interactive',
					'type'        => 'number',
					'min'         => -10,
					'max'         => 10,
					'inline'      => true,
					'placeholder' => esc_html__( '0', 'bricks' ),
					'required'    => array( 'x_parallax', '=', true ),
				);

				$controls['x_parallax_sep'] = array(
					'tab'   => 'content',
					'group' => 'x_interactive',
					'type'  => 'separator',
				);

				/* Floating effect controls */

				$controls['x_floating'] = array(
					'tab'   => 'content',
					'group' => 'x_interactive',
					'label' => esc_html__( 'Floating effect', 'bricksextras' ),
					'type'  => 'checkbox',
				);

				$controls['x_floating_direction'] = array(
					'tab'         => 'content',
					'label'       => esc_html__( 'Direction', 'bricks' ),
					'group'       => 'x_interactive',
					'type'        => 'select',
					'options'     => array(
						'horizontal' => esc_html__( 'Horizontal', 'bricks' ),
						'vertical'   => esc_html__( 'Vertical', 'bricks' ),
					),
					'inline'      => true,
					'placeholder' => esc_html__( 'Vertical', 'bricks' ),
					'required'    => array( 'x_floating', '=', true ),
				);

				$controls['x_floating_duration'] = array(
					'tab'            => 'content',
					'label'          => esc_html__( 'Duration', 'bricks' ) . ' (ms)',
					'group'          => 'x_interactive',
					'type'           => 'text',
					'hasDynamicData' => false,
					'inline'         => true,
					'css'            => array(
						array(
							'property' => '--x-floating-duration',
						),
					),
					'placeholder'    => '6000ms',
					'required'       => array( 'x_floating', '=', true ),
				);

				$controls['x_floating_distance'] = array(
					'tab'         => 'content',
					'label'       => esc_html__( 'Distance', 'bricks' ),
					'group'       => 'x_interactive',
					'inline'      => true,
					'type'        => 'number',
					'css'         => array(
						array(
							'property' => '--x-floating-distance',
						),
					),
					'units'       => array(
						'px' => array(
							'min'  => 1,
							'max'  => 200,
							'step' => 1,
						),
					),
					'required'    => array( 'x_floating', '=', true ),
					'placeholder' => '-20px',

				);

				$controls['x_floating_delay'] = array(
					'tab'            => 'content',
					'label'          => esc_html__( 'Delay', 'bricks' ) . ' (ms)',
					'inline'         => true,
					'css'            => array(
						array(
							'property' => '--x-floating-delay',
						),
					),
					'group'          => 'x_interactive',
					'type'           => 'text',
					'hasDynamicData' => false,
					'placeholder'    => '0ms',
					'required'       => array( 'x_floating', '=', true ),
				);

				$controls['x_floating_sep'] = array(
					'tab'   => 'content',
					'group' => 'x_interactive',
					'type'  => 'separator',
				);

				/* Tilt effect controls */

				$controls['x_tilt'] = array(
					'tab'   => 'content',
					'group' => 'x_interactive',
					'label' => esc_html__( 'Tilt hover effect', 'bricksextras' ),
					'type'  => 'checkbox',
				);

				$controls['x_tilt_max'] = array(
					'tab'         => 'content',
					'label'       => esc_html__( 'Maximum rotation', 'bricksextras' ) . ' (°)',
					'group'       => 'x_interactive',
					'type'        => 'number',
					'inline'      => true,
					'required'    => array( 'x_tilt', '=', true ),
					'placeholder' => '35',
				);

				$controls['x_tilt_start_x'] = array(
					'tab'         => 'content',
					'label'       => esc_html__( 'Rotate X', 'bricks' ) . ' (°)',
					'group'       => 'x_interactive',
					'type'        => 'number',
					'inline'      => true,
					'required'    => array( 'x_tilt', '=', true ),
					'placeholder' => '0',
				);

				$controls['x_tilt_start_y'] = array(
					'tab'         => 'content',
					'label'       => esc_html__( 'Rotate Y', 'bricks' ) . ' (°)',
					'group'       => 'x_interactive',
					'type'        => 'number',
					'inline'      => true,
					'required'    => array( 'x_tilt', '=', true ),
					'placeholder' => '0',
				);

				$controls['x_tilt_scale'] = array(
					'tab'         => 'content',
					'label'       => esc_html__( 'Scale', 'bricks' ),
					'group'       => 'x_interactive',
					'type'        => 'number',
					'inline'      => true,
					'required'    => array( 'x_tilt', '=', true ),
					'placeholder' => '1',
				);

				$controls['x_tilt_speed'] = array(
					'tab'         => 'content',
					'label'       => esc_html__( 'Speed', 'bricks' ) . ' (ms)',
					'group'       => 'x_interactive',
					'type'        => 'number',
					'inline'      => true,
					'required'    => array( 'x_tilt', '=', true ),
					'placeholder' => '300',
				);

				$controls['x_tilt_perspective'] = array(
					'tab'         => 'content',
					'label'       => esc_html__( 'Perspective', 'bricksextras' ),
					'group'       => 'x_interactive',
					'type'        => 'number',
					'inline'      => true,
					'required'    => array( 'x_tilt', '=', true ),
					'placeholder' => '1000',
				);

				$controls['x_tilt_glare'] = array(
					'tab'      => 'content',
					'group'    => 'x_interactive',
					'label'    => esc_html__( 'Add glare', 'bricksextras' ),
					'type'     => 'checkbox',
					'required' => array( 'x_tilt', '=', true ),
				);

				$controls['x_tilt_max_glare'] = array(
					'tab'         => 'content',
					'label'       => esc_html__( 'Max glare', 'bricksextras' ),
					'group'       => 'x_interactive',
					'type'        => 'number',
					'inline'      => true,
					'required'    => array( 'x_tilt', '=', true ),
					'placeholder' => '1',
				);

				$controls['x_tilt_color'] = array(
					'tab'      => 'content',
					'label'    => esc_html__( 'Color', 'bricks' ),
					'group'    => 'x_interactive',
					'type'     => 'color',
					'css'      => array(
						array(
							'property' => '--tilt-color',
							'selector' => '.js-tilt-glare-inner',
						),
						array(
							'property' => 'background-image',
							'selector' => '.js-tilt-glare-inner',
							'value'    => 'linear-gradient(0deg, rgba(255, 255, 255, 0) 0%, var(--tilt-color) 100%)!important',
						),
					),
					'required' => array( 'x_tilt', '=', true ),
				);

				$controls['x_tilt_breakpoint_separator'] = array(
					'tab'      => 'content',
					'group'    => 'x_interactive',
					'type'     => 'separator',
					'label'    => esc_html__( 'Disable', 'bricks' ),
					'required' => array( 'x_tilt', '=', true ),
				);

				$controls['x_tilt_breakpoint'] = array(
					'tab'      => 'content',
					'label'    => esc_html__( 'Breakpoint', 'bricks' ) . ' (px)',
					'group'    => 'x_interactive',
					'type'     => 'number',
					'inline'   => true,
					'required' => array( 'x_tilt', '=', true ),

				);

				return $controls;
	}

	/**
	 * Add tooltip controls.
	 *
	 * @param array $controls Existing controls.
	 * @return array Modified controls.
	 */
	public static function tooltip_controls( $controls ) {

		/* Tooltip  controls. */

		$controls['x_tooltips'] = array(
			'tab'   => 'content',
			'group' => 'x_tooltip_group',
			'label' => esc_html__( 'Content', 'bricks' ),
			'type'  => 'checkbox',
		);

		$controls['x_tooltip_content'] = array(
			'tab'           => 'content',
			'group'         => 'x_tooltip_group',
			'description'   => esc_html__( 'For use with the popover/tooltip element (enable Dynamic tooltip text)', 'bricksextras' ),
			'type'          => 'textarea',
			'rows'          => 10,
			'spellcheck'    => true,
			'inlineEditing' => true,
			'required'      => array( 'x_tooltips', '=', true ),
		);

		return $controls;
	}

	/**
	 * Render interactive effect attributes.
	 *
	 * @param array  $attributes Element attributes.
	 * @param string $key Attribute key.
	 * @param object $element Element object.
	 * @return array Modified attributes.
	 */
	public static function render_attributes( $attributes, $key, $element ) {

		if ( bricks_is_frontend() ) {

			if ( isset( $element->settings['x_parallax'] ) && true === $element->settings['x_parallax'] ) {

				wp_enqueue_script( 'x-rellax', BRICKSEXTRAS_URL . 'components/assets/js/rellax.min.js', array( 'bricks-scripts' ), '1.13.0', true );
				wp_enqueue_script( 'x-parallax', BRICKSEXTRAS_URL . 'components/assets/js/' . \BricksExtras\Helpers::maybe_minify_scripts( 'parallax' ) . '.js', array( 'x-rellax' ), \BricksExtras\Plugin::VERSION, true );

				if ( isset( $element->settings['scrollSpeedDefault'] ) ) {
						$attributes[ $key ]['data-rellax-speed'] = esc_attr( $element->settings['scrollSpeedDefault'] );
				} else {
						$attributes[ $key ]['data-rellax-speed'] = '0';
				}

				if ( isset( $element->settings['scrollSpeedDesktop'] ) ) {
						$attributes[ $key ]['data-rellax-desktop-speed'] = esc_attr( $element->settings['scrollSpeedDesktop'] );
				}

				if ( isset( $element->settings['scrollSpeedTablet'] ) ) {
						$attributes[ $key ]['data-rellax-tablet-speed'] = esc_attr( $element->settings['scrollSpeedTablet'] );
				}

				if ( isset( $element->settings['scrollSpeedMobile'] ) ) {
						$attributes[ $key ]['data-rellax-mobile-speed'] = esc_attr( $element->settings['scrollSpeedMobile'] );
				}

				if ( isset( $element->settings['scrollSpeedMobilePortrait'] ) ) {
						$attributes[ $key ]['data-rellax-xs-speed'] = esc_attr( $element->settings['scrollSpeedMobilePortrait'] );
				} else {
						$attributes[ $key ]['data-rellax-xs-speed'] = '0';
				}
			}

			if ( isset( $element->settings['x_floating'] ) && true === $element->settings['x_floating'] ) {

					wp_enqueue_style( 'x-floating', BRICKSEXTRAS_URL . 'components/assets/css/floating.css', array(), '1.0.0' );

					$attributes[ $key ]['data-x-floating'] = '';

				if ( isset( $element->settings['x_floating_direction'] ) && 'horizontal' === $element->settings['x_floating_direction'] ) {
						$attributes[ $key ]['data-x-floating'] = 'horizontal';
				}
			}

			if ( isset( $element->settings['x_tilt'] ) && true === $element->settings['x_tilt'] ) {

				wp_enqueue_script( 'x-vanilla-tilt', BRICKSEXTRAS_URL . 'components/assets/js/vanillatilt.min.js', array( 'bricks-scripts' ), '1.7.2', true );
				wp_enqueue_script( 'x-tilt', BRICKSEXTRAS_URL . 'components/assets/js/' . \BricksExtras\Helpers::maybe_minify_scripts( 'tilt' ) . '.js', array( 'x-vanilla-tilt' ), \BricksExtras\Plugin::VERSION, true );

				$x_tilt_config = array();

				$x_tilt_config['config'] = array();

				if ( isset( $element->settings['x_tilt_max'] ) ) {
					$x_tilt_config['config'] += array( 'max' => intval( $element->settings['x_tilt_max'] ) );
				}

				if ( isset( $element->settings['x_tilt_scale'] ) ) {
					$x_tilt_config['config'] += array( 'scale' => floatval( $element->settings['x_tilt_scale'] ) );
				}

				if ( isset( $element->settings['x_tilt_start_x'] ) ) {
					$x_tilt_config['config'] += array( 'startX' => intval( $element->settings['x_tilt_start_x'] ) );
				}

				if ( isset( $element->settings['x_tilt_start_y'] ) ) {
					$x_tilt_config['config'] += array( 'startY' => intval( $element->settings['x_tilt_start_y'] ) );
				}

				if ( isset( $element->settings['x_tilt_speed'] ) ) {
					$x_tilt_config['config'] += array( 'speed' => intval( $element->settings['x_tilt_speed'] ) );
				}

				if ( isset( $element->settings['x_tilt_perspective'] ) ) {
					$x_tilt_config['config'] += array( 'perspective' => intval( $element->settings['x_tilt_perspective'] ) );
				}

				if ( isset( $element->settings['x_tilt_glare'] ) ) {

					$x_tilt_config['config'] += array(
						'glare'     => true,
						'max-glare' => isset( $element->settings['x_tilt_max_glare'] ) ? floatval( $element->settings['x_tilt_max_glare'] ) : '1',
					);

				}

				if ( isset( $element->settings['x_tilt_breakpoint'] ) ) {
					$x_tilt_config['breakpoint'] = intval( $element->settings['x_tilt_breakpoint'] );
				}

				$attributes[ $key ]['data-x-tilt'] = wp_json_encode( $x_tilt_config );

			}

			if ( isset( $element->settings['x_tooltips'] ) && true === $element->settings['x_tooltips'] ) {

				if ( ! empty( $element->settings['x_tooltip_content'] ) ) {
					$tooltip_data                         = array(
						'content' => wp_kses_post( bricks_render_dynamic_data( $element->settings['x_tooltip_content'] ) ),
					);
					$attributes[ $key ]['data-x-tooltip'] = wp_json_encode( $tooltip_data );
				}
			}
		}

		return $attributes;
	}
}
