<?php

/**
 * 
 * DBG: url arg: '&DBG_TF=1'
 */
class TreeListView {

	private $_tbl;
	private $_tblParentField;
	private $_id;
	private $_listIds = array();
	private $_treeFlat = array();
	private $_listFlat = array();
	private $_data = array();

	public function __construct($tbl, $id, $parentField = 'P_ID') {
		$this->_tbl = $tbl;
		$this->_id = $id;
		$this->_tblParentField = $parentField;
	}

	public function fetchTreeFlat() {
		if (!empty($this->_treeFlat)) {
			return;
		}

		$this->_treeFlat = array();
		$db = DB::getDB();
		$sql = "select t.`ID`, t.`{$this->_tblParentField}` as PARENT_ID
			from `{$this->_tbl}` as t
			where t.`A_STATUS` in('WAITING','NORMAL')
			order by t.`{$this->_tblParentField}`, t.`SORT_PRIO`, t.`ID`
		";
		if(V::get('DBG_TF', '', $_GET) > 2){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">sql (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($sql);echo'</pre>';}
		$res = $db->query($sql);
		while ($r = $db->fetch($res)) {
			$this->_treeFlat[$r->PARENT_ID] []= $r->ID;
		}
		if(V::get('DBG_TF', '', $_GET) > 0){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">treeFlatAll (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($this->_treeFlat);echo'</pre>';}
	}

	public function generateListFlat() {
		if (!empty($this->_listFlat)) {
			return $this->_listFlat;
		}

		/**
			1					2768 Założenie konta SIP z numerem na platformie AMS [proces urucham
			2						2770 Zaloguj się na platformę AMS Jeżeli posiadasz konto na platformie
			2.1						2771 Dodanie nowego klienta Proces mówiący o tym jak dodać nowego k
			2.1.1						2772 Wprowadź dane klienta Wprowadź wszystkie dane klienta: imię, nazwi
			2.2						2774 Dodanie numeru telefonu dla istniejącego klienta Proces dodawania nume
			2.2.1						2773 Wprowadź dane dotyczące nowego numeru telefonu Wypełnij dane z tabeli: 
			2.2.2						2828 Edytowanie konta klienta Dodawanie dostępu do panelu klienckiego (miejsca  
		 * 
		 * 1	[2768]	deep:1
		 * 2	[2770]	deep:1
		 * 3	[2771]	deep:2
		 * 
		 */

		$this->_listFlat = array();//  array('ID'=>$id_proces, 'LIST_NRS' => array(1));

		$lastUserIds = array();
		$lastUserIds[] = (object)array('ID'=>$this->_id, 'LIST_NRS' => array(1), 'deep'=>1);
		for ($i = 0; $i < 1000; $i++) {
			if (empty($lastUserIds)) {
				break;
			}
			$vItem = array_shift($lastUserIds);

			$this->_listFlat[$vItem->ID] = $vItem;

			// next steps
			if (array_key_exists($vItem->ID, $this->_treeFlat)) {
				if (count($this->_treeFlat[$vItem->ID]) > 1) {
					$subNr = 1;
					foreach ($this->_treeFlat[$vItem->ID] as $vSubProcesId) {
						$vSubItem = (object)array('ID'=>$vSubProcesId, 'deep'=>$vItem->deep + 1);
						$vSubItem->LIST_NRS = $vItem->LIST_NRS;
						$vSubItem->LIST_NRS[] = $subNr++;
						$vSubItem->LIST_NRS[] = '';
						$vSubItem->p_ID = $vItem->ID;
						$lastUserIds[] = $vSubItem;
					}
				}
				else {
					foreach ($this->_treeFlat[$vItem->ID] as $vSubProcesId) {
						$vSubItem = (object)array('ID'=>$vSubProcesId, 'deep'=>$vItem->deep);
						$vSubItem->LIST_NRS = $vItem->LIST_NRS;
						$subNr = array_pop($vSubItem->LIST_NRS);
						$vSubItem->LIST_NRS[] = ++$subNr;
						$lastUserIds[] = $vSubItem;
					}
				}
			}
		}

		if(V::get('DBG_TF', '', $_GET) > 0){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">listFlat (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($this->_listFlat);echo'</pre>';}
		foreach ($this->_listFlat as $kID => $vItem) {
			$listNrOut = array();
			foreach ($vItem->LIST_NRS as $nr) {
				if ($nr) {
					$listNrOut[] = $nr;
				}
			}
			$this->_listFlat[$kID]->listNr = implode('.', $listNrOut);
		}

		$this->_listIds = array_keys($this->_listFlat);

		uasort($this->_listFlat, array($this, 'sortListCallback'));

		return $this->_listFlat;
	}

	public function getListIds() {
		return $this->_listIds;
	}

	public function fetchData() {
		$sqlIds = $this->_listIds;

		if (empty($sqlIds)) {
			return $this->_data;
		}

		$sqlGotoIds = array();

		$db = DB::getDB();
		$sql = "select t.*
			from `{$this->_tbl}` as t
			where t.`A_STATUS` in('WAITING','NORMAL')
				and t.`ID` in(" . implode(",", $sqlIds) . ")
		";
		if(V::get('DBG_TF', '', $_GET) > 2){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">sql (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($sql);echo'</pre>';}
		$res = $db->query($sql);
		while ($r = $db->fetch($res)) {
			if ($r->IF_TRUE_GOTO > 0) {
				$sqlGotoIds[] = $r->IF_TRUE_GOTO;
			}
			$this->_data[$r->ID] = $r;
		}

		if (!empty($sqlGotoIds)) {
			$sql = "select t.*
				from `{$this->_tbl}` as t
				where t.`A_STATUS` in('WAITING','NORMAL')
					and t.`ID` in(" . implode(",", $sqlGotoIds) . ")
			";
			if(V::get('DBG_TF', '', $_GET) > 2){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">sqlGoto (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($sql);echo'</pre>';}
			$res = $db->query($sql);
			while ($r = $db->fetch($res)) {
				$this->_data[$r->ID] = $r;
			}
		}

		if(V::get('DBG_TF', '', $_GET) > 0){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">data (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($this->_data);echo'</pre>';}

		return $this->_data;
	}

	public function getData($id) {
		return (array_key_exists($id, $this->_data))? $this->_data[$id] : null;
	}

	public function sortListCallback($a, $b) {
		$cntA = count($a->LIST_NRS);
		$cntB = count($b->LIST_NRS);
		$cnt = min($cntA, $cntB);
		for ($i = 0; $i < $cnt; $i++) {
			if ($a->LIST_NRS[$i] > $b->LIST_NRS[$i]) {
				return 1;
			} else if ($a->LIST_NRS[$i] < $b->LIST_NRS[$i]) {
				return -1;
			}
		}
		return ($cntA < $cntB)? -1 : 1;
	}

}
