<?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
 *\portion code Copyright (c) 2002 osCommerce
 *\package osCSS-2 <www http://www.oscss.org>
 *\version 2.1.0
 *\date  28/11/10, 08:18
 *\author oscim <mail aurelien@oscim.fr> <www http://www.oscim.fr>
 *\encode UTF-8
 *\group boxes
 *\file category_tree.php
 *\class osC_Category_tree

  Menu des catégories

  - add NOT_RECUP_CASSE_IN_TXT_CATEGORIES  Actif par defaut @a Hors-constructeur
    
    TODO: End comment code / oscim 30//11/2010
*/

class category_tree {
    var $root_category_id = 0,
        $max_level = 0,
        $data = array(),

        $root_start_string = '',
        $root_end_string = '',

        $parent_group_start_string = '',
        $parent_group_end_string = '',

        $parent_start_string = '',
        $parent_end_string = '',

        $child_start_string = '',
        $child_end_string = '',

        $breadcrumb_separator = '_',
        $breadcrumb_usage = true,
        $spacer_string = '',
        $spacer_multiplier = 1,
        $follow_cpath = false,
        $cpath_array = array(),
        $cpath_start_string = '',
        $cpath_end_string = '',
        $show_category_product_count = false,
        $category_product_count_start_string = ' (',
        $category_product_count_end_string = ')';

    /**
     * \fn __construct()
     */
    function __construct() {
      global $languages_id, $osCSS_Cache , $language;

      if (_cst_bool('SHOW_COUNTS'))  $this->show_category_product_count = true;

        if ($osCSS_Cache->read('category_tree-' . $language.'-type', 720)) {
          $this->data = $osCSS_Cache->getCache();
        } else {
          $this->data = array();
	  categorie::add_where_query(" and c.categories_hidden='1' ");
	  $list = categorie::get_query('','','',array('limit'=>0));
	  foreach($list as $categories)
            $this->data[$categories->parent_id][$categories->categories_id] = array('name' => $categories->categories_name, 'count' => 0);


          if ($this->show_category_product_count === true)  $this->calculateCategoryProductCount();

            $osCSS_Cache->writeBuffer($this->data);
        }

    }

  /**
   * \fn setData(&$data_array)
   * @param $data_array array
   */
  private function setData(&$data_array) {
    if (is_array($data_array)) {
      $this->data = array();

      for ($i=0, $n=sizeof($data_array); $i<$n; $i++) {
        $this->data[$data_array[$i]['parent_id']][$data_array[$i]['categories_id']] = array('name' => $data_array[$i]['categories_name'], 'count' => $data_array[$i]['categories_count']);
      }
    }
  }

 /**
  *\fn buildBranch($parent_id, $level = 0)
  *\brief Constructeur de branche
  * @param int $parent_id
  * @param int $level
  */
  private function buildBranch($parent_id, $level = 0) {

    $result = $this->parent_group_start_string;

    if (isset($this->data[$parent_id])) {
      $nbr = 0;
      foreach ($this->data[$parent_id] as $category_id => $category) {

        $category_link = $this->buildBreadcrumb($category_id);

        if ($level == 0 ||(isset($this->data[$category_id]) ) )  $result .= sprintf($this->root_start_string,' class="cat'.$parent_id.'_'.$category_id.'" ')  ;
        else $result .= $this->child_start_string ;

        $result .= str_repeat($this->spacer_string, $this->spacer_multiplier * $level) . '<a title="'. $category['name'] .'" href="' . tep_href_link(FILENAME_DEFAULT, 'cPath=' . $category_link ) . '">';

        if ($this->follow_cpath === true) {
          if (in_array($category_id, $this->cpath_array)) $result .= $this->cpath_start_string . $category['name'] . $this->cpath_end_string;
          else  $result .= (!_cst_bool('NOT_RECUP_CASSE_IN_TXT_CATEGORIES'))?strtolower($category['name']) : $category['name'];
        } else
          $result .= (!_cst_bool('NOT_RECUP_CASSE_IN_TXT_CATEGORIES'))? strtolower($category['name']) : $category['name'];

        if ($this->show_category_product_count === true)
          $result .= $this->category_product_count_start_string . $category['count'] . $this->category_product_count_end_string;

        $result .= '</a>';



        if (isset($this->data[$category_id]) && (($this->max_level == '0') || ($this->max_level > $level+1))) {
          if ($this->follow_cpath === true) {
            if (in_array($category_id, $this->cpath_array))
              $result .= $this->buildBranch($category_id, $level+1);
          } else
            $result .= $this->buildBranch($category_id, $level+1);
        }

        if ( ($this->max_level<$level) && ( (in_array($category_id,$this->cpath_array) && tep_has_category_subcategories($category_id) != false) || ($this->follow_cpath === false &&  tep_has_category_subcategories($category_id) != false ) ) )
          $result .= "\n" ;
        else
          $result .= $this->child_end_string ;

      $nbr++;
      }
    }
/*     if ($nbr != 0)*/ $result .= $this->parent_group_end_string;

    return $result;
  }


  /**
   *\fn buildBranchArray($parent_id, $level = 0, $result = '')
   *\brief Constructeur des branche en tableaux
   * @param int $parent_id
   * @param int $level
   * @param string $result
   */
  private function buildBranchArray($parent_id, $level = 0, $result = '') {
    if (empty($result)) {
      $result = array();
    }

    if (isset($this->data[$parent_id])) {
      foreach ($this->data[$parent_id] as $category_id => $category) {
        if ($this->breadcrumb_usage == true)  $category_link = $this->buildBreadcrumb($category_id);
        else  $category_link = $category_id;

        $result[] = array('id' => $category_link, 'title' => str_repeat($this->spacer_string, $this->spacer_multiplier * $level) . $category['name']);

        if (isset($this->data[$category_id]) && (($this->max_level == '0') || ($this->max_level > $level+1))) {
          if ($this->follow_cpath === true) {
            if (in_array($category_id, $this->cpath_array))  $result = $this->buildBranchArray($category_id, $level+1, $result);
          } else {
            $result = $this->buildBranchArray($category_id, $level+1, $result);
          }
        }
      }
    }

    return $result;
  }


  /**
   * \fn buildBreadcrumb($category_id, $level = 0)
   * @param $category_id int 
   * @param $level int
   */
  private function buildBreadcrumb($category_id, $level = 0) {
    $breadcrumb = '';

    foreach ($this->data as $parent => $categories) {
      foreach ($categories as $id => $info) {
        if ($id == $category_id) {
          if ($level < 1)  $breadcrumb = $id;
          else $breadcrumb = $id . $this->breadcrumb_separator . $breadcrumb;

          if ($parent != $this->root_category_id)  $breadcrumb = $this->buildBreadcrumb($parent, $level+1) . $breadcrumb;

        }
      }
    }

    return $breadcrumb;
  }


  /**
   * \fn buildTree($parent_id = '')
   * @param $parent_id
   */
  public function buildTree($parent_id = '') {
    return $this->buildBranch((empty($parent_id) ? $this->root_category_id : $parent_id));
  }

  /**

  */
  /**
   * \fn getTree($parent_id = '')
   * \brief Recup menu en array
   * @param $parent_id
   */
  public function getTree($parent_id = '') {
    return $this->buildBranchArray((empty($parent_id) ? $this->root_category_id : $parent_id));
  }

  function calculateCategoryProductCount() {
    foreach ($this->data as $parent => $categories) {
      foreach ($categories as $id => $info) {
        $this->data[$parent][$id]['count'] =  categorie::get_count_products_in_category($id);
        $cp=0;
        $parent_category = $parent;
        while ($parent_category != $this->root_category_id) {
          foreach ($this->data as $parent_parent => $parent_categories) {
            foreach ($parent_categories as $parent_category_id => $parent_category_info) {
              if ($parent_category_id == $parent_category) {
                $this->data[$parent_parent][$parent_category_id]['count'] += $this->data[$parent][$id]['count'];

                $parent_category = $parent_parent;
                break 2;
              }
              if($cp>100)break;
              $cp++;
            }
          }
        }
      }
    }
  }


  /**
   * \fn setRootCategoryID($root_category_id)
   * @param $root_category_id int
   */
  private function setRootCategoryID($root_category_id) {
    $this->root_category_id = $root_category_id;
  }

  /**
   * \fn setMaximumLevel($max_level)
   * \brief nbr niveau
   * @param int $max_level
   */
  public function setMaximumLevel($max_level) {
    $this->max_level = $max_level;
  }

  /**

  */
  /**
   * \fn setRootString($root_start_string, $root_end_string)
   * \brief Encapsulation Root
   * @param string $root_start_string
   * @param string $root_end_string
   */
  public function setRootString($root_start_string, $root_end_string) {
    $this->root_start_string = $root_start_string;
    $this->root_end_string = $root_end_string;
  }

  /**
   * \brief  Encapsulation item Root
   * @param $parent_start_string string 
   * @param $parent_end_string string 
   */
  public function setParentString($parent_start_string, $parent_end_string) {
    $this->parent_start_string = $parent_start_string;
    $this->parent_end_string = $parent_end_string;
  }

  /**
   * \brief Encapsulation Parent
   * @param $parent_group_start_string string
   * @param $parent_group_end_string string 
   */
  public function setParentGroupString($parent_group_start_string, $parent_group_end_string) {
    $this->parent_group_start_string = $parent_group_start_string;
    $this->parent_group_end_string = $parent_group_end_string;
  }

  /**
    
  */
  /**
   * \brief  Encapsulation item parent
   * @param $child_start_string string
   * @param $child_end_string string 
   */
  public function setChildString($child_start_string, $child_end_string) {
    $this->child_start_string = $child_start_string;
    $this->child_end_string = $child_end_string;
  }

  /**
   * \fn setBreadcrumbSeparator($breadcrumb_separator) 
   * @param $breadcrumb_separator string
   */
  public function setBreadcrumbSeparator($breadcrumb_separator) {
    $this->breadcrumb_separator = $breadcrumb_separator;
  }

  /**
   * \fn setBreadcrumbUsage($breadcrumb_usage) 
   * @param $breadcrumb_usage
   */
  public function setBreadcrumbUsage($breadcrumb_usage) {
      if ($breadcrumb_usage === true)  $this->breadcrumb_usage = true;
      else  $this->breadcrumb_usage = false;
    }

  /**
  */
  public function setSpacerString($spacer_string, $spacer_multiplier = 2) {
    $this->spacer_string = $spacer_string;
    $this->spacer_multiplier = $spacer_multiplier;
  }

  /**
  */
  public function setCategoryPath($cpath, $cpath_start_string = '', $cpath_end_string = '') {
    $this->follow_cpath = true;
    $this->cpath_array = explode($this->breadcrumb_separator, $cpath);
    $this->cpath_start_string = $cpath_start_string;
    $this->cpath_end_string = $cpath_end_string;
  }

  /**
  */
  public function setFollowCategoryPath($follow_cpath) {
    if ($follow_cpath === true)  $this->follow_cpath = true;
    else  $this->follow_cpath = false;
  }

   /**
  */
  public function setCategoryPathString($cpath_start_string, $cpath_end_string) {
      $this->cpath_start_string = $cpath_start_string;
      $this->cpath_end_string = $cpath_end_string;
    }

   /**
  */
  public function setShowCategoryProductCount($show_category_product_count) {
    $this->show_category_product_count = ($show_category_product_count === true)? true : false ;
  }

  /**
    encapusalation du nombre d'element enfants
  */
  public  function setCategoryProductCountString($category_product_count_start_string, $category_product_count_end_string) {
    $this->category_product_count_start_string = $category_product_count_start_string;
    $this->category_product_count_end_string = $category_product_count_end_string;
  }
}

/**
 * \example


  NOTE:
//     $osC_CategoryTree = new osC_CategoryTree();
//     $osC_CategoryTree->setParentGroupString('<ul>'."\n", '</ul>'."\n".'</li>'."\n");
//     $osC_CategoryTree->setChildString('<li %s>', '</li>'."\n");
//     $osC_CategoryTree->setRootString('<li %s>', '</li>'."\n");
//     $osC_CategoryTree->setSpacerString(' ', 2);
//     $osC_CategoryTree->setCategoryProductCountString('(',')');
//     echo $osC_CategoryTree->buildTree($catID) ;

  USAGE:
    setParentGroupString :: encapusalation html global pour parent
    setChildString :: encapusalation des elements enfants
    setRootString :: encapusalation des elements parent
    setCategoryProductCountString :: encapusalation des nbr element enfants
    setMaximumLevel :: max de niveau
 */
?>