<?php

/**
 * Power By Tmac PHP MVC framework
 * $Author: zhangwentao $  <zwttmac@qq.com>
 * $Id: Tmac.class.php 35 2011-11-30 08:54:55Z zhangwentao $
 * http://www.t-mac.org； 
 */
class Tmac
{

    /**
     * Model的instance数组
     * @var array
     */
    protected static $model = array();
    protected static $plugin = array();
    protected static $config = array();

    /**
     * core
     */
    public function __construct()
    {
        global $TmacConfig;
        //设置编码
        header("Content-type: text/html;charset={$TmacConfig['Common']['charset']}");
        //设置时区
        @date_default_timezone_set($TmacConfig['Common']['timezone']);
        //生成htaccess文件
        $htaccess = WEB_ROOT . '.htaccess';
        if ($TmacConfig['Common']['urlrewrite']) {
            if (is_file($htaccess)) {
                if (filesize($htaccess) > 132) {
                    //如果程序无法删除就需要手动删除
                    unlink($htaccess);
                    file_put_contents($htaccess, "RewriteEngine on\r\nRewriteBase " . ROOT . "\r\nRewriteCond %{SCRIPT_FILENAME} !-f\r\nRewriteCond %{SCRIPT_FILENAME} !-d\r\nRewriteRule ^.*$ index.php", LOCK_EX);
                }
            }
        }
        //不进行魔术过滤 php5.3废除了 set_magic_quotes_runtime(0);
        ini_set("magic_quotes_runtime", 0);
        //开启页面压缩
        if ($TmacConfig['Common']['gzip']) {
            function_exists('ob_gzhandler') ? ob_start('ob_gzhandler') : ob_start();
        } else {
            ob_start();
        }
        //页面报错
        $TmacConfig['Common']['errorreport'] ? error_reporting(E_ALL) : error_reporting(0);
        //控制异常
        set_exception_handler(array($this, 'exception'));
        session_start();
        //Router
        new Controller();
    }

    /**
     * 载入Model
     * @param string $model Model名 类名必须与文件名一致 "/"作为目录分隔符
     * @param string $app_name 项目名（如果需要跨项目调用）
     * @param string $ext   后缀名
     * @return object
     * @access public
     * @static
     */
    public final static function model($model, $app_name = APP_NAME, $ext = '.class.php')
    {
        //判断是否已经创建过此Model
        if (!array_key_exists($model, self::$model)) {
            //不存在
            $file = TMAC_BASE_PATH . $app_name . DIRECTORY_SEPARATOR . APPLICATION . DIRECTORY_SEPARATOR . 'Model' . DIRECTORY_SEPARATOR . str_replace('/', DIRECTORY_SEPARATOR, $model) . $ext;
            if (is_file($file)) {
                include_once($file);
                $model = str_replace('/', '', ($tmp = strrchr($model, '/')) === false ? $model : $tmp);
                $m = new $model();
                //执行_init方法
                in_array('_init', get_class_methods($model)) && $m->_init();
                //储存到model数组中 下次调用不再new
                self::$model[$model] = $m;
                return $m;
            } else {
                throw new TmacException('找不到Model文件:' . $file);
            }
        } else {
            //存在
            in_array('_init', get_class_methods(self::$model[$model])) && self::$model[$model]->_init();
            return self::$model[$model];
        }
    }

    /**
     * 载入插件
     * @param string $plugin   插件名 插件类名必须与文件名一致 "."作为目录分隔符
     * @param array $param     插件参数
     * @param string $ext      插件后缀名
     * @return object
     * @access public
     * @static
     */
    public final static function plugin($plugin, $param = array(), $ext = '.class.php')
    {
        //判断是否已经创建过此$plugin
        if (!array_key_exists($plugin, self::$plugin)) {
            $file_tmac = TMAC_PATH . 'Plugin' . DIRECTORY_SEPARATOR . str_replace('.', DIRECTORY_SEPARATOR, $plugin) . $ext;
            $file_app = APPLICATION_ROOT . 'Plugin' . DIRECTORY_SEPARATOR . str_replace('.', DIRECTORY_SEPARATOR, $plugin) . $ext;
            if (is_file($file_tmac)) {
                $file = $file_tmac;
            } elseif (is_file($file_app)) {
                $file = $file_app;
            } else {
                throw new TmacException('找不到Tmac核心包中的Plugin文件:' . $file_tmac . ',也找不到' . APP_NAME . '核心包中的Plugin文件:' . $file_app);
            }
            include_once($file);
            $plugin = str_replace('.', '', ($tmp = strrchr($plugin, '.')) === false ? $plugin : $tmp);
            $p = empty($param) ? new $plugin() : new $plugin($param);
            //储存到$plugin数组中 下次调用不再new
            self::$plugin[$plugin] = $p;
            return $p;
        } else {
            //存在
            return self::$plugin[$plugin];
        }
    }

    /**
     * 输出模板
     * @param string $view 模板路径以及文件名 可以用.作为目录分割
     */
    public final static function view($view = null, $tVar = null)
    {
        global $TmacConfig;
        $options = array(
            'template_dir' => APPLICATION_ROOT . $TmacConfig['Template']['template'], //设置系统模板文件的存放目录
            'cache_dir' => VAR_ROOT . $TmacConfig['Template']['cache_dir'], //指定缓存文件存放目录
            'auto_update' => $TmacConfig['Template']['auto_update'], //当模板文件有改动时重新生成缓存 [关闭该项会快一些]
            'cache_lifetime' => $TmacConfig['Template']['cache_lifetime'], //缓存生命周期(分钟)，为 0 表示永久 [设置为 0 会快一些]
            'suffix' => $TmacConfig['Template']['suffix'], //模板后缀
            'cache_open' => $TmacConfig['Template']['cache_open'], //是否开启缓存，程序调试时使用
            'value' => $tVar    //压到模板里的变量数据                               
        );
        $tpl = Template::getInstance();
        $tpl->setOptions($options); //设置模板参数
        $tpl->init();  //构造db     
        //如果是前台的模板就不用前缀（模板目录名）        
        if ($view == $TmacConfig['Template']['template_dir'] . DIRECTORY_SEPARATOR) {
            //如果模板路径，文件名为空的话就尝试把TMAC_CONTROLLER_FILE当作模板路径，文件名        
            $view_new = strtolower($_GET['TMAC_CONTROLLER_FILE']);  //都转成小写的                                    
            $view = $view . $view_new;  //前面加上模板目录名
        }
        $tpl->show($view);
    }

    /**
     * 获取某个文件的路径
     * @param string $file 文件路径
     * @return void
     * @access public
     * @static
     */
    public final static function file($file)
    {
        $file = str_replace(array('\\', '//', '\\\\'), '/', $file);
        return TMAC_BASE_PATH . $file;
    }

    /**
     * 载入Config
     * @param string $model Model名 类名必须与文件名一致 "."作为目录分隔符
     * @param string $app_name   项目名
     * @param string $ext   后缀名
     * @return object
     * @access public
     * @static
     */
    public final static function config($model, $app_name = APP_NAME, $ext = '.php')
    {
        // Extract the main group from the key
        $group_array = explode('.', $model);
        $group = $group_array[0];
        array_shift($group_array);
        if (!isset(self::$config[$group])) {
            //存在
            $file = TMAC_BASE_PATH . $app_name . DIRECTORY_SEPARATOR . APPLICATION . DIRECTORY_SEPARATOR . 'Config' . DIRECTORY_SEPARATOR . $group . $ext;
            if (is_file($file)) {
                include($file);
                if (isset(self::$config[$file])) {
                    self::$config[$group] = array_merge(self::$config[$group], $config);
                } else {
                    self::$config[$group] = $config;
                }
                unset($config);
            } else {
                throw new TmacException('找不到Config文件:' . $file);
            }
        }
        if (count($group_array) == 1) {
            $group_key = $group_array[0];
            $group_value = isset(self::$config[$group][$group_key]) ? self::$config[$group][$group_key] : '';
        } else {
            $group_value = self::$config[$group];
            foreach ($group_array AS $value) {
                if (isset($group_value[$value])) {
                    $group_value = $group_value[$value];
                }
            }
        }
        if (!isset($group_value)) {
            //self::log('error', 'Missing i18n entry ' . $key . ' for language ' . $locale);
            throw new TmacException('Config文件:' . $group . '里面的配置文件值不能为空!');
        }
        return $group_value;
    }

    /**
     * 获取缓存实例
     * @return object
     * @access public
     * @static
     */
    public final static function getCache()
    {
        return CacheDriver::getInstance();
    }

    /**
     * 获取数据库连接实例
     * @return objeact
     * @access public
     * @static
     */
    public final static function getDB($name)
    {
        return DatabaseDriver::getInstance($name);
    }

    /**
     * 获取模板引擎实例
     * @return object
     * @access public
     * @static
     */
    public final static function getTemplate()
    {
        return Template::getInstance();
    }

    /**
     * 控制异常的回调函数 回调函数必须为public
     * @param object $e
     * @access public
     */
    public final function exception($e)
    {
        $e->getError();
    }

}