<?php
/**
 * Media Player Audio element.
 *
 * @package BricksExtras
 */

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

require_once BRICKSEXTRAS_PATH . 'components/traits/media-player-trait.php';

use BricksExtras\Components\Traits\Media_Player_Trait;

/**
 * Media Player Audio element class.
 */
class X_Media_Player_Audio extends \Bricks\Element {

	use Media_Player_Trait;

	/**
	 * Element category.
	 *
	 * @var string
	 */
	public $category = 'extras';
	/**
	 * Element name.
	 *
	 * @var string
	 */
	public $name = 'xmediaplayeraudio';
	/**
	 * Element icon.
	 *
	 * @var string
	 */
	public $icon = 'ti-microphone';
	/**
	 * Required scripts.
	 *
	 * @var array
	 */
	public $scripts = array( 'Vp', 'xDoMediaPlayer' );
	/**
	 * Loop index.
	 *
	 * @var int
	 */
	public $loop_index = 0;
	/**
	 * Element is nestable.
	 *
	 * @var bool
	 */
	public $nestable = true;
	/**
	 * Control fields array.
	 *
	 * @var array
	 */
	public $control_fields = array();


	/**
	 * Get element label.
	 */
	public function get_label() {
		return esc_html__( 'Media Player', 'bricksextras' ) . ' (' . esc_html__( 'Audio', 'bricks' ) . ')';
	}

	/**
	 * Get element keywords.
	 */
	public function get_keywords() {
		return array( 'video', 'audio', 'media', 'player', 'controls' );
	}


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

		// Audio-specific control groups.
		$this->control_groups['controlsAudio'] = array(
			'title' => esc_html__( 'Player UI', 'bricksextras' ),
		);

		$this->control_groups['controlsAudioLayout'] = array(
			'title'    => esc_html__( 'Customize UI', 'bricksextras' ),
			'required' => array(
				array( 'layoutTypeAudio', '!=', array( 'custom' ) ),
			),
		);

		$this->control_groups['styleGeneral'] = array(
			'title' => esc_html__( 'Styles', 'bricks' ) . ' (' . esc_html__( 'General', 'bricks' ) . ')',
		);

		$this->control_groups['styleControls'] = array(
			'title' => esc_html__( 'Styles', 'bricks' ) . ' (' . esc_html__( 'Controls', 'bricks' ) . ')',
		);

		$this->control_groups['poster'] = array(
			'title'    => esc_html__( 'Poster image', 'bricks' ),
			'required' => array( 'playlistMode', '!=', true ),
		);

		$this->control_groups['behaviour'] = array(
			'title' => esc_html__( 'Config', 'bricksextras' ) . ' / ' . esc_html__( 'Behavior', 'bricks' ),
			array( 'layoutType', '!=', 'custom' ),
		);

		// Tooltips group.
		$this->control_groups['tooltips'] = array(
			'title' => esc_html__( 'Tooltips', 'bricksextras' ),
		);

		// Text tracks group.
		$this->control_groups['textTracks'] = array(
			'title'    => esc_html__( 'Text Tracks', 'bricksextras' ),
			'required' => array( 'playlistMode', '!=', true ),
		);

		// Chapters group.
		$this->control_groups['chapters'] = array(
			'title'    => esc_html__( 'Chapters', 'bricksextras' ),
			'required' => array( 'playlistMode', '!=', true ),
		);

		// Keyboard Shortcuts group.
		$this->control_groups['keyboardShortcuts'] = array(
			'title' => esc_html__( 'Keyboard shortcuts', 'bricks' ),
		);

		// Playlists group.
		$this->control_groups['playLists'] = array(
			'title' => esc_html__( 'Playlists', 'bricksextras' ),
		);

		// Downloads group.
		$this->control_groups['downloads'] = array(
			'title'    => esc_html__( 'Downloads', 'bricks' ),
			'required' => array( 'playlistMode', '!=', true ),
		);
	}

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

		// Set audio-specific background and border selectors.
		$this->controls['_background']['css'][1]['selector'] = '&[data-x-view-type=audio]';
		$this->controls['_border']['css'][1]['selector'] = '&[data-x-view-type=audio]';

		// Define shared variables at the beginning of the method to make them available throughout.
		$shared_vars    = $this->get_media_player_shared_variables();
		$control_fields = $shared_vars['controlFields'];

		$this->set_common_controls();

		// Add audio-specific waveform controls.
		$control_fields['enableWaveform'] = array(
			'tab'      => 'content',
			'label'    => esc_html__( 'Waveform', 'bricksextras' ),
			'type'     => 'checkbox',
			'inline'   => true,
			'required' => array( 'control', '=', array( 'time-slider' ) ),
		);

		$control_fields['waveformHeight'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Height', 'bricks' ),
			'type'        => 'number',
			'unit'        => false,
			'inline'      => true,
			'small'       => true,
			'placeholder' => '26',
			'required'    => array(
				array( 'control', '=', array( 'time-slider' ) ),
				array( 'enableWaveform', '=', true ),
			),
		);

		$control_fields['waveformBarWidth'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Width', 'bricks' ) . ' (' . esc_html__( 'Bar', 'bricks' ) . ')',
			'type'        => 'number',
			'unit'        => false,
			'inline'      => true,
			'small'       => true,
			'placeholder' => '2',
			'required'    => array(
				array( 'control', '=', array( 'time-slider' ) ),
				array( 'enableWaveform', '=', true ),
			),
		);

		$control_fields['waveformBarGap'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Gap', 'bricks' ),
			'type'        => 'number',
			'unit'        => false,
			'inline'      => true,
			'small'       => true,
			'placeholder' => '1',
			'required'    => array(
				array( 'control', '=', array( 'time-slider' ) ),
				array( 'enableWaveform', '=', true ),
			),
		);

		$control_fields['waveformColor'] = array(
			'tab'      => 'content',
			'label'    => esc_html__( 'Color', 'bricks' ),
			'type'     => 'color',
			'inline'   => true,
			'required' => array(
				array( 'control', '=', array( 'time-slider' ) ),
				array( 'enableWaveform', '=', true ),
			),
		);

		$control_fields['waveformPlayedColor'] = array(
			'tab'      => 'content',
			'label'    => esc_html__( 'Color', 'bricks' ) . ' (' . esc_html__( 'Played', 'bricks' ) . ')',
			'type'     => 'color',
			'inline'   => true,
			'required' => array(
				array( 'control', '=', array( 'time-slider' ) ),
				array( 'enableWaveform', '=', true ),
			),
		);

		$this->control_fields = $control_fields;

		$this->controls = array_merge( $this->controls, $this->get_media_player_controls( 'audio' ) );

		/* loading */

		$this->controls['loadingSep'] = array(
			'group'    => 'behaviour',
			'label'    => esc_html__( 'Loading media', 'bricksextras' ),
			'type'     => 'separator',
			'required' => array( 'providerControls', '!=', 'enable' ),
		);

		$this->controls['loadingType'] = array(
			'group'       => 'behaviour',
			'label'       => esc_html__( 'Media Loading', 'bricksextras' ),
			'type'        => 'select',
			'options'     => array(
				'visible' => esc_html__( 'When visible', 'bricksextras' ) . ' (' . esc_html__( 'Lazy load', 'bricksextras' ) . ')',
				'click'   => esc_html__( 'On click', 'bricksextras' ),
				'play'    => esc_html__( 'On play', 'bricksextras' ) . ' (' . esc_html__( "Fallback to 'on click' for iFrame providers", 'bricksextras' ) . ')',
				'custom'  => esc_html__( 'Custom', 'bricks' ) . ' (' . esc_html__( 'Interactions', 'bricks' ) . ')',
			),
			'placeholder' => esc_html__( 'When visible', 'bricksextras' ) . ' (' . esc_html__( 'Lazy load', 'bricksextras' ) . ')',
			'required'    => array( 'providerControls', '!=', 'enable' ),

		);

		/* poster image control */

		$this->controls['posterImageSep'] = array(
			'group'    => 'styleControls',
			'type'     => 'separator',
			'label'    => esc_html__( 'Poster image', 'bricks' ),
			'required' => array(
				array( 'layoutTypeAudio', '!=', 'custom' ),
			),
		);

		$poster_image_control = '.xmp-image img';

		$this->controls['posterImageHeight'] = array(
			'tab'         => 'content',
			'placeholder' => '36px',
			'label'       => esc_html__( 'Height', 'bricks' ),
			'type'        => 'number',
			'css'         => array(
				array(
					'property' => 'height',
					'selector' => $poster_image_control,
				),
			),
			'group'       => 'styleControls',
			'units'       => true,
			'rerender'    => false,
			'required'    => array(
				array( 'layoutTypeAudio', '!=', 'custom' ),
			),
		);

		$this->controls['posterImageWidth'] = array(
			'tab'         => 'content',
			'placeholder' => 'auto',
			'label'       => esc_html__( 'Width', 'bricks' ),
			'type'        => 'number',
			'css'         => array(
				array(
					'property' => 'width',
					'selector' => $poster_image_control,
				),
			),
			'group'       => 'styleControls',
			'units'       => true,
			'rerender'    => false,
			'required'    => array(
				array( 'layoutTypeAudio', '!=', 'custom' ),
			),
		);

		$this->controls['posterImageAspectRatio'] = array(
			'tab'         => 'content',
			'type'        => 'number',
			'group'       => 'styleControls',
			'placeholder' => '1/1',
			'label'       => esc_html__( 'Aspect ratio', 'bricks' ),
			'css'         => array(
				array(
					'property' => 'aspect-ratio',
					'selector' => $poster_image_control,
				),
			),
			'required'    => array(
				array( 'layoutTypeAudio', '!=', 'custom' ),
			),
		);

		$this->controls['posterImageBorder'] = array(
			'tab'      => 'content',
			'type'     => 'border',
			'group'    => 'styleControls',
			'label'    => esc_html__( 'Border', 'bricks' ),
			'css'      => array(
				array(
					'property' => 'border',
					'selector' => $poster_image_control,
				),
			),
			'required' => array(
				array( 'layoutTypeAudio', '!=', 'custom' ),
			),
		);

		/* audio UI */

		$this->controls['layoutTypeAudio'] = array(
			'group'       => 'controlsAudio',
			'label'       => esc_html__( 'UI type', 'bricksextras' ),
			'type'        => 'select',
			'inline'      => true,
			'options'     => array(
				'default' => esc_html__( 'Default', 'bricks' ),
				'custom'  => esc_html__( 'Custom', 'bricks' ),
			),
			'placeholder' => esc_html__( 'Default', 'bricks' ),
		);

		$this->controls['controlsAdvancedSep'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Custom', 'bricks' ),
			'description' => esc_html__( 'Add a block element inside the media player for the layout. Add the "media controls" element inside block. The style settings below can still be used to style the controls globally for the player', 'bricksextras' ),
			'type'        => 'separator',
			'group'       => 'controlsAudio',
			'required'    => array( 'layoutTypeAudio', '=', 'custom' ),
		);

		$this->controls['controlsTopSepAudio'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Top controls', 'bricksextras' ),
			'description' => esc_html__( 'Manage controls for this zone', 'bricksextras' ),
			'type'        => 'separator',
			'group'       => 'controlsAudioLayout',
			'required'    => array( 'layoutTypeAudio', '!=', 'custom' ),
		);

		$this->controls['controlsTopAudio'] = array(
			'group'         => 'controlsAudioLayout',
			'placeholder'   => esc_html__( 'Control', 'bricksextras' ),
			'titleProperty' => 'control',
			'type'          => 'repeater',
			'required'      => array( 'layoutTypeAudio', '!=', 'custom' ),
			'fields'        => $this->control_fields,
			'default'       => array(),
		);

		$this->controls['audiocontrolGapTop'] = array(
			'tab'      => 'content',
			'type'     => 'number',
			'units'    => true,
			'group'    => 'controlsAudioLayout',
			'label'    => esc_html__( 'Gap', 'bricks' ),
			'css'      => array(
				array(
					'property' => '--media-button-gap',
					'selector' => '.x-media-player_audio .xmp-controls_group_top',
				),
			),
			'required' => array(
				array( 'layoutTypeAudio', '!=', 'custom' ),
			),
		);

		$this->controls['controlsCenterSepAudio'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Center controls', 'bricksextras' ),
			'description' => esc_html__( 'Manage controls for this zone', 'bricksextras' ),
			'type'        => 'separator',
			'group'       => 'controlsAudioLayout',
			'required'    => array( 'layoutTypeAudio', '!=', 'custom' ),
		);

		$this->controls['controlsCenterAudio'] = array(
			'group'         => 'controlsAudioLayout',
			'placeholder'   => esc_html__( 'Control', 'bricksextras' ),
			'titleProperty' => 'control',
			'type'          => 'repeater',
			'required'      => array( 'layoutTypeAudio', '!=', 'custom' ),
			'fields'        => $this->control_fields,
			'default'       => array(),
		);

		$this->controls['audiocontrolGapCenter'] = array(
			'tab'      => 'content',
			'type'     => 'number',
			'units'    => true,
			'group'    => 'controlsAudioLayout',
			'label'    => esc_html__( 'Gap', 'bricks' ),
			'css'      => array(
				array(
					'property' => '--media-button-gap',
					'selector' => '.x-media-player_audio .xmp-controls_group_center',
				),
			),
			'required' => array(
				array( 'layoutTypeAudio', '!=', 'custom' ),
			),
		);

		$this->controls['controlsSepAudio'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Bottom controls', 'bricksextras' ),
			'description' => esc_html__( 'Manage controls for this zone', 'bricksextras' ),
			'type'        => 'separator',
			'group'       => 'controlsAudioLayout',
			'required'    => array( 'layoutTypeAudio', '!=', 'custom' ),
		);

		$this->controls['controlsBottomAudio'] = array(
			'group'         => 'controlsAudioLayout',
			'placeholder'   => esc_html__( 'Control', 'bricksextras' ),
			'titleProperty' => 'control',
			'type'          => 'repeater',
			'required'      => array( 'layoutTypeAudio', '!=', 'custom' ),
			'fields'        => $this->control_fields,
			'default'       => array(
				array( 'control' => 'seek-backward' ),
				array( 'control' => 'play' ),
				array( 'control' => 'seek-forward' ),
				array( 'control' => 'time' ),
				array( 'control' => 'title' ),
				array( 'control' => 'spacer' ),
				array( 'control' => 'chapters' ),
				array( 'control' => 'mute' ),
				array( 'control' => 'settings' ),
			),
		);

		$this->controls['audiocontrolGapBottom'] = array(
			'tab'      => 'content',
			'type'     => 'number',
			'units'    => true,
			'group'    => 'controlsAudioLayout',
			'label'    => esc_html__( 'Gap', 'bricks' ),
			'css'      => array(
				array(
					'property' => '--media-button-gap',
					'selector' => '.x-media-player_audio .xmp-controls_group_bottom',
				),
			),
			'required' => array(
				array( 'layoutTypeAudio', '!=', 'custom' ),
			),
		);

		$this->controls['maybeTimeSliderAudio'] = array(
			'group'       => 'controlsAudioLayout',
			'label'       => esc_html__( 'Time slider', 'bricksextras' ) . ' (' . esc_html__( 'Full width', 'bricksextras' ) . ')',
			'type'        => 'select',
			'options'     => array(
				'enable'  => esc_html__( 'Enable', 'bricks' ),
				'disable' => esc_html__( 'Disable', 'bricks' ),
			),
			'placeholder' => esc_html__( 'Enable', 'bricks' ),
			'inline'      => true,
			'required'    => array( 'layoutTypeAudio', '!=', 'custom' ),
			'info'        => esc_html__( 'Position above bottom controls', 'bricksextras' ),
		);

		$this->controls['downloadSep'] = array(
			'tab'         => 'content',
			'label'       => esc_html__( 'Downloads', 'bricks' ),
			'description' => esc_html__( 'Optionally add extra download options for the media', 'bricksextras' ),
			'type'        => 'separator',
			'group'       => 'downloads',
		);

		$this->controls['downloadAttributes'] = array(
			'group'       => 'downloads',
			'type'        => 'repeater',
			'placeholder' => esc_html__( 'Download', 'bricks' ),
			'fields'      => array(
				'downloads_id' => array(
					'label'       => esc_html__( 'Identifier', 'bricks' ),
					'type'        => 'text',
					'inline'      => true,
					'placeholder' => 'mp3-version',
				),
				'url'          => array(
					'label'       => esc_html__( 'URL', 'bricks' ),
					'type'        => 'text',
					'placeholder' => 'https://...',
				),
				'title'        => array(
					'label'       => esc_html__( 'Name', 'bricks' ) . ' (' . esc_html__( 'Optional', 'bricks' ) . ')',
					'type'        => 'text',
					'placeholder' => '',
				),
			),
		);
	}


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

		$settings = $this->settings;

		$provider = 'audio';

		$this->set_attribute( '_root', 'class', 'brxe-xmediaplayer' );

		$this->set_attribute( '_root', 'playsinline', 'true' );

		$is_gutenberg = \BricksExtras\Helpers::is_gutenberg_editor();

		$src = $this->get_media_source( $settings, $provider );

		$source_type = isset( $settings['sourceType'] ) ? $settings['sourceType'] : 'url';

		// Output download attributes if set.
		if ( isset( $settings['downloadAttributes'] ) && is_array( $settings['downloadAttributes'] ) && ! empty( $settings['downloadAttributes'] ) ) {
			$download_attributes = array();

			foreach ( $settings['downloadAttributes'] as $item ) {
				$download = array();

				if ( isset( $item['downloads_id'] ) ) {
					$rendered_id    = bricks_render_dynamic_data( $item['downloads_id'] );
					$download['id'] = sanitize_key( $rendered_id );
				}
				if ( isset( $item['title'] ) ) {
					$rendered_title    = bricks_render_dynamic_data( $item['title'] );
					$download['title'] = esc_attr( $rendered_title );
				}
				if ( isset( $item['url'] ) ) {
					$rendered_url    = bricks_render_dynamic_data( $item['url'] );
					$download['url'] = esc_url( $rendered_url, array( 'http', 'https' ) );
				}

				if ( ! empty( $download ) && ! empty( $download['id'] ) ) {
					$download_attributes[] = $download;
				}
			}

			if ( ! empty( $download_attributes ) ) {
				$download_attributes_json = htmlspecialchars(
					wp_json_encode( $download_attributes, JSON_HEX_APOS | JSON_HEX_QUOT ),
					ENT_QUOTES,
					'UTF-8'
				);

				$this->set_attribute( '_root', 'data-x-downloads', $download_attributes_json );
			}
		}

		if ( isset( $settings['multipleSources'] ) && 'url' === $source_type && ! empty( $settings['srcRepeaterAudio'] ) ) {
			$additional_sources = array();

			foreach ( $settings['srcRepeaterAudio'] as $item ) {

				if ( empty( bricks_render_dynamic_data( $item['source'] ?? '' ) ) ) {
					continue;
				}

				$source = array(
					'src'  => esc_url( bricks_render_dynamic_data( $item['source'] ) ),
					'type' => esc_attr( bricks_render_dynamic_data( $item['type'] ?? 'audio/mpeg' ) ),
				);

				$additional_sources[] = $source;
			}

			if ( ! empty( $additional_sources ) ) {
				$this->set_attribute( '_root', 'data-x-srcs', htmlspecialchars( wp_json_encode( $additional_sources ) ) );
			}
		}

		$color_scheme = isset( $settings['colorScheme'] ) ? esc_attr( $settings['colorScheme'] ) : 'dark';

		$positioning       = isset( $settings['positioning'] ) ? $settings['positioning'] : 'default';
		$layout            = isset( $settings['layout'] ) ? $settings['layout'] : 'default';
		$provider_controls = isset( $settings['providerControls'] ) ? 'enable' === $settings['providerControls'] : false;
		$loop              = isset( $settings['loop'] );
		$muted             = isset( $settings['muted'] );
		$autoplay          = isset( $settings['autoplay'] );
		$loading_type      = isset( $settings['loadingType'] ) ? $settings['loadingType'] : 'visible';

		if ( $provider_controls ) {
			$loading_type = 'visible';
		}

		$title                     = isset( $settings['title'] ) ? esc_attr( bricks_render_dynamic_data( $settings['title'] ) ) : '';
		$artist                    = isset( $settings['artist'] ) ? esc_attr( bricks_render_dynamic_data( $settings['artist'] ) ) : '';
		$maybe_tool_tips           = isset( $settings['maybeToolTips'] ) ? 'enable' === $settings['maybeToolTips'] : false;
		$default_tooltip_placement = isset( $settings['defaultTooltipPlacement'] ) ? esc_attr( $settings['defaultTooltipPlacement'] ) : 'top';
		$portal_settings           = isset( $settings['portalSettings'] );
		$text_tracks               = ! empty( $settings['textTracks'] ) ? $settings['textTracks'] : false;
		$image                     = \BricksExtras\Helpers::get_normalized_image_settings( $settings );
		$image_id                  = $image['id'];
		$image_url                 = bricks_render_dynamic_data( $image['url'] );
		$image_size                = $image['size'];
		$poster_url                = $image_url ? esc_url( $image_url ) : '';
		$controls_top_audio        = ! empty( $settings['controlsTopAudio'] ) ? $settings['controlsTopAudio'] : false;
		$controls_center_audio     = ! empty( $settings['controlsCenterAudio'] ) ? $settings['controlsCenterAudio'] : false;
		$controls_bottom_audio     = ! empty( $settings['controlsBottomAudio'] ) ? $settings['controlsBottomAudio'] : false;
		$chapters                  = ! empty( $settings['chapters'] ) ? $settings['chapters'] : false;
		$thumbnail_attr            = isset( $settings['thumbnailFile'] ) ? 'src="' . esc_url( bricks_render_dynamic_data( $settings['thumbnailFile'] ) ) . '"' : '';
		$thumbnails                = isset( $settings['thumbnailFile'] ) ? esc_url( bricks_render_dynamic_data( $settings['thumbnailFile'] ) ) : false;
		$layout_type               = isset( $settings['layoutType'] ) ? esc_attr( $settings['layoutType'] ) : 'small';
		$layout_type_audio         = isset( $settings['layoutTypeAudio'] ) ? $settings['layoutTypeAudio'] : 'default';
		$maybe_time_slider_audio   = isset( $settings['maybeTimeSliderAudio'] ) ? 'enable' === $settings['maybeTimeSliderAudio'] : true;
		$remember_player_settings  = isset( $settings['rememberPlayerSettings'] );
		$auto_local_poster         = isset( $settings['autoLocalPoster'] );
		$click_to_play             = isset( $settings['clickToPlay'] ) ? 'enable' === $settings['clickToPlay'] : true;
		$which_playlist            = isset( $settings['whichPlaylist'] ) ? $settings['whichPlaylist'] : 'section';
		$playlist_selector         = isset( $settings['playlistSelector'] ) ? $settings['playlistSelector'] : '';

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

		// Use the common config setup method from the trait.
		$config = $this->setup_common_config(
			$settings,
			$layout_type,
			$loading_type,
			$click_to_play,
			$auto_local_poster,
			$which_playlist,
			$playlist_selector,
			$poster_url,
			$thumbnails,
			$remember_player_settings
		);

		// Process chapters using the trait method.
		$chapters_array = $this->process_chapters( $settings );

		// Set chapters attribute if valid chapters exist.
		$this->set_chapters_attribute( $chapters_array );

		// Set common attributes using the trait method.
		$this->set_common_attributes(
			$settings,
			'audio',
			$config,
			$src,
			$layout_type,
			$positioning,
			$remember_player_settings ? $player_indentifier : '',
			$is_gutenberg
		);

		$output = '';

		if ( ! $provider_controls ) {

			if ( 'custom' !== $layout_type_audio ) {

				/* audio layout */

				if ( 'audio' === $provider ) {
					$output = $this->render_audio_player(
						$output,
						$provider,
						$layout_type_audio,
						$controls_top_audio,
						$controls_center_audio,
						$controls_bottom_audio,
						$maybe_time_slider_audio,
						$maybe_tool_tips,
						$default_tooltip_placement,
						$title,
						$artist,
						$thumbnail_attr,
						$color_scheme,
						$portal_settings,
						$player_indentifier,
						$settings
					);
				}
			}

			if ( 'custom' === $layout_type_audio ) {
				$output .= "<media-layout {$this->render_attributes( 'x-media-player_inner' )}>";
			} else {
				$output .= BricksExtras\Helpers::maybe_preview() ? "<media-layout {$this->render_attributes( 'x-media-player_hidden-inner' )}>" : '';
			}

			/* nesting elements */
			if ( 'custom' === $layout_type_audio || BricksExtras\Helpers::maybe_preview() ) {

				if ( method_exists( '\Bricks\Frontend', 'render_children' ) ) {
					$output .= "<media-controls  {$this->render_attributes( 'media-controls' )}>";
					$output .= \Bricks\Frontend::render_children( $this );
					$output .= '</media-controls>';
				}
			}

			if ( 'custom' === $layout_type_audio ) {
				$output .= '</media-layout>';
			} else {
				$output .= BricksExtras\Helpers::maybe_preview() ? '</media-layout>' : '';
			}

			$output .= '<div class="xmp-media-features">';

		} /* end of !providerControls */

		$output .= '<media-captions class="xmp-captions"></media-captions>';

		$output .= isset( $settings['announcer'] ) && 'disable' === $settings['announcer'] ? '' : '<media-announcer></media-announcer>';

		$output .= '</div>';

		$final_output = '';

		if ( ! $is_gutenberg ) {

			$final_output .= "<media-player {$this->render_attributes( '_root' )}>";
			$final_output .= '<media-provider>';

			if ( $text_tracks ) {
				$final_output .= $this->render_text_tracks( $text_tracks );
			}

			$final_output .= '</media-provider>';
			$final_output .= $output;

			$final_output .= '</media-player>';

		} else {

			$this->set_attribute( '_root', 'class', 'x-media-player_editor' );

			$final_output .= "<div {$this->render_attributes( '_root' )}>";
			$final_output .= "<div class='x-media-player_placeholder'>Media Player</div>";
			$final_output .= '</div>';

		}

		echo $final_output;
	}


	/**
	 * Render the audio player layout
	 *
	 * @param string $output Player output HTML.
	 * @param string $provider Media provider type.
	 * @param string $layout_type_audio Audio layout type.
	 * @param array  $controls_top_audio Top controls.
	 * @param array  $controls_center_audio Center controls.
	 * @param array  $controls_bottom_audio Bottom controls.
	 * @param bool   $maybe_time_slider_audio Time slider enabled.
	 * @param bool   $maybe_tool_tips Tooltips enabled.
	 * @param string $default_tooltip_placement Default tooltip placement.
	 * @param string $title Media title.
	 * @param string $artist Media artist.
	 * @param string $thumbnail_attr Thumbnail attributes.
	 * @param string $color_scheme Color scheme setting.
	 * @param bool   $portal_settings Portal enabled.
	 * @param string $player_indentifier Player identifier.
	 * @param array  $settings Element settings.
	 */
	private function render_audio_player(
		$output,
		$provider,
		$layout_type_audio,
		$controls_top_audio,
		$controls_center_audio,
		$controls_bottom_audio,
		$maybe_time_slider_audio,
		$maybe_tool_tips,
		$default_tooltip_placement,
		$title,
		$artist,
		$thumbnail_attr,
		$color_scheme,
		$portal_settings,
		$player_indentifier,
		$settings
	) {
		$output .= '<media-layout class="x-media-player_audio">';

		$player_controls_audio = '';

		if ( 'custom' !== $layout_type_audio ) {
			$player_controls_audio .= "<media-controls {$this->render_attributes( 'media-controls' )}>";

			if ( (bool) $controls_top_audio && ( 'audio' === $provider ) ) {
				$player_controls_audio .= '<div class="xmp-controls_group xmp-controls_group_top">';
				foreach ( $controls_top_audio as $control ) {
					$player_controls_audio .= $this->render_control(
						$control,
						$provider,
						$maybe_tool_tips,
						$default_tooltip_placement,
						'top',
						$title,
						$artist,
						$thumbnail_attr,
						$color_scheme,
						$portal_settings,
						$player_indentifier,
						$settings
					);
				}
				$player_controls_audio .= '</div>';
			}

			if ( (bool) $controls_center_audio ) {
				$player_controls_audio .= '<div class="xmp-controls_group xmp-controls_group_center">';
				foreach ( $controls_center_audio as $control ) {
					$player_controls_audio .= $this->render_control(
						$control,
						$provider,
						$maybe_tool_tips,
						$default_tooltip_placement,
						'top',
						$title,
						$artist,
						$thumbnail_attr,
						$color_scheme,
						$portal_settings,
						$player_indentifier,
						$settings
					);
				}
				$player_controls_audio .= '</div>';
			}

			if ( $maybe_time_slider_audio ) {
				$player_controls_audio .= $this->render_time_slider( '', $thumbnail_attr );
			}

			$player_controls_audio .= '<div class="xmp-controls_group xmp-controls_group_bottom">';

			if ( (bool) $controls_bottom_audio && 'audio' === $provider ) {
				foreach ( $controls_bottom_audio as $control ) {
					$player_controls_audio .= $this->render_control(
						$control,
						$provider,
						$maybe_tool_tips,
						$default_tooltip_placement,
						'bottom',
						$title,
						$artist,
						$thumbnail_attr,
						$color_scheme,
						$portal_settings,
						$player_indentifier,
						$settings
					);
				}
			}

			$player_controls_audio .= '</div>';
			$player_controls_audio .= '</media-controls>';
		}

		$output .= $player_controls_audio;
		$output .= '</media-layout>';

		return $output;
	}
}
