<?php
abstract class Ai1ec_Embeddable extends WP_Widget {

    /**
     * @var Ai1ec_Registry_Object
     */
    protected $_registry;

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

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

    /**
     * Get default values for shortcode or widget.
     *
     * @return array
     */
    abstract public function get_defaults();

    /**
     * Get values which are configurable in the Javascript widget.
     * Some things might not be configurable.
     *
     * @return array
     */
    abstract public function get_js_widget_configurable_defaults();

    /**
     * Create the html for the widget. Shared by all versions.
     *
     * @param array $args_for_widget
     * @param bool  $remote_request whether the request is for a remote site or not (useful to inline CSS)
     */
    abstract public function get_content( array $args_for_widget, $remote_request = false );

    /**
     * Add the required javascript for the widget. Needed for shortcode and Wordpress widget
     */
    abstract public function add_js();

    /**
     * Register the widget to the controller.
     *
     * @param string $id_base
     */
    abstract public function register_javascript_widget( $id_base );


    /**
     * Return options needed for thw "Widget creator page
     *
     * @return array
     */
    abstract public function get_configurable_for_widget_creation();

    /**
     * The human-readable name of the widget.
     *
     * @return string
     */
    abstract public function get_name();

    /**
     * The icon class associated with the widget. Defaults to calendar.
     *
     * @return string
     */
    public function get_icon() {
        return 'ai1ec-fa ai1ec-fa-calendar';
    }

    /**
     * Checks and returns widget requirements.
     *
     * @return string
     */
    abstract public function check_requirements();

    /**
     * Register widget class with current WP instance.
     * This must be static as otherwise the class would be instantiated twice,
     * one to register it and the other from Wordpress.
     *
     * @return string
     */
    public static function register_widget() {
        throw new Ai1ec_Exception( 'This should be implemented in child class' );
    }

    public function __construct( $id_base, $name, $widget_options = array(), $control_options = array() ) {
        $this->_id = $id_base;
        parent::__construct( $id_base, $name, $widget_options, $control_options );
        add_shortcode( $id_base, array( $this, 'shortcode' ) );
        add_filter(
            'ai1ec_content_remove_shortcode_' . $id_base,
            array( $this, 'is_this_to_remove_from_event' )
        );
        $this->_registry = apply_filters( 'ai1ec_registry', false );
        $this->register_javascript_widget( $id_base );
        add_filter( 'ai1ec_js_translations', array( $this, 'add_js_translations' ) );
        $this->_registry->get( 'css.frontend' )->add_link_to_html_for_frontend();
    }

    /**
     * @param array $translations
     * @return array
     */
    public function add_js_translations( array $translations ) {
        $translations['javascript_widgets'][$this->_id] = $this->get_js_widget_configurable_defaults();
        return $translations;
    }
    /**
     * Widget function.
     *
     * Outputs the given instance of the widget to the front-end.
     *
     * @param  array $args     Display arguments passed to the widget
     * @param  array $instance The settings for this widget instance
     * @return void
     */
    public function widget( $args, $instance ) {
        $defaults = $this->get_defaults();
        $instance = wp_parse_args( $instance, $defaults );
        $this->add_js();
        $args['widget_html'] = $this->get_content( $instance );
        if ( ! empty( $args['widget_html'] ) ) {
            $args['title'] = $instance['title'];
            $args          = $this->_filter_widget_args( $args );
            // Display theme
            $this->_registry->get( 'theme.loader' )->get_file(
                'widget.twig',
                $args
            )->render();
        }

    }

    /**
     * Renders shortcode
     *
     * @param array $atts
     * @param string $content
     */
    public function shortcode( $atts, $content = null ) {
        $defaults = $this->get_defaults();
        $atts = shortcode_atts( $defaults, $atts );
        $this->add_js();
        return $this->get_content( $atts );
    }

    /**
     * Renders js widget
     *
     * @param array $args
     */
    public function javascript_widget( $args ) {
        $defaults = $this->get_defaults();
        $args = wp_parse_args( $args, $defaults );
        return $this->get_content( $args, true );
    }

    /**
     * Returns whether this shortcode should be removed from event content.
     *
     * @return bool True.
     */
    public function is_this_to_remove_from_event() {
        return true;
    }

    /**
     * Filters default widget parameters like classes, html elements before and
     * after title or widget. Useful for Feature Events widget which has
     * different title styling.
     *
     * @param array $args Widget arguments.
     *
     * @return array Filtered arguments.
     */
    protected function _filter_widget_args( $args ) {
        return $args;
    }
}
