<?php
/**
 * Auxin Customize Setting Class
 *
 * 
 * @package    auxin
 * @author     averta (c) 2010-2016
 * @link       http://averta.net

*/

/**
 * Customizer Auxin Option Setting class.
 *
 * @see WP_Customize_Setting
 */
class Auxin_Customize_Setting extends WP_Customize_Setting {

    public $type = 'auxin_option';

    // Default value
    public $default = '';

    // The inline JS
    public $post_js = '';

    // A callback function that generates the custom for this setting
    public $style_callback;




    public function __construct( $manager, $id, $args = array() ) {

        add_action( 'customize_preview_init', array( $this, 'preview_init' ) );

        parent::__construct( $manager, $id, $args );

        if ( empty( $this->style_callback ) ) {
            $this->style_callback = array( $this, 'style_callback' );
        }

        // triggers on customizer preview
        add_action( "customize_preview_{$this->id_data['base']}" , array( $this, 'on_customizer_preview'  ) );

    }


    public function on_customizer_preview(){
        // Pass the value of setting to preview frame instead of the stored option value
        add_filter( "pre_auxin_option_{$this->id_data['base']}", array( $this, '_preview_filter' ) );
    }


    public function preview_init(){

        $custom_style = $this->custom_style();

        if( ( ! empty( $this->post_js ) || null !== $custom_style ) &&  'postMessage' == $this->transport ){

            wp_enqueue_script('customize-preview');
            $style_dom_id  = 'auxin-customizer-css-'. $this->id_data['base'];

            ob_start();
            ?>
            ;( function( $ ) {

                var style = { html: function(){} };
        <?php // Genetate the js code for creating style tag
                if( $this->style_callback !== array( $this, 'style_callback' ) ){ ?>
                    style = $( '#<?php echo $style_dom_id; ?>' );

                    if ( ! style.length ) {
                        style = $( 'head' ).append( '<style type=\"text/css\" id=\"<?php echo $style_dom_id; ?>\" />' ).find( '#<?php echo $style_dom_id; ?>' );
                    }
        <?php   } ?>

                wp.customize( '<?php echo $this->id_data['base']; ?>', function( value ) {

                    // apply initial setting value
                    style.html( '<?php echo str_replace( array( "\n", "\r" ) , array(" \ ", " \ "), $custom_style );  ?>' );

                    value.bind( function( to ) {
                        if( undefined !== style ){
                            console.log( wp.ajax );
                            wp.ajax.send( "auxin_customizer", {
                                success: function( data ){
                                    style.html( data );
                                },
                                error: function( data ){
                                    console.log( data );
                                },
                                data: {
                                  nonce: auxinCustomizerNonce,
                                  setting_value: to,
                                  setting_id: '<?php echo $this->id_data['base']; ?>'
                                }
                            });
                        }
                        <?php
                        // add the post_js script
                        echo $this->post_js; ?>
                    });
                });
            } )( jQuery );
            <?php
            $js = ob_get_clean();

            wp_add_inline_script( 'customize-preview', $js, 'after' );
        }

    }


    public function style_callback( $css = array() ){
        return null;
    }

    /**
     * Call the user defined callback for retrieving the custom styles
     *
     * @return string|array   The custom css style with placeholder (|to|)
     */
    public function custom_style(){
        return call_user_func( $this->style_callback, null );
    }


    /**
     * Get the root value for a setting, especially for multidimensional ones.
     *
     * @param mixed $default Value to return if root does not exist.
     * @return mixed
     */
    protected function get_root_value( $default = null ) {
        $id_base = $this->id_data['base'];
        if ( 'option' === $this->type ) {
            return get_option( $id_base, $default );
        } elseif ( 'theme_mod' === $this->type ) {
            return get_theme_mod( $id_base, $default );

        // @auxin-start
        } elseif ( 'auxin_option' === $this->type ) {
            return auxin_get_option( $id_base, $default );
        // @auxin-end
        } else {
            /*
             * Any WP_Customize_Setting subclass implementing aggregate multidimensional
             * will need to override this method to obtain the data from the appropriate
             * location.
             */
            return $default;
        }
    }


    /**
     * Set the root value for a setting, especially for multidimensional ones.
     *
     * @param mixed $value Value to set as root of multidimensional setting.
     * @return bool Whether the multidimensional root was updated successfully.
     */
    protected function set_root_value( $value ) {
        $id_base = $this->id_data['base'];

        if ( 'option' === $this->type ) {
            $autoload = true;
            if ( isset( self::$aggregated_multidimensionals[ $this->type ][ $this->id_data['base'] ]['autoload'] ) ) {
                $autoload = self::$aggregated_multidimensionals[ $this->type ][ $this->id_data['base'] ]['autoload'];
            }
            return update_option( $id_base, $value, $autoload );

        } else if ( 'theme_mod' === $this->type ) {
            set_theme_mod( $id_base, $value );
            return true;

        // @auxin-start
        } else if( 'auxin_option' === $this->type ){

            // update front-end options
            $is_updated = auxin_update_option( $id_base, $value );

            // option panel options
            $raw_options = get_option( THEME_ID.'_options', array() );
            $raw_options[ $id_base ] = $value;
            update_option( THEME_ID.'_options', $raw_options );

            // generate custom css and js codes
            AXI_FONT()->parse_typography();

            auxin_save_custom_css();
            auxin_save_custom_js();

            return $is_updated;

        // @auxin-end
        } else {
            /*
             * Any WP_Customize_Setting subclass implementing aggregate multidimensional
             * will need to override this method to obtain the data from the appropriate
             * location.
             */
            return false;
        }
    }


    /**
     * Save the value of the setting, using the related API.
     *
     * @param mixed $value The value to update.
     * @return bool The result of saving the value.
     */
    protected function update( $value ) {
        parent::update( $value );

        return $this->set_root_value( $value );
    }

}

