<?php
/**
 * Panorama Viewer element.
 *
 * @package BricksExtras
 */

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

/**
 * Panorama Viewer element class.
 */
class X_Panorama_Viewer extends \Bricks\Element {

	/**
	 * Element category.
	 *
	 * @var string
	 */
	public $category = 'extras';
	/**
	 * Element name.
	 *
	 * @var string
	 */
	public $name = 'xpanoramaviewer';
	/**
	 * Element icon.
	 *
	 * @var string
	 */
	public $icon = 'ti-world';
	/**
	 * CSS selector.
	 *
	 * @var string
	 */
	public $css_selector = '';
	/**
	 * Required scripts.
	 *
	 * @var array
	 */
	public $scripts = array( 'xPanoramaViewer' );
	/**
	 * 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__( 'Panorama Viewer', 'bricksextras' );
	}

	/**
	 * Get element keywords.
	 */
	public function get_keywords() {
		return array( '360', 'panorama', 'virtual tour', 'equirectangular', 'immersive', 'vr' );
	}

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

		$this->control_groups['viewer'] = array(
			'title' => esc_html__( 'Viewer Settings', 'bricksextras' ),
			'tab'   => 'content',
		);

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

		$this->control_groups['interaction'] = array(
			'title' => esc_html__( 'User Interaction', 'bricksextras' ),
			'tab'   => 'content',
		);

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

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

		$this->control_groups['sceneTitles'] = array(
			'title' => esc_html__( 'Scene Titles', 'bricks' ),
			'tab'   => 'content',
		);

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

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

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

		$this->controls['_justifyContent']['css'][0]['selector'] = '.x-panorama-viewer_inner';
		$this->controls['_alignItems']['css'][0]['selector']     = '.x-panorama-viewer_inner';
		$this->controls['_gap']['css'][0]['selector']            = '.x-panorama-viewer_inner';
		$this->controls['_flexDirection']['css'][0]['selector']  = '.x-panorama-viewer_inner';

		// Dimensions.
		$this->controls['aspectRatio'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Aspect ratio', 'bricks' ),
			'type'        => 'number',
			'units'       => false,
			'info'        => esc_html__( 'Refresh canvas after change if image stretched', 'bricksextras' ),
			'placeholder' => '2/1',
			'css'         => array(
				array(
					'selector' => '',
					'property' => 'aspect-ratio',
				),
			),
		);

		// Viewer Settings Group.

		$this->controls['pitch'] = array(
			'tab'         => 'content',
			'group'       => 'viewer',
			'label'       => 'Pitch (' . esc_html__( 'Initial', 'bricks' ) . ')',
			'type'        => 'number',
			'placeholder' => '0',
			'description' => esc_html__( 'Vertical', 'bricks' ) . ' (°)',
		);

		$this->controls['yaw'] = array(
			'tab'         => 'content',
			'group'       => 'viewer',
			'label'       => 'Yaw (' . esc_html__( 'Initial', 'bricksextras' ) . ')',
			'type'        => 'number',
			'placeholder' => '0',
			'description' => esc_html__( 'Horizontal', 'bricks' ) . ' (°)',
		);

		$this->controls['hfov'] = array(
			'tab'         => 'content',
			'group'       => 'viewer',
			'label'       => esc_html__( 'Field of view', 'bricksextras' ),
			'type'        => 'number',
			'placeholder' => '110',
			'min'         => 10,
			'max'         => 120,
		);

		$this->controls['autoRotate'] = array(
			'tab'         => 'content',
			'group'       => 'viewer',
			'label'       => esc_html__( 'Auto rotate speed', 'bricksextras' ),
			'type'        => 'number',
			'placeholder' => '0',
			'description' => esc_html__( 'Rotation speed in degrees per second (0 = disabled)', 'bricksextras' ),
		);

		// Controls Group.
		$this->controls['showZoomCtrl'] = array(
			'tab'         => 'content',
			'group'       => 'interaction',
			'label'       => esc_html__( 'Zoom Control', 'bricks' ),
			'type'        => 'select',
			'options'     => array(
				'enable'  => esc_html__( 'Enable', 'bricks' ),
				'disable' => esc_html__( 'Disable', 'bricks' ),
			),
			'inline'      => true,
			'placeholder' => esc_html__( 'Enable', 'bricks' ),
		);

		$this->controls['showFullscreenCtrl'] = array(
			'tab'         => 'content',
			'group'       => 'interaction',
			'label'       => esc_html__( 'Fullscreen Control', 'bricks' ),
			'type'        => 'select',
			'options'     => array(
				'enable'  => esc_html__( 'Enable', 'bricks' ),
				'disable' => esc_html__( 'Disable', 'bricks' ),
			),
			'inline'      => true,
			'placeholder' => esc_html__( 'Enable', 'bricks' ),
		);

		$this->controls['fullscreenFallback'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Fallback', 'bricks' ) . ' (' . esc_html__( 'Fullscreen', 'bricks' ) . ')',
			'group'       => 'interaction',
			'type'        => 'select',
			'options'     => array(
				'enable'  => esc_html__( 'Enable', 'bricks' ),
				'disable' => esc_html__( 'Disable', 'bricks' ),
			),
			'inline'      => true,
			'placeholder' => esc_html__( 'Enable', 'bricks' ),
			'info'        => esc_html__( 'Full window for browsers not supporting fullscreen', 'bricksextras' ),
			'required'    => array( 'showFullscreenCtrl', '!=', 'disable' ),
		);

		$this->controls['mouseZoom'] = array(
			'tab'         => 'content',
			'group'       => 'interaction',
			'label'       => esc_html__( 'Mouse wheel Zoom', 'bricksextras' ),
			'type'        => 'select',
			'options'     => array(
				'enable'  => esc_html__( 'Enable', 'bricks' ),
				'disable' => esc_html__( 'Disable', 'bricks' ),
			),
			'inline'      => true,
			'placeholder' => esc_html__( 'Enable', 'bricks' ),
		);

		$this->controls['mouseZoomSensitivity'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Scroll sensitivity', 'bricksextras' ),
			'group'       => 'interaction',
			'type'        => 'number',
			'min'         => 0.1,
			'max'         => 5,
			'step'        => 0.1,
			'placeholder' => '1',
			'info'        => esc_html__( 'Lower values = less sensitive scrolling', 'bricksextras' ),
		);

		$this->controls['friction'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Movement friction', 'bricksextras' ),
			'group'       => 'interaction',
			'type'        => 'number',
			'min'         => 0.01,
			'max'         => 1,
			'step'        => 0.01,
			'placeholder' => '0.5',
			'info'        => esc_html__( 'Higher values = stops movement faster', 'bricksextras' ),
		);

		$this->controls['draggable'] = array(
			'tab'         => 'content',
			'group'       => 'interaction',
			'label'       => esc_html__( 'Draggable', 'bricks' ),
			'type'        => 'select',
			'options'     => array(
				'enable'  => esc_html__( 'Enable', 'bricks' ),
				'disable' => esc_html__( 'Disable', 'bricks' ),
			),
			'inline'      => true,
			'placeholder' => esc_html__( 'Enable', 'bricks' ),
		);

		$this->controls['disableKeyboardCtrl'] = array(
			'tab'         => 'content',
			'group'       => 'interaction',
			'label'       => esc_html__( 'Keyboard controls', 'bricksextras' ),
			'type'        => 'select',
			'options'     => array(
				'enable'  => esc_html__( 'Enable', 'bricks' ),
				'disable' => esc_html__( 'Disable', 'bricks' ),
			),
			'inline'      => true,
			'placeholder' => esc_html__( 'Enable', 'bricks' ),
		);

		$this->controls['ariaLabelsSep'] = array(
			'type'  => 'separator',
			'label' => esc_html__( 'Aria Labels', 'bricksextras' ),
			'group' => 'labels',
		);

		$this->controls['ariaViewer'] = array(
			'tab'         => 'content',
			'group'       => 'labels',
			'label'       => esc_html__( 'Viewer', 'bricksextras' ),
			'type'        => 'text',
			'inline'      => true,
			'placeholder' => esc_html__( 'Panorama viewer', 'bricksextras' ),
		);

		$this->controls['ariaZoomIn'] = array(
			'tab'         => 'content',
			'group'       => 'labels',
			'label'       => esc_html__( 'Zoom in', 'bricksextras' ),
			'inline'      => true,
			'type'        => 'text',
			'placeholder' => esc_html__( 'Zoom in', 'bricksextras' ),
			'required'    => array( 'showZoomCtrl', '!=', 'disable' ),
		);

		$this->controls['ariaZoomOut'] = array(
			'tab'         => 'content',
			'group'       => 'labels',
			'label'       => esc_html__( 'Zoom out', 'bricksextras' ),
			'type'        => 'text',
			'inline'      => true,
			'placeholder' => esc_html__( 'Zoom out', 'bricksextras' ),
			'required'    => array( 'showZoomCtrl', '!=', 'disable' ),
		);

		$this->controls['ariaFullscreen'] = array(
			'tab'         => 'content',
			'group'       => 'labels',
			'label'       => esc_html__( 'Fullscreen', 'bricksextras' ),
			'type'        => 'text',
			'inline'      => true,
			'placeholder' => esc_html__( 'Toggle fullscreen', 'bricksextras' ),
			'required'    => array( 'showFullscreenCtrl', '!=', 'disable' ),
		);

		$this->controls['ariaBackButton'] = array(
			'tab'         => 'content',
			'group'       => 'labels',
			'label'       => esc_html__( 'Back', 'bricksextras' ),
			'type'        => 'text',
			'inline'      => true,
			'placeholder' => esc_html__( 'Go back to previous scene', 'bricksextras' ),
		);

		$this->controls['showScrollInstructions'] = array(
			'tab'         => 'content',
			'group'       => 'scrollInstructions',
			'label'       => esc_html__( 'Display gesture instructions', 'bricksextras' ),
			'type'        => 'select',
			'options'     => array(
				'enable'  => esc_html__( 'Enable', 'bricks' ),
				'disable' => esc_html__( 'Disable', 'bricks' ),
			),
			'inline'      => true,
			'placeholder' => esc_html__( 'Enable', 'bricks' ),
		);

		$this->controls['previewScrollInstructions'] = array(
			'type'     => 'checkbox',
			'label'    => esc_html__( 'Preview', 'bricks' ),
			'group'    => 'scrollInstructions',
			'required' => array(
				'showScrollInstructions',
				'!=',
				'disable',
			),
		);

		$this->controls['scrollInstructionsDesktopText'] = array(
			'tab'         => 'content',
			'group'       => 'scrollInstructions',
			'label'       => esc_html__( 'Desktop instructions text', 'bricksextras' ),
			'type'        => 'text',
			'placeholder' => sprintf(
			/* translators: %s: Key combination placeholder */
				esc_html__( 'Use %s + scroll to zoom', 'bricksextras' ),
				'{x_key}'
			),
			'required'    => array(
				'showScrollInstructions',
				'!=',
				'disable',
			),
		);

		$this->controls['scrollInstructionsMobileText'] = array(
			'tab'         => 'content',
			'group'       => 'scrollInstructions',
			'label'       => esc_html__( 'Touch device instructions text', 'bricksextras' ),
			'type'        => 'text',
			'placeholder' => esc_html__( 'Use two fingers to navigate', 'bricksextras' ),
			'required'    => array(
				'showScrollInstructions',
				'!=',
				'disable',
			),
		);

		$this->controls['scrollInstructionsStyleSep'] = array(
			'type'     => 'separator',
			'label'    => esc_html__( 'Overlay', 'bricks' ),
			'group'    => 'scrollInstructions',
			'required' => array(
				'showScrollInstructions',
				'!=',
				'disable',
			),
		);

		$this->controls['scrollInstructionsTypography'] = array(
			'tab'      => 'content',
			'group'    => 'scrollInstructions',
			'label'    => esc_html__( 'Typography', 'bricks' ),
			'type'     => 'typography',
			'css'      => array(
				array(
					'property' => 'font',
					'selector' => '.pnlm-scroll-instructions',
				),
			),
			'required' => array(
				'showScrollInstructions',
				'!=',
				'disable',
			),
		);

		$this->controls['scrollInstructionsBackground'] = array(
			'tab'      => 'content',
			'group'    => 'scrollInstructions',
			'label'    => esc_html__( 'Background', 'bricks' ),
			'type'     => 'background',
			'css'      => array(
				array(
					'property' => 'background',
					'selector' => '.pnlm-scroll-instructions',
				),
			),
			'required' => array(
				'showScrollInstructions',
				'!=',
				'disable',
			),
		);

		$this->controls['scrollInstructionsPadding'] = array(
			'tab'      => 'content',
			'group'    => 'scrollInstructions',
			'label'    => esc_html__( 'Padding', 'bricks' ),
			'type'     => 'spacing',
			'css'      => array(
				array(
					'property' => 'padding',
					'selector' => '.pnlm-scroll-instructions',
				),
			),
			'required' => array(
				'showScrollInstructions',
				'!=',
				'disable',
			),
		);

		$this->controls['scrollInstructionsBorder'] = array(
			'tab'      => 'content',
			'group'    => 'scrollInstructions',
			'label'    => esc_html__( 'Border', 'bricks' ),
			'type'     => 'border',
			'css'      => array(
				array(
					'property' => 'border',
					'selector' => '.pnlm-scroll-instructions',
				),
			),
			'required' => array(
				'showScrollInstructions',
				'!=',
				'disable',
			),
		);

		$this->controls['scrollInstructionsBoxShadow'] = array(
			'tab'      => 'content',
			'group'    => 'scrollInstructions',
			'label'    => esc_html__( 'Box shadow', 'bricks' ),
			'type'     => 'box-shadow',
			'css'      => array(
				array(
					'property' => 'box-shadow',
					'selector' => '.pnlm-scroll-instructions',
				),
			),
			'required' => array(
				'showScrollInstructions',
				'!=',
				'disable',
			),
		);

		$this->controls['scrollInstructionsWidth'] = array(
			'tab'         => 'content',
			'group'       => 'scrollInstructions',
			'label'       => esc_html__( 'Width', 'bricks' ),
			'type'        => 'number',
			'units'       => true,
			'css'         => array(
				array(
					'property' => 'width',
					'selector' => '.pnlm-scroll-instructions',
				),
			),
			'placeholder' => '100%',
			'required'    => array(
				'showScrollInstructions',
				'!=',
				'disable',
			),
		);

		$this->controls['scrollInstructionsHeight'] = array(
			'tab'         => 'content',
			'group'       => 'scrollInstructions',
			'label'       => esc_html__( 'Height', 'bricks' ),
			'type'        => 'number',
			'units'       => true,
			'css'         => array(
				array(
					'property' => 'height',
					'selector' => '.pnlm-scroll-instructions',
				),
			),
			'placeholder' => '100%',
			'required'    => array(
				'showScrollInstructions',
				'!=',
				'disable',
			),
		);

		$this->controls['scrollInstructionsMaxWidth'] = array(
			'tab'      => 'content',
			'group'    => 'scrollInstructions',
			'label'    => esc_html__( 'Max. width', 'bricks' ),
			'type'     => 'number',
			'units'    => true,
			'css'      => array(
				array(
					'property' => 'max-width',
					'selector' => '.pnlm-scroll-instructions',
				),
			),
			'required' => array(
				'showScrollInstructions',
				'!=',
				'disable',
			),
		);

		$this->controls['loadingStrategySep'] = array(
			'type'  => 'separator',
			'label' => esc_html__( 'Loading', 'bricks' ),
			'group' => 'loading',
		);

		$this->controls['loadingStrategy'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Loading method', 'bricks' ),
			'type'        => 'select',
			'group'       => 'loading',
			'options'     => array(
				'eager'        => esc_html__( 'Eager', 'bricks' ),
				'lazy'         => esc_html__( 'Lazy', 'bricks' ),
				'click'        => esc_html__( 'Click', 'bricks' ),
				'interactions' => esc_html__( 'Interactions', 'bricks' ),
			),
			'inline'      => true,
			'placeholder' => esc_html__( 'Lazy', 'bricks' ),
		);

		$this->controls['hideNestedContentInfo'] = array(
			'tab'      => 'content',
			'group'    => 'loading',
			'content'  => esc_html__( 'Nest content inside viewer to inform the user to click to load', 'bricksextras' ),
			'type'     => 'info',
			'required' => array( 'loadingStrategy', '=', 'click' ),
		);

		$this->controls['hideNestedContent'] = array(
			'tab'      => 'content',
			'group'    => 'loading',
			'label'    => esc_html__( 'Hide Nested Content in Builder', 'bricksextras' ),
			'type'     => 'checkbox',
			'inline'   => true,
			'required' => array( 'loadingStrategy', '=', 'click' ),
		);

		$this->controls['hideNestedContentOverlayColor'] = array(
			'tab'      => 'content',
			'group'    => 'loading',
			'label'    => esc_html__( 'Color', 'bricks' ) . ' (' . esc_html__( 'Overlay', 'bricks' ) . ')',
			'type'     => 'color',
			'inline'   => true,
			'css'      => array(
				array(
					'property' => 'background-color',
					'selector' => '.x-panorama-viewer_inner',
				),
			),
			'required' => array( 'loadingStrategy', '=', 'click' ),
		);

		$this->controls['placeholderImage'] = array(
			'group' => 'loading',
			'tab'   => 'content',
			'label' => esc_html__( 'Placeholder', 'bricks' ),
			'type'  => 'image',
			'info'  => esc_html__( 'Small image displayed before panorama image loads', 'bricksextras' ),
		);

		$this->controls['spinnerStyleSep'] = array(
			'type'  => 'separator',
			'label' => esc_html__( 'Spinner', 'bricks' ),
			'group' => 'loading',
		);

		$this->controls['previewSpinner'] = array(
			'type'  => 'checkbox',
			'label' => esc_html__( 'Preview', 'bricks' ),
			'group' => 'loading',
		);

		$this->controls['spinnerColor'] = array(
			'tab'   => 'content',
			'group' => 'loading',
			'type'  => 'color',
			'label' => esc_html__( 'Color', 'bricks' ),
			'css'   => array(
				array(
					'property' => 'color',
					'selector' => '.x-panorama-viewer::before',
				),
			),
		);

		$this->controls['spinnerTrackColor'] = array(
			'tab'   => 'content',
			'group' => 'loading',
			'type'  => 'color',
			'label' => esc_html__( 'Track color', 'bricks' ),
			'css'   => array(
				array(
					'property' => '--x-panorama-spinner-track-color',
					'selector' => '',
				),
			),
		);

		$this->controls['spinnerStrokeWidth'] = array(
			'tab'         => 'content',
			'group'       => 'loading',
			'type'        => 'number',
			'placeholder' => '2px',
			'units'       => true,
			'label'       => esc_html__( 'Width', 'bricks' ),
			'css'         => array(
				array(
					'property' => '--x-panorama-spinner-stroke-width',
					'selector' => '',
				),
			),
		);

		$this->controls['spinnerSize'] = array(
			'tab'         => 'content',
			'group'       => 'loading',
			'type'        => 'number',
			'units'       => true,
			'placeholder' => '3em',
			'label'       => esc_html__( 'Size', 'bricks' ),
			'css'         => array(
				array(
					'property' => '--x-panorama-spinner-size',
					'selector' => '',
				),
			),
		);

		$this->controls['hotSpotDebugSep'] = array(
			'type' => 'separator',
		);

		$this->controls['hotSpotDebug'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Hotspot debug', 'bricksextras' ),
			'type'        => 'checkbox',
			'inline'      => true,
			'description' => esc_html__( 'Preview', 'bricks' ) . ' (Pitch/Yaw)',
		);

		$hotspot_selector       = '.pnlm-hotspot-icon';
		$hotspot_selector_inner = '.pnlm-hotspot-icon-inner';

		// HOTSPOT ICON STYLING.
		$this->controls['hotspotIconBackground'] = array(
			'tab'   => 'style',
			'group' => 'hotspotIcon',
			'label' => esc_html__( 'Background', 'bricks' ),
			'type'  => 'background',
			'css'   => array(
				array(
					'property' => 'background',
					'selector' => $hotspot_selector_inner,
				),
			),
		);

		$this->controls['hotspotIconBorder'] = array(
			'tab'   => 'style',
			'group' => 'hotspotIcon',
			'label' => esc_html__( 'Border', 'bricks' ),
			'type'  => 'border',
			'css'   => array(
				array(
					'property' => 'border',
					'selector' => $hotspot_selector_inner,
				),
			),
		);

		$this->controls['hotspotIconBoxShadow'] = array(
			'tab'   => 'style',
			'group' => 'hotspotIcon',
			'label' => esc_html__( 'Box shadow', 'bricks' ),
			'type'  => 'box-shadow',
			'css'   => array(
				array(
					'property' => 'box-shadow',
					'selector' => '.pnlm-hotspot-icon',
				),
			),
		);

		$this->controls['hotspotIconPadding'] = array(
			'tab'   => 'style',
			'group' => 'hotspotIcon',
			'label' => esc_html__( 'Padding', 'bricks' ),
			'type'  => 'spacing',
			'css'   => array(
				array(
					'property' => 'padding',
					'selector' => $hotspot_selector_inner,
				),
			),
		);

		$this->controls['hotspotIconWidth'] = array(
			'tab'   => 'style',
			'group' => 'hotspotIcon',
			'label' => esc_html__( 'Width', 'bricks' ),
			'type'  => 'number',
			'units' => true,
			'css'   => array(
				array(
					'property' => 'width',
					'selector' => $hotspot_selector_inner,
				),
			),
		);

		$this->controls['hotspotIconHeight'] = array(
			'tab'   => 'style',
			'group' => 'hotspotIcon',
			'label' => esc_html__( 'Height', 'bricks' ),
			'type'  => 'number',
			'units' => true,
			'css'   => array(
				array(
					'property' => 'height',
					'selector' => $hotspot_selector_inner,
				),
			),
		);

		$this->controls['hotspotIconTypography'] = array(
			'tab'   => 'style',
			'group' => 'hotspotIcon',
			'label' => esc_html__( 'Typography', 'bricks' ),
			'type'  => 'typography',
			'css'   => array(
				array(
					'property' => 'font',
					'selector' => $hotspot_selector_inner,
				),
			),
		);

		$this->controls['hotspotPulseSep'] = array(
			'type'  => 'separator',
			'label' => esc_html__( 'Pulse Effect', 'bricksextras' ),
			'group' => 'hotspotIcon',
		);

		// PULSE EFFECT CONTROLS.
		$this->controls['hotspotPulseColor'] = array(
			'tab'   => 'style',
			'group' => 'hotspotIcon',
			'label' => esc_html__( 'Color', 'bricks' ),
			'type'  => 'color',
			'css'   => array(
				array(
					'property' => '--x-panorama-pulse-color',
					'selector' => '',
				),
			),
		);

		$this->controls['hotspotPulseDuration'] = array(
			'tab'         => 'style',
			'group'       => 'hotspotIcon',
			'label'       => esc_html__( 'Duration', 'bricks' ),
			'type'        => 'number',
			'units'       => true,
			'placeholder' => '2s',
			'css'         => array(
				array(
					'property' => '--x-panorama-pulse-duration',
					'selector' => '',
				),
			),
		);

		$this->controls['hotspotPulseSize'] = array(
			'tab'         => 'style',
			'group'       => 'hotspotIcon',
			'label'       => esc_html__( 'Size', 'bricks' ),
			'type'        => 'number',
			'units'       => false,
			'placeholder' => '2',
			'css'         => array(
				array(
					'property' => '--x-panorama-pulse-size',
					'selector' => '',
				),
			),
		);

		$this->controls['hotspotPulseDisable'] = array(
			'tab'   => 'style',
			'group' => 'hotspotIcon',
			'label' => esc_html__( 'Disable Pulse on Hover', 'bricksextras' ),
			'type'  => 'checkbox',
		);

		// HOTSPOT TOOLTIP STYLING todo.

		$this->controls['hotspotTooltipWidth'] = array(
			'tab'         => 'style',
			'group'       => 'hotspotTooltip',
			'label'       => esc_html__( 'Width', 'bricks' ),
			'type'        => 'number',
			'placeholder' => '100px',
			'units'       => true,
			'css'         => array(
				array(
					'property' => 'width',
					'selector' => '.pnlm-hotspot-tooltip',
				),
			),
		);

		$this->controls['hotspotTooltipMaxWidth'] = array(
			'tab'   => 'style',
			'group' => 'hotspotTooltip',
			'label' => esc_html__( 'Max. width', 'bricks' ),
			'type'  => 'number',
			'units' => true,
			'css'   => array(
				array(
					'property' => 'max-width',
					'selector' => '.pnlm-hotspot-tooltip',
				),
			),
		);

		$this->controls['hotspotTooltipBackground'] = array(
			'tab'   => 'style',
			'group' => 'hotspotTooltip',
			'label' => esc_html__( 'Background', 'bricks' ),
			'type'  => 'color',
			'css'   => array(
				array(
					'property' => 'background-color',
					'selector' => '.pnlm-hotspot-tooltip',
				),
				array(
					'property' => 'border-top-color',
					'selector' => '.pnlm-hotspot-tooltip:after',
				),
			),
		);

		$this->controls['hotspotTooltipBackground'] = array(
			'tab'   => 'style',
			'group' => 'hotspotTooltip',
			'label' => esc_html__( 'Background', 'bricks' ),
			'type'  => 'color',
			'css'   => array(
				array(
					'property' => 'background-color',
					'selector' => '.pnlm-hotspot-tooltip',
				),
				array(
					'property' => 'border-top-color',
					'selector' => '.pnlm-hotspot-tooltip:after',
				),
			),
		);

		$this->controls['hotspotTooltipTypography'] = array(
			'tab'   => 'style',
			'group' => 'hotspotTooltip',
			'label' => esc_html__( 'Typography', 'bricks' ),
			'type'  => 'typography',
			'css'   => array(
				array(
					'property' => 'font',
					'selector' => '.pnlm-hotspot-tooltip',
				),
			),
		);

		$this->controls['hotspotTooltipPadding'] = array(
			'tab'   => 'style',
			'group' => 'hotspotTooltip',
			'label' => esc_html__( 'Padding', 'bricks' ),
			'type'  => 'spacing',
			'css'   => array(
				array(
					'property' => 'padding',
					'selector' => '.pnlm-hotspot-tooltip',
				),
			),
		);

		$this->controls['hotspotTooltipBorder'] = array(
			'tab'   => 'style',
			'group' => 'hotspotTooltip',
			'label' => esc_html__( 'Border', 'bricks' ),
			'type'  => 'border',
			'css'   => array(
				array(
					'property' => 'border',
					'selector' => '.pnlm-hotspot-tooltip',
				),
			),
		);

		$this->controls['hotspotTooltipBoxShadow'] = array(
			'tab'   => 'style',
			'group' => 'hotspotTooltip',
			'label' => esc_html__( 'Box shadow', 'bricks' ),
			'type'  => 'box-shadow',
			'css'   => array(
				array(
					'property' => 'box-shadow',
					'selector' => '.pnlm-hotspot-tooltip',
				),
			),
		);

		/* scene titles */

		$scene_title_selector = '.pnlm-title-box';

		$this->controls['showSceneTitles'] = array(
			'tab'         => 'content',
			'group'       => 'sceneTitles',
			'type'        => 'select',
			'label'       => esc_html__( 'Show scene titles', 'bricksextras' ),
			'inline'      => true,
			'options'     => array(
				'true'  => esc_html__( 'True', 'bricksextras' ),
				'false' => esc_html__( 'False', 'bricksextras' ),
			),
			'placeholder' => esc_html__( 'False', 'bricksextras' ),
		);

		$this->controls['titleBackground'] = array(
			'tab'      => 'content',
			'group'    => 'sceneTitles',
			'type'     => 'background',
			'label'    => esc_html__( 'Background', 'bricks' ),
			'css'      => array(
				array(
					'property' => 'background',
					'selector' => $scene_title_selector,
				),
			),
			'required' => array( 'showSceneTitles', '=', 'true' ),
		);

		$this->controls['titleBorder'] = array(
			'tab'      => 'content',
			'group'    => 'sceneTitles',
			'type'     => 'border',
			'label'    => esc_html__( 'Border', 'bricks' ),
			'css'      => array(
				array(
					'property' => 'border',
					'selector' => $scene_title_selector,
				),
			),
			'required' => array( 'showSceneTitles', '=', 'true' ),
		);

		$this->controls['titleTypography'] = array(
			'tab'      => 'content',
			'group'    => 'sceneTitles',
			'type'     => 'typography',
			'label'    => esc_html__( 'Typography', 'bricks' ),
			'css'      => array(
				array(
					'property' => 'font',
					'selector' => $scene_title_selector,
				),
			),
			'required' => array( 'showSceneTitles', '=', 'true' ),
		);

		$this->controls['title_sep'] = array(
			'tab'      => 'content',
			'group'    => 'sceneTitles',
			'type'     => 'separator',
			'required' => array( 'showSceneTitles', '=', 'true' ),
		);

		$this->controls['titlePadding'] = array(
			'tab'      => 'content',
			'group'    => 'sceneTitles',
			'label'    => esc_html__( 'Padding', 'bricks' ),
			'type'     => 'spacing',
			'css'      => array(
				array(
					'property' => 'padding',
					'selector' => $scene_title_selector,
				),
			),
			'required' => array( 'showSceneTitles', '=', 'true' ),
		);

		$this->controls['titleMargin'] = array(
			'tab'      => 'content',
			'group'    => 'sceneTitles',
			'label'    => esc_html__( 'Margin', 'bricks' ),
			'type'     => 'spacing',
			'css'      => array(
				array(
					'property' => 'margin',
					'selector' => $scene_title_selector,
				),
			),
			'required' => array( 'showSceneTitles', '=', 'true' ),
		);
	}


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

		if ( bricks_is_builder_main() ) {
			return;
		}

		// Enqueue our custom script.

		wp_enqueue_script( 'x-pannellum', BRICKSEXTRAS_URL . 'components/assets/js/pannellum.min.js', array( 'bricks-scripts' ), '2.5.6', true );

		wp_enqueue_script( 'x-panoramaviewer', BRICKSEXTRAS_URL . 'components/assets/js/' . \BricksExtras\Helpers::maybe_minify_scripts( 'panoramaviewer' ) . '.js', array( 'x-pannellum' ), \BricksExtras\Plugin::VERSION, true );

		if ( ! self::$script_localized ) {

			wp_localize_script(
				'x-panoramaviewer',
				'xPanoramaViewer',
				array(
					'Instances' => array(),
				)
			);

			self::$script_localized = true;

		}

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


	/**
	 * Get nestable item.
	 */
	public function get_nestable_item() {

		return array(
			'name'     => 'xpanoramascene',
			'label'    => esc_html__( 'Panorama Scene', 'bricksextras' ),
			'settings' => array(
				'panoramaImage' => array(
					'url' => 'https://images.unsplash.com/photo-1707406045095-c333306c92f5?ixlib=rb-4.1.0&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&q=80&w=4120',
				),
			),
		);
	}

	/**
	 * Get nestable children.
	 */
	public function get_nestable_children() {
		return \BricksExtras\Helpers::get_nestable_children_helper( $this, 1 );
	}


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

		$settings = $this->settings;

		// Build configuration.
		$config = array(
			'type'        => 'equirectangular',
			'crossOrigin' => 'anonymous',
		);

		// Add scene ID if set (for tours).
		if ( ! empty( $settings['sceneId'] ) ) {
			$config['sceneId'] = sanitize_key( bricks_render_dynamic_data( $settings['sceneId'] ) );
		}

		// Optional settings.
		if ( isset( $settings['autoRotate'] ) && '' !== $settings['autoRotate'] ) {
			$config['autoRotate'] = floatval( $settings['autoRotate'] );
		}

		if ( isset( $settings['yaw'] ) && '' !== $settings['yaw'] ) {
			$config['yaw'] = floatval( $settings['yaw'] );
		}

		if ( isset( $settings['pitch'] ) && '' !== $settings['pitch'] ) {
			$config['pitch'] = floatval( $settings['pitch'] );
		}

		$config['hfov'] = isset( $settings['hfov'] ) ? floatval( $settings['hfov'] ) : 110;

		if ( isset( $settings['showZoomCtrl'] ) ) {
			$config['showZoomCtrl'] = 'enable' === $settings['showZoomCtrl'] ? true : false;
		}

		if ( isset( $settings['showFullscreenCtrl'] ) ) {
			$config['showFullscreenCtrl'] = 'enable' === $settings['showFullscreenCtrl'] ? true : false;
		}

		if ( isset( $settings['fullscreenFallback'] ) ) {
			$config['fullscreenFallback'] = 'enable' === $settings['fullscreenFallback'] ? true : false;
		}

		if ( isset( $settings['mouseZoom'] ) ) {
			$config['mouseZoom'] = 'enable' === $settings['mouseZoom'] ? true : false;
		}

		if ( isset( $settings['mouseZoomSensitivity'] ) && '' !== $settings['mouseZoomSensitivity'] ) {
			$config['mouseZoomSensitivity'] = floatval( $settings['mouseZoomSensitivity'] );
		}

		// Default to enabled unless explicitly disabled.
		$config['showScrollInstructions'] = ! isset( $settings['showScrollInstructions'] ) || 'disable' !== $settings['showScrollInstructions'];

		if ( isset( $settings['scrollInstructionsDesktopText'] ) && ! empty( $settings['scrollInstructionsDesktopText'] ) ) {
			$config['scrollInstructionsDesktopText'] = wp_kses_post( bricks_render_dynamic_data( $settings['scrollInstructionsDesktopText'] ) );
		}

		if ( isset( $settings['scrollInstructionsMobileText'] ) && ! empty( $settings['scrollInstructionsMobileText'] ) ) {
			$config['scrollInstructionsMobileText'] = wp_kses_post( bricks_render_dynamic_data( $settings['scrollInstructionsMobileText'] ) );
		}

		if ( isset( $settings['friction'] ) && '' !== $settings['friction'] ) {
			$config['friction'] = floatval( $settings['friction'] );
		}

		if ( isset( $settings['draggable'] ) ) {
			$config['draggable'] = 'enable' === $settings['draggable'] ? true : false;
		}

		if ( isset( $settings['disableKeyboardCtrl'] ) ) {
			$config['disableKeyboardCtrl'] = 'enable' === $settings['disableKeyboardCtrl'] ? true : false;
		}

		if ( ! empty( $settings['ariaZoomIn'] ) ) {
			$config['ariaZoomIn'] = bricks_render_dynamic_data( $settings['ariaZoomIn'] );
		}

		if ( ! empty( $settings['ariaZoomOut'] ) ) {
			$config['ariaZoomOut'] = bricks_render_dynamic_data( $settings['ariaZoomOut'] );
		}

		if ( ! empty( $settings['ariaFullscreen'] ) ) {
			$config['ariaFullscreen'] = bricks_render_dynamic_data( $settings['ariaFullscreen'] );
		}

		if ( ! empty( $settings['ariaBackButton'] ) ) {
			$config['ariaBackButton'] = bricks_render_dynamic_data( $settings['ariaBackButton'] );
		}

		if ( ! empty( $settings['ariaViewer'] ) ) {
			$config['ariaViewer'] = bricks_render_dynamic_data( $settings['ariaViewer'] );
		}

		if ( \BricksExtras\Helpers::maybe_preview() ) {
			$config['hotSpotDebug'] = isset( $settings['hotSpotDebug'] );
		}

		// Loading strategy.
		$loading_strategy          = isset( $settings['loadingStrategy'] ) ? esc_attr( $settings['loadingStrategy'] ) : 'lazy';
		$config['loadingStrategy'] = $loading_strategy;

		// Placeholder image for click to load.
		if ( ! empty( $settings['placeholderImage'] ) ) {
			$placeholder_image = \BricksExtras\Helpers::get_normalized_image_settings( $settings, 'placeholderImage' );
			if ( ! empty( $placeholder_image['url'] ) ) {
				$config['placeholderImage'] = esc_url( bricks_render_dynamic_data( $placeholder_image['url'] ) );
			}
		}

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

		// Set attributes.
		$this->set_attribute( '_root', 'data-panorama-config', htmlspecialchars( wp_json_encode( $config, JSON_HEX_APOS | JSON_HEX_QUOT ), ENT_QUOTES, 'UTF-8' ) );
		$this->set_attribute( '_root', 'data-loading-strategy', $loading_strategy );

		$this->set_attribute( '_root', 'data-show-scene-titles', ( isset( $settings['showSceneTitles'] ) && 'true' === $settings['showSceneTitles'] ) ? 'true' : 'false' );

		if ( \BricksExtras\Helpers::maybe_preview() && isset( $settings['hideNestedContent'] ) ) {
			$this->set_attribute( '_root', 'data-hide-nested-content', 'true' );
		}

		if ( \BricksExtras\Helpers::maybe_preview() ) {
			$this->set_attribute( '_root', 'data-preview-scroll-instructions', isset( $settings['previewScrollInstructions'] ) ? 'true' : 'false' );
			$this->set_attribute( '_root', 'data-preview-spinner', isset( $settings['previewSpinner'] ) ? 'true' : 'false' );
		}

		// Add data attribute for pulse disable setting.
		if ( ! empty( $settings['hotspotPulseDisable'] ) ) {
			$this->set_attribute( '_root', 'data-pulse-disable-hover', 'true' );
		}

		$output = '';

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

		$output .= "<div class='x-panorama-viewer'></div>";

		$output .= "<div class='x-panorama-viewer_inner'>";

		if ( method_exists( '\Bricks\Frontend', 'render_children' ) ) {
			$output .= \Bricks\Frontend::render_children( $this );
		}

		$output .= '</div>';

		$output .= '</div>';

		echo $output;
	}
}
