<?php if (!defined('HTTP_SERVER')) die('You can not access this file directly!');
/**
  \licence GPL 2005-2010  The osCSS developers - osCSS Open Source E-commerce
  \package osCSS-2 <www http://www.oscss.org>
  \version 2.1.0
  \date  15/12/10, 15:45
  \author oscim <mail aurelien@oscim.fr> <www http://www.oscim.fr>
  \encode UTF-8
  \file page.oscss_modules.php
  \class  oscss_modules
  \note: Gestion de l'appel des modules (rep modules, noyau them plugin ou them module)
  \brief load module not type
*/
class oscss_modules{

  /**
  private
  pile qui est appelé lors du _call d'un module et qui charge les commande en atente
  */
  private $temp;

  var $modules_chargee;
  protected static $_instance;

  /**
  */
  protected function __construct(){
    global $page;
    $this->ext=$page->ext;
    $this->lg=array();
    $page->page['modules']['sort']=array();
  }

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

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


  /**
   *    \brief
   		Scan template modules folders and display template boxes if exist, if not display default oscss boxes
    	le type permet de classer les box par groupe
    	Seul l'extentions .php est autoriser
    	cherche dans plugins theme, puis, boxes theme, puis noyau.
   * @param $file_to_display string
   * @param $type string : class de boite, en pile
   * @param $opt array : option supplementaire
   * @return boolean false Si l'index est deja utilise , true si ok
  */
  private function modules($file_to_display,$type='std',$opt) {
    global $page;
    $name_clean=(strchr($file_to_display,'.')==$this->ext)? substr($file_to_display,0,strlen($file_to_display)-4) :$file_to_display ;

    if (isset($page->page['modules']['list'][$name_clean])) $this->pile_commande($name_clean,$opt);

    $filename = DIR_WS_TEMPLATES . $page->page['template'] .'/' . DIR_WS_INCLUDES. '%s';

    if (page::TestFile(sprintf($filename,'plugins/').$name_clean.$this->ext)) {
      $path =sprintf($filename,'plugins/');
      $path_lg=sprintf($filename,'plugins/').'languages/'.$page->page['language'].'.php';
    }
    elseif (page::TestFile(sprintf($filename,'modules/').$name_clean.$this->ext)){
      $path =sprintf($filename,'modules/');
      $path_lg=DIR_WS_TEMPLATES . $page->page['template'] .'/' . DIR_WS_INCLUDES.'languages/'.$page->page['language'].'/modules/';
    }
    else{
      $path = DIR_WS_MODULES;
      $path_lg= DIR_WS_LANGUAGES.$page->page['language'].'/modules/';
    }

//     if(isset($page->page['modules']['list'][$name_clean]) ) return false;
    $array=(isset($page->page['modules']['list'][$name_clean])) ? $page->page['modules']['list'][$name_clean] : array();
    $array['name']=$file_to_display;
    $array['name_clean']=$name_clean;
    $array['path']=$path.$name_clean.$this->ext;
    $array['dir_lang']=$path_lg;
    $array=array_merge($array,(array)$opt);


    $page->page['modules']['list'][$name_clean]=$array;
    $page->page['modules']['sort'][$name_clean]=(isset($opt['sort']))? $opt['sort']: ((count($page->page['modules']['sort'])>0)?(count($page->page['modules']['sort'])+50):50);
    $page->page['modules'][$type][$name_clean]='true';

    return true;
  }


  /**
   * \fn tep_call_modules($modules=false,$type=false)
   * \brief
    Appel des modules
    Charment des langues associés
    !!! Les variables de page ne sont pas accessible dans le fichiers de langues

   * @param $modules string, le nom du modules
   * @param $type string : la class de modules
  */
  private function tep_call_modules($modules=false,$type=false){
    global $page;

    asort($page->page['modules']['sort']);

    if($type!=false && $modules!=false) {
      $key=(strchr($modules,'.')==$this->ext)? substr($modules,0,strlen($modules)-4) :$modules ;
      /** Charment de la pile d'action en attente */
      if (isset($this->temp[$key])  ){
        $page->page['modules'][$type][$key]=$this->temp[$key]['value'];
      }

      if (isset($page->page['modules'][$type]) && isset($page->page['modules'][$type][$key]) && $page->page['modules'][$type][$key] !='false') {
        $mod=$page->page['modules']['list'][$key];
        $function='sql_'.$mod['name_clean'];

        require_once($mod['path']);

        if ( ($res=$this->test_value_content($function)) !=false) $exe=true;
        elseif(function_exists($function)) $exe=false;
        else $exe=true;

        if ($exe) {
          $page->page['modules']['list'][$mod['name_clean']]['result_sql']=$res;
//           if (page::TestFile($mod['dir_lang']. $mod['name'])) require_once($mod['dir_lang']. $mod['name'] );
	  if(($path_lg=$page->fix_file($mod['dir_lang'] . $mod['name'],true)) !=false) $page->pile_file_lang($path_lg);
          return $mod['path'];
        }
        $this->modules_chargee[$key]=$page->page['modules'][$type][$key]='false';
      }else return false;
    }

    elseif($type !=false && !$modules){
      if (isset($page->page['modules']['sort'])) {
        foreach ($page->page['modules']['sort'] as $key=>$value){

          /** Charment de la pile d'action en attente */
          if (isset($this->temp[$key])  )
            $page->page['modules'][$type][$key]=$this->temp[$key]['value'];
          elseif (isset($this->temp['list']) && ( isset($this->temp['list'][$key]) && is_array($this->temp['list'][$key])) )
            $page->page['modules']['list'][$key]=array_merge( $page->page['modules']['list'][$key],$this->temp['list'][$key]);

          /** Verif etat et exe */
          if($page->page['modules'][$type][$key] !='false'){
            $mod=$this->ret_modules($key);
//             $file=$mod['dir_lang'] . $mod['name'] ;
            $function='sql_'.$mod['name_clean'];

            require_once($mod['path']);

            if ( ($res=$this->test_value_content($function)) !=false) $exe=true;
            elseif(function_exists($function)) $exe=false;
            else $exe=true;

            if($exe){
              if(page::TestFile($mod['dir_lang']. $mod['name']))require_once($mod['dir_lang']. $mod['name']);
	      if(($path_lg=$page->fix_file($mod['dir_lang'] . $mod['name'],true)) !=false) $page->pile_file_lang($path_lg);

// if (page::TestFile($file)) require_once($file);
              $this->modules_chargee[$key]=$page->page['modules'][$type][$key];
              $page->page['modules']['list'][$key]['result_sql']=$res;
            }
            else{
              $page->page['modules']['list'][$mod['name_clean']]['draw']='false';
              $this->modules_chargee[$key]=$page->page['modules'][$type][$key]='false';
            }
          }
        }
        return $this->modules_chargee;
      }else return false;
    }

    elseif(empty($type) && $modules!=false) {
      $key=(strchr($modules,'.')==$this->ext)? substr($modules,0,strlen($modules)-4) :$modules ;

      while($r=each($page->page['modules'])){
        /** Charment de la pile d'action en attente */
        if (isset($this->temp[$key])  )
          $page->page['modules'][$r['key']][$key]=$this->temp[$key]['value'];

        if (isset($page->page['modules'][$r['key']][$key]) && $page->page['modules'][$r['key']][$key] !='false'
	    && ( ($mod=$page->page['modules']['list'][$key]) && is_array($mod) ) ) {
          $function='sql_'.$mod['name_clean'];

          require_once($mod['path']);
          if ( ($res=$this->test_value_content($function)) !=false) $exe=true;
          elseif(function_exists($function)) $exe=false;
          else $exe=true;

          if ($exe) {
            $page->page['modules']['list'][$mod['name_clean']]['draw']='true';
            $page->page['modules']['list'][$mod['name_clean']]['result_sql']=$res;
//             if (page::TestFile($file)) require_once($mod['dir_lang']. $mod['name'] );
	    if(($path_lg=$page->fix_file($mod['dir_lang'] . $mod['name'],true)) !=false) $page->pile_file_lang($path_lg);
            return $mod['path'];
          }
          else{
            $page->page['modules']['list'][$mod['name_clean']]['draw']='false';
            $this->modules_chargee[$key]=$page->page['modules'][$type][$key]='false';
          }
        }
      }

      return false;
    }
    else return $page->page['modules'];
  }


  /**
   * \fn ret_modules($key)
   * \brief Fournis les element enregsitré du module
   * @param $key string la key du module
  */
  private function ret_modules($key){
    global $page;
    if(isset($page->page['modules']['list'][$key]))return $page->page['modules']['list'][$key];
    else return false;
  }


  /**
   * \fn
   * \brief  Ajoute des commande au module en cours de chargement des page
   * @param string modules
   * @param string/array soit le type ou class du module, soit un tableau d'option
  */
  private function pile_commande($module, $type, $action='', $value=''){
    if (is_array($type)){
      $this->temp['list'][$module]=$type;
    }else {
      $this->temp[$module]=array(
                                 'module'=>$module,
                                 'class'=>$type,
                                 'action'=>$action,
                                 'value'=>$value,
                                );
    }
  }


 /**
  * \fn test_value_content($function, $parameter='')
  * \brief Verifie que le resultat du module appelé n'est pas null, ou vide
  * @param $function
  * @param $parameter
  */
  private function test_value_content($function, $parameter=''){
    global $page;
    if (function_exists($function)) return call_user_func($function, $parameter);
    else return '';
  }

  /**
   * \fn _draw($mod,$parameter='')
   * \brief Return des contenu et resultat  sql
   * @param $mod array
   * @param $parameter
   */
  public function _draw($mod,$parameter=''){
    global $page;
    if (function_exists('draw_'.$mod['name_clean'])) return call_user_func('draw_'.$mod['name_clean'], $parameter);
    else return false;
  }

  /**
   * \fn _in_obj($mod,$parameter='')
   * \brief Return module  in object
   * @param $mod array
   * @param $parameter
   */
  public function _in_obj($mod,$parameter=''){
    global $page;
    if (function_exists('in_obj_'.$mod['name_clean'])) return call_user_func('in_obj_'.$mod['name_clean'], $parameter);
    else return false;
  }

  /**
   * \fn _resultsql($module)
   * \brief Return des contenu et resultat  sql
   * @param $module string
   */
  public function _resultsql($module){
    global $page;
    if(isset($page->page['modules']['list'][$module]['result_sql'])) return $page->page['modules']['list'][$module]['result_sql'];
    else return false;
  }


  /**
   * \fn _replace($module, $new_module)
   * @param $module string : nom du module a remplacer
   * @param $new_module array : tableau des element du nouveau module
  */
  public function _replace($module, $new_module){
    global $page;
//       if(isset($page->page['modules']['list'][$module])) {
//         $page->page['modules']['list'][$module]=$new_module;
//         return $page->page['modules']['list'][$module];
//       }else return false;
      $name_clean=(strchr($module,'.')==$this->ext)? substr($module,0,strlen($module)-4) :$module ;
      $this->pile_commande($name_clean,$new_module);
  }

 /**
  * \fn _quick_call($module,$filename='',$opt='')
  * \brief Rappel module en 2 tps
  * L'appel des module est théroqiement chargée par un call_module
  * si le module en cours de d'exec et desactivé, rappel un second module, appres l'appel a call
  * @param $module string la clef de module
  * @param $filename string la constante FILENAME, peut être hommis si elle est nommé sous la forme FILENAME_NOM_MODULE
  * @param $opt array
  * @return path du file a include
  */
  public function _quick_call($module,$filename='',$opt=''){
    global $page;
    if (!is_array($opt))$opt=array();
    $filename=(tep_not_null($filename))? $filename : @constant(strtoupper('filename_'.$module))  ;
    $page->oscss_modules->modules($filename,'center',$opt);
    $page->oscss_modules->_call();
//       $mod =$page->oscss_modules->_return($module);
      $page->oscss_modules->_draw($page->oscss_modules->_return($module));
//       return $mod['path'];
  }

  /**
   * \fn _add($file_to_display,$type='',$opt='')
   * \brief Alias de la function tep_call_modules
   * @param $file_to_display
   * @param $type
   * @param $opt
   */
  public function _add($file_to_display,$type='',$opt=''){
    global $page;
    return $this->modules($file_to_display,$type,$opt);
  }

  /**
   * \fn _bloque($module,$type)
   * \brief Alias de la function tep_call_modules
   * @param $modules bool
   * @param $type bool
   * @param $option array
   */
  public function _call($modules=false,$type=false,$option=''){
    global $page;
    if (!is_array($option))$option=array();

    return $this->tep_call_modules($modules,$type,$option);
  }

  /**
   * \brief  Alias de la function return
   * @param $key
   */
  public function _return($key){
    global $page;
    return $this->ret_modules($key);
  }

  /**
   * \fn _bloque($module,$type)
   * \brief Function qui chnage etat des modules
   * @param $module string nom du module
   * @param $type string la class du modules
   * @return boolean false si module + type introuvable
  */
  public function _bloque($module,$type){
    global $page;
    $this->pile_commande($module,$type,'etat','false');
    return true;
  }
}

/**
  \example
  [modules] => Array
      (
          [list] => Array
              (
                  [new_products] => Array
                      (
                          [name] => new_products.php
                          [name_clean] => new_products
                          [path] => includes/modules/new_products.php
                          [dir_lang] => includes/languages/french/modules/
                      )

              )

          [center] => Array
              (
                  [new_products] => true
              )

      )

*/
?>