<?php 

    // prevent direct file access
	if( !defined( 'ABSPATH' ) ) exit;
    
    class Pixe_Template{

        // return instance for use
        private static $instance;
        public static function get_instance(){
            return self::$instance;
        }
        public static function is_template(){
            return empty(self::$instance->template)? false: true;
        }
        public static function the_content(){
            
            // call the_post to init post variables
            if( (is_page() || is_single()) && have_posts() ){ the_post(); }

            $pixe_template = Pixe_Template::get_instance();

            // page transition
            if( !Pixe_Editor::is_editor() ){
                pixe_get_transition($pixe_template->template_settings);
            }

            // body content
            echo '<div class="pixe-body-wrap" >';
            echo '<div class="pixe-template-container pixe-box-sizing" >';
            echo '<div class="pixe-template-content" >';
            $pixe_template->get_content();
            echo '</div>'; // pixe-template-content
            echo '</div>'; // pixe-template-container
            echo '</div>';
        }

        // template variables
        private $dependency;
        private $template;
        private $template_settings;
        private $template_content;
        private $header;
        private $header_tablet;
        private $header_mobile;
        private $is_side_header = false;
        private $footer;
        private $footer_tablet;
        private $footer_mobile;
        private $template_parts;
        
        function __construct(){
            self::$instance = $this;
            $this->dependency = Pixe_Dependency::get();
            
            add_filter('template_include', array(&$this, 'template_include'), 99999);
            add_action('wp_enqueue_scripts', array(&$this, 'wp_enqueue_dependencies'));
            add_action('wp_enqueue_scripts', array(&$this, 'wp_head_style'), 11);
            add_action('wp_enqueue_scripts', array(&$this, 'wp_footer_script'), 11);
            add_action('wp_enqueue_scripts', array(&$this, 'wp_enqueue_inline'), 99999);
            add_action('wp_footer', array(&$this, 'wp_footer'));
        }

        // enqueue inline style the last
        function wp_enqueue_inline(){
            wp_enqueue_style('pixe-inline');
            wp_enqueue_style('pixe-template');

            wp_enqueue_script('pixe-inline');
        }

        // dependency scripts
        function wp_enqueue_dependencies(){

            // register handle for inline style & script
            wp_register_style('pixe-inline', false, array(), PIXE_VERSION);
            wp_register_style('pixe-template', false, array(), PIXE_VERSION);

            wp_register_script('pixe-inline', false, array('jquery'), PIXE_VERSION, true);

            // get inner template ( post template, popup )
            $this->template_parts = array();
            $templates = $this->dependency->get_template_dependency();

            foreach($templates as $template_id){
                $template = pixe_get_template($template_id);
                if( !empty($template) ){
                    $this->template_parts[] = $template;

                    // merge dependency
                    if( !empty($template->dependency) ){
                        $template_dependency = json_decode($template->dependency, true);
                        $this->dependency->set($template_dependency);
                    }
                }
            }

            if( !Pixe_Editor::is_editor() ){

                // always include these typo dependency
                $this->dependency->set(array(
                    'typo-preset' => array('text', 'button', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6')
                ));

                // enqueue script
                $this->dependency->enqueue_scripts();
            }

        }
        function get_dependencies(){
            
            // header
            if( !empty($this->header->dependency) ){
                $header = json_decode($this->header->dependency, true);
                $this->dependency->set($header);
            }

            // header tablet
            if( !empty($this->header_tablet->dependency) ){
                $header_tablet = json_decode($this->header_tablet->dependency, true);
                $this->dependency->set($header_tablet);
            }

            // header mobile
            if( !empty($this->header_mobile->dependency) ){
                $header_mobile = json_decode($this->header_mobile->dependency, true);
                $this->dependency->set($header_mobile);
            }

            // footer
            if( !empty($this->footer->dependency) ){
                $footer = json_decode($this->footer->dependency, true);
                $this->dependency->set($footer);
            }

            // footer tablet
            if( !empty($this->footer_tablet->dependency) ){
                $footer_tablet = json_decode($this->footer_tablet->dependency, true);
                $this->dependency->set($footer_tablet);
            }

            // footer mobile
            if( !empty($this->footer_mobile->dependency) ){
                $footer_mobile = json_decode($this->footer_mobile->dependency, true);
                $this->dependency->set($footer_mobile);
            }

            // template
            if( !empty($this->template->dependency) ){
                $template = json_decode($this->template->dependency, true);
                $this->dependency->set($template);
            }

            // content
            $is_editor = Pixe_Editor::is_editor();
            if( !$is_editor && (is_single() || is_page()) ){
                $post_id = apply_filters('pixe_template_post_id', get_the_ID());
                $content = pixe_get_post_dependency($post_id, $is_editor);
                $this->dependency->set($content);
            }

            // print_r($this->dependency->get_dependency());
        }
        function wp_footer(){
            if( !Pixe_Editor::is_editor() ){
                pixe_get_popup();
            }
        }
        function wp_footer_script(){
            ob_start();
            echo '(function($){';
            if( Pixe_Editor::is_editor() ){
                $this->dependency->print_editor_scripts();
            }else{
                echo 'window.pixeData = { ajaxUrl: \'' . esc_js(admin_url('admin-ajax.php')) . '\' };';
                $this->dependency->print_scripts();
            }
            echo '})(jQuery);';
            wp_add_inline_script('pixe-inline', ob_get_clean());
        }

        // styles
        function wp_head_style(){

            // get template style
            $styles = $this->get_styles();

            // merge template part style
            foreach($this->template_parts as $template){
                if( !empty($template->style) ){
                    $template_style = json_decode($template->style, true);
                    $styles = pixe_union_styles($styles, $template_style);
                }
            }

            // get style
            $page_css = '';
            if( !empty($styles['desktop']) ){
                $page_css .= $styles['desktop'];
            }
            if( !empty($styles['tablet']) ){
                $page_css .= pixe_device_css('tablet', $styles['tablet']);
            }
            if( !empty($styles['mobile']) ){
                $page_css .= pixe_device_css('mobile', $styles['mobile']);
            }

            // add core component styles
            ob_start();
            if( Pixe_Editor::is_editor() ){
                $this->dependency->print_editor_styles();
            }else{
                $this->dependency->print_styles(); 
            }
            wp_add_inline_style('pixe-inline', ob_get_clean());

            // add template styles
            wp_add_inline_style('pixe-template', wp_strip_all_tags($page_css));

            // page transition style
            $transition_settings = pixe_get_transition_data($this->template_settings);
            pixe_print_preload_animation_style($transition_settings);
        }
        function get_styles(){
            $styles = array(
                'desktop' => '',
                'tablet' => '',
                'mobile' => ''
            );

            // header device display
            $side_header_reset_css = '.pixe-template-content, .pixe-footer.pixe-style-fixed{ padding: 0; }';
            if( !empty($this->header_tablet) ){
                $styles['tablet'] .= '.pixe-header-desktop{ display: none; } .pixe-header-tablet{ display: flex; }';
                $styles['tablet'] .= $side_header_reset_css;
                $side_header_reset_css = '';
            }
            if( !empty($this->header_mobile) ){
                $styles['mobile'] .= '.pixe-header-desktop, .pixe-header-tablet{ display: none; } .pixe-header-mobile{ display: flex; }';
                $styles['mobile'] .= $side_header_reset_css;
            }

            // header
            if( !empty($this->header->style) ){
                $header_style = json_decode($this->header->style, true);
                $styles = pixe_union_styles($styles, $header_style);
            } 

            // header tablet
            if( !empty($this->header_tablet->style) ){
                $header_tablet_style = json_decode($this->header_tablet->style, true);
                $styles = pixe_union_styles($styles, $header_tablet_style);
            }

            // header mobile
            if( !empty($this->header_mobile->style) ){
                $header_mobile_style = json_decode($this->header_mobile->style, true);
                $styles = pixe_union_styles($styles, $header_mobile_style);
            } 

            // footer device display
            if( !empty($this->footer_tablet) ){
                $styles['tablet'] .= '.pixe-footer-desktop{ display: none; } .pixe-footer-tablet{ display: flex; }';
            }
            if( !empty($this->footer_mobile) ){
                $styles['mobile'] .= '.pixe-footer-desktop, .pixe-footer-tablet{ display: none; } .pixe-footer-mobile{ display: flex; }';
            }

            // footer
            if( !empty($this->footer->style) ){
                $footer_style = json_decode($this->footer->style, true);
                $styles = pixe_union_styles($styles, $footer_style);
            }

            // footer tablet
            if( !empty($this->footer_tablet->style) ){
                $footer_tablet_style = json_decode($this->footer_tablet->style, true);
                $styles = pixe_union_styles($styles, $footer_tablet_style);
            } 

            // footer mobile
            if( !empty($this->footer_mobile->style) ){
                $footer_mobile_style = json_decode($this->footer_mobile->style, true);
                $styles = pixe_union_styles($styles, $footer_mobile_style);
            } 

            // template
            if( !empty($this->template->style) ){
                $template_style = json_decode($this->template->style, true);
                $styles = pixe_union_styles($styles, $template_style);
            }

            // content
            if( !Pixe_Editor::is_editor() && (is_single() || is_page()) ){
                $post_id = apply_filters('pixe_template_post_id', get_the_ID());
                $content_style = pixe_get_post_style($post_id, Pixe_Editor::get_instance()->is_preview);
                foreach( $styles as $device => $value ){
                    if( !empty($content_style[$device]) ){
                        $styles[$device] .= $content_style[$device];
                    }
                }
            }

            return $styles;
        }

        // print header
        function get_header($device = 'desktop'){
            if( $device == 'desktop' && empty($this->header) ) return;
            if( $device == 'tablet' && empty($this->header_tablet) ) return;
            if( $device == 'mobile' && empty($this->header_mobile) ) return;
            
            $header_class = 'pixe-header';
            $editor_content = true;

            // header device
            switch($device){
                case 'desktop': 
                    $content = empty($this->header->content)? array(): json_decode($this->header->content, true);
                    $settings = empty($this->header->settings)? array(): json_decode($this->header->settings, true);
                    $header_class .= ' pixe-header-desktop';
                    $header_id = $this->header->id;
                    break;
                case 'tablet': 
                    $content = empty($this->header_tablet->content)? array(): json_decode($this->header_tablet->content, true);
                    $settings = empty($this->header_tablet->settings)? array(): json_decode($this->header_tablet->settings, true);
                    $header_class .= ' pixe-header-tablet';
                    $header_id = $this->header_tablet->id;
                    break;
                case 'mobile': 
                    $content = empty($this->header_mobile->content)? array(): json_decode($this->header_mobile->content, true);
                    $settings = empty($this->header_mobile->settings)? array(): json_decode($this->header_mobile->settings, true);
                    $header_class .= ' pixe-header-mobile';
                    $header_id = $this->header_mobile->id;
                    break;
            }

            // header style
            if( !empty($settings['header']['position']) ){
                if( $settings['header']['position'] == 'top-transparent' ){
                    $header_class .= ' pixe-transparent-header';
                }else if( $settings['header']['position'] == 'bottom' ){
                    $header_class .= ' pixe-bottom-header';
                }else if( in_array($settings['header']['position'], array('left', 'right')) ){
                    $this->is_side_header = true;
                    $editor_content = false;
                    $header_class .= ' pixe-side-header';
                }
            }
            if( empty($settings['header']['position']) || $settings['header']['position'] == 'top-transparent' ){
                if( !empty($settings['header']['mode']) ){
                    $header_class .= ' pixe-style-' . $settings['header']['mode'];
                }
            }

            // data attribute
            $atts = array( 'header-id' => $header_id, 'device' => $device );
            
            // translate content
            pixe_translate_multilingual_strings('header', $header_id, $content);

            // print
            pixe_print_div_open(array(
                'tag' => 'header',
                'class' => 'pixe-editor pixe-box-sizing ' . $header_class,
                'data-atts' => $atts
            ));
            pixe_get_builder_content($content, $editor_content, true);
            echo '</header>';
        }
        
        // print footer
        function get_footer($device = 'desktop'){
            if( $device == 'desktop' && empty($this->footer) ) return;
            if( $device == 'tablet' && empty($this->footer_tablet) ) return;
            if( $device == 'mobile' && empty($this->footer_mobile) ) return;

            $footer_class = 'pixe-footer';
            $device_class = '';

            // footer device
            switch($device){
                case 'desktop': 
                    $content = empty($this->footer->content)? array(): json_decode($this->footer->content, true);
                    $settings = empty($this->footer->settings)? array(): json_decode($this->footer->settings, true);
                    $device_class .= ' pixe-footer-desktop';
                    $footer_id = $this->footer->id;
                    break;
                case 'tablet': 
                    $content = empty($this->footer_tablet->content)? array(): json_decode($this->footer_tablet->content, true);
                    $settings = empty($this->footer_tablet->settings)? array(): json_decode($this->footer_tablet->settings, true);
                    $device_class .= ' pixe-footer-tablet';
                    $footer_id = $this->footer_tablet->id;
                    break;
                case 'mobile': 
                    $content = empty($this->footer_mobile->content)? array(): json_decode($this->footer_mobile->content, true);
                    $settings = empty($this->footer_mobile->settings)? array(): json_decode($this->footer_mobile->settings, true);
                    $device_class .= ' pixe-footer-mobile';
                    $footer_id = $this->footer_mobile->id;
                    break;
            }
            
            $footer_container = false;
            if( !empty($settings['footer']['mode']) ){
                $footer_container = true;
                $footer_class .= ' pixe-style-fixed';
                $footer_class .= ' pixe-style-' . $settings['footer']['mode'];
            }else{
                $footer_class .= $device_class;
            }

            // data attribute
            $atts = array( 'footer-id' => $footer_id );

            // translate content
            pixe_translate_multilingual_strings('footer', $footer_id, $content);
            
            echo $footer_container? '<div class="pixe-fixed-footer-container' . esc_attr($device_class) . '" >': '';
            echo '<footer class="' . esc_attr($footer_class) . '" >';
            pixe_print_div_open(array(
                'class' => 'pixe-editor pixe-box-sizing',
                'data-atts' => $atts
            ));
            pixe_get_builder_content($content, true, true);
            echo '</div>';
            echo '</footer>';
            echo $footer_container? '</div>': '';
        }

        // get content
        function get_content(){
            $this->get_header('desktop');
            $this->get_header('tablet');
            $this->get_header('mobile');

            $content = empty($this->template->content)? array(): json_decode($this->template->content, true);

            // translate content
            pixe_translate_multilingual_strings('synced_block', $this->template->id, $content);

            if( is_single() && get_post_type() == 'product' ){
                pixe_wc_single_product_template($content);
            }else{
                echo '<main class="pixe-editor pixe-box-sizing" >';
                pixe_get_builder_content($content, true, true);
                echo '</main>';
            }
            
            $this->get_footer('desktop');
            $this->get_footer('tablet');
            $this->get_footer('mobile');
        }

        // get template
        function get_template($slug = '', $overrides = array()){
            
            // get template by type
            if( !empty($overrides['template']) ){
                if( $overrides['template'] != 'none' ){
                    $this->template = pixe_get_template($overrides['template']);
                }

            // default template
            }else if( !empty($slug) ){
                global $pixe_site_data;

                // site template override
                if( !empty($pixe_site_data[$slug . '-template']) ){
                    $this->template = pixe_get_template($pixe_site_data[$slug . '-template']);
                }else{
                    $template_settings = pixe_get_template_area();
                    if( !empty($template_settings[$slug]) ){
                        $this->template = pixe_get_template($template_settings[$slug]);
                    }
                }
            }
            
            // each template part
            if( !empty($this->template) ){
                do_action('pixe_load_template', $this->template->id);
                $this->template_content = empty($this->template->content)? array(): json_decode($this->template->content, true);
                $this->template_settings = empty($this->template->settings)? array(): json_decode($this->template->settings, true);

                // header
                if( !empty($overrides['header']) ){
                    if( $overrides['header'] != 'none' ){
                        $this->header = pixe_get_template($overrides['header']);
                    } 
                }else if( !empty($this->template_settings['template']['header']) ){
                    $this->header = pixe_get_template($this->template_settings['template']['header']);
                }else{
                    $default_header = get_option('pixe_default_header', '');
                    if( !empty($default_header) ){
                        $this->header = pixe_get_template($default_header);
                    }
                }

                // header tablet
                if( !empty($overrides['tablet-header']) ){
                    if( $overrides['tablet-header'] != 'none' ){
                        $this->header_tablet = pixe_get_template($overrides['tablet-header']);
                    } 
                }else if( !empty($this->template_settings['template']['tablet-header']) ){
                    $this->header_tablet = pixe_get_template($this->template_settings['template']['tablet-header']);
                }

                // header mobile
                if( !empty($overrides['mobile-header']) ){
                    if( $overrides['mobile-header'] != 'none' ){
                        $this->header_mobile = pixe_get_template($overrides['mobile-header']);
                    } 
                }else if( !empty($this->template_settings['template']['mobile-header']) ){
                    $this->header_mobile = pixe_get_template($this->template_settings['template']['mobile-header']);
                }

                // footer
                if( !empty($overrides['footer']) ){
                    if( $overrides['footer'] != 'none' ){
                        $this->footer = pixe_get_template($overrides['footer']);
                    } 
                }else if( !empty($this->template_settings['template']['footer']) ){
                    $this->footer = pixe_get_template($this->template_settings['template']['footer']);
                }else{
                    $default_footer = get_option('pixe_default_footer', '');
                    if( !empty($default_footer) ){
                        $this->footer = pixe_get_template($default_footer);
                    }
                }

                // footer tablet
                if( !empty($overrides['tablet-footer']) ){
                    if( $overrides['tablet-footer'] != 'none' ){
                        $this->footer_tablet = pixe_get_template($overrides['tablet-footer']);
                    } 
                }else if( !empty($this->template_settings['template']['tablet-footer']) ){
                    $this->footer_tablet = pixe_get_template($this->template_settings['template']['tablet-footer']);
                }

                // footer mobile
                if( !empty($overrides['mobile-footer']) ){
                    if( $overrides['mobile-footer'] != 'none' ){
                        $this->footer_mobile = pixe_get_template($overrides['mobile-footer']);
                    } 
                }else if( !empty($this->template_settings['template']['mobile-footer']) ){
                    $this->footer_mobile = pixe_get_template($this->template_settings['template']['mobile-footer']);
                }

                return true;
            }

            return false;
        }
        
        // include template
        function body_class($classes){
            $classes[] = 'pixe-template';

            if( !empty($this->template_settings['layout']['class']) ){
                $classes[] = $this->template_settings['layout']['class'];
            }

            return $classes;
        }
        function template_include($template){
            if( !defined('PIXE_PRO_VERSION') ){
                $this->get_dependencies();
                return $template;
            }

            $overrides = array();
            $editor = Pixe_Editor::get_instance();
            $is_editor = Pixe_Editor::is_editor();
            
            // for template editor
            if( $is_editor ){
                if( $editor->type == 'template' || $editor->type == 'template_part' ){
                    return PIXE_LOCAL_URL . '/admin/template/template-editor.php'; 
                }
            }

            // override template for page / single page
            if( is_page() || is_single() ){
                
                // get post editor settings
                $revision = $editor->revision;
                if( $is_editor && $revision ){
                    $result = pixe_get_revision_data($revision, $editor->id);
                    $editor_settings = json_decode($result->settings, true);
                }else{
                    $post_id = apply_filters('pixe_template_post_id', get_the_ID());
                    $editor_settings = pixe_get_builder_settings($post_id, $is_editor);
                }

                // check of overrides template
                if( !empty($editor_settings['layout']) ){

                    // get template
                    $override_keys = array('template', 'header', 'tablet-header', 'mobile-header', 'footer', 'tablet-footer', 'mobile-footer');
                    foreach( $override_keys as $key ){
                        if( !empty($editor_settings['layout'][$key]) ){
                            $overrides[$key] = $editor_settings['layout'][$key];
                        }
                    }

                    // for popup
                    if( !empty($editor_settings['layout']['popup']) ){
                        $popups = $editor_settings['layout']['popup'];

                        $this->dependency->set(array(
                            'template' => $popups,
                            'popup' => 1
                        ));
                        
                        foreach( $popups as $popup_id ){
                            pixe_add_popup($popup_id);
                        }
                    }
                }
            }

            $overrides = apply_filters('pixe_template_override', $overrides);
            
            // other pages
            if( !empty($overrides['template']) ){
                $pixe_template = $this->get_template('', $overrides);

            }else{
                if( is_home() ){ 
                    $pixe_template = $this->get_template('home', $overrides);
                }else if( is_page() ){ 
                    $pixe_template = $this->get_template('page', $overrides);
                }else if( is_single() ){
                    $post_type = get_post_type();
                    $pixe_template = $this->get_template('single-' . $post_type, $overrides);
                    if( empty($pixe_template) ){
                        $pixe_template = $this->get_template('single', $overrides);
                    }
                }else if( is_404() ){
                    $pixe_template = $this->get_template('404', $overrides);
                }else if( is_search() ){
                    $pixe_template = $this->get_template('search', $overrides);

                // archive pages
                }else if( is_archive() ){
                    if( is_day() ){
                        $pixe_template = $this->get_template('date', $overrides);
                    }else if( is_month() ){
                        $pixe_template = $this->get_template('date', $overrides);
                    }else if( is_year() ){
                        $pixe_template = $this->get_template('date', $overrides);
                    }else if( is_author() ){
                        $pixe_template = $this->get_template('author', $overrides);
                    }else if( is_post_type_archive() ){
                        $post_type = get_query_var('post_type');
                        $pixe_template = $this->get_template('archive-post-' . $post_type, $overrides);
                    }else if( is_tax() || is_category() || is_tag() ){
                        $term = get_queried_object();
                        $taxonomy = $term->taxonomy;
                        $pixe_template = $this->get_template('archive-tax-' . $taxonomy, $overrides);
                    }

                    // all archive
                    if( empty($pixe_template) ){
                        $pixe_template = $this->get_template('archive', $overrides);
                    }
                }
            }
            
            // initiate dependencies for this page
            $this->get_dependencies();

            if( !empty($pixe_template) ){
                add_filter('body_class', array(&$this, 'body_class'));
                return PIXE_LOCAL_URL . '/admin/template/template.php';
            }

            return $template;
        }

    } // Pixe_Template

    new Pixe_Template();
