<?php

class categoryTreeItem {
  // id of parent category
  public $parent;
  // name of category
  public $name;
  // moderator list of category ????
  public $mod;
  // path from root to this category
  public $path;
  // children of category
  public $items = array();
  // type of category
  public $type;
  // is category public?
  public $public;
  // base id of category
  public $base;
  // config of category
  public $config;
  //manhtl: order
  public $order;

  public function __construct($tblblogcategory) {
    $this->parent = $tblblogcategory->getCatParent();
    $this->name = htmlspecialchars($tblblogcategory->getCatName());
    $this->mod = blogStore::getModule($tblblogcategory->getCatType());
    $this->type = $tblblogcategory->getCatType();
    $this->base = $tblblogcategory->getCatBase();
    $this->public = $tblblogcategory->getCatPublic();
    $this->config = sfYaml::load($tblblogcategory->getCatConfig());
    if (!@$this->config['listtype']) $this->config['listtype'] = @$this->config['multiple']? 'category': 'all';

    //manhtl: order
    $this->order = $tblblogcategory->getCatOrder();
    $path = explode(',', $tblblogcategory->getCatPath());
    $this->path = array();
    foreach ($path as $p) {
      $this->path[] = (int)$p;
    }
  }

  /**
   * Enter description here...
   *
   * @return unknown
   */
  public function getCatTypeName() {
    return commonData::getCatTypeName($this->type);
  }

  /**
   *
   * @param unknown_type $params
   * @param unknown_type $defaultValue
   * @return string
   * @uses getParams('config1/config2/config3', 'default');
   */
  public function getParam($params, $defaultValue = null) {
    $params = explode('/', $params);
    $ret = $this->config;
    foreach ($params as $param) {
      $ret = @$ret[$param];
      if ($ret==null) return $defaultValue;
    }
    return $ret;
  }

  /**
   * @uses setParam('config1/config2/config3', 'value');
   *
   * @param unknown_type $params
   * @param unknown_type $value
   */
  public function setParam($params, $value) {
    $params = explode('/', $params);
    $n = count($params);
    for ($i = count($params)-1; $i>=0; $i--) {
      $value = array($params[$i]=>$value);
    }
    $this->config = array_merge($this->config, $value);
  }

  /**
   * @return true if this category is root branch
   * Root branch is category that contain many branch but you can't insert entry in it
   */
  public function isRootBranch() {
    return $this->getParam('root')=='true';
  }


  /**
   * @return type of list (thumb: thumbnail, list: 2 columns)
   */
  public function getListType($index = 0) {
    $type = $this->getParam('list', 'thumb');
    if ($type == 'bigview' && $index > 0) $type = 'thumb';
    return $type;
  }

  /**
   * Enter description here...
   *
   * @return unknown
   */
  public function getListItemCount() {
    if ($this->type == 2) return 3;
    $counts = sfConfig::get('app_thumbnail_dir_count');
    return $counts[$this->getListType()];
  }

  /**
   * Enter description here...
   *
   * @return unknown
   */
  public function getDetailListItemCount() {
    if ($this->type == 2) return 18;
    $counts = sfConfig::get('app_thumbnail_list_count');
    return $counts[$this->getListType()];
  }

  /**
   * allow extensions for this cateogry
   *
   * @return array of extension (in lowercase)
   */
  public function getAllowExts($inZip = false) {
    $app_types = sfConfig::get('app_resource_type');
    $app_exts = sfConfig::get('app_resource_extension');
    $exts = $app_exts[array_search($this->type, $app_types)];
    foreach ($exts as $key => $ext) {
      if (preg_match('/^zip:(.*)$/', $ext, $match)) {
        if ($inZip) $exts[$key] = $match[1];
        else unset($exts[$key]);
      }
    }
    return $exts;
  }
}

class categoryTree {
  public $tree = array();
  public $flat = array();

  public function __construct($blogId = null) {
    $c = new Criteria();
    $c->add(TblblogcategoryPeer::CAT_BLOG, $blogId? $blogId: blogStore::$blogId);
    $c->addAscendingOrderByColumn(TblblogcategoryPeer::CAT_PATH);
    $tblblogcategorys = TblblogcategoryPeer::doSelect($c);

    foreach ($tblblogcategorys as $tblblogcategory) {
      $id = $tblblogcategory->getCatId();
      $parent = $tblblogcategory->getCatParent();
      $this->flat[$id] = new categoryTreeItem($tblblogcategory);
      if ($parent == -1) $this->tree[$id] = $this->flat[$id];
      else $this->flat[$parent]->items[$id] = $this->flat[$id];
    }
    $this->sortItems($this->tree);
  }

  public static function cmp( $a, $b ) {
    return $a->order > $b->order;
  }

  /**
   * Sort all items in tree by [order]
   *
   */
  public function sortItems(&$items) {
    uasort($items, array( __CLASS__, 'cmp' ));
    foreach ($items as $key=>$item) {
      $this->sortItems($items[$key]->items);
    }
  }

  /**
   * @param int $cat_id: id of category
   * @return categoryTreeItem object of category
   */
  public function getCatItem($cat_id) {
    return $this->flat[$cat_id];
  }

  /**
   * Enter description here...
   *
   * @param unknown_type $tree
   * @return string
   */
  public function getTree($tree = null, $filter = '/./', $extraInfo = false, $withRoot = false) {
    $root = ($tree==null);
    if ($root) $tree = $this->tree;
    $xml = '';
    foreach ($tree as $key=>$value) {
      if (!preg_match($filter, $value->type)) continue;
      $value->name = htmlspecialchars($value->name, ENT_QUOTES);
      $xml .= "<item id='tr$key' text='$value->name'>";
      if ($value->mod != null) $xml .= "<userdata name='mod'>$value->mod</userdata>";
      if ($extraInfo) {
        $xml .= "<userdata name='type'>$value->type</userdata><userdata name='public'>$value->public</userdata>";
        $xml .= "<userdata name='list'>".$value->getParam('list', 'thumb')."</userdata>";
        $xml .= "<userdata name='listtype'>".$value->config['listtype']."</userdata>";
        if (@$value->base !== null) $xml .= "<userdata name='base'>$value->base</userdata>";
      }
      if (count($value->items)>0) $xml .= $this->getTree($value->items, $filter, $extraInfo);
      $xml .= '</item>';
    }

    if ($withRoot && $root) $xml = "<item id='root' text='Gốc'>" . $xml . '</item>';
    if ($root) $xml = "<tree id='0'>" . $xml . '</tree>';
    return $xml;
  }
}

class categoryBaseTreeItem extends categoryTreeItem {
  public function __construct($tblcategory) {
    $this->parent = $tblcategory->getCgParentid();
    $this->name = htmlspecialchars($tblcategory->getCgName());
    $this->type = 0;
    $path = explode('/', $tblcategory->getCgFamily());
    $this->path = array();
    foreach ($path as $p) {
      $this->path[] = (int)$p;
    }
  }
}

/**
 * BaseTree to display System tree
 *
 */
class categoryBaseTree extends categoryTree {
  public function __construct() {
    $c = new Criteria();
    $c->add(TblcategoryPeer::CG_PUBLIC, 1);
    $tblcategorys = TblcategoryPeer::doSelect($c);

    foreach ($tblcategorys as $tblcategory) {
      $this->flat[$tblcategory->getCgId()] = new categoryBaseTreeItem($tblcategory);
    }

    foreach ($tblcategorys as $tblcategory) {
      $id = $tblcategory->getCgId();
      $parent = $tblcategory->getCgParentid();
      if ($parent == -1) $this->tree[$id] = $this->flat[$id];
      else $this->flat[$parent]->items[$id] = $this->flat[$id];
    }
  }
}
