<?php
/**
 * Image Hotspots element.
 *
 * @package BricksExtras
 */

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

/**
 * Image Hotspots element class.
 */
class X_Image_Hotspots extends \Bricks\Element {

	/**
	 * Element category.
	 *
	 * @var string
	 */
	public $category = 'extras';
	/**
	 * Element name.
	 *
	 * @var string
	 */
	public $name = 'ximagehotspots';
	/**
	 * Element icon.
	 *
	 * @var string
	 */
	public $icon = 'ti-image';
	/**
	 * CSS selector.
	 *
	 * @var string
	 */
	public $css_selector = '';
	/**
	 * Required scripts.
	 *
	 * @var array
	 */
	public $scripts = array( 'xImageHotspots' );
	/**
	 * Loop index.
	 *
	 * @var int
	 */
	public $loop_index = 0;
	/**
	 * Element is nestable.
	 *
	 * @var bool
	 */
	public $nestable = true;
	/**
	 * Script localized flag.
	 *
	 * @var bool
	 */
	private static $script_localized = false;



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

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

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

		$this->control_groups['image'] = array(
			'title' => esc_html__( 'Image', 'bricks' ),
			'tab'   => 'content',
		);

		$this->control_groups['markers'] = array(
			'title' => esc_html__( 'Marker style', 'bricksextras' ),
			'tab'   => 'content',
		);

		$this->control_groups['content'] = array(
			'title' => esc_html__( 'Popover style', 'bricksextras' ),
			'tab'   => 'content',
		);

		$this->control_groups['pulses'] = array(
			'title' => esc_html__( 'Pulses', 'bricksextras' ),
			'tab'   => 'content',
		);

		$this->control_groups['behaviour'] = array(
			'title' => esc_html__( 'Behavior', 'bricksextras' ),
			'tab'   => 'content',
		);

		$this->control_groups['animation'] = array(
			'title' => esc_html__( 'Animation', 'bricks' ),
			'tab'   => 'content',
		);
	}

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

		$this->controls['type'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Type', 'bricks' ),
			'type'        => 'select',
			'inline'      => true,
			'options'     => array(
				'hotspots' => esc_html__( 'Built-in Hotspots', 'bricksextras' ),
				'nestable' => esc_html__( 'Nested Hotspots', 'bricksextras' ),
			),
			'placeholder' => esc_html__( 'Built-in Hotspots', 'bricksextras' ),
		);

		$this->controls['nestedInfo'] = array(
			'tab'         => 'content',
			'description' => esc_html__( 'Nest in the Image Hotspot Marker element', 'bricksextras' ),
			'type'        => 'info',
			'required'    => array( 'type', '=', 'nestable' ),
		);

		$this->controls['hasLoop'] = array(
			'tab'      => 'content',
			'label'    => esc_html__( 'Query loop', 'bricks' ),
			'type'     => 'checkbox',
			'required' => array( 'type', '!=', 'nestable' ),
		);

		$this->controls['query'] = array(
			'tab'      => 'content',
			'label'    => esc_html__( 'Query', 'bricks' ),
			'type'     => 'query',
			'popup'    => true,
			'inline'   => true,
			'required' => array(
				array( 'type', '!=', 'nestable' ),
				array( 'hasLoop', '!=', '' ),
			),
		);

		$this->controls['markers'] = array(
			'tab'           => 'content',
			'placeholder'   => esc_html__( 'Markers', 'bricks' ),
			'title'         => esc_html__( 'Add Markers', 'bricksextras' ),
			'type'          => 'repeater',
			'titleProperty' => 'title',
			'checkLoop'     => true,
			'required'      => array(
				array( 'type', '!=', 'nestable' ),
			),
			'fields'        => array(
				'title'              => array(
					'label' => esc_html__( 'Button text', 'bricks' ),
					'type'  => 'text',
				),
				'position_x'         => array(
					'label'       => esc_html__( 'Position', 'bricks' ) . ' (X)',
					'type'        => 'text',
					'placeholder' => '0%',
				),
				'position_y'         => array(
					'label'       => esc_html__( 'Position', 'bricks' ) . ' (Y)',
					'type'        => 'text',
					'placeholder' => '0%',
				),
				'markerType'         => array(
					'label'       => esc_html__( 'Action', 'bricks' ),
					'type'        => 'text',
					'options'     => array(
						'popover' => esc_html__( 'popover', 'bricksextras' ),
						'link'    => esc_html__( 'Link', 'bricks' ),
					),
					'placeholder' => esc_html__( 'popover', 'bricksextras' ),
				),
				'link'               => array(
					'label' => esc_html__( 'Link', 'bricks' ),
					'type'  => 'link',
				),
				'content'            => array(
					'label' => esc_html__( 'Popover content', 'bricksextras' ),
					'type'  => 'editor',
				),
				'aria_label'         => array(
					'label' => 'aria-label',
					'type'  => 'text',
				),
				'markerImage'        => array(
					'label' => esc_html__( 'Image', 'bricks' ),
					'type'  => 'image',
				),
				'markerImageAltText' => array(
					'label' => esc_html__( 'Custom alt text', 'bricks' ),
					'type'  => 'text',
				),
				'custom_attributes'  => array(
					'label'       => esc_html__( 'Custom attributes', 'bricks' ),
					'type'        => 'repeater',
					'placeholder' => esc_html__( 'Attribute', 'bricks' ),
					'fields'      => array(
						'name'  => array(
							'label' => esc_html__( 'Name', 'bricks' ),
							'type'  => 'text',
						),
						'value' => array(
							'label' => esc_html__( 'Value', 'bricks' ),
							'type'  => 'text',
						),
					),
				),
			),
			'default'       => array(
				array(
					'title'      => esc_html__( 'Marker', 'bricks' ),
					'content'    => esc_html__( 'Popover content here ..', 'bricksextras' ),
					'position_x' => '30%',
					'position_y' => '10%',
					'aria_label' => esc_attr__( 'Toggle popover', 'bricksextras' ),
				),
				array(
					'title'      => esc_html__( 'Marker', 'bricks' ),
					'content'    => esc_html__( 'Popover content here ..', 'bricksextras' ),
					'position_x' => '60%',
					'position_y' => '30%',
					'aria_label' => esc_attr__( 'Toggle popover', 'bricksextras' ),
				),
			),
		);

		$this->controls['image'] = array(
			'tab'   => 'content',
			'label' => esc_html__( 'Image', 'bricks' ),
			'type'  => 'image',
			'group' => 'image',
		);

		$this->controls['altText'] = array(
			'tab'      => 'content',
			'label'    => esc_html__( 'Custom alt text', 'bricks' ),
			'type'     => 'text',
			'inline'   => true,
			'rerender' => false,
			'required' => array( 'image', '!=', '' ),
			'group'    => 'image',
		);

		/* markers */

		$marker       = '.x-marker_marker';
		$marker_inner = '.x-marker_marker-inner';

		$this->controls['markerIconSep'] = array(
			'tab'      => 'content',
			'group'    => 'markers',
			'label'    => esc_html__( 'Icon', 'bricks' ),
			'type'     => 'separator',
			'required' => array(
				array( 'type', '!=', 'nestable' ),
			),
		);

		$this->controls['icon'] = array(
			'tab'      => 'content',
			'group'    => 'markers',
			'label'    => esc_html__( 'Icon', 'bricks' ),
			'type'     => 'icon',
			'default'  => array(
				'icon'    => 'ion-ios-pin',
				'library' => 'ionicons',
			),
			'css'      => array(
				array(
					'property' => 'font-size',
					'selector' => $marker_inner . ' svg',
				),
			),
			'required' => array(
				array( 'type', '!=', 'nestable' ),
			),
		);

		$this->controls['iconSize'] = array(
			'tab'      => 'content',
			'group'    => 'markers',
			'label'    => esc_html__( 'Icon size', 'bricks' ),
			'type'     => 'number',
			'units'    => true,
			'css'      => array(
				array(
					'property' => 'font-size',
					'selector' => $marker_inner . '> *:not(.x-marker_marker-title)',
				),
			),
			'required' => array(
				array( 'type', '!=', 'nestable' ),
			),
		);

		$this->controls['markerImageSep'] = array(
			'tab'      => 'content',
			'group'    => 'markers',
			'label'    => esc_html__( 'Image', 'bricks' ),
			'type'     => 'separator',
			'required' => array(
				array( 'type', '!=', 'nestable' ),
			),
		);

		$this->controls['imageWidth'] = array(
			'tab'   => 'content',
			'group' => 'markers',
			'label' => esc_html__( 'Image width', 'bricks' ),
			'type'  => 'number',
			'units' => true,
			'css'   => array(
				array(
					'property' => 'width',
					'selector' => $marker_inner . ' .x-hotspots_marker-image',
				),
			),
		);

		$this->controls['imageHeight'] = array(
			'tab'   => 'content',
			'group' => 'markers',
			'label' => esc_html__( 'Image height', 'bricks' ),
			'type'  => 'number',
			'units' => true,
			'css'   => array(
				array(
					'property' => 'height',
					'selector' => $marker_inner . ' .x-hotspots_marker-image',
				),
			),
		);

		$this->controls['imageObjectFit'] = array(
			'tab'     => 'content',
			'group'   => 'markers',
			'label'   => esc_html__( 'Object fit', 'bricks' ),
			'type'    => 'select',
			'inline'  => true,
			'options' => array(
				'fill'       => esc_html__( 'Fill', 'bricks' ),
				'contain'    => esc_html__( 'Contain', 'bricks' ),
				'cover'      => esc_html__( 'Cover', 'bricks' ),
				'none'       => esc_html__( 'None', 'bricks' ),
				'scale-down' => esc_html__( 'Scale down', 'bricks' ),
			),
			'css'     => array(
				array(
					'property' => 'object-fit',
					'selector' => $marker_inner . ' .x-hotspots_marker-image',
				),
			),
		);

		$this->controls['imageBorder'] = array(
			'tab'   => 'content',
			'group' => 'markers',
			'label' => esc_html__( 'Image border', 'bricks' ),
			'type'  => 'border',
			'css'   => array(
				array(
					'property' => 'border',
					'selector' => $marker_inner . ' .x-hotspots_marker-image',
				),
			),
		);

		$this->controls['imageShadow'] = array(
			'tab'   => 'content',
			'group' => 'markers',
			'label' => esc_html__( 'Box shadow', 'bricks' ),
			'type'  => 'box-shadow',
			'css'   => array(
				array(
					'property' => 'box-shadow',
					'selector' => $marker_inner . ' .x-hotspots_marker-image',
				),
			),
		);

		$this->controls['marker_start'] = array(
			'tab'   => 'content',
			'group' => 'markers',
			'label' => esc_html__( 'Button', 'bricks' ),
			'type'  => 'separator',
		);

		$this->controls['markerTypography'] = array(
			'tab'   => 'content',
			'group' => 'markers',
			'type'  => 'typography',
			'label' => esc_html__( 'Typography', 'bricks' ),
			'css'   => array(
				array(
					'property' => 'font',
					'selector' => $marker_inner,
				),
			),
		);

		$this->controls['markerBackgroundColor'] = array(
			'tab'   => 'content',
			'group' => 'markers',
			'type'  => 'color',
			'label' => esc_html__( 'Background', 'bricks' ),
			'css'   => array(
				array(
					'property' => 'background-color',
					'selector' => $marker_inner,
				),
			),
		);

		$this->controls['markerBorder'] = array(
			'tab'   => 'content',
			'group' => 'markers',
			'type'  => 'border',
			'label' => esc_html__( 'Border', 'bricks' ),
			'css'   => array(
				array(
					'property' => 'border',
					'selector' => $marker,
				),
			),
		);

		$this->controls['markerBoxShadow'] = array(
			'tab'   => 'content',
			'group' => 'markers',
			'label' => esc_html__( 'Box shadow', 'bricks' ),
			'type'  => 'box-shadow',
			'css'   => array(
				array(
					'property' => 'box-shadow',
					'selector' => $marker_inner,
				),
			),
		);

		$this->controls['markerPadding'] = array(
			'tab'         => 'content',
			'group'       => 'markers',
			'label'       => esc_html__( 'Padding', 'bricks' ),
			'type'        => 'spacing',
			'placeholder' => array(
				'top'    => '20px',
				'right'  => '20px',
				'bottom' => '20px',
				'left'   => '20px',
			),
			'css'         => array(
				array(
					'property' => 'padding',
					'selector' => '.x-marker_marker-inner',
				),
			),
		);

		$this->controls['markerWidth'] = array(
			'tab'   => 'content',
			'group' => 'markers',
			'label' => esc_html__( 'Width', 'bricks' ) . ' (' . esc_html__( 'Button', 'bricks' ) . ')',
			'type'  => 'number',
			'units' => true,
			'css'   => array(
				array(
					'property' => 'width',
					'selector' => $marker_inner,
				),
			),
		);

		$this->controls['markerHeight'] = array(
			'tab'   => 'content',
			'group' => 'markers',
			'label' => esc_html__( 'Height', 'bricks' ) . ' (' . esc_html__( 'Button', 'bricks' ) . ')',
			'type'  => 'number',
			'units' => true,
			'css'   => array(
				array(
					'property' => 'height',
					'selector' => $marker_inner,
				),
			),
		);

		$this->controls['markerButtonDirection'] = array(
			'tab'      => 'content',
			'label'    => esc_html__( 'Direction', 'bricks' ),
			'group'    => 'markers',
			'tooltip'  => array(
				'content'  => 'flex-direction',
				'position' => 'top-left',
			),
			'type'     => 'direction',
			'css'      => array(
				array(
					'property' => 'flex-direction',
					'selector' => $marker_inner,
				),
			),
			'inline'   => true,
			'rerender' => true,
		);

		$this->controls['markerButtonjustifyContent'] = array(
			'tab'     => 'content',
			'label'   => esc_html__( 'Align main axis', 'bricks' ),
			'group'   => 'markers',
			'tooltip' => array(
				'content'  => 'justify-content',
				'position' => 'top-left',
			),
			'type'    => 'justify-content',
			'css'     => array(
				array(
					'property' => 'justify-content',
					'selector' => $marker_inner,
				),
			),
		);

		$this->controls['markerButtonalignItems'] = array(
			'tab'     => 'content',
			'label'   => esc_html__( 'Align cross axis', 'bricks' ),
			'group'   => 'markers',
			'tooltip' => array(
				'content'  => 'align-items',
				'position' => 'top-left',
			),
			'type'    => 'align-items',
			'css'     => array(
				array(
					'property' => 'align-items',
					'selector' => $marker_inner,
				),
			),
		);

		$this->controls['markerButtoncolumnGap'] = array(
			'tab'   => 'content',
			'label' => esc_html__( 'Gap', 'bricks' ),
			'group' => 'markers',
			'type'  => 'number',
			'units' => true,
			'css'   => array(
				array(
					'property' => 'gap',
					'selector' => $marker_inner,
				),
			),
		);

		/* popover content */

		$popover = '.x-marker_popover .tippy-content';

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

		$this->controls['popoverTypography'] = array(
			'tab'      => 'content',
			'group'    => 'content',
			'type'     => 'typography',
			'label'    => esc_html__( 'Typography', 'bricks' ),
			'rerender' => false,
			'css'      => array(
				array(
					'property' => 'font',
					'selector' => $popover,
				),
			),
		);

		$this->controls['popoverBackgroundColor'] = array(
			'tab'   => 'content',
			'group' => 'content',
			'type'  => 'color',
			'label' => esc_html__( 'Background', 'bricks' ),
			'css'   => array(
				array(
					'property' => 'background-color',
					'selector' => $popover,
				),
			),
		);

		$this->controls['popoverArrowColor'] = array(
			'tab'   => 'content',
			'group' => 'content',
			'type'  => 'color',
			'label' => esc_html__( 'Color', 'bricks' ) . ' (' . esc_html__( 'Arrow', 'bricks' ) . ')',
			'css'   => array(
				array(
					'property' => 'color',
					'selector' => '.x-marker .tippy-arrow',
				),
			),
		);

		$this->controls['popoverBorder'] = array(
			'tab'      => 'content',
			'group'    => 'content',
			'type'     => 'border',
			'rerender' => false,
			'label'    => esc_html__( 'Border', 'bricks' ),
			'css'      => array(
				array(
					'property' => 'border',
					'selector' => $popover,
				),
			),
		);

		$this->controls['popoverBoxShadow'] = array(
			'tab'      => 'content',
			'group'    => 'content',
			'label'    => esc_html__( 'Box shadow', 'bricks' ),
			'type'     => 'box-shadow',
			'rerender' => false,
			'css'      => array(
				array(
					'property' => 'box-shadow',
					'selector' => $popover,
				),
			),
		);

		$this->controls['popover_start'] = array(
			'tab'   => 'content',
			'group' => 'content',
			'type'  => 'separator',
		);

		$this->controls['popoverPadding'] = array(
			'tab'   => 'content',
			'group' => 'content',
			'label' => esc_html__( 'Padding', 'bricks' ),
			'type'  => 'spacing',
			'css'   => array(
				array(
					'property' => 'padding',
					'selector' => $popover,
				),
			),
		);

		/* behaviour */

		$this->controls['placement'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Preferred placement', 'bricksextras' ),
			'type'        => 'select',
			'group'       => 'behaviour',
			'options'     => array(
				'top'          => esc_html__( 'Top', 'bricks' ),
				'right'        => esc_html__( 'Right', 'bricks' ),
				'bottom'       => esc_html__( 'Bottom', 'bricks' ),
				'left'         => esc_html__( 'Left', 'bricks' ),
				'auto'         => esc_html__( 'Auto', 'bricks' ) . ' (' . esc_html__( 'Where there is enough space', 'bricksextras' ) . ')',
				'auto-start'   => esc_html__( 'Auto Start', 'bricksextras' ),
				'auto-end'     => esc_html__( 'Auto End', 'bricksextras' ),
				'top-start'    => esc_html__( 'Top Start', 'bricksextras' ),
				'top-end'      => esc_html__( 'Top End', 'bricksextras' ),
				'right-start'  => esc_html__( 'Right Start', 'bricksextras' ),
				'right-end'    => esc_html__( 'Right End', 'bricksextras' ),
				'bottom-start' => esc_html__( 'Bottom Start', 'bricksextras' ),
				'bottom-end'   => esc_html__( 'Bottom End', 'bricksextras' ),
				'left-start'   => esc_html__( 'Left Start', 'bricksextras' ),
				'left-end'     => esc_html__( 'Left End', 'bricksextras' ),
			),
			'placeholder' => esc_html__( 'Auto', 'bricks' ) . ' (' . esc_html__( 'Where there is enough space', 'bricksextras' ) . ')',
			'clearable'   => false,
		);

		$this->controls['interaction'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Trigger', 'bricks' ),
			'type'        => 'select',
			'group'       => 'behaviour',
			'options'     => array(
				'mouseenter focus' => 'mouseenter & focus',
				'click'            => 'click (default)',
				'mouseenter click' => 'mouseenter & click',
			),
			'inline'      => true,
			'placeholder' => 'click (default)',
			'clearable'   => false,
		);

		$this->controls['offsetSkidding'] = array(
			'tab'         => 'content',
			'group'       => 'behaviour',
			'label'       => esc_html__( 'Offset skidding', 'bricksextras' ) . '  (px)',
			'info'        => esc_html__( 'Distance along the side of the marker', 'bricksextras' ),
			'type'        => 'number',
			'placeholder' => '0',
			'units'       => false,
			'small'       => true,
		);

		$this->controls['offsetDistance'] = array(
			'tab'         => 'content',
			'group'       => 'behaviour',
			'label'       => esc_html__( 'Offset distance', 'bricksextras' ) . '  (px)',
			'info'        => esc_html__( 'Distance away from the marker', 'bricksextras' ),
			'type'        => 'number',
			'placeholder' => '10',
			'units'       => false,
			'small'       => true,
		);

		$this->controls['moveTransition'] = array(
			'tab'         => 'content',
			'group'       => 'behaviour',
			'label'       => esc_html__( 'Transition', 'bricks' ) . ' (ms)',
			'type'        => 'number',
			'placeholder' => '200',
			'units'       => false,
			'small'       => true,
		);

		$this->controls['moveFocus'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Move focus inside popover content', 'bricksextras' ),
			'type'        => 'select',
			'group'       => 'behaviour',
			'options'     => array(
				'enable'  => esc_html__( 'Enable', 'bricks' ),
				'disable' => esc_html__( 'Disable', 'bricks' ),
			),
			'placeholder' => esc_html__( 'Enable', 'bricks' ),
			'inline'      => true,
		);

		/* pulses */

		$this->controls['pulseType'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Pulses', 'bricksextras' ),
			'type'        => 'select',
			'group'       => 'pulses',
			'options'     => array(
				'single' => esc_html__( 'Single', 'bricks' ),
				'double' => esc_html__( 'Double', 'bricks' ),
				'none'   => esc_html__( 'None', 'bricks' ),
			),
			'inline'      => true,
			'placeholder' => esc_html__( 'Double', 'bricks' ),
			'clearable'   => false,
		);

		$this->controls['pauseonHover'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Pause on hover', 'bricks' ),
			'type'        => 'select',
			'group'       => 'pulses',
			'options'     => array(
				'none'    => esc_html__( 'Enable', 'bricks' ),
				'display' => esc_html__( 'Disable', 'bricks' ),
			),
			'inline'      => true,
			'placeholder' => esc_html__( 'Enable', 'bricks' ),
			'clearable'   => false,
			'css'         => array(
				array(
					'property' => '--x-pulse-pause',
					'selector' => '',
				),
			),
		);

		$this->controls['pulseSize'] = array(
			'tab'         => 'content',
			'group'       => 'pulses',
			'label'       => esc_html__( 'Scale', 'bricks' ),
			'css'         => array(
				array(
					'property' => '--x-pulse-size',
					'selector' => '',
				),
			),
			'type'        => 'number',
			'placeholder' => '1.2',
			'min'         => 0,
			'max'         => 0.1,
			'step'        => 3,
			'units'       => false,
			'inline'      => true,
		);

		$this->controls['pulseDuration'] = array(
			'tab'            => 'content',
			'group'          => 'pulses',
			'label'          => esc_html__( 'Duration', 'bricks' ) . ' (ms)',
			'css'            => array(
				array(
					'property' => '--x-pulse-duration',
					'selector' => '',
				),
			),
			'type'           => 'number',
			'placeholder'    => '2000',
			'inline'         => true,
			'hasDynamicData' => false,
			'unit'           => 'ms',
		);

		$this->controls['pulseColor'] = array(
			'tab'         => 'content',
			'group'       => 'pulses',
			'type'        => 'color',
			'label'       => esc_html__( 'Color', 'bricks' ),
			'placeholder' => 'rgba(0,0,0,0.4)',
			'css'         => array(
				array(
					'property' => '--x-pulse-color',
					'selector' => '',
				),
			),
		);

		/* animation */

		$this->controls['popoverTransitionIn'] = array(
			'tab'            => 'content',
			'group'          => 'animation',
			'label'          => esc_html__( 'Transition', 'bricks' ) . ' (' . esc_html__( 'Show', 'bricks' ) . ')',
			'css'            => array(
				array(
					'property' => '--x-popover-transitionin',
					'selector' => '',
				),
			),
			'type'           => 'number',
			'placeholder'    => '300',
			'inline'         => true,
			'unit'           => 'ms',
			'hasDynamicData' => false,
		);

		$this->controls['popoverTransitionOut'] = array(
			'tab'            => 'content',
			'group'          => 'animation',
			'label'          => esc_html__( 'Transition', 'bricks' ) . ' (' . esc_html__( 'Hide', 'bricks' ) . ')',
			'css'            => array(
				array(
					'property' => '--x-popover-transitionout',
					'selector' => '',
				),
			),
			'type'           => 'number',
			'placeholder'    => '300',
			'unit'           => 'ms',
			'inline'         => true,
			'hasDynamicData' => false,
		);

		$this->controls['popoverTranslateX'] = array(
			'tab'            => 'content',
			'group'          => 'animation',
			'label'          => esc_html__( 'Translate X', 'bricks' ),
			'css'            => array(
				array(
					'property' => '--x-popover-translatex',
					'selector' => '',
				),
			),
			'type'           => 'number',
			'placeholder'    => '0',
			'inline'         => true,
			'hasDynamicData' => false,
			'units'          => array(
				'px' => array(
					'min'  => 1,
					'max'  => 1000,
					'step' => 1,
				),
			),
		);

		$this->controls['popoverTranslateY'] = array(
			'tab'            => 'content',
			'group'          => 'animation',
			'label'          => esc_html__( 'Translate Y', 'bricks' ),
			'css'            => array(
				array(
					'property' => '--x-popover-translatey',
					'selector' => '',
				),
			),
			'type'           => 'number',
			'placeholder'    => '10',
			'inline'         => true,
			'hasDynamicData' => false,
			'units'          => array(
				'px' => array(
					'min'  => 1,
					'max'  => 1000,
					'step' => 1,
				),
			),
		);

		$this->controls['popoverScale'] = array(
			'tab'            => 'content',
			'group'          => 'animation',
			'label'          => esc_html__( 'Scale', 'bricks' ),
			'css'            => array(
				array(
					'property' => '--x-popover-scale',
					'selector' => '',
				),
			),
			'type'           => 'number',
			'placeholder'    => '0.95',
			'inline'         => true,
			'hasDynamicData' => false,
		);
	}


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

		if ( bricks_is_builder_main() ) {
			return;
		}

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

		if ( ! self::$script_localized ) {

			wp_localize_script(
				'x-hotspots',
				'xHotspots',
				array(
					'Instances' => array(),
				)
			);

			self::$script_localized = true;

		}

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

	/**
	 * Get normalized image settings.
	 *
	 * @param array  $settings Element settings.
	 * @param string $setting_name Setting name to retrieve.
	 */
	public function get_normalized_image_settings( $settings, $setting_name ) {
		if ( empty( $settings[ $setting_name ] ) ) {
			return array(
				'id'   => 0,
				'url'  => false,
				'size' => \BRICKS_DEFAULT_IMAGE_SIZE,
			);
		}

		$image = $settings[ $setting_name ];

		// Size.
		$image['size'] = empty( $image['size'] ) ? \BRICKS_DEFAULT_IMAGE_SIZE : $settings[ $setting_name ]['size'];

		// Image ID or URL from dynamic data.
		if ( ! empty( $image['useDynamicData'] ) ) {

			$images = $this->render_dynamic_data_tag( $image['useDynamicData'], 'image', array( 'size' => $image['size'] ) );

			if ( ! empty( $images[0] ) ) {
				if ( is_numeric( $images[0] ) ) {
					$image['id'] = $images[0];
				} else {
					$image['url'] = $images[0];
				}
			}
		}

		$image['id'] = empty( $image['id'] ) ? 0 : $image['id'];

		// If External URL, $image['url'] is already set.
		if ( ! isset( $image['url'] ) ) {
			$image['url'] = ! empty( $image['id'] ) ? wp_get_attachment_image_url( $image['id'], $image['size'] ) : false;
		}

		return $image;
	}

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

		// Icon.
		if ( isset( $this->settings['icon'] ) ) {
			$icon = self::render_icon( $this->settings['icon'], array( 'x-marker_marker-icon' ) );
		} else {
			$icon = false;
		}

		$image      = $this->get_normalized_image_settings( $this->settings, 'image' );
		$image_id   = $image['id'];
		$image_url  = $image['url'];
		$image_size = $image['size'];

		$alt_text = isset( $this->settings['altText'] ) ? esc_attr( bricks_render_dynamic_data( $this->settings['altText'] ) ) : '';

		$markers = empty( $this->settings['markers'] ) ? false : $this->settings['markers'];

		$config = array(
			'placement'      => isset( $this->settings['placement'] ) ? $this->settings['placement'] : 'auto',
			'offsetSkidding' => isset( $this->settings['offsetSkidding'] ) ? intval( $this->settings['offsetSkidding'] ) : 0,
			'offsetDistance' => isset( $this->settings['offsetDistance'] ) ? intval( $this->settings['offsetDistance'] ) : 10,
			'moveTransition' => isset( $this->settings['moveTransition'] ) ? intval( $this->settings['moveTransition'] ) : 200,
			'interaction'    => isset( $this->settings['interaction'] ) ? $this->settings['interaction'] : 'click',
			'pulseType'      => isset( $this->settings['pulseType'] ) ? $this->settings['pulseType'] : 'double',
			'moveFocus'      => isset( $this->settings['moveFocus'] ) ? 'enable' === $this->settings['moveFocus'] : true,
		);

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

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

		$output = "<div {$this->render_attributes( '_root' )}>";

		if ( ! isset( $this->settings['image'] ) ) {
			$output .= \BricksExtras\Helpers::placeholder_image();
		} else {

			if ( ! empty( $this->settings['altText'] ) ) {
				$image_attr = array(
					'class' => 'x-hotspots_image',
					'alt'   => esc_attr( bricks_render_dynamic_data( $this->settings['altText'] ) ),
				);
			} else {
				$image_attr = array( 'class' => 'x-hotspots_image' );
			}

			$image = wp_get_attachment_image(
				$image_id,
				$image_size,
				false,
				$image_attr
			);

			$output .= $image ? $image : ( '' !== $image_url ? '<img src="' . esc_url( $image_url ) . '" alt="' . esc_attr( $alt_text ) . '">' : '' );

		}

		$type = isset( $this->settings['type'] ) ? $this->settings['type'] : 'hotspots';

		if ( 'nestable' === $type ) {

			$this->set_attribute( 'x-image-hotspots_inner', 'class', array( 'x-image-hotspots_inner' ) );

			if ( method_exists( '\Bricks\Frontend', 'render_children' ) ) {
				$output .= "<div {$this->render_attributes( 'x-image-hotspots_inner' )}>";
				$output .= \Bricks\Frontend::render_children( $this );
				$output .= '</div>';
			}
		} elseif ( isset( $this->settings['hasLoop'] ) ) {
			// Query Loop.
			$query = new \Bricks\Query(
				array(
					'id'       => $this->id,
					'settings' => $this->settings,
				)
			);

			$marker = $markers[0];

			$output .= $query->render( array( $this, 'render_repeater_item' ), compact( 'marker', 'icon' ) );

			$query->destroy();
			unset( $query );
		} else {
			foreach ( $markers as $index => $marker ) {
				$output .= self::render_repeater_item( $marker, $icon );
			}
		}

		$output .= '</div>';

		echo $output;
	}


	/**
	 * Render repeater item.
	 *
	 * @param array  $marker Marker configuration.
	 * @param string $icon Icon HTML.
	 */
	public function render_repeater_item( $marker, $icon ) {

		$settings = $this->settings;
		$index    = $this->loop_index;
		$output   = '';

		$this->set_attribute( "x-marker-$index", 'class', array( 'x-marker' ) );
		$this->set_attribute( "x-marker_marker-$index", 'class', array( 'x-marker_marker' ) );
		$this->set_attribute( "x-marker_marker-inner-$index", 'class', array( 'x-marker_marker-inner' ) );

		$identifier = \BricksExtras\Helpers::generate_unique_identifier( $this->element, $this->id );

		$this->set_attribute( "x-marker-$index", 'data-x-id', $identifier . '_' . $index );

		$this->set_attribute(
			"x-marker_marker-$index",
			'style',
			array(
				'left: ' . esc_attr( bricks_render_dynamic_data( $marker['position_x'] ) ) . ';',
				'top: ' . esc_attr( bricks_render_dynamic_data( $marker['position_y'] ) ) . ';',
			)
		);

		$marker_type_setting = isset( $marker['markerType'] ) ? $marker['markerType'] : 'popover';

		$marker_type = strstr( $marker_type_setting, '{' ) ? $this->render_dynamic_data_tag( $marker_type_setting, 'text' ) : $marker_type_setting;

		$marker_is_link = 'popover' !== $marker_type;

		$this->set_attribute( "x-marker_popover-$index", 'class', array( 'x-marker_popover' ) );
		$this->set_attribute( "x-marker_popover-content-$index", 'class', array( 'x-marker_popover-content' ) );
		$this->set_attribute( "x-marker_marker-title-$index", 'class', array( 'x-marker_marker-title' ) );

		$link = ! empty( $marker['link'] ) ? $marker['link'] : '';

		if ( ! $marker_is_link ) {

			$this->set_attribute(
				"x-marker_marker-$index",
				'role',
				array(
					'button',
				)
			);

			$this->set_attribute( "x-marker_marker-$index", 'class', 'x-marker_marker-trigger' );

			$this->set_attribute(
				"x-marker_marker-$index",
				'aria-label',
				array(
					esc_attr( bricks_render_dynamic_data( $marker['aria_label'] ) ),
				)
			);

			$this->set_attribute(
				"x-marker_marker-$index",
				'tabindex',
				array(
					'0',
				)
			);

		} else {
			$this->set_link_attributes( "x-marker_marker-$index", $link );

			if ( 'both' === $marker_type ) {
				$this->set_attribute( "x-marker_marker-$index", 'class', 'x-marker_marker-trigger' );
			}
		}

		$custom_attributes = isset( $marker['custom_attributes'] ) ? $marker['custom_attributes'] : array();

		if ( count( $custom_attributes ) !== 0 ) {

			foreach ( $custom_attributes as $attribute ) {

				$attribute_name  = isset( $attribute['name'] ) ? esc_attr( bricks_render_dynamic_data( $attribute['name'] ) ) : '';
				$attribute_value = isset( $attribute['value'] ) ? esc_attr( bricks_render_dynamic_data( $attribute['value'] ) ) : '';

				$this->set_attribute( "x-marker_marker-$index", $attribute_name, $attribute_value );

			}
		}

		$maybe_marker_image = false;
		$image_output       = '';

		$marker_image_alt_text = isset( $marker['markerImageAltText'] ) ? esc_attr( bricks_render_dynamic_data( $marker['markerImageAltText'] ) ) : '';

		if ( isset( $marker['markerImage'] ) ) {

			if ( ! empty( $marker['markerImageAltText'] ) ) {
				$marker_image_attr = array(
					'class' => 'x-hotspots_marker-image',
					'alt'   => $marker_image_alt_text,
				);
			} else {
				$marker_image_attr = array( 'class' => 'x-hotspots_marker-image' );
			}

			$marker_image      = $this->get_normalized_image_settings( $marker, 'markerImage' );
			$marker_image_id   = $marker_image['id'];
			$marker_image_url  = $marker_image['url'];
			$marker_image_size = $marker_image['size'];

			if ( $marker_image_id ) {

				$maybe_marker_image = true;

				$marker_image_output = wp_get_attachment_image(
					$marker_image_id,
					$marker_image_size,
					false,
					$marker_image_attr
				);

				$image_output .= $marker_image_output;

			} elseif ( '' !== $marker_image_url ) {

					$maybe_marker_image = true;

					$image_output .= \BricksExtras\Helpers::placeholder_image(
						array(
							'src'   => $marker_image_url,
							'class' => 'x-hotspots_marker-image',
							'alt'   => $marker_image_alt_text,
						)
					);
			}
		}

		$marker_tag = $marker_is_link ? 'a' : 'button';

		$output .= "<div {$this->render_attributes( "x-marker-$index" )}>";

			$output .= '<' . $marker_tag . " {$this->render_attributes( "x-marker_marker-$index" )}><span {$this->render_attributes( "x-marker_marker-inner-$index" )}>";

		if ( (bool) $maybe_marker_image ) {
			$output .= $image_output;
		} elseif ( $icon ) {
				$output .= $icon;
		}

		if ( ! empty( $marker['title'] ) ) {
				$output .= "<span {$this->render_attributes( "x-marker_marker-title-$index" )}>" . wp_kses_post( bricks_render_dynamic_data( $marker['title'] ) ) . '</span>';
		}

			$output .= '</span></' . $marker_tag . '>';

		if ( isset( $marker['content'] ) ) {

			$content = $this->render_dynamic_data( $marker['content'] );
			$output .= 'link' !== $marker_type ? "<div {$this->render_attributes( "x-marker_popover-$index" )}><div {$this->render_attributes( "x-marker_popover-content-$index" )}>" . \Bricks\Helpers::parse_editor_content( $content ) . '</div></div>' : '';
		}

		$output .= '</div>';

		++$this->loop_index;

		return $output;
	}
}
