<?php
if (!defined("ROOT_PATH"))
{
	header("HTTP/1.1 403 Forbidden");
	exit;
}
class pjFrontPublic extends pjFront
{	
	public function __construct()
	{
		parent::__construct();
		
		$this->setAjax(true);
		
		$this->setLayout('pjActionEmpty');
	}
	
	public function pjActionCheckEmail()
	{
	    $this->setAjax(true);
	    if ($this->isXHR())
	    {
	        if (!$this->_get->check('c_email'))
	        {
	            echo 'false';
	            exit;
	        }
	        $c_email = $this->_get->toString('c_email');
	        if(empty($c_email))
	        {
	            echo 'false';
	            exit;
	        }
	        $pjAuthUserModel = pjAuthUserModel::factory()
	        	->join('pjClient', 't1.id=t2.foreign_id', 'left outer')
	        	->where('t1.email', $c_email);
	    	if ($this->isFrontLogged())
	        {
	            $pjAuthUserModel->where('t1.id !=', $this->getClientId());
	        }
	        echo $pjAuthUserModel->findCount()->getData() == 0 ? 'true' : 'false';
	    }
	    exit;
	}
	
	public function pjActionCheckout()
	{
		if ($this->isXHR() || $this->_get->check('_escaped_fragment_'))
		{
		    if ($this->_post->check('step_checkout'))
			{
			    if ((int) $this->option_arr['o_bf_captcha'] === 3 && $this->option_arr['o_captcha_type_front'] == 'system' && (!$this->_post->check('captcha')  || ($this->_post->check('captcha') && $this->_post->isEmpty('captcha')) || ($this->_post->check('captcha') && !pjCaptcha::validate(strtoupper($this->_post->toString('captcha')), $_SESSION[$this->defaultCaptcha])) ))
				{
					pjAppController::jsonResponse(array('status' => 'ERR', 'code' => 105, 'text' => __('system_105', true)));
				}
				$_SESSION[$this->defaultStore]['form'] = $this->_post->raw();
				$_SESSION[$this->defaultStore]['step_checkout'] = 1;
				
				pjAppController::jsonResponse(array('status' => 'OK', 'code' => 200, 'text' => __('system_200', true)));
			} else {
			    $cid = $this->_get->toInt('cid');
				$isRoomSelected = isset($_SESSION[$this->defaultStore], $_SESSION[$this->defaultStore]['all_rooms']) && !empty($_SESSION[$this->defaultStore]['all_rooms']);
				$isBookingAccepted = (int) $this->option_arr['o_accept_bookings'] === 1;
				$isAvailable = $this->pjActionCheckAvailability($cid);
				if ($isRoomSelected && $isBookingAccepted && $isAvailable)
				{
					$this->set('country_arr', pjBaseCountryModel::factory()
						->select('t1.*, t2.content AS name')
						->join('pjBaseMultiLang', "t2.model='pjBaseCountry' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
						->where('t1.status', 'T')
						->orderBy('`name` ASC')
						->findAll()
						->getData()
					);
					
					$this->set('room_arr', pjRoomModel::factory()
						->select('t1.*, t2.content AS name')
						->join('pjMultiLang', "t2.model='pjRoom' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
						->whereIn('t1.id', array_keys($_SESSION[$this->defaultStore]['all_rooms']))
					    ->where('t1.calendar_id', $cid)
						->findAll()
						->getDataPair('id')
					);
					
					$this->set('extra_arr', pjExtraModel::factory()
						->select('t1.*, t2.content AS name')
						->join('pjMultiLang', "t2.model='pjExtra' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
					    ->where('t1.calendar_id', $cid)
						->where('t1.status', 'T')
						->findAll()
						->getData()
					);
					
					$STORE = $_SESSION[$this->defaultStore];
					$session_prices = $this->calPrices($STORE['all_rooms'], $STORE['date_from'], $STORE['date_to'], @$_SESSION[$this->defaultVoucher], isset($STORE['extras']) ? $STORE['extras'] : array(), $STORE['_nights'], $this->option_arr, 'front');
					$this->set('session_prices', $session_prices);
					
					$this->set('calendar_arr', pjCalendarModel::factory()
							->select('t1.*, t2.content AS terms_url, t3.content AS terms_body')
							->join('pjMultiLang', "t2.model='pjCalendar' AND t2.foreign_id=t1.id AND t2.field='terms_url' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
							->join('pjMultiLang', "t3.model='pjCalendar' AND t3.foreign_id=t1.id AND t3.field='terms_body' AND t3.locale='".$this->getLocaleId()."'", 'left outer')
					    ->find($cid)
							->getData()
					);
					
					if (isset($_SESSION[$this->defaultStore]['step_search']) && isset($_SESSION[$this->defaultStore]['step_rooms']))
					{
						$_SESSION[$this->defaultStore]['step_extras'] = 1;
					}
					$this->set('status', 'OK');
				} else {
					$this->set('status', 'ERR');
					switch (FALSE)
					{
						case $isRoomSelected:
							$this->set('code', 108)->set('text', __('system_108', true));
							break;
						case $isBookingAccepted:
							$this->set('code', 109)->set('text', __('system_109', true));
							break;
						case $isAvailable:
							$this->set('code', 110)->set('text', __('system_110', true));
							break;
					}
				}
				
				if(pjObject::getPlugin('pjPayments') !== NULL)
				{
				    $this->set('payment_option_arr', pjPaymentOptionModel::factory()->getOptions($this->getForeignId()));
				    $this->set('payment_titles', pjPayments::getPaymentTitles($this->getForeignId(), $this->getLocaleId()));
				}else{
				    $this->set('payment_titles', __('payment_methods', true));
				}
				
				$bank_account = pjMultiLangModel::factory()
				->select('t1.content')
				->where('t1.model','pjOption')
				->where('t1.locale', $this->getLocaleId())
				->where('t1.field', 'o_bank_account')
				->limit(1)
				->findAll()->getDataIndex(0);
				$this->set('bank_account', $bank_account ? $bank_account['content'] : '');
			}
		}
	}
	
	public function pjActionExtras()
	{
		if ($this->isXHR() || $this->_get->check('_escaped_fragment_'))
		{
			$_rooms = $_adults = $_children = 0;
			$cid = $this->_get->toInt('cid');
			if (isset($_SESSION[$this->defaultStore]) &&
				isset($_SESSION[$this->defaultStore]['all_rooms']) &&
				!empty($_SESSION[$this->defaultStore]['all_rooms']) &&
				(int) $this->option_arr['o_accept_bookings'] === 1 &&
			    $this->pjActionCheckAvailability($cid))
			{
				
			    $dateFrom = new DateTime($_SESSION[$this->defaultStore]['date_from']);
			    $dateTo = new DateTime($_SESSION[$this->defaultStore]['date_to']);
			    $num_nights= $dateTo->diff($dateFrom)->format("%a"); 
				if ($this->option_arr['o_price_based_on'] == 'days')
				{
					$num_nights += 1;
				}
				$_SESSION[$this->defaultStore]['_nights'] = $num_nights;
				
				
				$rooms_price_stack = array();
				foreach ($_SESSION[$this->defaultStore]['all_rooms'] as $room_id => $room_arr)
				{
					$rooms_price_stack[$room_id] = array();
					foreach ($room_arr as $index => $room_info)
					{
						$_rooms += 1;
						$_adults += $room_info['adults'];
						$_children += $room_info['children'];
					}
				}

				$_SESSION[$this->defaultStore]['_rooms'] = $_rooms;
				$_SESSION[$this->defaultStore]['_persons'] = $_adults + $_children;
				$_SESSION[$this->defaultStore]['_adults'] = $_adults;
				$_SESSION[$this->defaultStore]['_children'] = $_children;
				$_SESSION[$this->defaultStore]['step_rooms'] = 1;
				
				$STORE = $_SESSION[$this->defaultStore];
				$session_prices = $this->calPrices($STORE['all_rooms'], $STORE['date_from'], $STORE['date_to'], @$_SESSION[$this->defaultVoucher], isset($STORE['extras']) ? $STORE['extras'] : array(), $STORE['_nights'], $this->option_arr, 'front');
				$this->set('session_prices', $session_prices);
				
				$this->set('room_arr', pjRoomModel::factory()
					->select('t1.*, t2.content AS name')
					->join('pjMultiLang', "t2.model='pjRoom' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
					->whereIn('t1.id', array_keys($_SESSION[$this->defaultStore]['all_rooms']))
				    ->where('t1.calendar_id', $cid)
					->findAll()
					->getDataPair('id')
				);
				
				$this->set('extra_arr', pjExtraModel::factory()
					->select('t1.*, t2.content AS name')
					->join('pjMultiLang', "t2.model='pjExtra' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
				    ->where('t1.calendar_id', $cid)
					->where('t1.status', 'T')
					->findAll()
					->getData()
				);
				
				$this->set('status', 'OK');
			} else {
				$this->set('status', 'ERR')->set('code', 101)->set('text', __('system_101', true));
			}
		}
	}
	
	public function pjActionPreview()
	{
	    if ($this->isXHR() || $this->_get->check('_escaped_fragment_'))
	    {
			if (isset($_SESSION[$this->defaultStore]['form']['c_country']) && (int) $_SESSION[$this->defaultStore]['form']['c_country'] > 0)
			{
				$this->set('country_arr', pjBaseCountryModel::factory()
					->select('t1.*, t2.content AS name')
					->join('pjBaseMultiLang', "t2.model='pjBaseCountry' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
					->find($_SESSION[$this->defaultStore]['form']['c_country'])
					->getData()
				);
			}
			$cid = $this->_get->toInt('cid');
			if (isset($_SESSION[$this->defaultStore]) && isset($_SESSION[$this->defaultStore]['step_checkout']) &&
				isset($_SESSION[$this->defaultStore]['all_rooms']) &&
				!empty($_SESSION[$this->defaultStore]['all_rooms']) &&
				(int) $this->option_arr['o_accept_bookings'] === 1 &&
			    $this->pjActionCheckAvailability($cid))
			{
				
				$dateFrom = new DateTime($_SESSION[$this->defaultStore]['date_from']);
				$dateTo = new DateTime($_SESSION[$this->defaultStore]['date_to']);
				$num_nights= $dateTo->diff($dateFrom)->format("%a");
				if ($this->option_arr['o_price_based_on'] == 'days')
				{
					$num_nights += 1;
				}
				$_SESSION[$this->defaultStore]['_nights'] = $num_nights;
									
				$this->set('status', 'OK');

				$this->set('room_arr', pjRoomModel::factory()
					->select(sprintf("t1.*, t2.content AS `name`,
						(SELECT `small_path` FROM `%1\$s` WHERE `foreign_id` = t1.id ORDER BY `sort` ASC LIMIT 1) AS `image`
						", pjGalleryModel::factory()->getTable()))
					->join('pjMultiLang', "t2.model='pjRoom' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
					->whereIn('t1.id', array_keys($_SESSION[$this->defaultStore]['all_rooms']))
				    ->where('t1.calendar_id', $cid)
					->findAll()
					->getDataPair('id')
				);
				
				$STORE = $_SESSION[$this->defaultStore];
				$session_prices = $this->calPrices($STORE['all_rooms'], $STORE['date_from'], $STORE['date_to'], @$_SESSION[$this->defaultVoucher], isset($STORE['extras']) ? $STORE['extras'] : array(), $STORE['_nights'], $this->option_arr, 'front');
				$this->set('session_prices', $session_prices);
				
				if(pjObject::getPlugin('pjPayments') !== NULL)
				{
				    $this->set('payment_titles', pjPayments::getPaymentTitles($this->getForeignId(), $this->getLocaleId()));
				}else{
				    $this->set('payment_titles', __('payment_methods', true));
				}
				$bank_account = pjMultiLangModel::factory()->select('t1.content')
	                    ->where('t1.model','pjOption')
	                    ->where('t1.locale', $this->getLocaleId())
	                    ->where('t1.field', 'o_bank_account')
	                    ->limit(1)
	                    ->findAll()->getDataIndex(0);
				$this->set('bank_account', $bank_account ? $bank_account['content'] : '');
			} else {
				$this->set('status', 'ERR')->set('code', 103)->set('text', __('system_103', true));
			}
		}
	}
	
	public function pjActionRooms()
	{
		if ($this->isXHR() || $this->_get->check('_escaped_fragment_'))
		{
		    if ($this->_get->check('date_from') && $this->_get->check('date_to') && $this->_get->check('guests'))
			{
			    if($this->option_arr['o_price_based_on'] == "nights" && $this->_get->toString('date_from') == $this->_get->toString('date_to'))
				{
					$this->set('status', 'ERR')->set('code', 132)->set('text', __('system_132', true));
				}else{
				    $date_from = pjDateTime::formatDate($this->_get->toString('date_from'), $this->option_arr['o_date_format']);
				    $date_to = pjDateTime::formatDate($this->_get->toString('date_to'), $this->option_arr['o_date_format']);
				    $guests = $this->_get->toInt('guests');
					
				    if($this->session->has($this->defaultStore))
				    {
				        $STORE = $this->session->getData($this->defaultStore);
				        if (isset($STORE['date_from']) && isset($STORE['date_to']) && isset($STORE['guests']) && ($STORE['date_from'] != $date_from || $STORE['date_to'] != $date_to ||$STORE['guests'] != $guests))
				        {
				            $this->session->setData($this->defaultStore, array());
				            $this->session->setData($this->defaultVoucher, array());
				        }
				    }else{
				        $this->session->setData($this->defaultStore, array());
				    }
				    $STORE = $this->session->getData($this->defaultStore);
				    $STORE['date_from'] = $date_from;
				    $STORE['date_to'] = $date_to;
				    $STORE['guests'] = $guests;
				    $STORE['step_search'] = 1;
				    $this->session->setData($this->defaultStore, $STORE);
				    $STORE = $this->session->getData($this->defaultStore);
				    
				    $dateFrom = new DateTime($STORE['date_from']);
				    $dateTo = new DateTime($STORE['date_to']);
				    $num_nights= $dateTo->diff($dateFrom)->format("%a");
					if ($this->option_arr['o_price_based_on'] == 'days')
					{
						$num_nights += 1;
					}
					$STORE['_nights'] = $num_nights;
					$STORE['_start_on'] = date("w", strtotime($date_from));
					$this->session->setData($this->defaultStore, $STORE);
					
					$nightMode = $this->option_arr['o_price_based_on'] == "nights";
					$cid = $this->_get->toInt('cid');
					$guests = $this->_get->toInt('guests');
					$pjRoomModel = pjRoomModel::factory();
					$arr = $pjRoomModel
						->select(sprintf("t1.*, t2.content AS `name`, t3.content AS `description`,
							(SELECT `medium_path` FROM `%1\$s` WHERE `foreign_id` = `t1`.`id` ORDER BY `sort` ASC LIMIT 1) AS `image`,
							(SELECT GROUP_CONCAT(COALESCE(`small_path`, '') ORDER BY `sort` ASC SEPARATOR '~:~') FROM `%1\$s` WHERE `foreign_id` = `t1`.`id` GROUP BY `foreign_id` LIMIT 3) AS `gallery`,
							(SELECT GROUP_CONCAT(COALESCE(`medium_path`, '') ORDER BY `sort` ASC SEPARATOR '~:~') FROM `%1\$s` WHERE `foreign_id` = `t1`.`id` GROUP BY `foreign_id` LIMIT 3) AS `medium`,
							(SELECT GROUP_CONCAT(COALESCE(`large_path`, '') ORDER BY `sort` ASC SEPARATOR '~:~') FROM `%1\$s` WHERE `foreign_id` = `t1`.`id` GROUP BY `foreign_id` LIMIT 3) AS `large`,
							(SELECT GROUP_CONCAT(COALESCE(`alt`, '') ORDER BY `sort` ASC SEPARATOR '~:~') FROM `%1\$s` WHERE `foreign_id` = `t1`.`id` GROUP BY `foreign_id` LIMIT 3) AS `alt`,
							(SELECT MIN(LEAST(`mon`, `tue`, `wed`, `thu`, `fri`, `sat`, `sun`)) FROM `%2\$s` AS `TP` WHERE `foreign_id` = `t1`.`id` AND ((`TP`.date_from <= '$date_to' ANd `TP`.date_to >= '$date_from') OR ( (`TP`.date_from IS NULL) OR (`TP`.date_to IS NULL) )) LIMIT 1) AS `price_from`
							",
							pjGalleryModel::factory()->getTable(),
							pjPriceModel::factory()->getTable()
						))
						->join('pjMultiLang', "t2.model='pjRoom' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
						->join('pjMultiLang', "t3.model='pjRoom' AND t3.foreign_id=t1.id AND t3.field='description' AND t3.locale='".$this->getLocaleId()."'", 'left outer')
						->where('t1.id > 0')
						->where('t1.calendar_id', $cid)
						->where('t1.max_people * t1.cnt >=', $guests)
						->findAll()
						->toArray('gallery', '~:~')
						->toArray('medium', '~:~')
						->toArray('large', '~:~')
						->toArray('alt', '~:~')
						->getData();
					# --
					$pjBookingRoomModel = pjBookingRoomModel::factory();
					if ($this->option_arr['o_allow_pending_time'] == 1) {
						$hours = $this->option_arr['o_pending_time'] / 60;
						$remainder = $this->option_arr['o_pending_time'] % 60;
						if ($remainder === 0)
						{
							$pending_time = sprintf("%u:00:00", $hours);
						} else {
							$pending_time = sprintf("%u:%u:00", $hours, $remainder);
						}
						$cond = "t2.status = 'pending' AND t2.created >= SUBTIME(NOW(), '".$pjBookingRoomModel->escapeStr($pending_time)."')";
					} else {
						$cond = "t2.status = 'pending'";
					}
					$tmp = $pjBookingRoomModel
						->select("t1.*, t2.date_from, t2.date_to")
						->join('pjBooking', sprintf("t2.id=t1.booking_id AND (t2.status = 'confirmed' OR (%5\$s)) AND t2.date_from %3\$s '%2\$s' AND t2.date_to %4\$s '%1\$s'",
							$pjRoomModel->escapeStr($date_from),
							$pjRoomModel->escapeStr($date_to),
							$nightMode ? "<" : "<=",
							$nightMode ? ">" : ">=",
							$cond), 'inner')
						->findAll()
						->getData();
					$sum = array();
					$init = array();
					$dt_from = strtotime($date_from);
					$dt_to = strtotime($date_to);
					for ($i = $dt_from; $i <= $dt_to; $i += 86400)
					{
						$init[date("Y-m-d", $i)] = 0;
					}
					
					foreach ($tmp as $value)
					{
						if (!isset($sum[$value["room_id"]]))
						{
							$sum[$value["room_id"]] = $init;
						}
						$from = strtotime($value["date_from"]);
						$to = strtotime($value["date_to"]);
						for ($z = $from; $z <= $to; $z += 86400)
						{
							if (($z >= $dt_from && $z <= $dt_to) === FALSE)
							{
								continue;
							}
							if ($z == $to && $nightMode)
							{
								continue;
							}
							
							$iso = date("Y-m-d", $z);
							$sum[$value["room_id"]][$iso] += 1;
						}
					}
					# Restrictions
					$restrictions = pjRestrictionRoomModel::factory()
						->select('t1.room_number_id, t3.room_id')
						->join('pjRestriction', "t2.id=t1.restriction_id", 'inner')
						->join('pjRoomNumber', "t3.id=t1.room_number_id", 'inner')
						->join('pjRoom', "t4.id=t3.room_id", 'inner')
						->where(sprintf('t2.date_from %s', $nightMode ? "<" : "<="), $date_to)
						->where(sprintf('t2.date_to %s', $nightMode ? ">" : ">="), $date_from)
						->groupBy('t1.room_number_id, t3.room_id')
						->findAll()
						->getData();
					$restriction_arr = array();
					foreach ($restrictions as $v) {
						if (!isset($restriction_arr[$v['room_id']])) {
							$restriction_arr[$v['room_id']] = 0;
						}
						$restriction_arr[$v['room_id']] += 1;
					}
					foreach ($arr as $k => $room)
					{
						$arr[$k]['max_bookings'] = isset($sum[$room['id']]) && !empty($sum[$room['id']]) ? ceil(max($sum[$room['id']])) : 0;
						$arr[$k]['unavailable_cnt'] = isset($restriction_arr[$room['id']]) ? (int) $restriction_arr[$room['id']] : 0;
						$arr[$k]['real_price_from'] = $this->getRoomPrice(
								$room['id'],
								$date_from,
								$date_to,
								($this->option_arr['o_price_based_on'] == 'nights'),
								null,
								null
						);
					}
					# --
	
					$limit_arr = array();
					if (!empty($date_to) && !empty($date_from))
					{
						 $limit_arr = pjLimitModel::factory()
							->where('t1.date_from <=', $date_to)
							->where('t1.date_to >=', $date_from)
							->findAll()
							->getData();
					}
					$this->set('limit_arr', $limit_arr);
						
					$this->set('arr', $arr)->set('status', 'OK');
				}
			} else {
				$this->set('status', 'ERR')->set('code', 100)->set('text', __('system_100', true));
			}
		}
	}
	
	public function pjActionRouter()
	{
		$this->setAjax(false);

		if ($this->_get->check('_escaped_fragment_'))
		{
			$templates = array('Search', 'Rooms', 'Extras', 'Checkout', 'Preview', 'Booking');
			preg_match('/^\/(\w+).*/', $this->_get->toString('_escaped_fragment_'), $m);
			if (isset($m[1]) && in_array($m[1], $templates))
			{
				$template = 'pjAction'.$m[1];
			
				if (method_exists($this, $template))
				{
					$this->$template();
				}
				$this->setTemplate('pjFrontPublic', $template);
			}
		}
	}
	
	public function pjActionSearch()
	{
		if ($this->isXHR() || $this->_get->check('_escaped_fragment_'))
		{
			
		}
	}
	
	public function pjActionBooking()
	{
	    if ($this->isXHR() || $this->_get->check('_escaped_fragment_'))
	    {
	        $booking_arr = pjBookingModel::factory()
	        ->where('t1.uuid', $this->_get->toString('uuid'))
	        ->limit(1)
	        ->findAll()
	        ->getDataIndex(0);
	        
	        if ($booking_arr !== FALSE && !empty($booking_arr))
	        {
	            if(pjObject::getPlugin('pjPayments') !== NULL)
	            {
	                $pjPlugin = pjPayments::getPluginName($booking_arr['payment_method']);
	                if(pjObject::getPlugin($pjPlugin) !== NULL)
	                {
	                    $params = $pjPlugin::getFormParams(array('payment_method' => $booking_arr['payment_method']), array(
	                        'locale_id'	    => $this->getLocaleId(),
	                        'return_url'	=> $this->option_arr['o_thankyou_page'],
	                        'id'			=> $booking_arr['id'],
	                        'foreign_id'	=> $this->getForeignId(),
	                        'uuid'		    => $booking_arr['uuid'],
	                        'name'		    => @$booking_arr['c_name'],
	                        'email'		    => @$booking_arr['c_email'],
	                        'phone'		    => @$booking_arr['c_phone'],
	                        'amount'		=> $booking_arr['deposit'],
	                        'cancel_hash'   => sha1($booking_arr['uuid'].strtotime($booking_arr['created']).PJ_SALT),
	                        'currency_code' => $this->option_arr['o_currency'],
	                    ));
	                    $params['option_foreign_id'] = $this->getForeignId(); 
	                    $this->set('params', $params);
	                }
	                
	                if ($booking_arr['payment_method'] == 'bank')
	                {
	                    $bank_account = pjMultiLangModel::factory()->select('t1.content')
	                    ->where('t1.model','pjOption')
	                    ->where('t1.locale', $this->getLocaleId())
	                    ->where('t1.field', 'o_bank_account')
	                    ->limit(1)
	                    ->findAll()->getDataIndex(0);
	                    $this->set('bank_account', $bank_account['content']);
	                }
	            }
	            
	            $this->set('booking_arr', $booking_arr);
	        }
		}
	}
	
	public function pjActionLogin()
	{
	    if ($this->isXHR() || $this->_get->check('_escaped_fragment_'))
	    {
	        if($this->_post->check('hb_login'))
	        {
	            $data = array();
	            $data['login_email'] = $this->_post->toString('login_email');
	            $data['login_password'] = $this->_post->toString('login_password');
	            $response = pjFrontClient::init($data)->doClientLogin();
	            $code = (int) $response['code'];
	            $login_err = __('plugin_base_login_err', true);
	            $text = '';
	            if(isset($login_err[$code]))
	            {
	                if($code == 5)
	                {
	                    $text = sprintf($login_err[$code], (int)$this->option_arr['o_failed_login_lock_after']);
	                }else{
	                    $text = $login_err[$code];
	                }
	            }
	            pjAppController::jsonResponse(array('status' => $response['status'], 'code' => $code, 'text' => $text));
	        }
	    }
	}
	public function pjActionLogout()
	{
	    if ($this->isXHR())
	    {
	        if($this->isFrontLogged())
	        {
	            $this->session->unsetData($this->defaultClient);
	        }
	        pjAppController::jsonResponse(array('status' => 'OK', 'code' => 200, 'text' => ''));
	    }
	    exit;
	}
	public function pjActionProfile()
	{
	    if ($this->isXHR() || $this->_get->check('_escaped_fragment_'))
	    {
	        if(self::isPost() && $this->_post->check('hb_profile'))
	        {
	            $pjClientModel = pjClientModel::factory();
	            $foreign_id = $this->_post->toInt('foreign_id');
	            $client = $pjClientModel->where('foreign_id', $foreign_id)->findAll()->getDataIndex(0);
	            $post = $this->_post->raw();
	            $pjClientModel->reset()->where('id', $client['id'])->limit(1)->modifyAll($post);	            
	            $data = array();
	            $data['email'] = isset($post['c_email']) ? $post['c_email'] : ":NULL";
	            $data['password'] = isset($post['c_password']) ? $post['c_password'] : ":NULL";
	            $data['name'] = isset($post['c_name']) ? $post['c_name'] : ":NULL";
             	$data['phone'] = isset($post['c_phone']) ? $post['c_phone'] : ":NULL";	            
	            pjAuthUserModel::factory()->set('id', $foreign_id)->modify($data);
	            pjFrontClient::init(array('id' => $foreign_id))->setClientSession();
	            pjAppController::jsonResponse(array('status' => 'OK', 'code' => 200, 'text' => __('front_update_profile_msg', true)));
	        }else{
	            $this->set('country_arr', pjBaseCountryModel::factory()
                ->select('t1.*, t2.content AS name')
                ->join('pjBaseMultiLang', "t2.model='pjBaseCountry' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
                ->where('t1.status', 'T')
                ->orderBy('`name` ASC')
                ->findAll()
                ->getData()
                );
	        }
	    }
	}
	public function pjActionForgot()
	{
	    if ($this->isXHR() || $this->_get->check('_escaped_fragment_'))
	    {
	        if(self::isPost() && $this->_post->check('hb_forgot'))
	        {
	            $params = array();
	            $params['locale_id'] = $this->getLocaleId();
	            $params['email'] = $this->_post->toString('email');
	            $resp = pjFrontClient::init($params)->doSendPassword();
	            $forgot_messages = __('forgot_messages', true, false);
	            $resp['text'] = $forgot_messages[$resp['code']];
	            pjAppController::jsonResponse($resp);
	        }
	    }
	}
	
	public function pjActionCancel()
	{
	    if ($this->isXHR() || $this->_get->check('_escaped_fragment_'))
	    {
	        if(self::isPost())
	        {
	        	$cancel_err = __('cancel_err', true);
	            if ($this->_post->check('booking_cancel'))
	            {
	                $pjBookingModel = pjBookingModel::factory();
	                $booking_id = $this->_post->toInt('id');
	                $booking_arr = $pjBookingModel
	                ->select('t1.*, t2.content AS `country`, t3.content AS `cancel_subject_admin`, t4.content AS `cancel_tokens_admin`')
	                ->join('pjMultiLang', "t2.model='pjBaseCountry' AND t2.foreign_id=t1.c_country AND t2.locale=t1.locale_id AND t2.field='name'", 'left outer')
	                ->join('pjMultiLang', "t3.model='pjCalendar' AND t3.foreign_id=t1.calendar_id AND t3.field='cancel_subject_admin' AND t3.locale=t1.locale_id", 'left outer')
	                ->join('pjMultiLang', "t4.model='pjCalendar' AND t4.foreign_id=t1.calendar_id AND t4.field='cancel_tokens_admin' AND t4.locale=t1.locale_id", 'left outer')
	                ->find($booking_id)
	                ->getData();
	                if (!empty($booking_arr))
	                {
	                    if($booking_arr['status'] == 'cancelled')
	                    {
	                        self::jsonResponse(array('status' => 'ERR', 'code' => 102, 'text' => $cancel_err[4]));
	                    }
	                    $pjBookingModel
	                    ->reset()
	                    ->where(sprintf("SHA1(CONCAT(`id`, `created`, '%s')) = ", PJ_SALT), $this->_post->toString('hash'))
	                    ->limit(1)
	                    ->modifyAll(array('status' => 'cancelled'));
	                    
	                    $pjBookingExtraModel = pjBookingExtraModel::factory();
	                    $pjBookingRoomModel= pjBookingRoomModel::factory();
	                    $booking_arr['extras'] = $pjBookingExtraModel
	                    ->select('t1.*, t2.content AS `name`')
	                    ->join('pjMultiLang', "t2.model='pjExtra' AND t2.foreign_id=t1.extra_id AND t2.field='name' AND t2.locale='".$booking_arr['locale_id']."'", 'left join')
	                    ->where('t1.booking_id', $booking_id)
	                    ->findAll()
	                    ->getData();
	                    
	                    $booking_arr['rooms'] = $pjBookingRoomModel
	                    ->reset()
	                    ->select('t1.*, (SELECT COUNT(*) FROM `'.$pjBookingRoomModel->getTable().'` WHERE `booking_id`=t1.booking_id) AS `cnt`, t2.content AS `name`')
	                    ->join('pjMultiLang', "t2.model='pjRoom' AND t2.foreign_id=t1.room_id AND t2.field='name' AND t2.locale='".$booking_arr['locale_id']."'", 'left join')
	                    ->where('t1.booking_id', $booking_id)
	                    ->findAll()
	                    ->getData();
	                        
                        pjFront::pjActionConfirmSend($this->option_arr, $booking_arr, 'cancel', $booking_arr['locale_id']);
                        
                        self::jsonResponse(array('status' => 'OK', 'code' => 200, 'text' => $cancel_err[5]));
	                }else{
	                    self::jsonResponse(array('status' => 'ERR', 'code' => 101, 'text' => $cancel_err[2]));
	                }
	            }else{
	                self::jsonResponse(array('status' => 'ERR', 'code' => 100, 'text' => $cancel_err[1]));
	            }
	        }
	        if(self::isGet())
	        {
	            if ($this->_get->check('hash') && $this->_get->check('id') &&  $this->_get->toInt('id') > 0)
	            {
	                $pjBookingModel = pjBookingModel::factory();
	                $get_hash = $this->_get->toString('hash');
	                $id = $this->_get->toInt('id');
	                $arr = $pjBookingModel
	                ->select("t1.*, t2.content AS `country_title`")
	                ->join('pjMultiLang', "t2.model='pjBaseCountry' AND t2.foreign_id=t1.c_country AND t2.field='name' AND t2.locale=" . $this->getLocaleId(), 'left outer')
	                ->find($id)
	                ->getData();
	                if (empty($arr))
	                {
	                    $this->set('status', 2);
	                } else {
	                    if ($arr['status'] == 'cancelled')
	                    {
	                        $this->set('status', 4);
	                    } else {
	                        $hash = sha1($arr['id'] . $arr['created'] . PJ_SALT);
	                        if ($get_hash != $hash)
	                        {
	                            $this->set('status', 3);
	                        } else {
	                            
	                            $room_arr = pjBookingRoomModel::factory()
	                            ->select('t1.*, t2.content AS `name`')
	                            ->join('pjMultiLang', sprintf("t2.model='pjRoom' AND t2.foreign_id=t1.room_id AND t2.field='name' AND t2.locale='%u'", $this->getLocaleId()), 'left outer')
	                            ->join('pjRoom', 't3.id=t1.room_id', 'inner')
	                            ->where('t1.booking_id', $arr['id'])
	                            ->findAll()
	                            ->getData();
	                            
	                            $_rooms = $_adults = $_children = 0;
	                            
	                            $dateFrom = new DateTime($arr['date_from']);
	                            $dateTo = new DateTime($arr['date_to']);
	                            $num_nights= $dateTo->diff($dateFrom)->format("%a");
	                            
	                            if ($this->option_arr['o_price_based_on'] == 'days')
	                            {
	                                $num_nights += 1;
	                            }
	                            
	                            foreach ($room_arr as $room)
	                            {
	                                $_rooms += 1;
	                                $_adults += $room['adults'];
	                                $_children += $room['children'];
	                            }
	                            
	                            $arr['_nights'] = $num_nights;
	                            $arr['_persons'] = $_adults + $_children;
	                            $arr['_rooms'] = $_rooms;
	                            
	                            $arr['room_arr'] = array();
	                            foreach ($room_arr as $room)
	                            {
	                                if (!isset($arr['room_arr'][$room['room_id']]))
	                                {
	                                    $arr['room_arr'][$room['room_id']] = array();
	                                }
	                                $arr['room_arr'][$room['room_id']][] = $room;
	                            }
	                            
	                            $arr['extra_arr'] = pjBookingExtraModel::factory()
	                            ->select('t1.*, t2.content AS `name`, t3.per')
	                            ->join('pjMultiLang', sprintf("t2.model='pjExtra' AND t2.foreign_id=t1.extra_id AND t2.field='name' AND t2.locale='%u'", $this->getLocaleId()), 'left outer')
	                            ->join('pjExtra', 't3.id=t1.extra_id', 'inner')
	                            ->where('t1.booking_id', $arr['id'])
	                            ->findAll()
	                            ->getData();
	                            
	                            $client = pjClientModel::factory()->find($arr['client_id'])->getData();
	                            $auth_client = pjAuthUserModel::factory()->find($client['foreign_id'])->getData();
	                            if(isset($client['c_country']) && (int) $client['c_country'] > 0)
	                            {
	                                $country_arr = pjBaseCountryModel::factory()
	                                ->select('t1.id, t2.content AS country_title')
	                                ->join('pjBaseMultiLang', "t2.model='pjBaseCountry' AND t2.foreign_id=t1.id AND t2.field='name' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
	                                ->find($client['c_country'])->getData();
	                                if (!empty($country_arr))
	                                {
	                                    $country = $country_arr['country_title'];
	                                    $this->set('country', $country);
	                                }
	                            }
	                            
	                            $this->set('arr', $arr);
	                            $this->set('client', $client);
	                            $this->set('auth_client', $auth_client);
	                            
	                            if(pjObject::getPlugin('pjPayments') !== NULL)
	                            {
	                                $this->set('payment_option_arr', pjPaymentOptionModel::factory()->getOptions($this->getForeignId()));
	                                $this->set('payment_titles', pjPayments::getPaymentTitles($this->getForeignId(), $this->getLocaleId()));
	                            }else{
	                                $this->set('payment_titles', __('payment_methods', true));
	                            }
	                        }
	                    }
	                }
	            }else{
	                $this->set('status', 1);
	            }
	        }
	    }
	}
	
	public function pjActionGetExtrasPayments()
	{
	    $this->setAjax(true);
	    if ($this->isXHR())
	    {
    	    if(self::isGet() && $this->_get->check('id') && $this->_get->check('hash') && $this->_get->toInt('id') > 0 && !$this->_get->isEmpty('hash'))
    	    {
    	        $id = $this->_get->toInt('id');
    	        $hash = $this->_get->toString('hash');
    	        $pjExtraPaymentModel = pjExtraPaymentModel::factory();
    	        $arr = $pjExtraPaymentModel->reset()->find($id)->getData();
    	        if(!empty($arr))
    	        {
    	            $check_hash = sha1($id.$arr['created'].PJ_SALT);
    	            if($check_hash == $hash)
    	            {
    	                $locale_id = $this->getLocaleId();
    	                $this->set('arr', $arr);
    	                $this->set('client_id', $arr['client_id']);
    	                $this->set('locale_id', $locale_id);
    	                if(pjObject::getPlugin('pjPayments') !== NULL)
    	                {
    	                    $this->set('payment_option_arr', pjPaymentOptionModel::factory()->getOptions($this->getForeignId()));
    	                    $this->set('payment_titles', pjPayments::getPaymentTitles($this->getForeignId(), $locale_id));
    	                }else{
    	                    $this->set('payment_titles', __('payment_methods', true));
    	                }
    	                $response = array('status' => 'OK', 'code' => '200');
    	            }else{
    	                $response = array('status' => 'ERR', 'code' => '103');
    	            }
    	        }else{
    	            $response = array('status' => 'ERR', 'code' => '102');
    	        }
    	    }else{
    	        $response = array('status' => 'ERR', 'code' => '100');
    	    }
    	    $this->set('response', $response);
	    }
	}
	
	public function pjActionExtrasPaymentForm()
	{
	    $this->setAjax(true);
	    if(self::isPost() && $this->_post->check('id') && $this->_post->check('client_id') && $this->_post->check('payment_method'))
	    {
	        if(pjObject::getPlugin('pjPayments') !== NULL)
	        {
	            $id = $this->_post->toInt('id');
	            $client_id = $this->_post->toInt('client_id');
	            $locale_id = $this->_post->toInt('locale_id');
	            $client = pjClientModel::factory()->find($client_id)->getData();
	            $user = pjAuthUserModel::factory()->find($client['foreign_id'])->getData();
	            $arr = pjExtraPaymentModel::factory()->find($id)->getData();
	            
	            $payment_method = $this->_post->toString('payment_method');
	            $pjPlugin = pjPayments::getPluginName($payment_method);
	            if(pjObject::getPlugin($pjPlugin) !== NULL)
	            {
	                $params = $pjPlugin::getFormParams(array('payment_method' => $payment_method), array(
	                    'locale_id'	    => $locale_id,
	                    'return_url'	=> $this->option_arr['o_thankyou_page'],
	                    'id'			=> $id,
	                    'foreign_id'	=> $this->getForeignId(),
	                    'uuid'		    => $arr['uuid'],
	                    'name'		    => @$user['name'],
	                    'email'		    => @$user['email'],
	                    'phone'		    => @$user['phone'],
	                    'amount'		=> $arr['amount'],
	                	'cancel_hash'   => sha1($arr['uuid'].$arr['created'].PJ_SALT),
	                    'currency_code' => $this->option_arr['o_currency'],
	                ));
	                $params['option_foreign_id'] = $this->getForeignId(); 
					if (isset($params['notify_url']))
					{
						if (base64_encode(base64_decode($params['notify_url'], true)) === $params['notify_url'])
						{
							$notify_url = base64_decode($params['notify_url']);
							$base64 = true;
						} else {
							$notify_url = $params['notify_url'];
							$base64 = false;
						}
						
						$pipe = '|foreign_id=' . $this->getForeignId();
						
						if (preg_match('/payment_method=[\w\_]+$/', $notify_url))
						{
							$notify_url .= $pipe;
						} else {
							$notify_url = preg_replace('/payment_method=[\w\_]+/', '${0}' . $pipe, $notify_url);
						}
						
						if ($base64)
						{
							$params['notify_url'] = base64_encode($notify_url);
						} else {
							$params['notify_url'] = $notify_url;
						}
					}
	                $this->set('params', $params);
	            }
	            if ($payment_method == 'bank')
	            {
	                $bank_account = pjMultiLangModel::factory()->select('t1.content')
	                ->where('t1.model','pjOption')
	                ->where('t1.locale', $locale_id)
	                ->where('t1.field', 'o_bank_account')
	                ->limit(1)
	                ->findAll()->getDataIndex(0);
	                $this->set('bank_account', $bank_account['content']);
	            }
	            $this->set('payment_method', $payment_method);
	        }
	    }
	}
}
?>