<?php
namespace SabaiApps\Directories\Component\View\Mode;

use SabaiApps\Directories\Application;
use SabaiApps\Directories\Component\Entity\Model\Bundle;
use SabaiApps\Directories\Component\Entity\Type\Query;
use SabaiApps\Directories\Request;

abstract class AbstractMode implements IMode {

	protected $_application, $_name, $_info;

	public function __construct( Application $application, $name ) {
		$this->_application = $application;
		$this->_name        = $name;
	}

	public function __toString() {
		return $this->_name;
	}

	public function viewModeInfo( $key = null ) {
		if ( ! isset( $this->_info ) ) {
			$this->_info = (array) $this->_viewModeInfo();
		}

		return isset( $key ) ? ( isset( $this->_info[ $key ] ) ? $this->_info[ $key ] : null ) : $this->_info;
	}

	public function viewModeSupports( Bundle $bundle ) {
		if ( $view_modes_disabled = $this->_application->Entity_BundleTypeInfo( $bundle, 'view_modes_disable' ) ) {
			return ! in_array( $this->_name, (array) $view_modes_disabled );
		}
		return true;
	}

	public function viewModeSettingsForm( Bundle $bundle, array $settings, array $parents = array() ) {}

	public function viewModeOnInitSettings( Bundle $bundle, array &$viewSettings, Request $request ) {}

	public function viewModeNav( Bundle $bundle, array $settings ) {
		return array(
			array(
				array( array( 'filters' ) ),
				array( array( 'search', 'filter', 'num' ), array(), array( 'sort', 'add' ) ),
			), // header
			array(
				array( array(), array( 'load_more' ), array( 'perpages', 'pagination' ) ),
			), // footer
		);
	}

	public function viewModeAssets( Bundle $bundle, array $settings ) {}

	public function viewModeOnQuery( Bundle $bundle, Query $query, array $settings ) {}

	public function imageSettingsForm( Bundle $bundle, $prefix = '', array $settings = array(), $required = false, array $parents = array(), $weight = null ) {
		$image_fields = $this->_application->Entity_Field_options(
			$bundle,
			array(
				'interface'       => 'Field\Type\IImage',
				'return_disabled' => true,
			)
		);
		if ( empty( $image_fields[0] ) ) {
			return array();
		}

		return array(
			$prefix . 'image_field' => array(
				'#type'             => 'select',
				'#title'            => __( 'Image field', 'directories-pro' ),
				'#description'      => __( 'Select the field used to display the image for each list item.', 'directories-pro' ),
				'#horizontal'       => true,
				'#options'          => array( '' => __( '— Select —', 'directories-pro' ) ) + $image_fields[0],
				'#options_disabled' => array_keys( $image_fields[1] ),
				'#default_value'    => isset( $settings[ $prefix . 'image_field' ] ) ? $settings[ $prefix . 'image_field' ] : null,
				'#weight'           => isset( $weight ) ? $weight : null,
				'#required'         => $required,
			),
			$prefix . 'image_size'  => array(
				'#title'         => __( 'Image size', 'directories-pro' ),
				'#type'          => 'select',
				'#options'       => array(
					'thumbnail'        => __( 'Thumbnail', 'directories-pro' ),
					'thumbnail_scaled' => __( 'Thumbnail (scaled)', 'directories-pro' ),
					'medium'           => __( 'Medium size', 'directories-pro' ),
					'large'            => __( 'Large size', 'directories-pro' ),
				),
				'#default_value' => isset( $settings[ $prefix . 'image_size' ] ) ? $settings[ $prefix . 'image_size' ] : 'thumbnail',
				'#weight'        => isset( $weight ) ? $weight + 1 : null,
				'#horizontal'    => true,
				'#states'        => array(
					'visible' => array(
						sprintf( 'select[name="%s"]', $this->_application->Form_Form_fieldName( array_merge( $parents, array( $prefix . 'image_field' ) ) ) ) => array(
							'type'  => '!value',
							'value' => '',
						),
					),
				),
			),
		);
	}

	/**
	 * Generates a form array for grid column settings.
	 *
	 * @param array       $settings
	 * @param array       $parents
	 * @param string|null $label
	 * @param string|null $name
	 * @param array|null  $columns
	 * @param bool        $responsive
	 * @param bool        $horizontal
	 * @return array
	 */
	protected function _getGridColumnSettingsForm( array $settings, array $parents = array(), $label = null, $name = null, ?array $columns = null, $responsive = true, $horizontal = true ) {
		if ( ! isset( $name ) ) {
			$name = $this->_name . '_cols';
		}
		if ( ! isset( $columns ) ) {
			$columns = array( 2, 3, 4, 6 );
		}
		$column_options = array();
		foreach ( $columns as $num ) {
			$column_options[ $num ] = sprintf( _n( '%d column', '%d columns', $num, 'directories-pro' ), $num );
		}
		$form = array(
			$name => array(
				'#type'          => 'select',
				'#title'         => isset( $label ) ? $label : __( 'Number of columns', 'directories-pro' ),
				'#options'       => $responsive ? $column_options + array( 'responsive' => __( 'Responsive', 'directories-pro' ) ) : $column_options,
				'#default_value' => isset( $settings[ $name ] ) ? $settings[ $name ] : null,
				'#horizontal'    => $horizontal,
			),
		);
		if ( $responsive ) {
			$column_options = array(
				1 => sprintf( __( '%d column', 'directories-pro' ), 1 ),
			) + $column_options;
			foreach ( array(
				'xs'  => '< 360px',
				'xsm' => '>= 360px',
				'sm'  => '>= 576px',
				'md'  => '>= 768px',
				'lg'  => '>= 992px',
				'xl'  => '>= 1200px',
				'xxl' => '>= 1400px',
			) as $width => $width_label ) {
				$form[ $name . '_responsive' ][ $width ] = array(
					'#field_prefix'  => $width_label,
					'#type'          => 'select',
					'#options'       => $width !== 'xs' ? array( 'inherit' => __( 'Inherit from smaller', 'directories-pro' ) ) + $column_options : $column_options,
					'#default_value' => isset( $settings[ $name . '_responsive' ][ $width ] ) ? $settings[ $name . '_responsive' ][ $width ] : 'inherit',
					'#horizontal'    => $horizontal,
					'#states'        => array(
						'visible' => array(
							sprintf( 'select[name="%s"]', $this->_application->Form_Form_fieldName( array_merge( $parents, array( $name ) ) ) ) => array( 'value' => 'responsive' ),
						),
					),
				);
			}
		}

		return $form;
	}

	abstract protected function _viewModeInfo();
}
