<?php

/**
 * A factory class for html elements
 *
 * @author     Time.ly Network, Inc.
 * @since      2.0
 * @package    Ai1EC
 * @subpackage Ai1EC.Factory
 */
class Ai1ec_Factory_Html extends Ai1ec_Base {

    /**
     * @var boolean
     */
    protected $pretty_permalinks_enabled = false;

    /**
     * @var string
     */
    protected $page;

    /**
     * The contructor method.
     *
     * @param Ai1ec_Registry_Object $registry
     */
    public function __construct(
        Ai1ec_Registry_Object $registry
     ) {
        parent::__construct( $registry );
        $app = $registry->get( 'bootstrap.registry.application' );
        $this->page = $app->get( 'calendar_base_page' );
        $this->pretty_permalinks_enabled = $app->get( 'permalinks_enabled' );
    }

    /**
     * Creates an instance of the class which generates href for links.
     *
     * @param array $args
     * @param string $type
     *
     * @return Ai1ec_Href_Helper
     */
    public function create_href_helper_instance( array $args, $type = 'normal' ) {
        $href = new Ai1ec_Html_Element_Href( $args, $this->page );
        $href->set_pretty_permalinks_enabled( $this->pretty_permalinks_enabled );
        switch ( $type ) {
            case 'category':
                $href->set_is_category( true );
                break;
            case 'tag':
                $href->set_is_tag( true );
                break;
            case 'author':
                $href->set_is_author( true );
                break;
            default:
                break;
        }
        return $href;
    }

    /**
     * Create the html element used as the UI control for the datepicker button.
     * The href must keep only active filters.
     *
     * @param array           $args         Populated args for the view
     * @param int|string|null $initial_date The datepicker's initially set date
     * @param string          $title        Title to display in datepicker button
     * @param string          $title_short  Short names in title
     * @return Ai1ec_Generic_Html_Tag
     */
    public function create_datepicker_link(
        array $args, $initial_date = null, $title = '', $title_short = ''
    ) {
        $settings    = $this->_registry->get( 'model.settings' );
        $date_system = $this->_registry->get( 'date.system' );

        $date_format_pattern = $date_system->get_date_pattern_by_key(
            $settings->get( 'input_date_format' )
        );

        if ( null === $initial_date ) {
            // If exact_date argument was provided, use its value to initialize
            // datepicker.
            if ( isset( $args['exact_date'] ) &&
                $args['exact_date'] !== false &&
                $args['exact_date'] !== null ) {
                $initial_date = $args['exact_date'];
            }
            // Else default to today's date.
            else {
                $initial_date = $date_system->current_time();
            }
        }
        // Convert initial date to formatted date if required.
        if ( Ai1ec_Validation_Utility::is_valid_time_stamp( $initial_date ) ) {
            $initial_date = $date_system->format_date(
                $initial_date,
                $settings->get( 'input_date_format' )
            );
        }

        $href_args = array(
            'action'     => $args['action'],
            'cat_ids'    => $args['cat_ids'],
            'tag_ids'    => $args['tag_ids'],
            'exact_date' => "__DATE__",
        );
        $href_args = apply_filters(
            'ai1ec_date_picker_href_args',
            $href_args,
            $args
        );
        $data_href = $this->create_href_helper_instance( $href_args );

        $attributes = array(
            'data-date' => $initial_date,
            'data-date-format' => $date_format_pattern,
            'data-date-weekstart' => $settings->get( 'week_start_day' ),
            'href' => '#',
            'data-href' => $data_href->generate_href(),
            'data-lang' => str_replace( '_', '-', get_locale() ),
        );
        $loader = $this->_registry->get( 'theme.loader' );
        $file = $loader->get_file( 'date-icon.png' );

        $args = array(
            'attributes'  => $attributes,
            'data_type'   => $args['data_type'],
            'icon_url'    => $file->get_url(),
            'text_date'   => __( 'Choose a date using calendar', AI1EC_PLUGIN_NAME ),
            'title'       => $title,
            'title_short' => $title_short,
        );

        return $loader->get_file( 'datepicker_link.twig', $args );
    }

    /**
     * Creates a select2 Multiselect.
     *
     * @param array $args      The arguments for the select.
     * @param array $options   The options of the select
     * @param array $view_args The args used in the front end.
     *
     * @return Ai1ec_File_Twig
     *
     * @staticvar $cached_flips    Maps of taxonomy identifiers.
     * @staticvar $checkable_types Map of types and taxonomy identifiers.
     */
    public function create_select2_multiselect(
        array $args,
        array $options,
        array $view_args = null
    ) {
        // if no data is present and we are in the frontend, return a blank
        // element.
        if ( empty( $options ) && null !== $view_args ) {
            return $this->_registry->get( 'html.element.legacy.blank' );
        }
        static $cached_flips    = array();

        static $checkable_types = array(
            'category' => 'cat_ids',
            'tag'      => 'tag_ids',
            'author'   => 'auth_ids',
        );

        $use_id         = isset( $args['use_id'] );
        $options_to_add = array();
        foreach ( $options as $term ) {
            $option_arguments = array();
            $color            = false;
            if ( $args['type'] === 'category' ) {
                $color = $this->_registry->get( 'model.taxonomy' )
                    ->get_category_color( $term->term_id );
            }
            if ( $color ) {
                $option_arguments['data-color'] = $color;
            }
            if ( null !== $view_args ) {
                // create the href for ajax loading
                $href = $this->create_href_helper_instance(
                    $view_args,
                    $args['type']
                );
                $href->set_term_id( $term->term_id );
                $option_arguments['data-href'] = $href->generate_href();
                // check if the option is selected
                $type_to_check = '';
                // first let's check the correct type
                if ( isset( $checkable_types[$args['type']] ) ) {
                    $type_to_check = $checkable_types[$args['type']];
                }
                // let's flip the array. Just once for performance sake,
                // the categories doesn't change in the same request
                if ( ! isset( $cached_flips[$type_to_check] ) ) {
                    $cached_flips[$type_to_check] = array_flip(
                        $view_args[$type_to_check]
                    );
                }
                if ( isset( $cached_flips[$type_to_check][$term->term_id] ) ) {
                    $option_arguments['selected'] = 'selected';
                }
            }
            if ( true === $use_id ) {
                $options_to_add[] = array(
                    'text'  => $term->name,
                    'value' => $term->term_id,
                    'args'  => $option_arguments,
                );
            } else {
                $options_to_add[] = array(
                    'text'  => $term->name,
                    'value' => $term->name,
                    'args'  => $option_arguments,
                );
            }
        }
        $select2_args = array(
            'multiple'         => 'multiple',
            'data-placeholder' => $args['placeholder'],
            'class'            => 'ai1ec-select2-multiselect-selector span12'
        );
        if ( isset( $args['class'] ) ) {
            $select2_args['class'] .= ' ' . $args['class'];
        }
        $container_class = false;
        if ( isset( $args['type'] ) ) {
            $container_class = 'ai1ec-' . $args['type'] . '-filter';
        }
        $loader  = $this->_registry->get( 'theme.loader' );
        $select2 = $loader->get_file(
            'select2_multiselect.twig',
            array(
                'name'            => $args['name'],
                'id'              => $args['id'],
                'container_class' => $container_class,
                'select2_args'    => $select2_args,
                'options'         => $options_to_add,
            ),
            true
        );
        return $select2;
    }

    /**
     * Creates a select2 input.
     *
     * @param array $args The arguments of the input.
     *
     * @return Ai1ec_File_Twig
     */
    public function create_select2_input( array $args ) {
        if( ! isset ( $args['name'] ) ) {
            $args['name'] = $args['id'];
        }
        // Get tags.
        $tags = get_terms(
            'events_tags',
            array(
                'orderby' => 'name',
                'hide_empty' => 0,
            )
        );

        // Build tags array to pass as JSON.
        $tags_json = array();
        foreach ( $tags as $term ) {
            $tags_json[] = $term->name;
        }
        $tags_json = json_encode( $tags_json );
        $tags_json = _wp_specialchars( $tags_json, 'single', 'UTF-8' );
        $loader =$this->_registry->get( 'theme.loader' );
        $select2_args = array(
            'data-placeholder' => __( 'Tags (optional)', AI1EC_PLUGIN_NAME ),
            'class'            => 'ai1ec-tags-selector span12',
            'data-ai1ec-tags'  => $tags_json
        );
        $select2 = $loader->get_file(
            'select2_input.twig',
            array(
                'name'            => $args['name'],
                'id'              => $args['id'],
                'select2_args'    => $select2_args,

            ),
            true
        );
        return $select2;
    }
}
