<?php
namespace BricksUltimate\Elements;

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

use BricksUltimate\Helpers;

class FlexGallery extends \Bricks\Element {
	public $category 		= 'ultimate';
	public $name 			= 'bu-flex-gallery';
	public $icon 			= 'ti-gallery';
	public $tag 			= 'div';

	// Return localized element label
	public function get_label() {
		return esc_html__( '(BU)Flex Gallery', 'bricksultimate' );
	}

	// Set builder controls
	public function set_controls() {

		$this->controls['source'] = [
			'tab' 		=> 'content',
			'type'      => 'select',
			'label'     => esc_html__('Source', 'bricksultimate'),
			'options'   => [
				'media' => esc_html__('WP Media', 'bricksultimate'),
				'wc'  	=> esc_html__('WooCommerce Gallery', 'bricksultimate'),
			]
		];

		$this->controls['items'] = [
			'tab'  		=> 'content',
			'type' 		=> 'image-gallery',
			'required' 	=> [ 'source', '=', 'media' ],
			'unsplash' 	=> false
		];

		$this->controls['exlFeatImg'] = [
			'tab' 		=> 'content',
			'type'      => 'checkbox',
			'label'     => esc_html__('Exclude featured image', 'bricksultimate'),
			'reset' 	=> true,
			'required' 	=> ['source', '=', 'wc']
		];

		$this->controls['isFullWidth'] = [
			'tab' 		=> 'content',
			'type'      => 'checkbox',
			'label'     => esc_html__('First image cover the full width?', 'bricksultimate'),
			'reset' 	=> true,
		];

		$this->controls['updateWithVariation'] = [
			'tab' 		=> 'content',
			'type'      => 'checkbox',
			'label'     => esc_html__('Update with variation image?', 'bricksultimate'),
			'description' => esc_html__('Go to Add To Cart element -> Swatches section and enter .update-with-variations CSS class name into the (BU)Product Image element selector input box.', 'bricksultimate'),
			'reset' 	=> true,
			'required'  => [ ['isFullWidth', '=', true], ['source', '=', 'wc'] ]
		];

		$this->controls['divider'] = [
			'tab'         => 'content',
			'type'        => 'separator',
		];

		$this->controls['thumbSize'] = [
			'tab' 		=> 'content',
			'type'      => 'select',
			'label'     => esc_html__('Thumbnail resolution', 'bricksultimate'),
			'options'   => $this->control_options['imageSizes'],
			'default'   => 'large',
			'required' 	=> [ 'source', '!=', 'media' ],
		];

		$this->controls['aspectRatio'] = [
			'tab' 		=> 'content',
			'type'      => 'text',
			'label'     => esc_html__('Image aspect ratio', 'bricksultimate'),
			'placeholder'   => '16:9',
			'hasDynamicData' => false,
			'inline' 	=> true,
		];

		$this->controls['minWidth'] = [
			'tab' 		=> 'content',
			'type'      => 'number',
			'label'     => esc_html__('Image min width(px)', 'bricksultimate'),
			'unit' 		=> 'px',
			'min' 		=> 0,
			'max' 		=> 10000,
			'step' 		=> 1,
			'css' 		=> [
				[
					'selector' 	=> '.bu-image-item',
					'property' 	=> 'min-width'
				]
			]
		];

		$this->controls['justifyContent'] = [
			'tab' 		=> 'content',
			'label' 	=> esc_html__( 'Thumbnails alignment', 'bricksultimate' ),
			'tooltip' 	=> [
				'content'  => 'justify-content',
				'position' => 'top-left',
			],
			'type'     => 'justify-content',
			'css'      => [
				[
					'property' => 'justify-content',
				],
			],
			'default' => 'center',
		];

		$this->controls['spaceAroundImage'] = [
			'tab' 		=> 'content',
			'type'      => 'number',
			'label'     => esc_html__('Space around images(px)', 'bricksultimate'),
			'unit' 		=> 'px',
			'min' 		=> 0,
			'max' 		=> 100,
			'step' 		=> 1,
			'default' 	=> 5,
			'inline' 	=> true,
			'css' 		=> [
				[
					'property' 	=> '--image-gap',
				]
			]
		];

		$this->controls['layout'] = [
			'tab' 		=> 'content',
			'type'      => 'select',
			'label'     => esc_html__('Grid type', 'bricksultimate'),
			'options'   => [
				'flex'  	=> esc_html__('Flex', 'bricksultimate'),
				'grid'  	=> esc_html__('Grid', 'bricksultimate'),
				'tiles'  	=> esc_html__('Tiles', 'bricksultimate'),
			],
			'default' 	=> 'flex',
			'inline' 	=> true,
			'small' 	=> true
		];

		$this->controls['columns'] = [
			'tab'         => 'content',
			'label'       => esc_html__( 'Columns', 'bricks' ),
			'type'        => 'number',
			'min'         => 1,
			'breakpoints' => true,
			'placeholder' => 3
		];

		$this->controls['link'] = [
			'tab'         => 'content',
			'label'       => esc_html__( 'Link to', 'bricks' ),
			'type'        => 'select',
			'options'     => [
				'lightbox'   => esc_html__( 'Lightbox', 'bricks' ),
				'attachment' => esc_html__( 'Attachment Page', 'bricks' ),
				'media'      => esc_html__( 'Media File', 'bricks' ),
				'none' 		 => esc_html__( 'None', 'bricks' ),
			],
			'inline'      => true,
			'placeholder' => esc_html__( 'None', 'bricks' ),
			'default' 	  => 'none'
		];

		$this->controls['lbLibrary'] = [
			'tab' 		=> 'content',
			'label' 	=> esc_html__( 'Library', 'bricks' ),
			'type' 		=> 'select',
			'options' 	=> [
				'pswp'  => esc_html__( 'Photoswipe', 'bricks' ),
				'lg' 	=> esc_html__( 'Light Gallery', 'bricks' ),
			],
			'inline' 	=> true,
			'default' 	=> 'pswp',
			'placeholder' => esc_html__( 'Photoswipe', 'bricks' ),
			'required'    => [ 'link', '=', 'lightbox' ],
		];

		$this->controls['alt'] = [
			'tab'   => 'content',
			'label' => esc_html__( 'Show alt', 'bricks' ),
			'type'  => 'checkbox',
			'required'    => [ 'lbLibrary', '=', 'lg' ],
		];

		$this->controls['caption'] = [
			'tab'   => 'content',
			'label' => esc_html__( 'Show caption', 'bricks' ),
			'type'  => 'checkbox',
			'required'    => [ 'lbLibrary', '=', 'lg' ],
		];

		$this->controls['thumbnails'] = [
			'tab'   => 'content',
			'label' => esc_html__( 'Show thumbnails', 'Lightbox' ),
			'type'  => 'checkbox',
			'required' => [ 'lbLibrary', '=', 'lg' ],
		];

		$this->controls['thumbnailsRight'] = [
			'tab'   => 'content',
			'label' => esc_html__( 'Show thumbnails at right side', 'Lightbox' ),
			'type'  => 'checkbox',
			'required' => [ 'thumbnails', '=', true ],
		];

		$this->controls['lightboxImageSize'] = [
			'tab'         => 'content',
			'label'       => esc_html__( 'Lightbox image size', 'bricks' ),
			'type'        => 'select',
			'options'     => $this->control_options['imageSizes'],
			'placeholder' => esc_html__( 'Full', 'bricks' ),
			'required'    => [ 'link', '=', 'lightbox' ],
		];

		$this->controls['imageHoverSep'] = [
			'tab'         => 'content',
			'label'       => esc_html__( 'Image hover action', 'bricks' ),
			'type'        => 'separator',
		];

		$this->controls['imageOpacity'] = [
			'tab' 		=> 'content',
			'label' 	=> esc_html__( 'Opacity', 'bricks' ),
			'type' 		=> 'number',
			'min' 		=> 0,
			'max' 		=> 1,
			'step' 		=> 0.1,
			'inline' 	=> true,
			'small' 	=> true,
			'unitless' 	=> true,
			'css' 		=> [
				[
					'property' 	=> 'opacity',
					'selector' 	=> '.bu-image-item-contents'
				]
			]
		];

		$this->controls['imageHOpacity'] = [
			'tab' 		=> 'content',
			'label' 	=> esc_html__( 'Hover opacity', 'bricks' ),
			'type' 		=> 'number',
			'min' 		=> 0,
			'max' 		=> 1,
			'step' 		=> 0.1,
			'inline' 	=> true,
			'small' 	=> true,
			'unitless' 	=> true,
			'css' 		=> [
				[
					'property' 	=> 'opacity',
					'selector' 	=> '.bu-image-item-contents:hover'
				]
			]
		];

		$this->controls['imageHOpacityTd'] = [
			'tab' 		=> 'content',
			'label' 	=> esc_html__( 'Transition duration(sec)', 'bricks' ),
			'type' 		=> 'number',
			'min' 		=> 0,
			'max' 		=> 10,
			'step' 		=> 0.1,
			'inline' 	=> true,
			'small' 	=> true,
			'unit' 		=> 's',
			'default' 	=> 0.2,
			'css' 		=> [
				[
					'property' 	=> 'transition',
					'selector' 	=> '.bu-image-item-contents',
					'value' 	=> 'all %s ease-in'
				]
			]
		];
	}

	// Enqueue element styles and scripts
	public function enqueue_scripts() {
		//if( bricks_is_builder() || bricks_is_builder_iframe() || bricks_is_builder_call() ){
			wp_enqueue_style( 'bu-flex-gallery', Helpers::get_asset_url('css') . 'flexgallery.min.css', [], filemtime(Helpers::get_asset_path('css') . 'flexgallery.min.css'), 'all' );
		//}

		if( isset( $this->settings['link'] ) && $this->settings['link'] != 'none' && ! empty( $this->settings['lbLibrary'] ) && $this->settings['lbLibrary'] == 'pswp' ) {
			wp_enqueue_style( 'bricks-photoswipe' );
			wp_enqueue_script( 'bricks-photoswipe' );
		}
		
		if( isset( $this->settings['link'] ) && $this->settings['link'] != "none" && ! empty( $this->settings['lbLibrary'] ) && $this->settings['lbLibrary'] == 'lg' ) {
			wp_enqueue_style( 'bu-flex-gallery-lg', Helpers::get_asset_url('css') . 'lightgallery.min.css', [], '2.7.0', 'all' );

			if( isset( $this->settings['thumbnails'] ) ) {
				wp_enqueue_style( 'bu-lg-thumbnail', Helpers::get_asset_url('css') . 'lg-thumbnail.min.css', [], '2.7.0', 'all' );
				wp_enqueue_script( 'bu-lg-thumbnail', Helpers::get_asset_url('js') . 'lg-thumbnail.min.js', [], '2.7.0', true );
			}
			
			wp_enqueue_script( 'bu-flex-gallery-lg', Helpers::get_asset_url('js') . 'lightgallery.min.js', [], '2.0', true );
			wp_enqueue_script( 'bu-flex-gallery-lb', Helpers::get_asset_url('js') . 'flexgallery.min.js', [], filemtime(Helpers::get_asset_path('js') . 'flexgallery.min.js'), 'all' );
		}
	}

	// Render element HTML
	public function render() {
		$settings = $this->settings;

		if ( ! isset( $settings['source'] ) ) {
			return $this->render_element_placeholder( ['title' => esc_html__( 'Select the source for images.', 'bricksultimate' )] );
		}

		$image_ids = []; $size = false;

		if ( $settings['source'] == 'media' ) {
			$items = isset( $settings['items'] ) ? $settings['items'] : false;
			$size = ! empty( $items['size'] ) ? $items['size'] : BRICKS_DEFAULT_IMAGE_SIZE;

			// Dynamic Data
			if ( ! empty( $items['useDynamicData'] ) ) {
				$items['images'] = [];

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

				if ( is_array( $images ) ) {
					foreach ( $images as $image_id ) {
						if( is_array( $image_id ) )
							$image_ids = array_keys( $image_id );
						else
							$image_ids[] = $image_id;
					}
				}
			} elseif ( $items && is_array( $items['images'] ) ) {
				foreach ( $items['images'] as $image_id ) {
					$image_ids[] = $image_id['id'];
				}
			}
		}

		//* get the woocommerce gallery
		elseif ( class_exists( 'WooCommerce' ) && $settings['source'] == 'wc' ) {
			global $porduct;

			$product_id = $this->post_id;

			$object = \Bricks\Query::get_loop_object();
			if( is_object( $object ) ) {
				$product_id = $object->ID;
			}

			$product = wc_get_product( $product_id );

			if( $product === false ) {
				return $this->render_element_placeholder( ['title' => esc_html__( 'This is not a WooCommerce product.', 'bricksultimate' )] );
			}

			$featured_image_id = $product->get_image_id();
			$image_ids = array_unique( $product->get_gallery_image_ids() );

			if( $featured_image_id && empty( $settings['exlFeatImg']) ) {
				array_unshift( $image_ids, $featured_image_id );
			}
		} else {
			$image_ids = false;
		}
		
		if( $image_ids ) {

			$link_to = ! empty( $settings['link'] ) ? $settings['link'] : "none";
			$columns = ! empty( $settings['columns'] ) ? $settings['columns'] : 3;
			$aspect_ratio = isset( $settings['aspectRatio'] ) ? esc_attr( $settings['aspectRatio'] ) : "16:9";
			$aspect_ratio = explode(":", $aspect_ratio);
			$aspect_ratio = ($aspect_ratio[1] / $aspect_ratio[0]);
			$aspect_ratio = number_format($aspect_ratio * 100, 2) . "%";
			
			if( version_compare( BRICKS_VERSION, '1.5' , '>') )
				$breakpoint_classes = $this->get_columns_per_breakpoint_css_classes( $columns, $settings );
			else
				$breakpoint_classes = $this->generate_columns_per_breakpoint_css_classes( $columns, $settings );

			$layout = Helpers::get_value( $settings, 'layout', 'flex' );

			$this->set_attribute( '_root', 'itemtype', "http://schema.org/ImageGallery");
			$this->set_attribute( '_root', 'class', "layout-{$layout}");

			if( ! empty( $settings['lbLibrary'] ) && $settings['lbLibrary'] == 'lg' ) {
				$this->set_attribute( '_root','class', 'bu-lg-initiated' );

				$showThumbs = isset( $settings['thumbnails'] ) ? 'yes' : "no";
				$showThumbsRight = isset( $settings['thumbnailsRight'] ) ? 'yes' : "no";
				$this->set_attribute( "_root", 'data-lb-thumbnails', $showThumbs );
				$this->set_attribute( "_root", 'data-lb-thumbs-right', $showThumbsRight );
			}

			echo "<{$this->tag} {$this->render_attributes('_root')} itemscope>";

			$count = count( $image_ids );

			foreach( $image_ids as $index => $image_id ) {
				if( $image_id ) {
					$data = wp_get_attachment_metadata( $image_id );

					if( ! $data ) {
						continue;
					}

					$item_classes  = [ 'bu-image-item', 'layout-' . $layout ];
					$items_styles  = [];
					$image_classes = [ 'bu-image-item-contents', 'css-filter' ];

					if ( count( $breakpoint_classes ) && $layout == 'flex' ) { //$layout != 'tiles'
						$item_classes = array_merge( $item_classes, $breakpoint_classes );
					}

					//* make first image full width
					if( $index == 0 && isset( $settings['isFullWidth'] ) ) {
						$this->set_attribute( "bu-img-item-$index", "style", 'width: 100%' );
						if( ! empty( $settings['updateWithVariation'] ) )
							$this->set_attribute( "bu-img-item-$index", "class", [ 'update-with-variations' ] );
					} elseif( $index == 1 && $count <= 2 && isset( $settings['isFullWidth'] ) ) {
						$this->set_attribute( "bu-img-item-$index", "style", 'width: 100%' );
					} elseif( $layout == 'tiles' ) {
						$gap = $settings['spaceAroundImage'];
						$ratio = \number_format( ( $data['width'] / $data['height'] ) / $columns, 2, '.', '' );
						$this->set_attribute( "bu-img-item-$index", "style", 'width: ' . ( ( $ratio * 100 ) ) . '%' ); //- 2 * $gap
					}

					$this->set_attribute( "bu-img-item-$index", "class", $item_classes );
					$this->set_attribute( "bu-img-item-$index", "itemprop", "associatedMedia" );
					$this->set_attribute( "bu-img-item-$index", "itemtype", "http://schema.org/ImageObject" );
					
					$alt = '';

					if ( $link_to === 'lightbox' ) {
						$lightbox_image_size = ! empty( $settings['lightboxImageSize'] ) ? $settings['lightboxImageSize'] : 'full';
						$lightbox_image      = wp_get_attachment_image_src( $image_id, $lightbox_image_size );
						$lightbox_image      = ! empty( $lightbox_image ) && is_array( $lightbox_image ) ? $lightbox_image : [ wp_get_attachment_image_url($image_id, 'full'), 800, 600 ];
						$alt = esc_attr(get_post_meta($image_id, '_wp_attachment_image_alt', true));
						$caption = isset( $settings['caption'] ) ? '<p class="bu-lb-caption">' . wp_get_attachment_caption( $image_id ) . '</p>' : false;

						if( ! empty( $settings['lbLibrary'] ) && $settings['lbLibrary'] == 'lg' ) {
							$this->set_attribute( "bu-img-item-$index", 'data-src', $lightbox_image[0] );
							$this->set_attribute( "bu-img-item-$index", 'data-width', $lightbox_image[1] );
							$this->set_attribute( "bu-img-contents-$index", 'href', $lightbox_image[0] );
						} else {
							$image_classes[] = 'bricks-lightbox';

							$this->set_attribute( "bu-img-contents-$index", 'data-pswp-src', $lightbox_image[0] );
							$this->set_attribute( "bu-img-contents-$index", 'data-pswp-width', $lightbox_image[1] );
							$this->set_attribute( "bu-img-contents-$index", 'data-pswp-height', $lightbox_image[2] );
							$this->set_attribute( "bu-img-contents-$index", 'data-pswp-index', $index );
							$this->set_attribute( "bu-img-contents-$index", 'href', 'javascript:void(0)' );
							$this->set_attribute( "bu-img-contents-$index", 'data-pswp-id', 'flex-' . $this->id );
						}

						$this->set_attribute( "bu-img-contents-$index", 'itemprop', "contentUrl" );

						$this->set_attribute( "bu-img-item-$index", 'data-sub-html', ( $alt && isset( $settings['alt'] ) ? "<h4>{$alt}</h4>" : '' ) . $caption );
						$this->set_attribute( "bu-img-contents-$index", 'alt', $alt );

						$link_tag = 'a';
					} elseif ( $link_to === 'attachment' ) {
						$link_tag = 'a';
						$this->set_attribute( "bu-img-contents-$index", 'itemprop', "contentUrl" );
						$this->set_attribute( "bu-img-contents-$index", 'href', get_permalink( $image_id ) );
						$this->set_attribute( "bu-img-contents-$index", 'target', "_blank" );
					} elseif ( $link_to === 'media' ) {
						$link_tag = 'a';

						$this->set_attribute( "bu-img-contents-$index", 'itemprop', "contentUrl" );
						$this->set_attribute( "bu-img-contents-$index", 'href', esc_url( wp_get_attachment_image_url( $image_id, 'full' ) ) );
						$this->set_attribute( "bu-img-contents-$index", 'target', "_blank" );
					} else {
						$link_tag = 'div';
					}

					echo "<div {$this->render_attributes( "bu-img-item-{$index}" )} itemscope>";

					$img = wp_get_attachment_image_src( $image_id, ( ( $size ) ? $size : Helpers::get_value( $settings, 'thumbSize', 'large' ) ) );

					if ( $this->lazy_load() ) {
						$image_classes[] = 'bricks-lazy-hidden';
						$this->set_attribute( "bu-img-contents-$index", 'data-style', "background-image: url({$img[0]})" );
					} else {
						$this->set_attribute( "bu-img-contents-$index", 'style', "background-image: url({$img[0]})" );
					}

					$this->set_attribute( "bu-img-contents-$index", 'width', $img[1] );
					$this->set_attribute( "bu-img-contents-$index", 'height', $img[2] );
					$this->set_attribute( "bu-img-contents-$index", 'class', $image_classes );

					echo "<figure class=\"bu-image-item-sizer\" style=\"padding-bottom: {$aspect_ratio}\"><{$link_tag} {$this->render_attributes( "bu-img-contents-$index" )}>";
					?>
						<img width="<?php echo esc_attr( $img[1] ); ?>" height="<?php echo esc_attr( $img[2] ); ?>" src="<?php echo esc_url( $img[0] ); ?>" alt="<?php echo $alt; ?>"/>
					<?php
					//* close markup
					echo "</{$link_tag}></figure></div>";
				}
			}

			if( $layout == "grid" ) {
				$this->getGridColumns( $columns, $settings );
			}

			echo "</{$this->tag}>";
		}
	}

	public function get_columns_per_breakpoint_css_classes( $columns, $settings ) {
		$breakpoint_classes = [];

		if( ! class_exists( '\Bricks\Breakpoints' ) )
			return;

		foreach ( \Bricks\Breakpoints::$breakpoints as $breakpoint ) {
			// Base breakpoint
			if ( ! empty( $breakpoint['base'] ) && $columns ) {
				$column_width         = $this->calc_column_width( $columns );
				$breakpoint_classes[] = 'bricks-col-' . $column_width;
			}

			// Mobile breakpoint
			else {
				$breakpoint_key = $breakpoint['key']; // e.g. tablet_portrait

				// @since 1.3.5 breakpoint syntax with colon
				if ( ! empty( $settings[ "columns:$breakpoint_key" ] ) ) {
					$column_width         = $this->calc_column_width( $settings[ "columns:$breakpoint_key" ] );
					$breakpoint_classes[] = 'bricks-col-' . str_replace( '_', '-', $breakpoint_key ) . '-' . $column_width;
				}

				// @pre 1.3.5 breakpoint syntax with underscore
				elseif ( ! empty( $settings[ "columns_$breakpoint_key" ] ) ) {
					$column_width         = $this->calc_column_width( $settings[ "columns_$breakpoint_key" ] );
					$breakpoint_classes[] = 'bricks-col-' . str_replace( '_', '-', $breakpoint_key ) . '-' . $column_width;
				}
			}
		}

		return $breakpoint_classes;
	}

	public function getGridColumns($columns, $settings ) {
		$css = '';

		$selector = "#brxe-{$this->id}.layout-grid, .brxe-{$this->css_selector}.layout-grid";

		if( ! class_exists( '\Bricks\Breakpoints' ) )
			return;

		foreach ( \Bricks\Breakpoints::$breakpoints as $breakpoint ) {
			// Base breakpoint
			if ( ! empty( $breakpoint['base'] ) && $columns ) {
				$css .= "{$selector}{grid-template-columns: repeat({$columns}, 1fr)}";
			}

			// Mobile breakpoint
			else {
				$breakpoint_key = $breakpoint['key']; // e.g. tablet_portrait

				// @since 1.3.5 breakpoint syntax with colon
				if ( ! empty( $settings[ "columns:$breakpoint_key" ] ) ) {
					$css .= "@media (max-width: " . $breakpoint['width'] . "px){ 
						{$selector} {
							grid-template-columns: repeat(" . $settings[ "columns:$breakpoint_key" ] . ", 1fr);
						}
					}";
				}

				// @pre 1.3.5 breakpoint syntax with underscore
				elseif ( ! empty( $settings[ "columns_$breakpoint_key" ] ) ) {
					$css .= "@media (max-width: " . $breakpoint['width'] . "px){ 
						{$selector} {
							grid-template-columns: repeat(" . $settings[ "columns_$breakpoint_key" ] . ", 1fr);
						}
					}";
				}
			}
		}

		if( $css ) {
			echo "<style type='text/css'>{$css}</style>";
		}
	}
}