<?php

require_once('ErrorDebug.php');
require_once('URCValues.php');
require_once('URCSystemData.php');
require_once('URCTemplateData.php');

class URCCustomDevData {

	var $dealerGrpId = -1;
	var $dealerId = -1;

	function __construct($dealerGrpId, $dealerId) {	
		$this->dealerGrpId = $dealerGrpId;
		$this->dealerId = $dealerId;
	}

	public function getDeviceList() {

		$urcDevices = DB::table('a_c_devices')->where('owner', '=', $this->dealerId)->
			select('id', 'created_at', 'name')->get(); 

		return $urcDevices;
	}

	public function getDevice($customDevId) {

		$urcDevice = DB::table('a_c_devices')->where('owner', '=', $this->dealerId)->where('id', '=', $customDevId)->first(); 
		if(!$urcDevice) {
			return false;
		}

		$urcBtns = DB::table('a_c_btns')->where('device_id', '=', $deviceId)->orderBy('page_id', 'asc')->get();

		$urcConDB = DB::table('a_c_con_db')->where('device_id', '=', $deviceId)->get();

		$urcKeyDB = DB::table('a_c_keys_db')->where('device_id', '=', $deviceId)->get();

		$deviceObj = new stdClass;
		$deviceObj->name = $urcDevice->name;
		$deviceObj->id = $deviceId;
		$deviceObj->dev_type = $urcDevice->dev_type;
		$deviceObj->meta_pwr_on = $urcDevice->meta_pwr_on;
		$deviceObj->meta_pwr_off = $urcDevice->meta_pwr_off;
		$deviceObj->meta_pwr_toggle = $urcDevice->meta_pwr_toggle;
		$deviceObj->meta_in_toggle = $urcDevice->meta_in_toggle;

		$deviceObj->pages = array();	

		$deviceObj->repeat = new stdClass;
		$deviceObj->repeat->min = $urcDevice->repeat_min;
		$deviceObj->repeat->macro = $urcDevice->repeat_macro;
		if($urcConDB) {
			$deviceObj->dbCon = $urcConDB;
		}
		else {
			$deviceObj->dbCon = array();
		}

		if($urcKeyDB) {
			$deviceObj->dbKey = $urcKeyDB;
		}
		else {
			$deviceObj->dbKey = array();
		}

		$deviceObj->type = $urcDevice->target_type;
		if($deviceObj->type == URCValues::DB_TYPE_IP ||
			$deviceObj->type == URCValues::DB_TYPE_UDP) {

			$deviceObj->ramp = new stdClass;
			$deviceObj->ramp->start = $urcDevice->ramp_start;
			$deviceObj->ramp->speed = $urcDevice->ramp_speed;

			$deviceObj->attr = new stdClass;
			$deviceObj->attr->auto_cr = $urcDevice->auto_cr;
			$deviceObj->attr->con_time = $urcDevice->con_time;
			$deviceObj->attr->delay_after_send = $urcDevice->delay_after_send;
		}

		$pageIdx = 0;
		$pageObj = null;
		$curPageId = -2;//-1 is used in db.
		foreach($urcBtns as $btn) {
			
			if($btn->page_id != $curPageId) {

				$deviceObj->pages[$pageIdx] = new stdClass;
				$pageObj = &$deviceObj->pages[$pageIdx];
				$pageIdx++;

				$pageObj->id = $btn->page_id;
				$pageObj->btns = array();
				
				$curPageId = $btn->page_id;
			}

			if($btn->page_hidden) {
				
				if(!isset($pageObj->page_hidden)) {
					$pageObj->page_hidden = 1;
				}
			}
			else {
				
				if(isset($pageObj->page_hidden)) {
					$pageObj->page_hidden = 0;
				}
			}
			
			unset($btn->page_id);
			unset($btn->page_hidden);			
			$pageObj->btns[] = $btn;
		}

		//ErrorDebug::write('getDevice');
		//ErrorDebug::write(json_encode($deviceObj));

		return $deviceObj;		
	}

	public function getDeviceInfo($customDevId) {

		$urcDevice = DB::table('a_c_devices')->where('owner', '=', $this->dealerId)->where('id', '=', $customDevId)->first(); 
		if(!$urcDevice) {
			return false;
		}

		$deviceObj = new stdClass;
		$deviceObj->name = $urcDevice->name;
		$deviceObj->id = $customDevId;
		$deviceObj->dev_type = $urcDevice->dev_type;
		$deviceObj->meta_pwr_on = $urcDevice->meta_pwr_on;
		$deviceObj->meta_pwr_off = $urcDevice->meta_pwr_off;
		$deviceObj->meta_pwr_toggle = $urcDevice->meta_pwr_toggle;
		$deviceObj->meta_in_toggle = $urcDevice->meta_in_toggle;

		$deviceObj->repeat = new stdClass;
		$deviceObj->repeat->min = $urcDevice->repeat_min;
		$deviceObj->repeat->macro = $urcDevice->repeat_macro;
		
		$deviceObj->type = $urcDevice->target_type;
		if($deviceObj->type == URCValues::DB_TYPE_IP ||
			$deviceObj->type == URCValues::DB_TYPE_UDP) {

			$deviceObj->ramp = new stdClass;
			$deviceObj->ramp->start = $urcDevice->ramp_start;
			$deviceObj->ramp->speed = $urcDevice->ramp_speed;

			$deviceObj->attr = new stdClass;
			$deviceObj->attr->auto_cr = $urcDevice->auto_cr;
			$deviceObj->attr->con_time = $urcDevice->con_time;
			$deviceObj->attr->delay_after_send = $urcDevice->delay_after_send;
		}

		return $deviceObj;		
	}

	public function save($roomId, $deviceId, $name, &$errMsg) {

		$errMsg = '';

		$existingDevs = DB::table('a_c_devices')->where('owner', '=', $this->dealerId)->get();
		if(count($existingDevs) >= URCValues::MAX_CUSTOM_DEV_CNT) {
			$errMsg = "couldn't add the device(MAX:".URCValues::MAX_CUSTOM_DEV_CNT.")";
			return false;
		}

		if(!URCSystemData::isValidRoomForDealer($this->dealerGrpId, $roomId)) {
			$errMsg = "not valid for this dealer";
			return false;
		}

		try
		{
			DB::begintransaction();

			//device
			$urcDev = DB::table('a_devices')->where('id', '=', $deviceId)-> 
				where('room_id', '=', $roomId)->first();
			if(!$urcDev) {
				$errMsg = "could't find the device";
				throw new \Exception($errMsg);
			}
			unset($urcDev->room_id);
			/*
			if($customDevId >= 0) {
				
				//set
				$dbOrg = DB::table('a_c_devices')->where('owner', '=', $this->dealerId)->where('id', '=', $customDevId)->first();
				if(!$dbOrg) {

				}

				//delete existing custom device			
				$this->emptyDevice($customDevId);
			
				DB::table('a_c_devices')->where('id', '=', $customDevId)->update($urcDev);
			}
			else {
			*/
				
			//add custom device
			unset($urcDev->id);
			$urcDev->name = $name;
			$urcDev->owner = $this->dealerId;
			$urcDev->created_at = date('Y-m-d H:i:s');
			$customDevId = DB::table('a_c_devices')->insertGetId((array)$urcDev);
			//}
			if($customDevId < 0) {
				$errMsg = "couldn't add the device";
				throw new \Exception($errMsg);
			}

			//buttons
			$urcBtns = DB::table('a_btns')->where('device_id', '=', $deviceId)-> 
				where('room_id', '=', $roomId)->get();
			if(count($urcBtns) > 0) {
				$addedItems = array();
				foreach($urcBtns as $item) {
					unset($item->room_id);
					$item->device_id = $customDevId;
					$addedItems[] = (array)$item;					
				}
				DB::table('a_c_btns')->insert($addedItems);
			}

			//con dev
			$urcConDB = DB::table('a_con_db')->where('device_id', '=', $deviceId)-> 
				where('room_id', '=', $roomId)->get();
			if(count($urcConDB) > 0) {
				$addedItems = array();
				foreach($urcConDB as $item) {
					unset($item->room_id);
					$item->device_id = $customDevId;
					$addedItems[] = (array)$item;
				}
				DB::table('a_c_con_db')->insert($addedItems);
			}

			//key
			$urcKeyDB = DB::table('a_keys_db')->where('device_id', '=', $deviceId)-> 
				where('room_id', '=', $roomId)->get();
			if(count($urcKeyDB) > 0) {
				$addedItems = array();
				foreach($urcKeyDB as $item) {
					unset($item->room_id);
					$item->device_id = $customDevId;
					$addedItems[] = (array)$item;
				}
				DB::table('a_c_keys_db')->insert($addedItems);
			}

			DB::commit();
		}
		catch(\Exception $e) 
		{
			DB::rollback();
			if(strlen($errMsg) <= 0) {
				$errMsg = "can't create device";
			}
			return false;
		}

		return true;
	}

	public function saveFromTemplate($roomId, $deviceId, $name, &$errMsg) {

		$errMsg = '';

		$existingDevs = DB::table('a_c_devices')->where('owner', '=', $this->dealerId)->get();
		if(count($existingDevs) >= URCValues::MAX_CUSTOM_DEV_CNT) {
			$errMsg = "couldn't add the device(MAX:".URCValues::MAX_CUSTOM_DEV_CNT.")";
			return false;
		}

		if(!URCTRoomData::isValidRoom($this->dealerId, $roomId)) {
			$errMsg = "not valid for this dealer";
			return false;
		}

		try
		{
			DB::begintransaction();

			//device
			$urcDev = DB::table('a_t_devices')->where('id', '=', $deviceId)-> 
				where('room_id', '=', $roomId)->first();
			if(!$urcDev) {
				$errMsg = "could't find the device";
				throw new \Exception($errMsg);
			}
			unset($urcDev->room_id);
				
			//add custom device
			unset($urcDev->id);
			$urcDev->name = $name;
			$urcDev->owner = $this->dealerId;
			$urcDev->created_at = date('Y-m-d H:i:s');
			$customDevId = DB::table('a_c_devices')->insertGetId((array)$urcDev);
			//}
			if($customDevId < 0) {
				$errMsg = "couldn't add the device";
				throw new \Exception($errMsg);
			}

			//buttons
			$urcBtns = DB::table('a_t_btns')->where('device_id', '=', $deviceId)-> 
				where('room_id', '=', $roomId)->get();
			if(count($urcBtns) > 0) {
				$addedItems = array();
				foreach($urcBtns as $item) {
					unset($item->room_id);
					$item->device_id = $customDevId;
					$addedItems[] = (array)$item;					
				}
				DB::table('a_c_btns')->insert($addedItems);
			}

			//con dev
			$urcConDB = DB::table('a_t_con_db')->where('device_id', '=', $deviceId)-> 
				where('room_id', '=', $roomId)->get();
			if(count($urcConDB) > 0) {
				$addedItems = array();
				foreach($urcConDB as $item) {
					unset($item->room_id);
					$item->device_id = $customDevId;
					$addedItems[] = (array)$item;
				}
				DB::table('a_c_con_db')->insert($addedItems);
			}

			//key
			$urcKeyDB = DB::table('a_t_keys_db')->where('device_id', '=', $deviceId)-> 
				where('room_id', '=', $roomId)->get();
			if(count($urcKeyDB) > 0) {
				$addedItems = array();
				foreach($urcKeyDB as $item) {
					unset($item->room_id);
					$item->device_id = $customDevId;
					$addedItems[] = (array)$item;
				}
				DB::table('a_c_keys_db')->insert($addedItems);
			}

			DB::commit();
		}
		catch(\Exception $e) 
		{
			DB::rollback();
			if(strlen($errMsg) <= 0) {
				$errMsg = "can't create device";
			}
			return false;
		}

		return true;
	}
	
	public function delete($customDevId) {

		$dbData = DB::table('a_c_devices')->where('owner', '=', $this->dealerId)->where('id', '=', $customDevId)->first();
		if(!$dbData) {
			return false;
		}

		try
		{
			DB::begintransaction();

			DB::table('a_c_devices')->where('owner', '=', $this->dealerId)->where('id', '=', $customDevId)->delete();

			$this->emptyDevice($customDevId);

			DB::commit();
		}
		catch(\Exception $e) 
		{
			DB::rollback();
			return false;
		}

		return true;
	}

	public function copyDeviceInfo(&$urcCustomDev, $roomId, $name, $target, $attr) {

		$urcDev = new URCDeviceData($roomId);			

		$deviceId = $urcDev->getNewDeviceId();
		if($deviceId < 0)
			return -1;
		$urcDev->setNewDeviceId($deviceId+1);//DB::table('a_rooms')->where('id', '=', $roomId)->update(array('device_id_start' => $deviceId+1));
		
		//check already exist
		if($urcDev->isExistDevice($deviceId))
			return -1;

		$urcCustomDev->room_id = $roomId;
		$urcCustomDev->id = $deviceId;
		$urcCustomDev->name = $name;
		unset($urcCustomDev->owner);
		unset($urcCustomDev->created_at);

		$urcCustomDev->target_type = $target->type;
		$urcCustomDev->target_addr = $target->addr;
		$urcCustomDev->target_port = $target->port;
		$urcCustomDev->repeat_min = $attr->repeat_min;
		$urcCustomDev->repeat_macro = $attr->repeat_macro;
		if($target->type == URCValues::DB_TYPE_IP ||
			$target->type == URCValues::DB_TYPE_UDP) {
			$urcCustomDev->ramp_start = $attr->ramp_start;
			$urcCustomDev->ramp_speed = $attr->ramp_speed;
			$urcCustomDev->auto_cr = $attr->auto_cr;
		}
		
		//ErrorDebug::write('on:'.$metaPwrOn.'off:'.$metaPwrOff.'toggle:'.$metaPwrToggle.'in:'.$metaInToggle);
		
		//add
		DB::table('a_devices')->insert((array)$urcCustomDev);
		
		return $deviceId;
	}

	public function apply($customDevId, $roomId, $name, $target, $attr, $favOption, &$errMsg) {

		$urcCustomDev = DB::table('a_c_devices')->where('owner', '=', $this->dealerId)->where('id', '=', $customDevId)->first();
		if(!$urcCustomDev) {
			$errMsg = "can't find custom device";
			return false;
		}	

		if(!URCSystemData::isValidRoomForDealer($this->dealerGrpId, $roomId)) {
			$errMsg = "not valid for this dealer";
			return false;
		}
	
		try
		{
			DB::begintransaction();

			//device
			$deviceId = $this->copyDeviceInfo($urcCustomDev, $roomId, $name, $target, $attr);
			if($deviceId < 0) {
				$errMsg = "copy dev info error";
				throw new \Exception($errMsg);
			}				
			
			//btns
			$urcCustomBtns = DB::table('a_c_btns')->where('device_id', '=', $customDevId)->get();
			if(count($urcCustomBtns) > 0) {
				$addedItems = array();
				foreach($urcCustomBtns as $item) {
					$item->room_id = $roomId;
					$item->device_id = $deviceId;

					//ErrorDebug::write('org:'.$item->macro);					
					$macro = json_decode($item->macro);
					$actCnt = count($macro);
					for($actIdx = 0; $actIdx < $actCnt; $actIdx++) {
						//if($macro[$actIdx]->device_id == $customDevId) {
						$macro[$actIdx]->device_id = $deviceId;
						//}
						//else {
						//	ErrorDebug::write('unknown action');
						//}
					}
					$item->macro = json_encode($macro);					
					//ErrorDebug::write('chg:'.$item->macro);
					
					$addedItems[] = (array)$item;
				}
				DB::table('a_btns')->insert($addedItems);
			}

			//con dev
			$urcCustomConDB = DB::table('a_c_con_db')->where('device_id', '=', $customDevId)->get();
			if(count($urcCustomConDB) > 0) {
				$addedItems = array();
				foreach($urcCustomConDB as $item) {
					$item->room_id = $roomId;
					$item->device_id = $deviceId;
					$addedItems[] = (array)$item;
				}
				DB::table('a_con_db')->insert($addedItems);
			}

			//key
			$urcCustomKeyDB = DB::table('a_c_keys_db')->where('device_id', '=', $customDevId)->get();
			if(count($urcCustomKeyDB) > 0) {
				$addedItems = array();
				foreach($urcCustomKeyDB as $item) {
					$item->room_id = $roomId;
					$item->device_id = $deviceId;
					$addedItems[] = (array)$item;
				}
				DB::table('a_keys_db')->insert($addedItems);
			}

			$urcDev = new URCDeviceData($roomId);			
			if(!$urcDev->addMainBtn($name, $deviceId, $urcCustomDev->category)) {
				throw new \Exception('fail to add device button');
			}

			DB::commit();
		}
		catch(\Exception $e) 
		{
			DB::rollback();

			$errMsg = $e->getMessage();
			//ErrorDebug::write('dberr:'.$e->getMessage());
			return false;
		}

		return true;
	}

	public function copyDeviceInfoFromTemplate(&$urcCustomDev, $roomId, $name, $target, $attr) {

		$urcDev = new URCTDeviceData($roomId);			

		$deviceId = $urcDev->getNewDeviceId();
		if($deviceId < 0)
			return -1;
		$urcDev->setNewDeviceId($deviceId+1);//DB::table('a_rooms')->where('id', '=', $roomId)->update(array('device_id_start' => $deviceId+1));
		
		//check already exist
		if($urcDev->isExistDevice($deviceId))
			return -1;

		$urcCustomDev->room_id = $roomId;
		$urcCustomDev->id = $deviceId;
		$urcCustomDev->name = $name;
		unset($urcCustomDev->owner);
		unset($urcCustomDev->created_at);

		$urcCustomDev->target_type = $target->type;
		$urcCustomDev->target_addr = $target->addr;
		$urcCustomDev->target_port = $target->port;
		$urcCustomDev->repeat_min = $attr->repeat_min;
		$urcCustomDev->repeat_macro = $attr->repeat_macro;
		if($target->type == URCValues::DB_TYPE_IP ||
			$target->type == URCValues::DB_TYPE_UDP) {
			$urcCustomDev->ramp_start = $attr->ramp_start;
			$urcCustomDev->ramp_speed = $attr->ramp_speed;
			$urcCustomDev->auto_cr = $attr->auto_cr;
		}
		
		//ErrorDebug::write('on:'.$metaPwrOn.'off:'.$metaPwrOff.'toggle:'.$metaPwrToggle.'in:'.$metaInToggle);
		
		//add
		DB::table('a_t_devices')->insert((array)$urcCustomDev);
		
		return $deviceId;
	}

	public function applyToTemplate($customDevId, $roomId, $name, $target, $attr, $favOption, &$errMsg) {

		$urcCustomDev = DB::table('a_c_devices')->where('owner', '=', $this->dealerId)->where('id', '=', $customDevId)->first();
		if(!$urcCustomDev) {
			$errMsg = "can't find custom device";
			return false;
		}	

		if(!URCTRoomData::isValidRoom($this->dealerId, $roomId)) {
			$errMsg = "not valid for this dealer";
			return false;
		}

		try
		{
			DB::begintransaction();

			//device
			$deviceId = $this->copyDeviceInfoFromTemplate($urcCustomDev, $roomId, $name, $target, $attr);
			if($deviceId < 0) {
				$errMsg = "copy dev info error";
				throw new \Exception($errMsg);
			}				
			
			//btns
			$urcCustomBtns = DB::table('a_c_btns')->where('device_id', '=', $customDevId)->get();
			if(count($urcCustomBtns) > 0) {
				$addedItems = array();
				foreach($urcCustomBtns as $item) {
					$item->room_id = $roomId;
					$item->device_id = $deviceId;

					//ErrorDebug::write('org:'.$item->macro);					
					$macro = json_decode($item->macro);
					$actCnt = count($macro);
					for($actIdx = 0; $actIdx < $actCnt; $actIdx++) {
						//if($macro[$actIdx]->device_id == $customDevId) {
						$macro[$actIdx]->device_id = $deviceId;
						//}
						//else {
						//	ErrorDebug::write('unknown action');
						//}
					}
					$item->macro = json_encode($macro);					
					//ErrorDebug::write('chg:'.$item->macro);
					
					$addedItems[] = (array)$item;
				}
				DB::table('a_t_btns')->insert($addedItems);
			}

			//con dev
			$urcCustomConDB = DB::table('a_c_con_db')->where('device_id', '=', $customDevId)->get();
			if(count($urcCustomConDB) > 0) {
				$addedItems = array();
				foreach($urcCustomConDB as $item) {
					$item->room_id = $roomId;
					$item->device_id = $deviceId;
					$addedItems[] = (array)$item;
				}
				DB::table('a_t_con_db')->insert($addedItems);
			}

			//key
			$urcCustomKeyDB = DB::table('a_c_keys_db')->where('device_id', '=', $customDevId)->get();
			if(count($urcCustomKeyDB) > 0) {
				$addedItems = array();
				foreach($urcCustomKeyDB as $item) {
					$item->room_id = $roomId;
					$item->device_id = $deviceId;
					$addedItems[] = (array)$item;
				}
				DB::table('a_t_keys_db')->insert($addedItems);
			}

			$urcDev = new URCTDeviceData($roomId);			
			if(!$urcDev->addMainBtn($name, $deviceId, $urcCustomDev->category)) {
				throw new \Exception('fail to add device button');
			}

			DB::commit();
		}
		catch(\Exception $e) 
		{
			DB::rollback();

			$errMsg = $e->getMessage();
			//ErrorDebug::write('dberr:'.$e->getMessage());
			return false;
		}

		return true;
	}

	public function emptyDevice($customDevId) {

		//delete connected Device 
		DB::table('a_c_keys_db')->where('device_id', '=', $customDevId)->delete();

		//delete keyboard data
		DB::table('a_c_con_db')->where('device_id', '=', $customDevId)->delete();
		
		DB::table('a_c_btns')->where('device_id', '=', $customDevId)->delete();
	}


}
