<?php

if (!defined('BASEPATH'))
    exit('No direct script access allowed');

class Js_css {

    public $js_main_dir = '';    // location of main js dirrectory
    public $css_main_dir = '';  // location of main css dirrectory
    protected $js_list = array();      // java script files list
    protected $css_list = array();     // css files list
    protected $ignore_js_list = array();   // js ignore list
    protected $ignore_css_list = array();  // css ignore list
    protected $js_string_list = array();
    protected $css_string_list = array();
    protected $js_parse_list = array();
    protected $css_parse_list = array();

    /**
     * Add item to array
     * @param mixed $item - string or array
     * @param array $array
     */
    protected function _add_to_array($item, &$array) {
        if (!empty($item)) {
            if (is_array($item)) {
                foreach ($item as $v) {
                    $this->_add_to_array($v, $array);
                }
            } else {
                $item = trim($item);
                if (array_search($item, $array) === FALSE) {
                    $array[] = $item;
                }
            }
        }
    }

    public function get_js_list() {

        return $this->js_list;
    }

    public function get_css_list() {

        return $this->css_list;
    }

    /**
     * Add js file to js list
     * @param mixed     - path to js file. Like '/myfolder/myfile.js'
     * @return \Js_css
     */
    public function add_js() {
        $numargs = func_num_args();
        // Check for no args
        if ($numargs > 0) {
            // Add args
            $arg_list = func_get_args();
            foreach ($arg_list as $item) {
                $this->_add_to_array($item, $this->js_list);
            }
        }

        return $this;
    }

    /**
     * Add css file to css list
     * @param mixed     - path to css file. Like '/myfolder/myfile.css'
     * @return \Js_css
     */
    public function add_css() {
        $numargs = func_num_args();
        // Check for no args
        if ($numargs > 0) {
            // Add args
            $arg_list = func_get_args();
            foreach ($arg_list as $item) {
                $this->_add_to_array($item, $this->css_list);
            }
        }

        return $this;
    }

    /**
     * Add js string to js_string_list. This text will be add to page head.
     * @param mixed - like 'alert('hello world');'
     * @return \Js_css
     */
    public function add_js_string() {
        $numargs = func_num_args();
        // Check for no args
        if ($numargs > 0) {
            // Add args
            $arg_list = func_get_args();
            foreach ($arg_list as $item) {
                $this->_add_to_array($item, $this->js_string_list);
            }
        }

        return $this;
    }

    /**
     * Add css text to css_string_list. This text will be add to page head.
     * @param mixed - like '#table{color:red;}'
     * @return \Js_css
     */
    public function add_css_string() {
        $numargs = func_num_args();
        // Check for no args
        if ($numargs > 0) {
            // Add args
            $arg_list = func_get_args();
            foreach ($arg_list as $item) {
                $this->_add_to_array($item, $this->css_string_list);
            }
        }

        return $this;
    }

    /**
     * Add js file from module to project head
     * @param string $file - path to js file.
     * @param array $content - text variables to parse
     * Ex. if js file name is test.js and it located in myModule/views/js
     *      then line be like this - $this->js_css->parse('myModule/js/test.js');
     */
    public function parse_js($file, $content = array()) {

        $this->js_parse_list[$file] = $content;
    }

    /**
     * Add css file from module to project head
     * @param string $file - path to css file.
     * @param array $content - text variables to parse
     * Ex. if css file name is test.css and it located in myModule/views/css
     *      then line be like this - $this->js_css->parse('myModule/css/test.css');
     */
    public function parse_css($file, $content = array()) {

        $this->css_parse_list[$file] = $content;
    }

    /**
     * Remove js
     * @param mixed
     * @return \Js_css
     */
    public function remove_js() {
        $numargs = func_num_args();
        // Check for no args
        if ($numargs > 0) {
            // Add args
            $arg_list = func_get_args();
            foreach ($arg_list as $item) {
                $this->_add_to_array($item, $this->ignore_js_list);
            }
        }

        return $this;
    }

    /**
     * Remove css
     * @param mixed
     * @return \Js_css
     */
    public function remove_css() {
        $numargs = func_num_args();
        // Check for no args
        if ($numargs > 0) {
            // Add args
            $arg_list = func_get_args();
            foreach ($arg_list as $item) {
                $this->_add_to_array($item, $this->ignore_css_list);
            }
        }

        return $this;
    }

    protected function _reverse_array_items($array, $first_item, $second_item) {
        $id_1 = array_search($first_item, $array);
        $id_2 = array_search($second_item, $array);
        if ($id_1 && $id_2) {
            $tmp = $array[$id_1];
            $array[$id_1] = $array[$id_2];
            $array[$id_2] = $tmp;
        }

        return $array;
    }

    /**
     * Reverses the order of loading files
     * @param string $first_file
     * @param string $second_file
     * @return \Js_css
     */
    public function js_reverse($first_file, $second_file) {
        $this->js_list = $this->_reverse_array_items($this->js_list, $first_file, $second_file);

        return $this;
    }

    /**
     * Reverses the order of loading files
     * @param string $first_file
     * @param string $second_file
     * @return \Js_css
     */
    public function css_reverse($first_file, $second_file) {
        $this->css_list = $this->_reverse_array_items($this->css_list, $first_file, $second_file);

        return $this;
    }

    /**
     * Create js string from js_list
     * @return string
     */
    public function get_js_string() {
        $result = '';
        foreach ($this->js_list as $record) {
            if (array_search($record, $this->ignore_js_list) === FALSE) {
                $result .= '<script type="text/javascript" src="' . $this->js_main_dir . $record . '"></script>' . PHP_EOL;
            }
        }

        $CI = & get_instance();

        // Parse js
        if (!empty($this->js_parse_list)) {
            $CI->load->library('parser');
            foreach ($this->js_parse_list as $file => $content) {
                $this->add_js_string($CI->parser->parse($file, $content, TRUE));
            }
        }

        // Add js text
        if (!empty($this->js_string_list)) {
            $data = implode("\n", $this->js_string_list);

            if (ENVIRONMENT == 'production') {
                $CI->load->driver('cache', $CI->config->item('cache_init_config'));
                // Prepare cache_key
                $cache_key = $CI->uri->current_page . '_' . md5($data) . '.js';
                $cache_life_time = $CI->config->item('cache_life_time') * 2;
                
                // Minimize js
                $CI->load->library('jsmin', '');
                $CI->cache->save($cache_key, JSMin::minify($data), $cache_life_time);
                $result .= '<script type="text/javascript" src="' . base_url('/getassets/' . $cache_key) . '"></script>' . PHP_EOL;
            } else {
                $result .= '<script type="text/javascript">';
                $result .= $data;
                $result .= '</script>';
            }
        }

        return $result;
    }

    /**
     * Create css string from css_list
     * @return string
     */
    public function get_css_string() {
        $result = '';
        foreach ($this->css_list as $record) {
            if (array_search($record, $this->ignore_css_list) === FALSE) {
                $result .= '<link type="text/css" rel="stylesheet" href="' . $this->css_main_dir . $record . '" />' . PHP_EOL;
            }
        }

        $CI = & get_instance();

        // Parse css
        if (!empty($this->css_parse_list)) {
            $CI->load->library('parser');
            foreach ($this->css_parse_list as $file => $content) {
                $this->add_css_string($CI->parser->parse($file, $content, TRUE));
            }
        }

        // Add css text
        if (!empty($this->css_string_list)) {
            $data = implode("\n", $this->css_string_list);

            if (ENVIRONMENT == 'production') {
                $CI->load->driver('cache', $CI->config->item('cache_init_config'));
                // Prepare cache_key
                $cache_key = $CI->uri->current_page . '_' . md5($data) . '.css';
                $cache_life_time = $CI->config->item('cache_life_time') * 2;
                $CI->load->library('cssmin', $data);
                $CI->cache->save($cache_key, $CI->cssmin->min(), $cache_life_time);
                $result .= '<link type="text/css" rel="stylesheet" href="' . base_url('/getassets/' . $cache_key) . '" />' . PHP_EOL;
            } else {
                $result .= '<style type="text/css">';
                $result .= $data;
                $result .= '</style>';
            }
        }

        return $result;
    }

}
