<?php

class Przypomnij {

	private $_data;
	private $_fltrs;
	private $_deepRecurseLimit;
	private $_dSource = array();
	private $_tblIdCache = array();
	private $_tblAclCache = array();

	public function __construct() {
		$this->_data = array();// [type][id] = {id, _title, _type, _l_app, _l_app_date}
		$this->_data['projekt'] = array();
		$this->_data['koresp'] = array();
		$this->_data['proces'] = array();

		$this->_fltrs = array();// type => selected value
		$this->_fltrs['user'] = '';// L_APPOITMENT_USER
		$this->_fltrs['date_from'] = '';
		$this->_fltrs['date_to'] = '';

		$this->_deepRecurseLimit = 3;
	}

	public function setRecurseLimit($deepRecurseLimit) {
		$this->_deepRecurseLimit = $deepRecurseLimit;
	}

	public function getRawData() {
		return $this->_data;
	}

	public function fetchData() {
		$db = DB::getDB();
		$sql = "select kor.ID
				, kor.ID_PROJECT
				, kor.A_STATUS
				, kor.L_APPOITMENT_USER
				, kor.L_APPOITMENT_DATE
				, kor.L_APPOITMENT_INFO
				, kor.A_RECORD_CREATE_DATE
				, kor.A_RECORD_CREATE_AUTHOR
				, kor.K_TYP_KORESP, kor.K_TYP_RODZAJ
				-- ? , kor.K_TYP_RODZAJ_OPIS
				, kor.K_OD_KOGO
				, kor.OD_KOGO_ADRES
				, kor.K_ZAWARTOS
				-- TODO:	, proj.M_DIST_DESC
				, kor.K_LOKALIZACJA
				, kor.K_LOKALIZACJA_OPIS
			from `IN7_DZIENNIK_KORESP` as kor
			where kor.`A_STATUS` not in ('OFF_HARD','DELETED')
		";
		$res = $db->query($sql);
		while ($r = $db->fetch($res)) {
			$r->_task_type = 'koresp';
			$r->_show = false;
			$r->_acl_proj_id = (int)$r->ID_PROJECT;
			$r->_title = "<strong>{$r->K_OD_KOGO}</strong><br><em>{$r->OD_KOGO_ADRES}</em><br>{$r->K_ZAWARTOS}";
			$r->_type = "{$r->K_TYP_KORESP}-{$r->K_TYP_RODZAJ}";
			$r->_l_app = $r->L_APPOITMENT_USER;
			$r->_l_app_date = $r->L_APPOITMENT_DATE;
			$this->_data['koresp'][$r->ID] = $r;
		}

		$sql = "select proj.ID
				, proj.P_ID
				, proj.A_STATUS
				, proj.M_DIST_DESC
				, proj.M_DIST_TYPE
				, proj.L_APPOITMENT_DATE
				, proj.L_APPOITMENT_USER
				, proj.L_APPOITMENT_INFO
				, proj.A_RECORD_CREATE_DATE
				, proj.A_RECORD_CREATE_AUTHOR
				, proj.M_DISTRIBUTOR
				-- ? , proj.M_DIST_DATE
				-- ? , proj.A_RECORD_CREATE_AUTHOR, proj.A_RECORD_UPDATE_AUTHOR, proj.A_RECORD_UPDATE_DATE
				-- ? , proj.A_PROBLEM, proj.A_PROBLEM_DATE, proj.A_PROBLEM_DESC
			from `IN7_MK_BAZA_DYSTRYBUCJI` as proj
			where proj.`A_STATUS` NOT IN ('OFF_HARD','DELETED')
		";
		$res = $db->query($sql);
		while ($r = $db->fetch($res)) {
			$r->M_DIST_DESC = htmlspecialchars($r->M_DIST_DESC);// TODO: fix bug in html a href inside M_DIST_DESC
			$r->_task_type = 'projekt';
			$r->_show = false;
			$r->_acl_proj_id = (int)$r->P_ID;
			$r->_title = $r->M_DIST_DESC;
			$r->_type = $r->M_DIST_TYPE;
			$r->_l_app = $r->L_APPOITMENT_USER;
			$r->_l_app_date = $r->L_APPOITMENT_DATE;
			$this->_data['projekt'][$r->ID] = $r;
		}

		$sql = "select p.ID
				, p.`DESC`
				, p.`A_STATUS`
				, p.`TYPE`
				, p.`L_APPOITMENT_DATE`
				, p.`L_APPOITMENT_USER`
				, p.`L_APPOITMENT_INFO`
			from `CRM_PROCES` as p
			where p.`TYPE`='PROCES_INIT'
				and p.`A_STATUS` in('NORMAL', 'WAITING')
				and p.`L_APPOITMENT_DATE`!=''
				and p.`L_APPOITMENT_USER`!=''
		";
		$res = $db->query($sql);
		while ($r = $db->fetch($res)) {
			$r->_task_type = 'proces';
			$r->_show = false;
			$r->_title = $r->DESC;
			$r->_type = $r->TYPE;
			$r->_l_app = $r->L_APPOITMENT_USER;
			$r->_l_app_date = $r->L_APPOITMENT_DATE;
			$this->_data['proces'][$r->ID] = $r;
		}

		$this->_fetchLAppUsers();
	}

	public function setFltrUser($userName) {
		foreach ($this->_data as $kType => $vTasks) {
			foreach ($vTasks as $kId => $vTask) {
				if (!$userName) {
					$this->_data[$kType][$kId]->_show = true;
				} else {
					if ($vTask->_l_app == $userName) {
						$this->_data[$kType][$kId]->_show = true;
					} else {
						$this->_data[$kType][$kId]->_show = false;
					}
				}
			}
		}
	}

	private function _fetchLAppUsers() {
		$this->_createCacheTable();
		$this->_updateCacheTable();

		$projTodo = array();
		foreach ($this->_data['projekt'] as $kID => $vProj) {
			if (empty($vProj->_l_app)) {
				if ($vProj->_acl_proj_id > 0) {
					$projTodo[$vProj->_acl_proj_id][$vProj->ID] = 'projekt';
				}
			}
		}
		foreach ($this->_data['koresp'] as $kID => $vKoresp) {
			if (empty($vKoresp->_l_app)) {
				if ($vKoresp->_acl_proj_id > 0) {
					$projTodo[$vKoresp->_acl_proj_id][$vKoresp->ID] = 'koresp';
				}
			}
		}

		if (empty($projTodo)) {
			return;
		}

		$db = DB::getDB();
		$projIds = array_keys($projTodo);
		$sql = "select c.`ID`, c.`ID_PROJECT`, c.`L_APPOITMENT_USER`, c.`L_APPOITMENT_DATE`
			from `_PRZYPOMNIJ_CACHE` as c
			where c.`ID_PROJECT` in(" . implode(",", $projIds) . ")
		";
if(V::get('DBG_P', '', $_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);
		if (!$res) {
			if ($db->has_errors()) {
				echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">DB Errors: (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($db->get_errors());echo'</pre>';
			}
		}
		while ($r = $db->fetch($res)) {
			foreach ($projTodo[$r->ID_PROJECT] as $kRowId => $vType) {
				if ($vType == 'projekt') {
					if (isset($this->_data['projekt'][$kRowId])) {
						if (!empty($r->L_APPOITMENT_USER)) {
							$this->_data['projekt'][$kRowId]->_l_app = $r->L_APPOITMENT_USER;
						}
					} else {
						//echo '<p style="color:red">'."Error not set \$this->_data['projekt'][$kRowId]".'</p>';
					}
				}
				else if ($vType == 'koresp') {
					if (!empty($r->L_APPOITMENT_USER)) {
						$this->_data['koresp'][$kRowId]->_l_app = $r->L_APPOITMENT_USER;
						if (!empty($r->L_APPOITMENT_DATE) && empty($this->_data['koresp'][$kRowId]->_l_app_date)) {
							//$this->_data['koresp'][$kRowId]->_l_app_date = $r->L_APPOITMENT_DATE;
							$this->_data['koresp'][$kRowId]->_l_app_date = '0000-00-00';
						}
					}
				}
			}
		}
	}

	private function _fetchLAppUsersRec() {
		$projTodo = array();
		$db = DB::getDB();
		$loopLimit = $this->_deepRecurseLimit;
		$firstLoop = true;
		do {
			if(V::get('DBG_P', '', $_GET) > 2){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">loop(' . ($this->_deepRecurseLimit - $loopLimit) . ') start projTodo (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($projTodo);echo'</pre>';}

			foreach ($this->_data['projekt'] as $kID => $vProj) {
				if (empty($vProj->_l_app)) {
					if ($vProj->_acl_proj_id > 0) {
						if (isset($this->_data['projekt'][$vProj->_acl_proj_id])) {// already fetched from DB
							if (!empty($this->_data['projekt'][$vProj->_acl_proj_id]->_l_app)) {
								$this->_data['projekt'][$vProj->ID]->_l_app = $this->_data['projekt'][$vProj->_acl_proj_id]->_l_app;
							} else {
								$this->_data['projekt'][$vProj->ID]->_acl_proj_id = $this->_data['projekt'][$vProj->_acl_proj_id]->_acl_proj_id;
							}
						} else {
							$projTodo[$vProj->_acl_proj_id][$vProj->ID] = 'projekt';
						}
					} else if (!$vProj->_acl_proj_id) {
						//if ($firstLoop) echo '<p>'."Error: Projekt {$vProj->ID} nie ma P_ID ani L_APPOITMENT_USER! Autor: {$vProj->A_RECORD_CREATE_AUTHOR} / {$vProj->A_RECORD_CREATE_DATE}".'</p>';
						$this->_data['projekt'][$kID]->_acl_proj_id = -1;// set error
					} else if ($vProj->_acl_proj_id < 0) {
						//if ($firstLoop) echo '<p>'."Error: Projekt {$vProj->ID} ma P_ID = -1, brak L_APPOITMENT_USER! Autor: {$vProj->A_RECORD_CREATE_AUTHOR} / {$vProj->A_RECORD_CREATE_DATE}".'</p>';
						$this->_data['projekt'][$kID]->_acl_proj_id = -1;// set error
					}
				}
			}
			foreach ($this->_data['koresp'] as $kID => $vKoresp) {
				if (empty($vKoresp->_l_app)) {
					if ($vKoresp->_acl_proj_id > 0) {
						if (!empty($this->_data['projekt'][$vKoresp->_acl_proj_id]->_l_app)) {
							$this->_data['koresp'][$vKoresp->ID]->_l_app = $this->_data['projekt'][$vKoresp->_acl_proj_id]->_l_app;
						} else {
							$this->_data['koresp'][$vKoresp->ID]->_acl_proj_id = $this->_data['projekt'][$vKoresp->_acl_proj_id]->_acl_proj_id;
							if ($vKoresp->_acl_proj_id > 0) {
								$projTodo[$vKoresp->_acl_proj_id][$vKoresp->ID] = 'koresp';
							} else {
								//echo '<p style="color:red">'."Error: brak l_app w projektach dla Koresp {$vKoresp->ID}".'</p>';
							}
						}
					} else {
						//if ($firstLoop) echo '<p>'."Error: Korespondencja {$vKoresp->ID} ma ID_PROJECT = {$vKoresp->_acl_proj_id}, brak L_APPOITMENT_USER! Autor: {$vKoresp->A_RECORD_CREATE_AUTHOR} / {$vKoresp->A_RECORD_CREATE_DATE}".'</p>';
						$this->_data['koresp'][$kID]->_acl_proj_id = -1;// set error
					}
				}
			}

			if ($firstLoop) $firstLoop = false;

			if (empty($projTodo)) {
				if(V::get('DBG_P', '', $_GET) > 2){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">loop(' . ($this->_deepRecurseLimit - $loopLimit) . ')  (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r("break loop " . ($this->_deepRecurseLimit - $loopLimit));echo'</pre>';}
				break;
			}
			if(V::get('DBG_P', '', $_GET) > 2){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">loop(' . ($this->_deepRecurseLimit - $loopLimit) . ') $projTodo (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($projTodo);echo'</pre>';}
			$projIds = array_keys($projTodo);
			$sql = "select `ID`, `P_ID`, `L_APPOITMENT_USER`, `L_APPOITMENT_USER`
				from `IN7_MK_BAZA_DYSTRYBUCJI`
				where `ID` in(" . implode(",", $projIds) . ")
			";
			if(V::get('DBG_P', '', $_GET) > 2){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">loop(' . ($this->_deepRecurseLimit - $loopLimit) . ') sql (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($sql);echo'</pre>';}
			$res = $db->query($sql);
			if (!$res) {
				if ($db->has_errors()) {
					echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">DB Errors: (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($db->get_errors());echo'</pre>';
				}
			}
			while ($r = $db->fetch($res)) {
				//if(V::get('DBG_P', '', $_GET) > 2){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">loop(' . ($this->_deepRecurseLimit - $loopLimit) . ') r [isset($projTodo[$r->ID]) = '.isset($projTodo[$r->ID]).'] (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($r);echo'</pre>';}
				foreach ($projTodo[$r->ID] as $kRowId => $vType) {
					if ($vType == 'projekt') {
						if (isset($this->_data['projekt'][$kRowId])) {
							$this->_data['projekt'][$kRowId]->_acl_proj_id = (int)$r->P_ID;
							if (!empty($r->L_APPOITMENT_USER)) {
								$this->_data['projekt'][$kRowId]->_l_app = $r->L_APPOITMENT_USER;
								//if (!empty($r->L_APPOINTMENT_DATE)) {
								//	$this->_data['projekt'][$kRowId]->_l_app = $r->L_APPOITMENT_USER;
								//}
							}
						} else {
							echo '<p style="color:red">'."Error not set \$this->_data['projekt'][$kRowId]".'</p>';
						}
					} else if ($vType == 'koresp') {
						$this->_data['koresp'][$kRowId]->_acl_proj_id = (int)$r->P_ID;
						if (!empty($r->L_APPOITMENT_USER)) {
							$this->_data['koresp'][$kRowId]->_l_app = $r->L_APPOITMENT_USER;
							//if (!empty($r->L_APPOINTMENT_DATE)) {
							//	$this->_data['projekt'][$kRowId]->_l_app = $r->L_APPOITMENT_USER;
							//}
						}
					}
				}

				unset($projTodo[$r->ID]);
			}
if(V::get('DBG_P', '', $_GET) > 2){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">loop(' . ($this->_deepRecurseLimit - $loopLimit) . ') this->_data (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($this->_data);echo'</pre>';}

		} while (--$loopLimit);
	}

	public function getAllowedUsersList() {
		$allowedUsers = array();
		$db = DB::getDB();
		$sql = "select distinct `L_APPOITMENT_USER` from `IN7_MK_BAZA_DYSTRYBUCJI` where `L_APPOITMENT_USER`!='' and `A_STATUS` not in ('OFF_HARD','DELETED') ";
		// TODO: $zap_sql = "SELECT DISTINCT  `L_APPOITMENT_USER` FROM  `IN7_MK_BAZA_DYSTRYBUCJI` WHERE  `L_APPOITMENT_USER` !=  '' and (  A_CLASSIFIED in  ('".implode( "','" , $_SESSION['AUTH_LDAP_CLIENT__LDAP_USERS'][$_SESSION['ADM_ACCOUNT']])."') or A_CLASSIFIED=''   ) ";
		$res = $db->query($sql) or die("blad zapytania do bazy {$sql}");
		while ($r = $db->fetch($res)) {
			$allowedUsers[$r->L_APPOITMENT_USER] = true;
		}

		$sql = "select distinct `L_APPOITMENT_USER` from `IN7_DZIENNIK_KORESP` where `L_APPOITMENT_USER`!='' and `A_STATUS` not in ('OFF_HARD','DELETED') ";
		//TODO: $zap_sql = "SELECT DISTINCT  `L_APPOITMENT_USER` FROM  `IN7_DZIENNIK_KORESP` WHERE  `L_APPOITMENT_USER` !=  '' and (  A_CLASSIFIED in  ('".implode( "','" , $_SESSION['AUTH_LDAP_CLIENT__LDAP_USERS'][$_SESSION['ADM_ACCOUNT']])."') or A_CLASSIFIED=''   )  ; ";
		$res = $db->query($sql) or die("blad zapytania do bazy {$sql}");
		while ($r = $db->fetch($res)) {
			$allowedUsers[$r->L_APPOITMENT_USER] = true;
		}

		$sql = "select distinct `L_APPOITMENT_USER` from `CRM_PROCES` where `L_APPOITMENT_USER`!='' and `A_STATUS` not in ('OFF_HARD','DELETED') ";
		//TODO: $zap_sql = "SELECT DISTINCT  `L_APPOITMENT_USER` FROM  `IN7_DZIENNIK_KORESP` WHERE  `L_APPOITMENT_USER` !=  '' and (  A_CLASSIFIED in  ('".implode( "','" , $_SESSION['AUTH_LDAP_CLIENT__LDAP_USERS'][$_SESSION['ADM_ACCOUNT']])."') or A_CLASSIFIED=''   )  ; ";
		$res = $db->query($sql) or die("blad zapytania do bazy {$sql}");
		while ($r = $db->fetch($res)) {
			$allowedUsers[$r->L_APPOITMENT_USER] = true;
		}

		$sql = "select distinct `L_APPOITMENT_USER` from `CRM_LISTA_ZASOBOW` where `L_APPOITMENT_USER`!='' and `A_STATUS` not in ('OFF_HARD','DELETED') ";
		//TODO: $zap_sql = "SELECT DISTINCT  `L_APPOITMENT_USER` FROM  `IN7_DZIENNIK_KORESP` WHERE  `L_APPOITMENT_USER` !=  '' and (  A_CLASSIFIED in  ('".implode( "','" , $_SESSION['AUTH_LDAP_CLIENT__LDAP_USERS'][$_SESSION['ADM_ACCOUNT']])."') or A_CLASSIFIED=''   )  ; ";
		$res = $db->query($sql) or die("blad zapytania do bazy {$sql}");
		while ($r = $db->fetch($res)) {
			$allowedUsers[$r->L_APPOITMENT_USER] = true;
		}

		ksort($allowedUsers);

		return $allowedUsers;
	}

	private function _createCacheTable() {
		$db = DB::getDB();
		$sql = "CREATE TABLE IF NOT EXISTS `_PRZYPOMNIJ_CACHE` (
				`ID` int(11) NOT NULL AUTO_INCREMENT,
				`ID_PROJECT` int(11) NOT NULL,
				`_l_app_user` varchar(40) NOT NULL DEFAULT '',
				`P_ID` varchar(20) NOT NULL DEFAULT '0',
				`A_RECORD_CREATE_DATE` datetime NOT NULL,
				`A_RECORD_CREATE_AUTHOR` varchar(40) NOT NULL DEFAULT '',
				`A_RECORD_UPDATE_DATE` datetime NOT NULL DEFAULT '0000-00-00 00:00:00',
				`A_RECORD_UPDATE_AUTHOR` varchar(40) NOT NULL DEFAULT '',
				`L_APPOITMENT_DATE` varchar(30) NOT NULL DEFAULT '',
				`L_APPOITMENT_USER` varchar(40) NOT NULL DEFAULT '',
				`L_APPOITMENT_INFO` varchar(200) NOT NULL DEFAULT '',
				`L_CALENDAR` enum('NO','YES') NOT NULL DEFAULT 'NO',
				`A_STATUS` enum('WAITING','NORMAL','MONITOR','WARNING','OFF_SOFT','OFF_HARD','DELETED') NOT NULL DEFAULT 'WAITING',
				`M_DIST_DATE` date NOT NULL DEFAULT '0000-00-00',
				`M_DIST_TYPE` varchar(64) NOT NULL DEFAULT 'INNE',
				`M_DIST_DESC` varchar(255) NOT NULL DEFAULT '',
				`M_DISTRIBUTOR` varchar(200) NOT NULL DEFAULT '',
				PRIMARY KEY (`ID`),
				KEY `P_ID` (`P_ID`),
				KEY `ID_PROJECT` (`ID_PROJECT`)
			) ENGINE=MyISAM  DEFAULT CHARSET=latin2;
		";
		if(V::get('DBG_P', '', $_GET) > 3){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">sql (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($sql);echo'</pre>';}
		$db->query($sql);
	}

	private function _updateCacheTable() {
		$db = DB::getDB();
		$sql = "truncate table `_PRZYPOMNIJ_CACHE`; ";
		$db->query($sql);
		$sql = "insert into `_PRZYPOMNIJ_CACHE` (`ID_PROJECT`,`P_ID`,`_l_app_user`,`L_APPOITMENT_USER`,`L_APPOITMENT_DATE`)
			select `ID`,`P_ID`,`L_APPOITMENT_USER`,`L_APPOITMENT_USER`,`L_APPOITMENT_DATE`
			from `IN7_MK_BAZA_DYSTRYBUCJI`
				where 1=1
		";
		$db->query($sql);

		// test recurse update l_app
		$sql = "select c._l_app_user
				, p.L_APPOITMENT_USER
				, p1.L_APPOITMENT_USER
				, p2.L_APPOITMENT_USER
				, p3.L_APPOITMENT_USER
				, p4.L_APPOITMENT_USER
				, p5.L_APPOITMENT_USER
				, p.ID
				, p1.ID
				, p2.ID
				, p3.ID
				, p4.ID
				, p5.ID
			from `_PRZYPOMNIJ_CACHE` as c
				left join `IN7_MK_BAZA_DYSTRYBUCJI` as p on (p.ID=c.ID_PROJECT)
				left join `IN7_MK_BAZA_DYSTRYBUCJI` as p1 on (p1.ID=p.P_ID)
				left join `IN7_MK_BAZA_DYSTRYBUCJI` as p2 on (p2.ID=p1.P_ID)
				left join `IN7_MK_BAZA_DYSTRYBUCJI` as p3 on (p3.ID=p2.P_ID)
				left join `IN7_MK_BAZA_DYSTRYBUCJI` as p4 on (p4.ID=p3.P_ID)
				left join `IN7_MK_BAZA_DYSTRYBUCJI` as p5 on (p5.ID=p4.P_ID)
			where c.`_l_app_user`=''
		";

		// for i to recurse limit
		$sql = "update `_PRZYPOMNIJ_CACHE` as c
				left join `IN7_MK_BAZA_DYSTRYBUCJI` as p on (p.ID=c.ID_PROJECT)
				left join `IN7_MK_BAZA_DYSTRYBUCJI` as p1 on (p1.ID=p.P_ID)
				left join `IN7_MK_BAZA_DYSTRYBUCJI` as p2 on (p2.ID=p1.P_ID)
				left join `IN7_MK_BAZA_DYSTRYBUCJI` as p3 on (p3.ID=p2.P_ID)
				left join `IN7_MK_BAZA_DYSTRYBUCJI` as p4 on (p4.ID=p3.P_ID)
				left join `IN7_MK_BAZA_DYSTRYBUCJI` as p5 on (p5.ID=p4.P_ID)
			set
				c.`_l_app_user`=IF(p.`L_APPOITMENT_USER`!='', p.`L_APPOITMENT_USER`
					, IF(p1.`L_APPOITMENT_USER`!='', p1.`L_APPOITMENT_USER`
						, IF(p2.`L_APPOITMENT_USER`!='', p2.`L_APPOITMENT_USER`
							, IF(p3.`L_APPOITMENT_USER`!='', p3.`L_APPOITMENT_USER`
								, IF(p4.`L_APPOITMENT_USER`!='', p4.`L_APPOITMENT_USER`
									, IF(p5.`L_APPOITMENT_USER`!='', p5.`L_APPOITMENT_USER`
										, ''
									)
								)
							)
						)
					)
				)
			where c.`_l_app_user`=''
		";
		$db->query($sql);
	}

	public function orderByDateAsc($t1, $t2) {
		return $this->orderByDate($t1, $t2, true);
	}

	public function orderByDateDesc($t1, $t2) {
		return $this->orderByDate($t1, $t2, false);
	}

	public function orderByDate($t1, $t2, $asc = true) {
		$a = $t1->_l_app_date;
		$b = $t2->_l_app_date;
		if ($a == $b) {
			return 0;
		}
		if ($asc) {
			return ($a > $b)? 1 : -1;
		} else {
			return ($a < $b)? 1 : -1;
		}
	}

	public function getTasksByDate($asc = true) {
		$tasks = array();
		foreach ($this->_data as $kType => $vTasks) {
			foreach ($vTasks as $kId => $vTask) {
				$tasks[] = $vTask;
			}
		}

		if ($asc) {
			usort($tasks, array($this, 'orderByDateAsc'));
		} else {
			usort($tasks, array($this, 'orderByDateDesc'));
		}

		return $tasks;
	}

	public function getZasobIdByType($type) {
		if (!isset($this->_tblIdCache[$type])) {
			$this->_tblIdCache[$type] = null;

			$allowedTypes = array('projekt', 'proces', 'koresp');
			if (empty($type) || !in_array($type, $allowedTypes)) {
				echo '<div class="alert alert-error cls-line-' . __LINE__ . '">' . "Brak dostępu" . '</div>';
				return null;
			}

			Lib::loadClass('ProcesHelper');
			switch ($type) {
				case 'projekt':
					$this->_tblIdCache[$type] = ProcesHelper::getZasobTableID('IN7_MK_BAZA_DYSTRYBUCJI');
					break;
				case 'koresp':
					$this->_tblIdCache[$type] = ProcesHelper::getZasobTableID('IN7_DZIENNIK_KORESP');
					break;
				case 'proces':
					$this->_tblIdCache[$type] = ProcesHelper::getZasobTableID('CRM_PROCES');
					break;
				default:
					echo '<div class="alert alert-error cls-line-' . __LINE__ . '">' . "Brak dostępu" . '</div>';
					return null;
			}
		}
		return $this->_tblIdCache[$type];
	}

	private function getTblAclByType($type) {
		if (!isset($this->_tblAclCache[$type])) {
			$this->_tblAclCache[$type] = null;

			$zasobID = $this->getZasobIdByType($type);
			if (!$zasobID) {
				echo '<div class="alert alert-error cls-line-' . __LINE__ . '">' . "Brak dostępu" . '</div>';
				return null;
			}

			Lib::loadClass('ProcesHelper');
			$zasobObj = ProcesHelper::getZasobTableInfo($zasobID);
			if (!$zasobObj) {
				echo '<div class="alert alert-error cls-line-' . __LINE__ . '">' . "Zasob TABELA ID={$zasobID} nie istnieje" . '</div>';
				return null;
			}

			$userAcl = User::getAcl();
			$userAcl->fetchGroups();

			if (!$userAcl->hasTableAcl($zasobObj->ID)) {
				echo '<div class="alert alert-error cls-line-' . __LINE__ . '">' . "Brak uprawnień do tabeli ID={$zasobObj->ID}" . '</div>';
				return null;
			}

			$tblAcl = $userAcl->getTableAcl($zasobObj->ID);
			$this->_tblAclCache[$type] = $tblAcl;
		}
		return $this->_tblAclCache[$type];
	}

	private function getDataSource($tblAcl) {
		$tblName = $tblAcl->getName();
		if (!isset($this->_dSource[$tblName])) {
			$this->_dSource[$tblName] = null;

			Lib::loadClass('Data_Source');
			$dataSource = new Data_Source($tblAcl->getDB());
			$dataSource->setTable($tblAcl->getName());
			$realFieldList = $tblAcl->getRealFieldList();
			$dataSource->setCols($realFieldList);
			$dataSource->setColTypes($tblAcl->getTypes());
			$dataSource->setVirtualCols($tblAcl->getVirtualFieldList());
			$dataSource->setFieldGroupWrite('A_ADM_COMPANY', $tblAcl->hasFieldType('A_ADM_COMPANY'));
			$dataSource->setFieldGroupRead('A_CLASSIFIED', $tblAcl->hasFieldType('A_CLASSIFIED'));

			$this->_dSource[$tblName] = $dataSource;
		}

		return $this->_dSource[$tblName];
	}

	private function getEditAppDateFields() {
		$fields = array();
		$fields[] = 'L_APPOITMENT_DATE';
		$fields[] = 'L_APPOITMENT_USER';
		$fields[] = 'L_APPOITMENT_INFO';
		return $fields;
	}

	public function sendAjaxEditAppDateInline() {
		// $_GET [rowid] => 2286, [type] => proces, [fldId] => date
		$rowID = V::get('rowid', 0, $_GET, 'int');
		$type = V::get('type', '', $_GET);
		$fields = $this->getEditAppDateFields();

		$DBG = ('1' == V::get('DBG', '', $_REQUEST));
		header("Content-type: text/plain");

		if ($rowID <= 0) {
			echo '<div class="alert alert-error cls-line-' . __LINE__ . '">' . "Brak dostępu" . '</div>';
			exit;
		}

		$tblAcl = $this->getTblAclByType($type);
		if (!$tblAcl) {
			echo '<div class="alert alert-error cls-line-' . __LINE__ . '">' . "Brak dostępu (acl)" . '</div>';
			exit;
		}

		$tblAcl->init();

		$dataSource = $this->getDataSource($tblAcl);
		if (!$dataSource) {
			echo '<div class="alert alert-error cls-line-' . __LINE__ . '">' . "Brak danych" . '</div>';
			exit;
		}

		$row = $dataSource->getItem($rowID);
		if (!$row) {
			echo "404: No item ID({$rowID})";
			exit;
		}

		?>
		<blockquote>Rekord <strong><?php echo $row->ID; ?></strong> typu <?php echo $type; ?></blockquote>
		<?php

		foreach ($fields as $fieldName) {
			$fieldID = $tblAcl->getFieldIdByName($fieldName);
			if (!$fieldID) {
				if ($DBG) echo "404: No field by name ({$fieldName})";
				continue;
			}
			if ($DBG) echo "fieldID: {$fieldID}\n";

			if (!$tblAcl->isAllowed($fieldID, 'R', $row)) {
				if ($DBG) echo " R not allowed\n";
			} else {
				if ($DBG) echo " R allowed\n";
			}

			if (!$tblAcl->isAllowed($fieldID, 'W', $row)) {
				if ($DBG) echo " W not allowed\n";
			} else {
				if ($DBG) echo " W allowed\n";
			}

			$fieldVal = '';
			if ($tblAcl->isAllowed($fieldID, 'R', $row)) {
				$fieldVal = V::get($fieldName, $fieldVal, $row);
			}
			$fieldVal = V::get("f{$fieldID}", $fieldVal, $_POST);

			$vCol = $tblAcl->getField($fieldID);
			$vCol['label'] = (!empty($vCol['label']))? $vCol['label'] : $vCol['name'];

			$tsValues = array();
			Lib::loadClass('Typespecial');
			$typeSpecial = Typespecial::getInstance($fieldID, $vCol['name']);
			if ($typeSpecial) {
				if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">Typespecial('.$fieldID.') (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($typeSpecial);echo'</pre>';}
				$specialValues = $typeSpecial->getEditSelectedValuesByIds($zasobID, $row->ID, $fieldName, V::get($fieldName, $fieldVal, $row));
				if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">Typespecial('.$fieldID.') specialValues (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($specialValues);echo'</pre>';}
				if (!empty($specialValues)) {
					$tsValues[$row->ID] = implode('<br>', $specialValues);
				}
			}

			?>
			<label for="<?php echo "f{$fieldID}"; ?>" class="AjaxTableEdit-label">
				<strong title="<?php echo "[{$fieldID}] {$fieldName}"; ?>"><?php echo "{$vCol['label']}"; ?></strong>
				<?php if (!empty($vCol['opis'])) : ?>
					<em><?php echo $vCol['opis']; ?></em>
				<?php endif; ?>
			</label>
			<?php
			$fieldParams = array('widthClass'=>'inside-modal', 'maxGrid'=>6);
			if (!empty($tsValues[$row->ID])) {
				$fieldParams['typespecialValue'] = $tsValues[$row->ID];
			}
			$vDefault = $dataSource->getColDefault($fieldName);
			if (!empty($vDefault)) {
				$fieldParams['default'] = $vDefault;
			}
			echo $tblAcl->showFormItem('W', $fieldID, "f{$fieldID}", $fieldVal, $fieldParams, $row);
		}

		echo '<p style="padding:100px 0;"></p>';
		exit;
	}

	public function _getDateFltrTypes() {
		$fltrDate = array();
		$fltrDate[] = 'BRAK';
		$fltrDate[] = 'PO_TERMINIE';
		$fltrDate[] = 'DZISIAJ';
		$fltrDate[] = 'W_CIAGU_7_DNI';
		$fltrDate[] = 'PO_7_DNIACH';
		return $fltrDate;
	}

	public function getDateHideFltrTypes() {
		$fltrDate = $this->_getDateFltrTypes();
		foreach ($fltrDate as $i => $fltr) {
			$fltrDate[$i] = "fltr-hide_{$fltr}";
		}
		return $fltrDate;
	}

	public function getDateFltrTypes() {
		$fltrDate = $this->_getDateFltrTypes();
		foreach ($fltrDate as $i => $fltr) {
			$fltrDate[$i] = "date-{$fltr}";
		}
		return $fltrDate;
	}

	public function getTaskDateFltrType($taskDate) {
		$nowDay = date("Y-m-d");
		$nowDayPlus7 = date("Y-m-d", mktime(0,0,0, date("m"), date("d") + 7, date("Y")));

		$clsData = '';
		$appDay = substr($taskDate, 0, 10);
		if (empty($taskDate)) {
			$clsData = 'date-BRAK';
		} else if ($appDay < $nowDay) {
			$clsData = 'date-PO_TERMINIE';
		} else if ($appDay == $nowDay) {
			$clsData = 'date-DZISIAJ';
		} else if ($appDay > $nowDay && $appDay <= $nowDayPlus7) {
			$clsData = 'date-W_CIAGU_7_DNI';
		} else {
			$clsData = 'date-PO_7_DNIACH';
		}
		return $clsData;
	}

	public function sendAjaxEditAppDateInlineSave() {
		$DBG = ('1' == V::get('DBG', '', $_REQUEST));
		sleep(1);// TODO: RMME DBG loading

		$rowID = V::get('rowid', 0, $_POST, 'int');
		$type = V::get('type', '', $_POST);
		$fields = $this->getEditAppDateFields();

		if ($rowID <= 0) {
			echo '<div class="alert alert-error cls-line-' . __LINE__ . '">' . "Brak dostępu" . '</div>';
			exit;
		}

		$tblAcl = $this->getTblAclByType($type);
		if (!$tblAcl) {
			echo '<div class="alert alert-error cls-line-' . __LINE__ . '">' . "Brak dostępu (acl)" . '</div>';
			exit;
		}

		$tblAcl->init();

		$dataSource = $this->getDataSource($tblAcl);
		if (!$dataSource) {
			echo '<div class="alert alert-error cls-line-' . __LINE__ . '">' . "Brak danych" . '</div>';
			exit;
		}

		$row = $dataSource->getItem($rowID);
		if (!$row) {
			echo "404: No item ID({$rowID})";
			exit;
		}

		$sqlObj = new stdClass();
		$allData = new stdClass();
		foreach ($fields as $fieldName) {
			$fieldID = $tblAcl->getFieldIdByName($fieldName);
			if (!$fieldID) {
				if ($DBG) echo "404: No field by name ({$fieldName})";
				continue;
			}
			if ($DBG) echo "fieldID: {$fieldID}\n";

			if (!$tblAcl->isAllowed($fieldID, 'W', $row)) {
				if ($DBG) echo " W not allowed\n";
				continue;
			} else {
				if ($DBG) echo " W allowed\n";
			}

			$fieldVal = V::get($fieldName, '', $row);
			$sqlObj->{$fieldName} = V::get("f{$fieldID}", $fieldVal, $_POST);

			if (empty($_POST["f{$fieldID}"]) && strlen($_POST["f{$fieldID}"]) == 0) {// fix bug in input type date and value="0000-00-00"
				$sqlObj->{$fieldName} = $tblAcl->fixEmptyValueFromUser($fieldID);
			}
		}
		if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">TODO: save type ('.$type.') ID(' . $rowid . ') (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($sqlObj);echo'</pre>';}
		$sqlObj->ID = $row->ID;

		$dbID = $tblAcl->getDB();
		$db = DB::getDB($dbID);
		if (!$db) {
			header('HTTP/1.0 406 Not Acceptable');
			exit;
		}

		$tblName = $tblAcl->getName();

		$sqlObj->ID = $rowID;
		if($DBG){echo'<pre style="max-height:200px;overflow:auto;border:1px solid red;text-align:left;">TODO: Save ('.$tblName.') (' . __CLASS__ . '::' . __FUNCTION__ . ':' . __LINE__ . '): ';print_r($sqlObj);echo'</pre>';}

		$allData = array();
		$allData['L_APPOITMENT_DATE'] = $sqlObj->L_APPOITMENT_DATE;
		$allData['L_APPOITMENT_USER'] = $sqlObj->L_APPOITMENT_USER;
		$allData['L_APPOITMENT_INFO'] = $sqlObj->L_APPOITMENT_INFO;

		$ret = $db->UPDATE_OBJ($tblName, $sqlObj);
		if ($ret > 0) {
			echo '<div class="alert alert-success">';
				echo "Rekord zapisany pomyślnie";//"Record saved successfully";
			echo '</div>';

			echo '<div class="EditAppDateInlineSave" style="display:none">';
				echo '<span class="l_app_date">' . $allData['L_APPOITMENT_DATE'] . '</span>';
				echo '<span class="l_app_user">' . $allData['L_APPOITMENT_USER'] . '</span>';
				echo '<span class="l_app_info">' . $allData['L_APPOITMENT_INFO'] . '</span>';
				echo '<span class="date_fltr_type">' . $this->getTaskDateFltrType($allData['L_APPOITMENT_DATE']) . '</span>';
			echo '</div>';
		} else if ($ret == 0) {
			echo '<div class="alert alert-info">';
				echo "Nie wprowadzono żadnych zmian";
				if ($db->has_errors()) {
					$errors = $db->get_errors();
					echo implode('<br>', $errors);
				}
			echo '</div>';
		} else {
			echo '<div class="alert alert-error">';
				echo '<h4>' . "Wystąpiły błędy!" . '</h4>';
				if ($db->has_errors()) {
					$errors = $db->get_errors();
					echo implode('<br>', $errors);
				}
			echo '</div>';
		}

		exit;
	}

}
