<?php

    // prevent direct file access
	if( !defined( 'ABSPATH' ) ) exit;
    
    class Pixe_Dependency{
            
        private $dependency;
        private $styles = array(); // shows on both front and back end
        private $scripts = array(); // only for front end
        private $core_scripts = array(); // for both front and back end
        private $typo = array();

        public function set($d){
            if( empty($d) ) return;

            if( empty($this->dependency) ){
                $this->dependency = $d;
            }else{
                foreach( $d as $slug => $data ){
                    if( empty($data) ) continue;

                    if( empty($this->dependency[$slug]) ){
                        $this->dependency[$slug] = $data;
                    }else if( is_array($this->dependency[$slug]) && is_array($data) ){
                        $this->dependency[$slug] = pixe_union($this->dependency[$slug], $data);
                    }
                }
            }
        }
        public function get_dependency(){
            return $this->dependency;
        }
        public function register_style($slug, $data){
            $this->styles[$slug] = $data;
        }
        public function register_script($slug, $data){
            $this->scripts[$slug] = $data;
        }
        public function register_core_script($slug, $data){
            $this->core_scripts[$slug] = $data;
        }
        public function get_script_handle($handle, $deps){
            foreach($deps as $slug => $data){
                if( !empty($handle[$slug]) ) continue;

                $element = Pixe_Builder::get_element($slug);
                if( class_exists($element) ){
                    $handle[$slug] = $element::get_title();;
                }else{
                    $handle[$slug] = ucwords(str_replace(array('-', '_'), ' ', $slug));
                }
                
                // replace wc handle
                $handle[$slug] = str_replace('Wc', 'WC', $handle[$slug]);
            }

            return $handle;
        }
        public function get_script_handles(){
            $handle = array();
            $handle = $this->get_script_handle($handle, $this->styles);
            $handle = $this->get_script_handle($handle, $this->scripts);
            $handle = $this->get_script_handle($handle, $this->core_scripts);

            ksort($handle);
            return $handle;
        }
        
        // init
        function __construct(){ }

        // enqueue necessary file
        public function enqueue_scripts(){
            $performance = pixe_get_tool_settings('performance');
            
            // add global script file
            if( !empty($performance['enable-script-file']) ){
                $upload_dir = wp_upload_dir();
                if( file_exists($upload_dir['basedir'] . '/pixe-global-style.css') ){
                    $css_version = filemtime($upload_dir['basedir'] . '/pixe-global-style.css');
                    wp_enqueue_style('pixe-global-css', $upload_dir['baseurl'] . '/pixe-global-style.css', array(), $css_version);
                }
                if( file_exists($upload_dir['basedir'] . '/pixe-global-script.js') ){
                    $js_version = filemtime($upload_dir['basedir'] . '/pixe-global-script.js');
                    wp_enqueue_script('pixe-global-js', $upload_dir['baseurl'] . '/pixe-global-script.js', array('jquery'), $js_version, array('in_footer' => true, 'strategy'  => 'async'));
                }
            }

            // enqueue scripts
            wp_enqueue_script('jquery');

            // navigation & touch navigation & pagination icon dependency
            if( !empty($this->dependency['navigation']) || !empty($this->dependency['touch-navigation']) || !empty($this->dependency['pagination']) ){
                $controls = pixe_get_controls();

                // navigation
                if( !empty($this->dependency['navigation']) ){
                    foreach( $this->dependency['navigation'] as $slug ){
                        if( empty($controls['navigation'][$slug]['dependency']) ) continue;
                        $this->set(array('icon-dep' => $controls['navigation'][$slug]['dependency']));
                    }
                }

                // touch navigation
                if( !empty($this->dependency['touch-navigation']) ){
                    foreach( $this->dependency['touch-navigation'] as $slug ){
                        if( empty($controls['touch'][$slug]['dependency']) ) continue;
                        $this->set(array('icon-dep' => $controls['touch'][$slug]['dependency']));
                    }
                }

                // pagination
                if( !empty($this->dependency['pagination']) ){
                    foreach( $this->dependency['pagination'] as $slug ){
                        if( empty($controls['pagination'][$slug]['dependency']) ) continue;
                        $this->set($controls['pagination'][$slug]['dependency']);
                    }
                }
            }

            // button preset dependency
            if( !empty($this->dependency['button-preset']) ){
                $buttons = pixe_get_button_preset();
                foreach( $this->dependency['button-preset'] as $slug ){
                    if( empty($buttons['preset'][$slug]['dependency']) ) continue;
                    $this->set($buttons['preset'][$slug]['dependency']);
                }
            }

            // variable preset dependency
            $variables = pixe_get_variables();
            if( !empty($variables['dependency']) ){
                $this->set($variables['dependency']);
            }

            $this->dependency['font-family'] = empty($this->dependency['font-family'])? array(): $this->dependency['font-family'];

            // check preset for used fonts
            $this->typo = pixe_get_typo();
            if( !empty($this->dependency['typo-preset']) ){
                foreach( $this->dependency['typo-preset'] as $preset_name ){
                    if( !empty($this->typo['preset'][$preset_name]['value']) ){
                        $preset_value = $this->typo['preset'][$preset_name]['value'];
                        if( !empty($preset_value['font-family']) && !in_array($preset_value['font-family'], $this->dependency['font-family']) ){
                            $this->dependency['font-family'][] = $preset_value['font-family'];
                        }
                        if( !empty($preset_value['tablet-font-family']) && !in_array($preset_value['tablet-font-family'], $this->dependency['font-family']) ){
                            $this->dependency['font-family'][] = $preset_value['tablet-font-family'];
                        }
                        if( !empty($preset_value['mobile-font-family']) && !in_array($preset_value['mobile-font-family'], $this->dependency['font-family']) ){
                            $this->dependency['font-family'][] = $preset_value['mobile-font-family'];
                        }
                    }
                }
            }

            // enqueue google font
            $url = '';
            $font_display = empty($this->typo['google-font-display'])? 'swap': $this->typo['google-font-display'];
            foreach($this->dependency['font-family'] as $font){
                if( !empty($this->typo['googleFont'][$font]) ){
                    $font_slug = pixe_to_slug($font);
                    $font_data = $this->typo['googleFont'][$font];

                    if( !empty($font_data['atts']) ){
                        $href  = 'https://fonts.googleapis.com/css?family=' . $font_data['atts'];
                        $href .= empty($font_data['subset'])? '': '&subset=' . join(',', $font_data['subset']);
                        $href .= '&display=' . $font_display;
                        wp_enqueue_style('google-font-' . $font_slug, $href, array(), PIXE_VERSION);
                    }
                    
                }
            }

            // enqueue icon 
            $use_icons = empty($this->dependency['icon-dep'])? array(): $this->dependency['icon-dep'];
            pixe_enqueue_icons($use_icons);

            // lightbox
            if( !empty($this->dependency['lightbox']) ){
                pixe_enqueue_lightbox();
            }

        }

        // style
        public function get_style_dependency(){
            $styles = array();
            foreach($this->styles as $slug => $data){
                if( function_exists($data) ){
                    $styles[$slug] = $data();
                }
            }

            return $styles;
        }

        // return inner template that this page uses
        public function get_template_dependency(){
            return empty($this->dependency['template'])? array(): $this->dependency['template'];
        }

        // get css to display in header
        public function print_style($dep){
            if( !empty($this->styles[$dep]) && function_exists($this->styles[$dep]) ){
                $this->styles[$dep]();
            }
        }
        public function print_styles(){
            $performance = pixe_get_tool_settings('performance');
            $global_file_deps = array();
    
            // start including preset
            pixe_print_esc_css(pixe_color_preset_css());

            // variable preset
            $variables = pixe_get_variables();
            if( !empty($variables['style']['desktop']) ){
                pixe_print_esc_css($variables['style']['desktop']);
            }
            if( !empty($variables['style']['tablet']) ){
                pixe_print_esc_css(pixe_device_css('tablet', $variables['style']['tablet']));
            }
            if( !empty($variables['style']['mobile']) ){
                pixe_print_esc_css(pixe_device_css('mobile', $variables['style']['mobile']));
            }

            // no global script file
            if( empty($performance['enable-script-file']) ){
                pixe_main_styles();
                pixe_main_tablet_styles();
                pixe_main_mobile_styles();

            // with global script file
            }else if( !empty($performance['script-file']) ){
                $global_file_deps = $performance['script-file'];
            }

            // custom font
            if( !empty($this->dependency['font-family']) ){
                pixe_print_esc_css(pixe_custom_font_css($this->dependency['font-family']));
            }

            // typo preset
            if( !empty($this->dependency['typo-preset']) ){
                pixe_print_esc_css(pixe_typo_preset_css($this->dependency['typo-preset']));
            }

            // button preset
            if( !empty($this->dependency['button-preset']) ){
                pixe_print_esc_css(pixe_buttons_preset_css($this->dependency['button-preset']));
            }

            // controls preset
            pixe_print_esc_css(pixe_controls_preset_css($this->dependency));

            // style for specific page
            if( !empty($this->dependency) ){
                foreach($this->dependency as $slug => $value){
                    switch($slug){
                        case 'animation':
                            if( is_array($value) ){
                                foreach($value as $animation_name){
                                    pixe_print_esc_css(pixe_animation_css($animation_name));
                                }
                            }
                            break;
                        case 'template':
                        case 'typo-preset':
                        case 'button-preset':
                        case 'bullet':
                        case 'navigation':
                        case 'touch-navigation':
                        case 'pagination':
                            break;

                        default:
                            if( !in_array($slug, $global_file_deps) ){
                                $this->print_style($slug);
                            }
                            break;
                    }

                    do_action('pixe_print_dependency_style/' . $slug);
                }
            }
        }

        // backend styles
        public function print_editor_styles(){
            pixe_main_styles();
            pixe_main_tablet_styles();
            pixe_main_mobile_styles();
            
            foreach($this->styles as $slug => $value ){
                $this->print_style($slug);
                
                do_action('pixe_print_editor_dependency_style/' . $slug);
            }
        }

        // script to display in footer
        public function print_script($dep){
            if( !empty($this->core_scripts[$dep]) && function_exists($this->core_scripts[$dep]) ){
                $this->core_scripts[$dep]();   
            }
            if( !empty($this->scripts[$dep]) && function_exists($this->scripts[$dep]) ){
                $this->scripts[$dep]();   
            }
        }
        public function print_scripts(){
            $performance = pixe_get_tool_settings('performance');
            $global_file_deps = array();
            
            // no global script file
            if( empty($performance['enable-script-file']) ){
                pixe_main_scripts();

            // with global script file
            }else if( !empty($performance['script-file']) ){
                $global_file_deps = $performance['script-file'];
            }
            
            if( !empty($this->dependency) ){
                foreach($this->dependency as $slug => $value){
                    if( !in_array($slug, $global_file_deps) ){
                        $this->print_script($slug);
                    }

                    do_action('pixe_print_dependency_script/' . $slug);
                }
            }
        }
        // backend script
        public function print_editor_scripts(){
            pixe_main_scripts();

            // load all scripts in editor area
            foreach($this->core_scripts as $slug => $value ){
                if( function_exists($value) ){
                    $value();
                }
            }
        }

        // get static object
        private static $instance;
        public static function get(){
            if( empty(self::$instance) ){
                self::$instance = new Pixe_Dependency();
            }
            return self::$instance;
        }

    }
