<?php if (!defined('HTTP_SERVER')) die('You can not access this file directly!');
/**
  @licence GPL 2005-2011  The osCSS developers - osCSS Open Source E-commerce
  @portion code Copyright (c) 2002 osCommerce
  @package osCSS-2 <www http://www.oscss.org>
  @version 2.1.0
  @date  28/01/11, 00:08
  @author oscim <mail aurelien@oscim.fr> <www http://www.oscim.fr>
  @encode UTF-8
  \class page
  \file
  \dir includes/classes/

  \brief Constructeur de page public

  	Cette class centralise et assure l'ensemble des appels du coté public.
  	Initialise autant le type, la destination, les tags, titres que les inititalisation des class necessaire \n
*/

class page {
  public  $page;

  public $oscss_boxes;

  /**
    \brief public Contient les propriete des element devant être remplacé dans les pages
  */
  public $propriete = array();

  public $currencies;
  /**
    \brief Title intermediarire
  */
  public $title;

  /**
    \brief Array file lang (.txt)

  */
  private $PileFileLang=array();
  /**
    Array file exist cache

  */
  private static $PileFile=array();
  /**
    \brief Array cache global

  */
  private static $GlobalCache=array();
  /**
    @p object cache global

  */
  private static $objCache;
  /**
    @p bool admin liaison base

  */
  private static $CookieAdmin;
  /**
    @a string res md5 url en cours
    public
  */
  public static $keyCacheName;
  /**
    @a bool recalcul mode
     public
  */
  public static $CacheCalcul;

  private $file_registered;

  protected static $_instance;



  private function __construct(){
    $this->ext='.php';
    $this->page['var']['develop']  ='false';
    $this->page['header']['file']=array();
    $this->page['footer']['file']=array();
    $this->page['modules']=array();
    $this->page['plugins']=array();
    $this->page['boxes']=array();
    $this->page['type']='none';
    $this->page['content']=FILENAME_DEFAULT;
    $this->page['class']='none';
    $this->page['script']='';

    $this->PileFileLang=array();

    self::$CacheCalcul=(isset($_GET['cache']) && $_GET['cache']=='calcul')? true :false;

    /**
      base page en cours
    */
//     $b=basename($_SERVER['REQUEST_URI']);
    $b=basename($_SERVER['SCRIPT_NAME']) . (( ($quey_string=tep_get_all_get_params(array('cache','page'))) !='')? '?'.$quey_string : '')  ;
    self::$keyCacheName=md5($b);

    //! key cache file
    self::$objCache = new osCSS_Cache;
    if(self::$CacheCalcul) self::$objCache->clear('Global-'.self::$keyCacheName);
    if (self::$objCache->read('Global-'.self::$keyCacheName) )  self::$GlobalCache= self::$objCache->getCache();

    self::$GlobalCache['page_courante']= $b;
    /**
            Page necessitant une identifcation obligatoire
    */
    /* Noyau */
    $this->file_registered=array(
                FILENAME_ACCOUNT,FILENAME_ADDRESS_BOOK,FILENAME_ADDRESS_BOOK_PROCESS,FILENAME_CHECKOUT_PAYMENT_ADDRESS,FILENAME_CHECKOUT_PAYMENT,FILENAME_CHECKOUT_SHIPPING,FILENAME_CHECKOUT_CONFIRMATION,FILENAME_CHECKOUT_SHIPPING_ADDRESS,FILENAME_LOGIN,FILENAME_PASSWORD_FORGOTTEN
    );
    /* module, hack */
    if(defined('FILENAME_RETURN')) {
      $this->file_registered[]=FILENAME_RETURN;
      $this->file_registered[]=FILENAME_RETURNS_TRACK;
    }
    /**
            Page de devant pas être indéxe dans le fils d'arianne (breadcrumb)
    */
    $this->file_not_breadcrumb[]='';

    /**
      Prise en charge cookie admin
    */
    self::$CookieAdmin =(isset($_COOKIE['oscss_admin']))? true : false ;
  }

  public static function getInstance() {
      if(self::$_instance == null) {
	  self::$_instance = new self();
      }
      return self::$_instance;
  }

  /**
    @fn StopCacheVar()
    @brief Stock mise en cache var et element de page
  */
  public static function StopCacheVar(){
    self::$objCache->writeBuffer(self::$GlobalCache);
  }

  /**
    @fn GetCacheVar()
  */
  public static function GetCacheVar(){
    return self::$GlobalCache;
  }

  /**
    @fn AddCacheVar($pile, $name, $var)
    @param $pile string
    @param $name string
    @param $var array/string
    ex page::AddCacheVar('boxes',$key,$array);
  */
  public static function AddCacheVar($pile, $name, $var){
    self::$GlobalCache[$pile][$name]=$var;
  }

  /**
   * \brief retour du nom du template
  */
  private static function oscss_get_template() {
    if(!defined('TEMPLATE_NAME')) die(__('FATAL ERROR: no template defined !'));
    elseif(!is_dir(DIR_WS_TEMPLATES . TEMPLATE_NAME) )  die(__('FATAL ERROR: the template directory do not exist!'));
    else return TEMPLATE_NAME;
  }

  /**
    @fn oscss_get_gabarit_template()
    \brief traite le nom de la page pour determine le gabarit utilisé
    \li -> template/products_info.(type produit).php (ex product_info.type_1)
    \li -> template/template.(type produit).php (ex product_info.type_1)
    \li -> template/nom_page.(cpath or product_id).php (ex product_info.p_12)
    \li -> template/template.(cpath or product_id).php
    \li -> template/nom_page.php
    \li -> template/type.nom_page.(cpath or product_id).php
    \li -> template/type.nom_page.php
    \li -> template/type.template.(cpath or product_id).php
    \li -> template/type.template.php
    \li -> template/template.php
      NOTE: Si cptah vide, alors cherche suffixe error
    @param [out] $this page[type] determine la class de gabarit.
    @param [out] $this page[content]
    @return retour du nom du template
  */
  private function oscss_get_gabarit_template() {
    if(isset(self::$GlobalCache['gabarit'])) return $this->page['gabarit']=self::$GlobalCache['gabarit'];

    $page="%1\$s.%2\$s.php";
    $path=DIR_WS_TEMPLATES . $this->page['template']  .'/';
    switch($this->page['type']){
      case 'product':
        if (empty($this->page['var']['product_info']['products_id'])) $suffixe='error';
        else $suffixe='p_'.$this->page['var']['product_info']['products_id'];
      break;
      case 'listing':
      case 'listing_cat':
        if (!tep_not_null($this->page['var']['cPath'])) $suffixe='error';
        else {
	  if(strpos($this->page['var']['cPath'],'_')!=false)
	    $suffixe='c_'.substr($this->page['var']['cPath'], 0, strpos($this->page['var']['cPath'],'_')).'.childs';
	  else
	    $suffixe='c_'.$this->page['var']['cPath'];
	}
      break;
    }
    $p_red=substr($this->page['content'],0,-4);
    if (isset($_GET['popup']) && self::TestFile($path.'popup.php') )
      $this->page['gabarit']='popup.php';
    // type products
    elseif($this->page['type']=='product' && self::TestFile($path.sprintf($page,$p_red,'type_'.$this->page['var']['product_info']['type'])) )
      $this->page['gabarit']=sprintf($page,$p_red,'type_'.$this->page['var']['product_info']['type']);
    elseif($this->page['type']=='product' && self::TestFile($path.sprintf($page,'template','type_'.$this->page['var']['product_info']['type'])) )
      $this->page['gabarit']=sprintf($page,'template','type_'.$this->page['var']['product_info']['type']);
    //page
    elseif(isset($suffixe) && self::TestFile($path.sprintf($page,$p_red,$suffixe)) )
      $this->page['gabarit']=sprintf($page,$p_red,$suffixe);
    elseif(isset($suffixe) && self::TestFile($path.sprintf($page,'template',$suffixe)) )
      $this->page['gabarit']=sprintf($page,'template',$suffixe) ;
    elseif(self::TestFile($path.$this->page['content']))
      $this->page['gabarit']=$this->page['content'] ;
    // class
    elseif(isset($suffixe) && self::TestFile($path.$this->page['class'].'.'.sprintf($page,$p_red,$suffixe) ))
        $this->page['gabarit']=$this->page['class'].'.'.sprintf($page,$p_red,$suffixe) ;
    elseif(self::TestFile($path.$this->page['class'].'.'.$this->page['content'] ))
      $this->page['gabarit']=$this->page['class'].'.'.$this->page['content'] ;
    elseif(isset($suffixe) && self::TestFile($path.$this->page['class'].'.'.sprintf($page,'template',$suffixe) ))
      $this->page['gabarit']=$this->page['class'].'.'.sprintf($page,'template',$suffixe) ;
    elseif(self::TestFile($path.$this->page['class'].'.'.'template.php' ))
      $this->page['gabarit']=$this->page['class'].'.'.'template.php' ;
    // type
    elseif(isset($suffixe) && self::TestFile($path.$this->page['type'].'.'.sprintf($page,$p_red,$suffixe) ))
        $this->page['gabarit']=$this->page['type'].'.'.sprintf($page,$p_red,$suffixe) ;
    elseif(self::TestFile($path.$this->page['type'].'.'.$this->page['content'] ))
      $this->page['gabarit']=$this->page['type'].'.'.$this->page['content'] ;
    elseif(isset($suffixe) && self::TestFile($path.$this->page['type'].'.'.sprintf($page,'template',$suffixe) ))
      $this->page['gabarit']=$this->page['type'].'.'.sprintf($page,'template',$suffixe) ;
    elseif(self::TestFile($path.$this->page['type'].'.'.'template.php' ))
      $this->page['gabarit']=$this->page['type'].'.'.'template.php' ;
    // base
        elseif(self::TestFile($path  .'template.php'))
        $this->page['gabarit']='template.php';
    else die(__('object page (lg '.__LINE__.') FATAL ERROR: the gabarit template not found!'));

    self::$GlobalCache['gabarit']=$this->page['gabarit'];
  }


  /**
    \fn type_content()
    \brief determine le type de page (class de page)
  */
  private function type_content(){
    if(isset(self::$GlobalCache['gabarit'])){
      $this->page['class']=self::$GlobalCache['class_content'];
      return $this->page['type']=self::$GlobalCache['type_content'];
    }
    if (isset($_GET['popup'])){
      $this->page['type']='popup';
    }elseif ($this->page['content']=='index.php' ||$this->page['content']=='home.php'  && (empty($_SERVER['QUERY_STRING']) || (isset($_GET['osCsid']) || isset($_GET['divers']) ) )) {
      $this->page['type']='home';
    }elseif ($this->page['content']=='index.php' && (!empty($_SERVER['QUERY_STRING']) && isset($_GET['customers_id']) )) {
      $this->page['type']='member';
      $this->page['class']='single';
    }elseif (in_array(substr($this->page['content'],0,7), array('account','address')) || in_array(substr(basename($_SERVER['SCRIPT_NAME']),0,-4), array('account','address')) ) {
      $this->page['type']='account';
    }elseif (substr($this->page['content'],0,8) =='checkout') {
      $this->page['type']='checkout';
    }elseif (substr($this->page['content'],0,7) =='product') {
      $this->page['type']='product';
      $this->page['class']='single';
    }elseif (in_array(substr($this->page['content'],0,6) , array('shoppi'))) {
      $this->page['type']='cart';
    }elseif (substr($this->page['content'],0,9) =='index_cat') {
      $this->page['type']='listing_cat';
    }elseif (in_array(substr($this->page['content'],0,6) , array('listin','index_','index.'))) {
      $this->page['type']='listing';
    }elseif (in_array(substr($this->page['content'],0,7) , array('content')) &&  isset($_GET['content']) ) {
      $this->page['type']='content';
      $this->page['class']='single';
    }else {
      $this->page['type']='none';
    }

    self::$GlobalCache['type_content']=$this->page['type'];
    self::$GlobalCache['class_content']=(isset($this->page['class'])? $this->page['class'] :'single' );
  }


  /**
    \fn fix_file($path, $lg=false, $core=NULL)
    \brief Surclasse les fichiers du core par ceux du template
      Boxe, module, content, class, etc..
    @param $path string path
    @param $lg boolean lg  mode language
    @param $core boolean core force fichier du core
    @return path
  */
  static public function fix_file($path, $lg=false, $core=NULL){
    global $page;
    $doublon=array();
    static $doublon;
    $sortie=NULL;
    $file=basename($path);
    $path=dirname($path);
    $path.=(!preg_match("#.*/$#",$path))?'/':'';
    $file_path=(substr($path,0,strlen(DIR_FS_CATALOG)) ==DIR_FS_CATALOG)? substr($path,strlen(DIR_FS_CATALOG)) : $path;
    $file_path=(substr($file_path,0,strlen( tep_get_http())) == tep_get_http())? substr($file_path,strlen( tep_get_http())) : $file_path;
    $path_template=DIR_WS_TEMPLATES . (isset($page->page['template'])? $page->page['template'] : TEMPLATE_NAME ) .'/';

    if($lg && $file=substr($file,0,-4) ) {
      if($core==NULL || $core==false)
	foreach( array('txt','php') as $ext_lg)
	  if( ($s=$path_template.$file_path.$file.'.'.$ext_lg) && self::TestFile($s) && !in_array($s,(array)$doublon))  $sortie= $s;

      if($sortie==NULL)
	foreach( array('txt','php') as $ext_lg)
	  if( ($s=$path.$file.'.'.$ext_lg) && self::TestFile($s) && !in_array($s,(array)$doublon))  $sortie= $s;
    }
    else {
      if( ($s=$path_template.$file_path.$file) && self::TestFile($s) && !in_array($s,(array)$doublon))  $sortie= $s;
      elseif( ($s=$path.$file) && self::TestFile($s) && !in_array($s,(array)$doublon) )  $sortie= $s;
    }
    $doublon[]=$sortie;

    return ($sortie!=NULL)? $sortie : false;
  }

  /**
    \brief Chargeur de fichier de langues
    \note Specifique au .txt
  */
  public function pile_file_lang($path_file){
    global $lang;
    if(substr($path_file,0,strlen(DIR_FS_CATALOG)) !=DIR_FS_CATALOG) $path_file= DIR_FS_CATALOG.$path_file;

    if(!in_array($path_file,(array)$this->PileFileLang))
      include_once($path_file);
  }

  /**
    \brief Appelé en debut et fin d'appli
    Charge et stock le cache des fichier de lang en .txt
    \note Specifique au .txt
  */
  public function cache_lang($load=true){
    global $lang,$languages_id;
    //! instance cache
    $osCSS_Cache = new osCSS_Cache;
    if(self::$CacheCalcul)$osCSS_Cache->clear('fo_lang-'.$languages_id.'-'.self::$keyCacheName);
    $osCSS_Cache->read('fo_lang-'.$languages_id.'-'.self::$keyCacheName);
    if($load){
      $res= $osCSS_Cache->getCache();
      global $lang;
      $lang=$res['lang'];
      $this->PileFileLang=$res['PileFile'];
    } else{
      $pilefile=array();
      foreach(get_included_files() as $e)
        if(substr($e,-3)=='txt') $pilefile[]=$e;

      if(count($pilefile)>0) {
        $variable = array('lang'=>$lang,'PileFile'=>array_merge($pilefile,(array)$this->PileFileLang) );
        $osCSS_Cache->writeBuffer($variable);
      }
    }
  }

  /**
   * \fn TestFile($file)
   * \brief test si fichier existe et cache du test
    enregsitrement a la volee
   * \return boolean
  */
  public static function TestFile($file){
    $keytemp=md5($file);
    $result=self::Testfile_exists($file,$keytemp);
    return _test_bool($result);
  }

  /**
    @fn Testfile_exists($file,$keytemp)
    @param $file
    @param $keytemp
  */
  private static function Testfile_exists($file,$keytemp){
    if(isset(self::$GlobalCache['PileFile'][$keytemp])) return self::$GlobalCache['PileFile'][$keytemp];
    elseif(file_exists($file)) return self::$GlobalCache['PileFile'][$keytemp]='true';
    else return self::$GlobalCache['PileFile'][$keytemp]='false';
  }



  /**
   * \fn draw_file_header()
   * \brief Seul les variables global (GET,POST,etc) et l'object this sont accessible dans les fichiers appelé par cette fcuntion
      Fonction appelé dans le header des themes
  */
  private function draw_file_header(){

    $page=$this;
    $language=$this->page['language'];
    $PHP_SELF=$this->page['content'];
    $template=$this->page['template'];
    $current_category_id=$this->ret_var_page('current_category_id');
    $languages_id=$this->ret_var_page('languages_id');

    $init_theme=DIR_WS_TEMPLATES . $this->page['template']  .'/cfg/init.php';
    if(self::TestFile($init_theme)) include($init_theme);

    /* chargement des js en sortie*/
    $this->javascript->cstr_header();

    if( ($name=$page->the_type()) && ($page->return_object($name) !=false) ) {
      $class=$page->return_object($name);
      if(method_exists($class, 'get_header' )) $class->get_header();
    }

    if(isset($this->page['header']['file'])){
      $files=$this->page['header']['file'];
      ksort($files);
      foreach($files as $key=>$values) tep_include_file($values['file']);
    }
    print $this->javascript->init_prepa();

    if(isset($this->page['header']['script'])) {
      $files=$this->page['header']['script'];
      ksort($files);
      foreach($files as $key=>$values) print $values['script'];
    }

    /**
      \brief Recherche des fichier dans include/js et chargement des fichier specique au content
    */
    $file=DIR_WS_INCLUDES.'js/'.$this->page_content_clean().'.js.php';
      if( ($file=self::fix_file($file)) && $file !=false ) tep_include_file($file);
  }


  /**
   * \fn draw_file_footer()
   * \brief Seul les variables global (GET,POST,etc) et l'object this sont accessible dans les fichiers appelé par cette fcuntion
  */
  private function draw_file_footer(){
    if(isset($this->page['footer']['file'])){
      $files=$this->page['footer']['file'];
      ksort($files);
      foreach($files as $key=>$values) tep_include_file($values['file']);
    }
  }

  /**
   * \fn pre_init()
   * \brief
   * \note fonction qui doit être appelé dans le application_top
  */
  public function pre_init(){
    $this->breadcrumb->add(HEADER_TITLE_TOP,  tep_get_httpdir() );
    $this->breadcrumb->add(HEADER_TITLE_CATALOG, tep_href_link(FILENAME_DEFAULT));

    // set the template
    $this->page['template'] = page::oscss_get_template();

  }

  /**
   * \fn init($p_content,$language)
   * \brief
    fonction qui doit être appelé par le fichier à la racine de la boutique juste apres le application_top
    Le fichier de langue principal est chargée, priorité a cleui du template
    @param $p_content
    @param $language
  */
  public function init($p_content,$language){
    $this->page['script']=$p_content;
    $this->page['content']=trim($p_content);
    $this->page['language']=$language;
    $this->type_content();
    $page=$this;

    /* Init class gestion js */
    $this->new_class('javascript');

    /* Appel fichier langue specifique page */
    if(($path=self::fix_file(DIR_WS_LANGUAGES . $language . '/' . $this->page['content'],true)) !=false) $this->pile_file_lang($path);
    elseif(($path=self::fix_file(DIR_WS_LANGUAGES .  'fr_FR/' . $this->page['content'],true)) !=false) $this->pile_file_lang($path);

    $path_template=DIR_WS_TEMPLATES . $this->page['template'] .'/';
    if (self::TestFile($path_template.DIR_WS_INCLUDES .'lib.functions.theme.php' )) require_once($path_template .DIR_WS_INCLUDES .'lib.functions.theme.php');

    //! activ class aca generic
    $aca=$this->new_class('generic');
    $aca=generic::getInstance();
    $res=$aca->check_action('',@$_GET['action']);
  }


  /**
    @fn post_init($bread=true)
    @note fonction qui doit être appelé par le fichier à la racine de la boutique juste avant l'appel a require(path_gabarit());
    @param $bread bool
  */
  public function post_init($bread=true){

    $this->new_class('oscss_plugins');
    $this->new_class('categorie');
    //! Class specifique type de page
    if (in_array($this->the_type(),array('listing','product','account','home','content'))){
      global $ACA;
      $this->new_class($this->the_type(),true);
      $ACA = $this->return_object($this->the_type());
    }
    //! Init du theme
      $this->oscss_get_gabarit_template();
    ///! recup elements des plugins
    $this->page['plugins']['present']=$this->oscss_plugins->plugins_active('generic');

    if(self::TestFile(DIR_WS_TEMPLATES . $this->page['template'] .'/' . DIR_WS_INCLUDES. 'plugins/'.$this->the_type().'/'))
      $this->page['plugins']['type']=$this->oscss_plugins->plugins_active($this->the_type());

    //! fil rouge
    if($bread) {
      if(($this->page['type']=='account')&& $this->page['script'] !=FILENAME_ACCOUNT )  $this->breadcrumb->add(NAVBAR_TITLE_1, tep_href_link(FILENAME_ACCOUNT, '', 'SSL'));

      if (!in_array($this->page['script'],$this->file_not_breadcrumb)) {
        $mode=(in_array($this->page['script'],$this->file_registered))? 'SSL': 'NONSSL';
        $this->title=(defined('NAVBAR_TITLE')) ? NAVBAR_TITLE: ((defined('NAVBAR_TITLE_2')) ? NAVBAR_TITLE_2 : NAVBAR_TITLE_1 );
        $this->breadcrumb->add($this->title, tep_href_link($this->page['script'], '',$mode));
      }
    }

    //! Class permanente
    $this->new_class('oscss_modules');
    $this->new_class('oscss_boxes');
  }

  /**
    \brief Return path tmplate courant
  */
  public function getPathTemplate(){
    return DIR_WS_TEMPLATES . $this->page['template'] .'/';
  }

  /**
    \brief femeture de session
  */
  public function tep_session_close(){
    $navigation=navigation_history::getInstance();
    $navigation->set_close();
    tep_session_close();
}

  /**
    \brief Force un contenu,qui n'est pas celui herité du fichier de la racine de la boutique
    @param $p_content string
  */
  public function force_content($p_content){
    $this->page['content']=trim($p_content);
    $this->type_content();
  }

  /**
   * \brief  Force un gabarit, qui detremine le choix du gabarit de page
   * @param $gabarit string
  */
  public function force_gabarit($gabarit){ $this->page['gabarit']=trim($gabarit); }

  /**
   * \fn add_var_page($key,$value='')
   * \brief  Add des var
    @param $key string
    @param $value string/array/int
  */
  public function add_var_page($key,$value=''){
    if (empty($key)) return false;
    $this->page['var'][$key]=$value;
  }

  /**
    \brief return var
    @param $key string
  */
  private function ret_var_page($key){
    if (empty($key) || !isset($this->page['var'][$key])) return false;
    return $this->page['var'][$key];
  }

  /**
   * \fn _draw_in_page($string)
   * \brief Charge un element dans la page, si var ou cst bool defini
   @param [in] $string \a string Nom constante de reference
    [out] $this object this->var[]
   @return  boolean
  */
  public function _draw_in_page($string){
    if (empty($string)) return false;
    $key=strtoupper($string);
    if (isset($this->page['var'][$key]) and ( (is_string($this->page['var'][$key]) && strtoupper($this->page['var'][$key])=='TRUE')||( is_bool($this->page['var'][$key]) && $this->page['var'][$key]==TRUE) )) return true;
    elseif (!isset($this->page['var'][$key])) return _cst_bool($key);
    else return false;
  }

  /**
   * \brief Charge la valeur de la constante,en reference, uniquement si elle n'as pas ete redéfini par le template
     @param [in] $string string Nom constante de reference
     [out] self this->var[]
     @return string
  */
  public function _conf_value($string){
    if (empty($string)) return false;
    $key=strtoupper($string);
    if (isset($this->page['var'][$key]) and  is_string($this->page['var'][$key]) ) return $this->page['var'][$key];
    elseif (!isset($this->page['var'][$key])) return tep_cst_define($key);
    else return false;
  }

  /**
   * \fn new_class($class)
   * \brief Ajout d'un objet par l'appel de son fichier
   @param $class \a string
  */
  public function new_class($class){
    if (!class_exists($class)) return false;
    if (isset($this->$class))return $this->$class;
    global $page;
    $vars = '';
    if(func_num_args()>1) {
      for($i=1;$i<(func_num_args()-1);$i++){
        $t[$i] = func_get_arg($i);
        $vars.="\$t[$i],";
      }
      $t[$i] = func_get_arg($i);
      $vars.="\$t[$i]";
    }

    if(!is_callable(array($class,'getInstance')))eval("\$ret=\$this->$class= new $class($vars);");
    else  eval("\$ret=\$this->$class=$class::getInstance($vars);");

    return $this->$class;
  }


  /**
   * \fn return_object($class)
   * @param $class string
   * @return  object
   */
  public function return_object($class){ return (isset($this->$class)) ? $this->$class : false ; }

  /**
    \brief Add d'un objet à l'objet this
  */
  public function add_object($name,$object){ return (!is_object($object)) ? false : $this->$name= $object ; }

  /**
    \brief Appel public des function de chargeur des extensions
    !! Not method Static
      @param $key_object string object key de l'obj (ex 'dsrte' pour la class 'dsrte_oscss' )
	*Cet arguement peut être hommis dans la mesure ou il est identique à l'appel précédent (permanence du dernier object appelé)
      @param $funct string $function de construction block (_top, _head, _draw)
      @p all tous les arguement a passer à la function
  */
  public function _call($key_object, $funct){

    $object=$key_object;
    $vars='';
    if(func_num_args()>2) {
      for($i=2;$i<(func_num_args()-1);$i++){
        $t[$i] = func_get_arg($i);
        $vars.="\$t[$i],";
      }
      $t[$i] = func_get_arg($i);
      $vars.="\$t[$i]";
    }

    if(!isset($this->$object))
      trigger_error(__CLASS__.'object:page (lg'.__LINE__.'):: Error class introuvable: '.(string)$key_object , E_USER_ERROR);
    elseif(!method_exists($key_object,$funct)){
      trigger_error(__CLASS__.' (lg'.__LINE__.'):: class '.(string)$key_object.' function introuvable: '.(string)$funct , E_USER_ERROR);
      return false;
    }

    if ($vars !='') {
      eval("\$ret = \$this->\$object->$funct($vars);");
      return  $ret;
    }
    else return $this->$object->$funct();
  }


  /**
    \fn oscss_content()
    \brief  Scan template content folders and display template content if exist, if not display default oscss content
  */
  public function oscss_content() {
    $filename = DIR_WS_TEMPLATES . $this->page['template'] . '/includes/content/'. $this->page['content'];
    if (self::TestFile($filename)) $this->page['path_content'] = (DIR_WS_TEMPLATES . $this->page['template'] . '/includes/content/'. $this->page['content']);
    else $this->page['path_content'] = (DIR_WS_INCLUDES.'content/' . $this->page['content']);

    return($this->page['path_content']);
  }

  /**
    @fn page_content()
  */
  public function page_content(){ return $this->page['content']; }

  /**
    @fn page_content_clean()
  */
  public function page_content_clean(){ return substr($this->page['content'],0,strlen($this->page['content'])-strlen($this->ext)); }

  /**
    @fn path_gabarit()
  */
  public function path_gabarit(){ return DIR_WS_TEMPLATES . $this->page['template']  .'/'.$this->page['gabarit']; }

  /**
    \fn draw_breadcrumb($caract =' &raquo; ')
    \brief Sortie menu breadcrumb
    @param $caract string caratére entre les items
  */
  public function draw_breadcrumb($caract =' &raquo; '){ return $this->breadcrumb->trail($caract); }

  /**
    @fn ret_messageStack()
  */
  public function ret_messageStack(){ return $this->messageStack; }

  /**
    @fn ret_template()
  */
  public function ret_template(){ return $this->page['template'] ; }

  /**
    \fn the_title()
    \brief Nom de la page
  */
  public function the_title(){ return $this->page['the_title'] ; }

  /**
    \fn the_script()
    \brief Nom de la page
  */
  public function the_script(){ return $this->page['script'] ; }

  /**
    @fn the_var($key)
    @brief return var if exist
    @param $key string nom de la variable
    @return value/false
  */
  public function the_var($key){ return $this->ret_var_page($key); }

  /**
    @fn  the_template()
    \brief Nom du template
  */
  public function the_template(){ return $this->page['template']; }

  /**
    @fn the_content($court=false)
    \brief Nom du content
  */
  public function the_content($court=false){ return (!$court) ? $this->page['content'] : substr($this->page['content'],0,  -strlen($this->ext) ) ; }

  /**
    \fn ret_page_type()
    \brief alias the_type()
    @p string page['type'] type page (account, checkout, adresse, product);
  */
  public function ret_page_type(){ return $this->the_type() ;}

  /**
    @fn the_type()
    \brief retourne le type de page
  */
  public function the_type(){ return (isset($this->page['type'])? $this->page['type'] : 'none') ; }

  /**
    @fn oscss_body_id()
    @note Get the boxes
  */
  public function oscss_body_id() { return 'Page_'.substr($this->page['content'],0,-4); }

  /**
   \fn is_registered()
   \brief control identification
    */
  public function is_registered(){
    if (!tep_session_is_registered('customer_id')) {
//       $this->navigation_history->set_snapshot();
      tep_redirect(tep_href_link(FILENAME_LOGIN, '', 'SSL'));
    }
  }

  /**
    @fn is_page_type($type)
    @param $type string/array
    @return boolean
  */
  public function is_page_type($type){ return ( (is_array($type) && in_array($this->page['type'],$type)) || ($type ==$this->page['type']) ) ? true : false ; }

 /**
   \fn is_page_here($page)
   \brief  retour de vrai si page passé en argument et equal à page content en cours
   @param [in] $page string nom de la page en cours (sans extension)
    [out] $page = object this  string page_content_clean
   @return boolean
  */
  public function is_page_here($page){
    if ( (substr($page,strlen($page)-4,strlen($page))==$this->ext) && ($this->page_content() == $page) )return true;
    elseif ( (substr($page,0,-4)==$this->ext) && ($this->page_content_clean() == $page) )return true;
    else return false;
  }


  /**
    @fn ($db_key, $value='')
    @param [in] $db_key string la key  du champs de db
    @param [in] $value la valeur du champs
    @p [out] $this page['type']
    @p [out] $this  propriete[$db_key]['class_page'] qui correspond au type de page sur lesquel il s'execute
  */
  public function prop_ctrl($db_key, $value=''){
    if(isset($this->propriete[$db_key]) && in_array($this->page['type'],explode(',',$this->propriete[$db_key]['class_page'])) )
      if(isset($this->propriete[$db_key]['replace'])) return $this->propriete[$db_key]['replace'];
  }


  /**
    @fn add_file_header($file,$option=''
    @brief  Ajoute un ficher au chageur du header,ces elements seront ensuite chargé dans le header
    @param $file string : path+non de fichier a charger
    @param $option array : les option supp key/value
  */
  public function add_file_header($file,$option=''){
    $option=(is_array($option))? $option : array();
    $sort=(isset($option['sort']))? $option['sort']*10 :5*10;
    $sort=(($sort+(count($this->page['header']['file']))));

    $this->page['header']['file'][$sort]=array_merge(array('file'=>$file),$option);
  }

  /**
    @fn add_file_footer($file,$option='')
    @brief Ajoute un ficher au chageur du header,ces elements seront ensuite chargé dans le header
    @param $file string : path+non de fichier a charger
    @param $option array : les option supp key/value
  */
  public function add_file_footer($file,$option=''){
    $option=(is_array($option))? $option : array();
    $sort=(isset($option['sort']))? $option['sort']*10 :5*10;
    $sort=(($sort+(count($this->page['footer']['file']))));

    $this->page['footer']['file'][$sort]=array_merge(array('file'=>$file),$option);
  }



  /**
    \fn tep_get_header()
    \brief draw header
  */
  public function tep_get_header(){
    //! report des var d'enviroennement
    global $lang;

    $page=$this;
    $language=$this->page['language'];
    $PHP_SELF=$this->page['content'];
    $template=$this->page['template'];
    $current_category_id=$this->ret_var_page('current_category_id');
    $languages_id=$this->ret_var_page('languages_id');

    /**
      \brief Langue specifique au template
      \note specifique text __()
    */
    if(($path=self::fix_file(DIR_WS_LANGUAGES . $language.'.php' ,true)) !=false) $this->pile_file_lang($path);
    elseif(($path=self::fix_file(DIR_WS_LANGUAGES . 'fr_FR.php' ,true)) !=false) $this->pile_file_lang($path);

    /**
      @brief Chargement des module actifs
    */
    $this->oscss_plugins->active_plugins();
    $plugins=(isset($this->page['plugins']['actif']))?$this->page['plugins']['actif']:array();
    $this->add_var_page('plugins',$plugins);
    while($r=each($plugins)){
      /**
       \brief Boxes
	@e shearch fonction xxxx_force_box()
      */
      $fct=$r['value'].'_force_box';
      if (function_exists($fct)){
        $this->page['boxes']['list']=array_merge($this->page['boxes']['list'],$fct());
      }

      /**
        @brief propriete
	@e shearch fonction xxxx_add_propriete()
      */
      $fct=$r['value'].'_add_propriete';
      if (function_exists($fct)){
        $this->propriete=array_merge($this->propriete,$fct());
      }

      /**
       @brief Chargement des scritps
       @e shearch fonction xxxx_scripts() (librairie)
       @e shearch fonction xxxx_init_scripts() (exec Or inline )
      */
      $fct=$r['value'].'_scripts';
      if (function_exists($fct)){
        $this->javascript->add_multi($fct());
      }
      $fct=$r['value'].'_init_scripts';
      if (function_exists($fct)){
        $this->javascript->add_multi($fct());
      }
    }

      /**
        Gestion des tag, title et key
      */
      if (_cst_bool('SEO_ENABLED')){
	$seo_urls=seo_url::getInstance($languages_id);
	$seo_urls->header_tags(substr($_SERVER['SCRIPT_NAME'],strlen(DIR_WS_CATALOG) ), $_SERVER['QUERY_STRING']);
	$the_title= $seo_urls->header_tag['title'];
	$the_desc= $seo_urls->header_tag['desc'];
        $the_key_words= $seo_urls->header_tag['keywords'];
      }else {
        $the_desc= HEAD_DESC_TAG_ALL;
        $the_key_words= HEAD_KEY_TAG_ALL;
	$the_title='';
      }
      $this->page['the_title']=(tep_not_null($the_title)? $the_title : (tep_not_null($this->title)? $this->title: STORE_NAME));

    $file=DIR_WS_TEMPLATES . $this->page['template']  .'/header.php';
    if(self::TestFile($file)) include($file);

    /**
    */
    if(self::$CookieAdmin)
      echo '<div class="osCSS_Admin" style="position:absolute; right:20px; top:0;">'.
// 	    '<a href="'.tep_href_link(substr($_SERVER['SCRIPT_NAME'],strlen(DIR_WS_CATALOG) ), tep_get_all_get_params(array('cache')).'cache=calcul').'">Recalculer page</a> '.
	    '<a href="'.tep_href_link(substr($_SERVER['SCRIPT_NAME'],strlen(DIR_WS_CATALOG) ), tep_get_all_get_params(array('cache')).'cache=calcul').'">Recalculer page</a> '.
	   '</div>';
  }


  /**
    \fn tep_get_sidebar($bar='sidebar')
    \brief draw sidebar
    @param $bar string bar le nom du fichier a inclure (par defaut sidebar) sans extension
  */
  public function tep_get_sidebar($bar='sidebar'){
    // report des var d'enviroennement
    $page=$this;
    $language=$this->page['language'];
    $PHP_SELF=$this->page['content'];
    $template=$this->page['template'];
    $current_category_id=$this->ret_var_page('current_category_id');
    $languages_id=$this->ret_var_page('languages_id');
    $currencies=$page->currencies;
    $request_type=$page->ret_var_page('request_type');

    global $lang;

    $file=DIR_WS_TEMPLATES . $this->page['template']  .'/'.$bar.'.php';
    if(self::TestFile($file)) require_once($file);
  }

  /**
    \fn tep_get_footer()
    \brief draw footer
  */
  public function tep_get_footer(){
    $page=$this;
    if ($this->page['var']['develop']=='true') $this->develop();

    $plugins=$this->the_var('plugins');
    while($r=each($plugins)){
      /**
       Boxes
      @e shearch fonction xxxx_force_box()
      */
//       $fct=$r['value'].'_init_scripts_footer';
//       if (function_exists($fct)){
//         $this->page['boxes']['list']=array_merge($this->page['boxes']['list'],$fct());
//       }

      $fct=$r['value'].'_init_scripts_footer';
      if (function_exists($fct)){
        $this->javascript->add_multi($fct());
      }
    }
    $file=DIR_WS_TEMPLATES . $this->page['template']  .'/footer.php';
    if(self::TestFile($file)) require_once($file);
  }


  /**
    \fn pos_init($type,$pile, $array)
    \brief Init pile pour navigation dans la pile avec next, prev
    @param $type string  (modules/boxes/plugins)
    @param $pile string nom de la pile
    @param $array string $array (contenu de la pile)
  */
  public function pos_init($type,$pile, $array){
    if(!isset($this->position[$type][$pile])){
      $this->position[$type][$pile]=(array)$array;
      $this->position_[$type][$pile]['max']=count($array);
      $this->position_[$type][$pile]['current']=0;
    }else return false;
  }

  /**
    \fn pos_next($type,$pile)
    \brief deplacement dans la pile
    @param $type string  (modules/boxes/plugins)
    @param $pile string nom de la pile
  */
  public function pos_next($type,$pile){
    if(isset($this->position[$type][$pile])){
      if($this->position_[$type][$pile]['current']>0 && $this->position_[$type][$pile]['current']<=$this->position_[$type][$pile]['max'])  next($this->position[$type][$pile]);
      $this->position_[$type][$pile]['current']++;
      return key($this->position[$type][$pile]);
    }
  }

  /*  */
  /**
    \fn develop()
    \brief Panneau lateral debugg
    \note: cf config du theme, var debugg
  */
  public function develop(){
    $this->new_class('develop');
    $this->develop->draw_block();
  }

  /**
   * \fn debugg($precis='')
   * \brief display error
   * @param $precis string
   */
  public function debugg($precis=''){
    if (tep_not_null($precis) && isset($this->$precis)) print_r($this->$precis);
    else print_r($this/*->page*/);
  }
 }
?>