<?php
if (!defined("ROOT_PATH"))
{
	header("HTTP/1.1 403 Forbidden");
	exit;
}
class pjFrontEnd extends pjFront
{
	public function __construct()
	{
		parent::__construct();
		
		$this->setAjax(true);
		
		$this->setLayout('pjActionEmpty');
	}
	
	public function pjActionAddToCart()
	{
		if ($this->isXHR())
		{
			if (isset($_POST['qty']) && isset($_POST['id']) && isset($_POST['type']))
			{
				$this->cart->update($_POST['type'] . "_" . $_POST['id'], $_POST['qty']);
				pjAppController::jsonResponse(array('status' => 'OK', 'code' => 206, 'text' => __('system_206', true)));
			}
			pjAppController::jsonResponse(array('status' => 'ERR', 'code' => 105, 'text' => __('system_105', true)));
		}
		exit;
	}
	
	public function pjActionRemoveFromCart()
	{
		if ($this->isXHR())
		{
			if (isset($_POST['id']) && isset($_POST['type']) && !$this->cart->isEmpty())
			{
				$this->cart->remove($_POST['type'] . "_" . $_POST['id']);
				pjAppController::jsonResponse(array('status' => 'OK', 'code' => 207, 'text' => __('system_207', true)));
			}
			pjAppController::jsonResponse(array('status' => 'ERR', 'code' => 106, 'text' => __('system_106', true)));
		}
		exit;
	}
	
	public function pjActionEmptyCart()
	{
		if ($this->isXHR())
		{
			if (!$this->cart->isEmpty())
			{
				$this->cart->clear();
				pjAppController::jsonResponse(array('status' => 'OK', 'code' => 208, 'text' => __('system_208', true)));
			}
			pjAppController::jsonResponse(array('status' => 'ERR', 'code' => 107, 'text' => __('system_107', true)));
		}
		exit;
	}
	
	public function pjActionUpdateCart()
	{
		if ($this->isXHR())
		{
			if (isset($_POST['qty']) && !empty($_POST['qty']) && !$this->cart->isEmpty())
			{
				foreach ($_POST['qty'] as $key => $qty)
				{
					$this->cart->update($key, $qty);
				}
				$_SESSION[$this->defaultForm] = array_merge($_SESSION[$this->defaultForm], array(
					'back' => $_POST['back'],
					'forth' => $_POST['forth']
				));
				pjAppController::jsonResponse(array('status' => 'OK', 'code' => 209, 'text' => __('system_209', true)));
			}
			pjAppController::jsonResponse(array('status' => 'ERR', 'code' => 108, 'text' => __('system_108', true)));
		}
		exit;
	}
	
	public function pjActionValidateCart()
	{
		if ($this->isXHR())
		{
			$is_valid = $this->getValidate($this->getSummary());
			die($is_valid ? 'true' : 'false');
		}
		die('false');
	}
	
	public function pjActionCheckAvailability()
	{
		if ($this->isXHR())
		{
			$date_from = pjUtil::formatDate($_POST['date_from'], $this->option_arr['o_date_format'], 'Y-m-d');
			$date_to = pjUtil::formatDate($_POST['date_to'], $this->option_arr['o_date_format'], 'Y-m-d');

			$hour_from = $_POST['hour_from'];
			$hour_to = $_POST['hour_to'];
			$minute_from = $_POST['minute_from'];
			$minute_to = $_POST['minute_to'];
			
			$dt_from = $date_from . " " . $hour_from . ":" . $minute_from . ":00";
			$dt_to = $date_to . " " . $hour_to . ":" . $minute_to . ":00";
			
			$FORM = @$_SESSION[$this->defaultForm];
			if ($FORM['date_from'] != $date_from || $FORM['date_to'] != $date_to ||
				$FORM['hour_from'] != $hour_from || $FORM['hour_to'] != $hour_to ||
				$FORM['minute_from'] != $minute_from || $FORM['minute_to'] != $minute_to)
			{
				$this->cart->clear();
			}
			
			$_SESSION[$this->defaultForm] = array_merge($_SESSION[$this->defaultForm],
				compact('date_from', 'date_to', 'hour_from', 'hour_to', 'minute_from', 'minute_to'));

			if (strtotime($dt_from) >= strtotime($dt_to))
			{
				if (isset($_POST['item_id']))
				{
					$this->setTemplate('pjFrontEnd', 'pjActionCheckItem');
				} elseif (isset($_POST['package_id'])) {
					$this->setTemplate('pjFrontEnd', 'pjActionCheckPackage');
				}
				return;
			}
				
			if (isset($_POST['item_id']))
			{
				$arr = pjItemModel::factory()
					->select(sprintf("t1.*,
						(SELECT MIN(cnt) FROM `%1\$s` AS `t2` WHERE `t1`.`id`=`t2`.`item_id` AND '$date_from' BETWEEN `t2`.`date_from` AND `t2`.`date_to`) AS `min_from`,
						(SELECT MIN(cnt) FROM `%1\$s` AS `t2` WHERE `t1`.`id`=`t2`.`item_id` AND '$date_to' BETWEEN `t2`.`date_from` AND `t2`.`date_to`) AS `min_to`,
						ABS(DATEDIFF('%2\$s', '%3\$s')) + 1 AS `necessary_days`,
						(SELECT COALESCE(SUM(bi.qty), 0)
							FROM `%4\$s` AS `bi`
							INNER JOIN `%5\$s` AS `b` ON b.id = bi.booking_id
								AND b.status = 'confirmed'
								AND b.dt_from <= '%7\$s'
								AND b.dt_to > '%6\$s'
							WHERE (bi.foreign_id = t1.id AND bi.type = 'item')
							OR (bi.foreign_id IN (SELECT pi.package_id
									FROM `%8\$s` AS `pi`
									INNER JOIN `%9\$s` AS `p` ON p.id = pi.package_id
									WHERE pi.item_id = t1.id) AND bi.type = 'package')
							LIMIT 1
						) AS `booked_qty`
						",
						pjAvailabilityModel::factory()->getTable(), $date_from, $date_to,
						pjBookingItemModel::factory()->getTable(), pjBookingModel::factory()->getTable(),
						$dt_from, $dt_to,
						pjPackageItemModel::factory()->getTable(),
						pjPackageModel::factory()->getTable()
					))
					->find($_POST['item_id'])
					->getData();
				
				$max_cnt = pjUtil::getMaxCount($arr['cnt'], $arr['min_from'], $arr['min_from']);
				if (!empty($arr)
					&& (int) $arr['is_active'] === 1
					&& (int) $max_cnt > 0
					&& (int) $arr['booked_qty'] < (int) $max_cnt)
				{
					$price = $this->getPrice($arr['id'], 'item', $dt_from, $dt_to);
					$this->set('price', $price);
				} else {
					$other_arr = pjItemModel::factory()
						->select(sprintf("t1.*, t2.content AS `title`,
							(SELECT MIN(cnt) FROM `%1\$s` AS `t2` WHERE `t1`.`id`=`t2`.`item_id` AND '$date_from' BETWEEN `t2`.`date_from` AND `t2`.`date_to`) AS `min_from`,
							(SELECT MIN(cnt) FROM `%1\$s` AS `t2` WHERE `t1`.`id`=`t2`.`item_id` AND '$date_to' BETWEEN `t2`.`date_from` AND `t2`.`date_to`) AS `min_to`,
							ABS(DATEDIFF('%2\$s', '%3\$s')) + 1 AS `necessary_days`,
							(SELECT COALESCE(SUM(bi.qty), 0)
								FROM `%4\$s` AS `bi`
								INNER JOIN `%5\$s` AS `b` ON b.id = bi.booking_id
									AND b.status = 'confirmed'
									AND b.dt_from <= '%7\$s'
									AND b.dt_to > '%6\$s'
								WHERE (bi.foreign_id = t1.id AND bi.type = 'item')
								OR (bi.foreign_id IN (SELECT pi.package_id
										FROM `%9\$s` AS `pi`
										INNER JOIN `%10\$s` AS `p` ON p.id = pi.package_id
										WHERE pi.item_id = t1.id) AND bi.type = 'package')
								LIMIT 1
							) AS `booked_qty`,
							(SELECT `medium_path` FROM `%8\$s`
								WHERE `foreign_id` = `t1`.`id`
								LIMIT 1) AS `pic`",
							pjAvailabilityModel::factory()->getTable(), $date_from, $date_to,
							pjBookingItemModel::factory()->getTable(), pjBookingModel::factory()->getTable(),
							$dt_from, $dt_to, pjGalleryModel::factory()->getTable(),
							pjPackageItemModel::factory()->getTable(), pjPackageModel::factory()->getTable()))
						->join('pjMultiLang', "t2.model='pjItem' AND t2.foreign_id=t1.id AND t2.field='title' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
						->where('t1.id !=', $_POST['item_id'])
						->where('t1.is_active', 1)
						->having('`booked_qty` < `cnt`')
						->limit(4)
						->findAll()
						->getData();

					$this->set('other_arr', $other_arr);
				}
				$this->set('arr', $arr);
				
				$this->setTemplate('pjFrontEnd', 'pjActionCheckItem');
				
			} elseif (isset($_POST['package_id'])) {
				
				$arr = pjPackageModel::factory()
					->select(sprintf("t1.*,
						(SELECT MIN(cnt) FROM `%1\$s` AS `t2` WHERE `t2`.`item_id` IN (SELECT `item_id` FROM `%9\$s` WHERE `package_id` = `t1`.`id`) AND '$date_from' BETWEEN `t2`.`date_from` AND `t2`.`date_to`) AS `min_from`,
						(SELECT MIN(cnt) FROM `%1\$s` AS `t2` WHERE `t2`.`item_id` IN (SELECT `item_id` FROM `%9\$s` WHERE `package_id` = `t1`.`id`) AND '$date_to' BETWEEN `t2`.`date_from` AND `t2`.`date_to`) AS `min_to`,
						(SELECT MIN(`cnt`) FROM `%8\$s` WHERE `id` IN (SELECT `item_id` FROM `%9\$s` WHERE `package_id` = t1.id) LIMIT 1) AS `cnt`,
						ABS(DATEDIFF('%2\$s', '%3\$s')) + 1 AS `necessary_days`,
						(SELECT COALESCE(SUM(bi.qty), 0)
							FROM `%4\$s` AS `bi`
							INNER JOIN `%5\$s` AS `b` ON b.id = bi.booking_id
								AND b.status = 'confirmed'
								AND b.dt_from <= '%7\$s'
								AND b.dt_to > '%6\$s'
							WHERE (bi.foreign_id = t1.id AND bi.type = 'package')
							LIMIT 1
						) AS `booked_qty`
						",
						pjAvailabilityModel::factory()->getTable(), $date_from, $date_to,
						pjBookingItemModel::factory()->getTable(), pjBookingModel::factory()->getTable(),
						$dt_from, $dt_to, pjItemModel::factory()->getTable(), pjPackageItemModel::factory()->getTable()
					))
					->find($_POST['package_id'])
					->getData();
				
				$item_in_pacakge_arr = pjItemModel::factory()
					->select(sprintf("t1.*,
							(SELECT MIN(cnt) FROM `%1\$s` AS `t2` WHERE `t1`.`id`=`t2`.`item_id` AND '$date_from' BETWEEN `t2`.`date_from` AND `t2`.`date_to`) AS `min_from`,
							(SELECT MIN(cnt) FROM `%1\$s` AS `t2` WHERE `t1`.`id`=`t2`.`item_id` AND '$date_to' BETWEEN `t2`.`date_from` AND `t2`.`date_to`) AS `min_to`,
							ABS(DATEDIFF('%2\$s', '%3\$s')) + 1 AS `necessary_days`,
							(SELECT COALESCE(SUM(bi.qty), 0)
							FROM `%4\$s` AS `bi`
							INNER JOIN `%5\$s` AS `b` ON b.id = bi.booking_id
							AND b.status = 'confirmed'
							AND b.dt_from <= '%7\$s'
							AND b.dt_to > '%6\$s'
							WHERE (bi.foreign_id = t1.id AND bi.type = 'item')
							OR (bi.foreign_id IN (SELECT pi.package_id
							FROM `%8\$s` AS `pi`
							INNER JOIN `%9\$s` AS `p` ON p.id = pi.package_id
							WHERE pi.item_id = t1.id) AND bi.type = 'package')
							LIMIT 1
					) AS `booked_qty`
							",
							pjAvailabilityModel::factory()->getTable(), $date_from, $date_to,
							pjBookingItemModel::factory()->getTable(), pjBookingModel::factory()->getTable(),
							$dt_from, $dt_to,
							pjPackageItemModel::factory()->getTable(),
							pjPackageModel::factory()->getTable()
					))
					->where("(t1.id IN (SELECT `TPI`.item_id FROM `".pjPackageItemModel::factory()->getTable()."` AS `TPI` WHERE `TPI`.package_id=".$_POST['package_id']."))")
					->findAll()
					->getData();
				
				$max_cnt = pjUtil::getMaxCount($arr['cnt'], $arr['min_from'], $arr['min_from']);
				$avail_items_in_package = $max_cnt - (int) $arr['booked_qty'];
				
				foreach($item_in_pacakge_arr as $k => $v)
				{
					$item_max_cnt = pjUtil::getMaxCount($v['cnt'], $v['min_from'], $v['min_from']);
					if((int) $v['booked_qty'] <= (int) $item_max_cnt)
					{
						if((int) $item_max_cnt - (int) $v['booked_qty'] < $avail_items_in_package)
						{
							$avail_items_in_package = (int) $item_max_cnt - (int) $v['booked_qty'];
						}
					}
				}
				
				if (!empty($arr)
					&& (int) $arr['is_active'] === 1
					&& (int) $max_cnt > 0
					&& (int) $arr['booked_qty'] < (int) $max_cnt
					&& $avail_items_in_package > 0)
				{
					$price = $this->getPrice($arr['id'], 'package', $dt_from, $dt_to);
					$this->set('price', $price);
				} else {
					
					$other_arr = pjPackageModel::factory()
						->select(sprintf("t1.*, t2.content AS `title`,
							(SELECT MIN(cnt) FROM `%1\$s` AS `t2` WHERE `t2`.`item_id` IN (SELECT `item_id` FROM `%9\$s` WHERE `package_id` = `t1`.`id`) AND '$date_from' BETWEEN `t2`.`date_from` AND `t2`.`date_to`) AS `min_from`,
							(SELECT MIN(cnt) FROM `%1\$s` AS `t2` WHERE `t2`.`item_id` IN (SELECT `item_id` FROM `%9\$s` WHERE `package_id` = `t1`.`id`) AND '$date_to' BETWEEN `t2`.`date_from` AND `t2`.`date_to`) AS `min_to`,
							ABS(DATEDIFF('%2\$s', '%3\$s')) + 1 AS `necessary_days`,
							(SELECT COALESCE(SUM(bi.qty), 0)
								FROM `%4\$s` AS `bi`
								INNER JOIN `%5\$s` AS `b` ON b.id = bi.booking_id
									AND b.status = 'confirmed'
									AND b.dt_from <= '%7\$s'
									AND b.dt_to > '%6\$s'
								WHERE (bi.foreign_id = t1.id AND bi.type = 'package')
								OR (bi.foreign_id IN (SELECT `item_id` FROM `%9\$s` WHERE `package_id` = t1.id) AND bi.type = 'item')
								LIMIT 1
							) AS `booked_qty`,
							(SELECT MIN(`cnt`) FROM `%8\$s` WHERE `id` IN (SELECT `item_id` FROM `%9\$s` WHERE `package_id` = t1.id) LIMIT 1) AS `cnt`,
							(SELECT `medium_path` FROM `%10\$s`
								WHERE `foreign_id` IN (SELECT `item_id` FROM `%9\$s` WHERE `package_id` = t1.id)
								ORDER BY ISNULL(`sort`), `sort` ASC, `id` ASC
								LIMIT 1) AS `pic`",
							pjAvailabilityModel::factory()->getTable(), $date_from, $date_to,
							pjBookingItemModel::factory()->getTable(), pjBookingModel::factory()->getTable(),
							$dt_from, $dt_to, pjItemModel::factory()->getTable(), pjPackageItemModel::factory()->getTable(),
							pjGalleryModel::factory()->getTable()))
						->join('pjMultiLang', "t2.model='pjPackage' AND t2.foreign_id=t1.id AND t2.field='title' AND t2.locale='".$this->getLocaleId()."'", 'left outer')
						->where('t1.id !=', $_POST['package_id'])
						->where('t1.is_active', 1)
						->having('`booked_qty` < `cnt`')
						->limit(4)
						->findAll()
						->getData();

					$this->set('other_arr', $other_arr);
				}
				$this->set('arr', $arr);
				$this->set('avail_items_in_package', $avail_items_in_package);
				
				$this->setTemplate('pjFrontEnd', 'pjActionCheckPackage');
			}
		}
	}

	public function pjActionProcessOrder()
	{
		$this->setAjax(true);
		
		if ($this->isXHR())
		{
			if (!isset($_POST['er_preview']) || !isset($_SESSION[$this->defaultForm]) || empty($_SESSION[$this->defaultForm]))
			{
				pjAppController::jsonResponse(array('status' => 'ERR', 'code' => 109, 'text' => __('system_109', true)));
			}
			
			if ((int) $this->option_arr['o_accept_bookings'] !== 1)
			{
				pjAppController::jsonResponse(array('status' => 'ERR', 'code' => 120, 'text' => __('system_120', true)));
			}
			
			if ((int) $this->option_arr['o_bf_captcha'] === 3 && (!isset($_SESSION[$this->defaultForm]['captcha']) || (isset($_SESSION[$this->defaultForm]['captcha'])  && !pjCaptcha::validate($_SESSION[$this->defaultForm]['captcha'], @$_SESSION[$this->defaultCaptcha]))))
			{
				pjAppController::jsonResponse(array('status' => 'ERR', 'code' => 110, 'text' => __('system_110', true)));
			}
			$_SESSION[$this->defaultCaptcha] = NULL;
			unset($_SESSION[$this->defaultCaptcha]);
						
			$summary = $this->getSummary();
			if (!$this->getValidate($summary))
			{
				pjAppController::jsonResponse(array('status' => 'ERR', 'code' => 111, 'text' => __('system_111', true)));
			}
			
			$data = array();
			
			$data['dt_from'] = $summary['dt_from'];
			$data['dt_to'] = $summary['dt_to'];
			
			$data['calendar_id'] = $this->getForeignId();
			$data['status'] = $this->option_arr['o_status_if_not_paid'];
			$data['uuid'] = pjUtil::uuid();
			$data['ip'] = $_SERVER['REMOTE_ADDR'];
			$data['locale_id'] = $this->getLocaleId();
			
			$data = array_merge($_SESSION[$this->defaultForm], $data);
			
			if (isset($data['payment_method']) && $data['payment_method'] != 'creditcard')
			{
				unset($data['cc_type']);
				unset($data['cc_num']);
				unset($data['cc_exp_month']);
				unset($data['cc_exp_year']);
				unset($data['cc_code']);
			}
			
			$data['price'] = $summary['price'];
			$data['deposit'] = $summary['deposit'];
			$data['security'] = $summary['security'];
			$data['tax'] = $summary['tax'];
			$data['delivery'] = $summary['delivery'];
			$data['collection'] = $summary['collection'];
			$data['total'] = $summary['total'];
			
			$pjBookingModel = pjBookingModel::factory();
			if (!$pjBookingModel->validates($data))
			{
				pjAppController::jsonResponse(array('status' => 'ERR', 'code' => 114, 'text' => __('system_114', true)));
			}
			
			$booking_id = $pjBookingModel->setAttributes($data)->insert()->getInsertId();
			if ($booking_id !== false && (int) $booking_id > 0)
			{
				$pjBookingItemModel = pjBookingItemModel::factory()->setBatchFields(array(
					'booking_id', 'foreign_id', 'type', 'qty', 'unit_price'
				));
				foreach ($summary['items'] as $item)
				{
					$key = $item['type'] . "_" . $item['id'];
					$pjBookingItemModel->addBatchRow(array($booking_id, $item['id'], $item['type'], $summary['cart'][$key], $item['price']));
				}
				$pjBookingItemModel->insertBatch();
				
				$invoice_arr = $this->pjActionGenerateInvoice($booking_id);
				
				# Confirmation
				$booking_arr = $pjBookingModel
					->reset()
					->select('t1.*, t2.content AS country')
					->join('pjMultiLang', "t2.model='pjCountry' AND t2.foreign_id=t1.c_country_id AND t2.locale=t1.locale_id AND t2.field='name'", 'left outer')
					->find($booking_id)
					->getData();
				if (!empty($booking_arr))
				{
					$calendar_arr = pjCalendarModel::factory()
						->select(sprintf("t1.*, t2.content AS confirm_subject_client, t3.content AS confirm_tokens_client,
							t4.content AS confirm_subject_admin, t5.content AS confirm_tokens_admin,
							(SELECT GROUP_CONCAT(`email`) FROM `%s` WHERE `role_id` = '1' AND `status` = 'T') AS `email`", pjUserModel::factory()->getTable()))
						->join('pjMultiLang', "t2.model='pjCalendar' AND t2.foreign_id=t1.id AND t2.field='confirm_subject_client' AND t2.locale='".$booking_arr['locale_id']."'", 'left outer')
						->join('pjMultiLang', "t3.model='pjCalendar' AND t3.foreign_id=t1.id AND t3.field='confirm_tokens_client' AND t3.locale='".$booking_arr['locale_id']."'", 'left outer')
						->join('pjMultiLang', "t4.model='pjCalendar' AND t4.foreign_id=t1.id AND t4.field='confirm_subject_admin' AND t4.locale='".$booking_arr['locale_id']."'", 'left outer')
						->join('pjMultiLang', "t5.model='pjCalendar' AND t5.foreign_id=t1.id AND t5.field='confirm_tokens_admin' AND t5.locale='".$booking_arr['locale_id']."'", 'left outer')
						->find($booking_arr['calendar_id'])
						->toArray('email', ',')
						->getData();
					if (!empty($calendar_arr))
					{
						pjFrontEnd::pjActionConfirmSend($this->option_arr, $booking_arr, $calendar_arr, 'confirm');
					}
				}
				# -- Confirmation
				
				// Reset SESSION vars
				$this->cart->clear();
				
				$_SESSION[$this->defaultForm] = NULL;
				unset($_SESSION[$this->defaultForm]);
				
				pjAppController::jsonResponse(array(
					'status' => 'OK',
					'code' => 210,
					'text' => __('system_210', true),
					//'booking_id' => $booking_id,
					//'invoice_id' => @$invoice_arr['data']['id'],
					'booking_uuid' => $data['uuid'],
					'payment_method' => @$data['payment_method']
				));
			} else {
				pjAppController::jsonResponse(array('status' => 'ERR', 'code' => 119, 'text' => __('system_119', true)));
			}
		}
		exit;
	}
	
	public function pjActionGetTime()
	{
		$this->setAjax(true);
	
		if ($this->isXHR())
		{
			$this->set('day_limit', $this->getDayLimit($_GET['iso_date']));
		}
	}
	
	public function pjActionGetTerms()
	{
		if ($this->isXHR())
		{
			$this->set('terms_arr', $this->getTerms($this->getForeignId()));
		}
	}
	
	public function pjActionLoad()
	{
		$this->setAjax(false);
		$this->setLayout('pjActionFront');
		
		ob_start();
		header("Content-type: text/javascript");
		
		if(isset($_GET['locale']) && (int) $_GET['locale'] > 0)
		{
			$_SESSION[$this->defaultLangMenu] = 'hide';
			$_SESSION[$this->defaultLocale] = (int) $_GET['locale'];
			$this->loadSetFields(true);
		}else{
			$_SESSION[$this->defaultLangMenu] = 'show';
		}
		
		$result = $this->getDates();
		
		$this->set('first_working_date', $result['first_working_date']);
		$this->set('days_off', $result['days_off']);
		$this->set('dates_off', $result['dates_off']);
		$this->set('dates_on', $result['dates_on']);
		$this->set('default_times', $result['default_times']);
		$this->set('custom_times', $result['custom_times']);
	}
	
	public function pjActionLoadCss()
	{
	    $dm = new pjDependencyManager(PJ_INSTALL_PATH, PJ_THIRD_PARTY_PATH);
		$dm->load(PJ_CONFIG_PATH . 'dependencies.php')->resolve();
		
		$theme = isset($_GET['theme']) ? $_GET['theme'] : $this->option_arr['o_theme'];
		if((int) $theme > 0)
		{
			$theme = 'theme' . $theme;
		}
		$arr = array(
			array('file' => 'jquery-ui.custom.min.css', 'path' => $dm->getPath('pj_jquery_ui') . 'css/smoothness/'),
			array('file' => 'pjEquipmentRental.css', 'path' => PJ_CSS_PATH),
			array('file' => "$theme.css", 'path' => PJ_CSS_PATH . 'themes/'),
			array('file' => 'transitions.css', 'path' => PJ_CSS_PATH)
		);
		header("Content-type: text/css");
		foreach ($arr as $item)
		{
			ob_start();
			@readfile($item['path'] . $item['file']);
			$string = ob_get_contents();
			ob_end_clean();
			
			if ($string !== FALSE)
			{
				echo str_replace(
					array('images/ui-', "pjWrapper"),
					array(
							PJ_INSTALL_URL . $dm->getPath('pj_jquery_ui') . 'css/smoothness/images/ui-',
							"pjWrapperEquipment_" . $theme
					),
					$string
				) . "\n";
			}
		}
		exit;
	}
	
	public function pjActionCaptcha()
	{
	    $this->setAjax(true);
	    header("Cache-Control: max-age=3600, private");
	    $pjCaptcha = new pjCaptcha(PJ_WEB_PATH . 'obj/Anorexia.ttf', $this->defaultCaptcha, 6);
	    $pjCaptcha->setImage(PJ_IMG_PATH . 'frontend/er-captcha.png')->init(@$_GET['rand']);
	    exit;
	}
	
	public function pjActionCheckCaptcha()
	{
		if ($this->isXHR())
		{
			echo isset($_SESSION[$this->defaultCaptcha]) && isset($_GET['captcha']) && $_SESSION[$this->defaultCaptcha] == strtoupper($_GET['captcha']) ? 'true' : 'false';
		}
		exit;
	}

	public function pjActionUpdatePrice()
	{
		$this->setAjax(true);
		
		$price = pjUtil::formatCurrencySign(number_format($_POST['price'] * (int) $_POST['qty'], 2), $this->option_arr['o_currency']);
		
		pjAppController::jsonResponse(array('status' => 'OK', 'code' => 200, 'price' => $price));
	}
	
	public function pjActionConfirmAuthorize()
	{
		$this->setAjax(true);
		
		if (pjObject::getPlugin('pjAuthorize') === NULL)
		{
			$this->log('Authorize.NET plugin not installed');
			exit;
		}
		
		if (!isset($_POST['x_invoice_num']))
		{
			$this->log('Missing arguments');
			exit;
		}
		
		$pjInvoiceModel = pjInvoiceModel::factory();
		$pjBookingModel = pjBookingModel::factory();
		
		$invoice_arr = $pjInvoiceModel
			->where('t1.uuid', $_POST['x_invoice_num'])
			->limit(1)
			->findAll()
			->getData();
		if (!empty($invoice_arr))
		{
			$invoice_arr = $invoice_arr[0];
			$booking_arr = $pjBookingModel
				->select('t1.*, t2.content AS country')
				->join('pjMultiLang', "t2.model='pjCountry' AND t2.foreign_id=t1.c_country_id AND t2.locale=t1.locale_id AND t2.field='name'", 'left outer')
				->where('t1.uuid', $invoice_arr['order_id'])
				->limit(1)
				->findAll()
				->getData();
			if (!empty($booking_arr))
			{
				$booking_arr = $booking_arr[0];
				$calendar_arr = pjCalendarModel::factory()
					->select(sprintf("t1.*, t2.content AS payment_subject_client, t3.content AS payment_tokens_client,
						t4.content AS payment_subject_admin, t5.content AS payment_tokens_admin,
						(SELECT GROUP_CONCAT(`email`) FROM `%s` WHERE `role_id` = '1' AND `status` = 'T') AS `email`", pjUserModel::factory()->getTable()))
					->join('pjMultiLang', "t2.model='pjCalendar' AND t2.foreign_id=t1.id AND t2.field='payment_subject_client' AND t2.locale='".$booking_arr['locale_id']."'", 'left outer')
					->join('pjMultiLang', "t3.model='pjCalendar' AND t3.foreign_id=t1.id AND t3.field='payment_tokens_client' AND t3.locale='".$booking_arr['locale_id']."'", 'left outer')
					->join('pjMultiLang', "t4.model='pjCalendar' AND t4.foreign_id=t1.id AND t4.field='payment_subject_admin' AND t4.locale='".$booking_arr['locale_id']."'", 'left outer')
					->join('pjMultiLang', "t5.model='pjCalendar' AND t5.foreign_id=t1.id AND t5.field='payment_tokens_admin' AND t5.locale='".$booking_arr['locale_id']."'", 'left outer')
					->find($booking_arr['calendar_id'])
					->toArray('email', ',')
					->getData();
				$option_arr = pjOptionModel::factory()->getPairs($booking_arr['calendar_id']);

				$params = array(
					'transkey' => $option_arr['o_authorize_key'],
					'x_login' => $option_arr['o_authorize_mid'],
					'md5_setting' => $option_arr['o_authorize_hash'],
					'key' => md5($this->option_arr['private_key'] . PJ_SALT)
				);
				
				$response = $this->requestAction(array('controller' => 'pjAuthorize', 'action' => 'pjActionConfirm', 'params' => $params), array('return'));
				if ($response !== FALSE && $response['status'] === 'OK')
				{
					$pjBookingModel
						->reset()
						->set('id', $booking_arr['id'])
						->modify(array('status' => $option_arr['o_status_if_paid']));
						
					$pjInvoiceModel
						->reset()
						->set('id', $invoice_arr['id'])
						->modify(array('status' => 'paid', 'modified' => ':NOW()'));
					
					pjFrontEnd::pjActionConfirmSend($option_arr, $booking_arr, $calendar_arr, 'payment');
				} elseif (!$response) {
					$this->log('Authorization failed');
				} else {
					$this->log('Booking not confirmed. ' . $response['response_reason_text']);
				}
			} else {
				$this->log('Booking not found');
			}
		} else {
			$this->log('Invoice not found');
		}
		exit;
	}

	public function pjActionConfirmPaypal()
	{
		$this->setAjax(true);
		
		if (pjObject::getPlugin('pjPaypal') === NULL)
		{
			$this->log('Paypal plugin not installed');
			pjAppController::jsonResponse(array('status' => 'ERR', 'text' => 'Paypal plugin not installed'));
		}
		
		$input = file_get_contents('php://input');
		$post = json_decode($input, true);
		if ($post) {
		    $_REQUEST = array_merge($_REQUEST, $post);
		}
		
		$pjInvoiceModel = pjInvoiceModel::factory();
		$pjBookingModel = pjBookingModel::factory();

		$invoice_arr = $pjInvoiceModel
		->where('t1.uuid', $_REQUEST['custom'])
		->limit(1)
		->findAll()
		->getData();

		if (!empty($invoice_arr))
		{
			$invoice_arr = $invoice_arr[0];
			$booking_arr = $pjBookingModel
				->select('t1.*, t2.content AS country')
				->join('pjMultiLang', "t2.model='pjCountry' AND t2.foreign_id=t1.c_country_id AND t2.locale=t1.locale_id AND t2.field='name'", 'left outer')
				->where('t1.uuid', $invoice_arr['order_id'])
				->limit(1)
				->findAll()
				->getData();
			if (!empty($booking_arr))
			{
				$booking_arr = $booking_arr[0];
				$calendar_arr = pjCalendarModel::factory()
					->select(sprintf("t1.*, t2.content AS payment_subject_client, t3.content AS payment_tokens_client,
						t4.content AS payment_subject_admin, t5.content AS payment_tokens_admin,
						(SELECT GROUP_CONCAT(`email`) FROM `%s` WHERE `role_id` = '1' AND `status` = 'T') AS `email`", pjUserModel::factory()->getTable()))
					->join('pjMultiLang', "t2.model='pjCalendar' AND t2.foreign_id=t1.id AND t2.field='payment_subject_client' AND t2.locale='".$booking_arr['locale_id']."'", 'left outer')
					->join('pjMultiLang', "t3.model='pjCalendar' AND t3.foreign_id=t1.id AND t3.field='payment_tokens_client' AND t3.locale='".$booking_arr['locale_id']."'", 'left outer')
					->join('pjMultiLang', "t4.model='pjCalendar' AND t4.foreign_id=t1.id AND t4.field='payment_subject_admin' AND t4.locale='".$booking_arr['locale_id']."'", 'left outer')
					->join('pjMultiLang', "t5.model='pjCalendar' AND t5.foreign_id=t1.id AND t5.field='payment_tokens_admin' AND t5.locale='".$booking_arr['locale_id']."'", 'left outer')
					->find($booking_arr['calendar_id'])
					->toArray('email', ',')
					->getData();
				$option_arr = pjOptionModel::factory()->getPairs($booking_arr['calendar_id']);
				$params = array(
				    'request'		=> $_REQUEST,
				    'cancel_hash'	=> sha1($booking_arr['uuid'].strtotime($booking_arr['created']).PJ_SALT),
				    'txn_id' => @$booking_arr['txn_id'],
				    'paypal_address' => @$option_arr['o_paypal_address'],
				    'deposit' => @$invoice_arr['paid_deposit'],
				    'currency' =>  @$invoice_arr['currency'],
				    'key' => md5($this->option_arr['private_key'] . PJ_SALT)
				);

				$response = $this->requestAction(array('controller' => 'pjPaypal', 'action' => 'pjActionConfirm', 'params' => $params), array('return'));
				if ($response !== FALSE && $response['status'] === 'OK')
				{
					$this->log('Booking confirmed');
					$pjBookingModel->reset()->set('id', $booking_arr['id'])->modify(array(
						'status' => $option_arr['o_status_if_paid'],
						'txn_id' => $response['transaction_id'],
						'processed_on' => ':NOW()'
					));
					
					$pjInvoiceModel
						->reset()
						->set('id', $invoice_arr['id'])
						->modify(array('status' => 'paid', 'modified' => ':NOW()'));
						
					pjFrontEnd::pjActionConfirmSend($option_arr, $booking_arr, $calendar_arr, 'payment');
					pjAppController::jsonResponse(array('status' => 'OK', 'text' => 'Booking confirmed'));
				} elseif (!$response) {
					$this->log('Authorization failed');
					pjAppController::jsonResponse(array('status' => 'ERR', 'text' => 'Authorization failed'));
				} else {
					$this->log('Booking not confirmed');
					pjAppController::jsonResponse(array('status' => 'ERR', 'text' => 'Booking not confirmed'));
				}
			} else {
				$this->log('Booking not found');
				pjAppController::jsonResponse(array('status' => 'ERR', 'text' => 'Booking not found'));
			}
		} else {
			$this->log('Invoice not found');
			pjAppController::jsonResponse(array('status' => 'ERR', 'text' => 'Invoice not found'));
		}
	}
	
	public function pjActionCancel()
	{
		$this->setAjax(false);
		
		$this->setLayout('pjActionCancel');
		
		$pjBookingModel = pjBookingModel::factory();
	
		if (isset($_POST['booking_cancel']))
		{
			$booking_arr = $pjBookingModel
				->select('t1.*, t2.content AS country')
				->join('pjMultiLang', "t2.model='pjCountry' AND t2.foreign_id=t1.c_country_id AND t2.locale=t1.locale_id AND t2.field='name'", 'left outer')
				->find($_POST['id'])
				->getData();
			if (count($booking_arr) > 0)
			{
				$sql = "UPDATE `".$pjBookingModel->getTable()."` SET status = 'cancelled' WHERE SHA1(CONCAT(`id`, '".PJ_SALT."')) = '" . $_POST['hash'] . "'";
	
				$pjBookingModel->reset()->execute($sql);
	
				$calendar_arr = pjCalendarModel::factory()
					->select(sprintf("t1.*, t2.content AS cancel_subject_client, t3.content AS cancel_tokens_client,
						t4.content AS cancel_subject_admin, t5.content AS cancel_tokens_admin,
						(SELECT GROUP_CONCAT(`email`) FROM `%s` WHERE `role_id` = '1' AND `status` = 'T') AS `email`", pjUserModel::factory()->getTable()))
					->join('pjMultiLang', "t2.model='pjCalendar' AND t2.foreign_id=t1.id AND t2.field='cancel_subject_client' AND t2.locale='".$booking_arr['locale_id']."'", 'left outer')
					->join('pjMultiLang', "t3.model='pjCalendar' AND t3.foreign_id=t1.id AND t3.field='cancel_tokens_client' AND t3.locale='".$booking_arr['locale_id']."'", 'left outer')
					->join('pjMultiLang', "t4.model='pjCalendar' AND t4.foreign_id=t1.id AND t4.field='cancel_subject_admin' AND t4.locale='".$booking_arr['locale_id']."'", 'left outer')
					->join('pjMultiLang', "t5.model='pjCalendar' AND t5.foreign_id=t1.id AND t5.field='cancel_tokens_admin' AND t5.locale='".$booking_arr['locale_id']."'", 'left outer')
					->find($booking_arr['calendar_id'])
					->toArray('email', ',')
					->getData();
				$option_arr = pjOptionModel::factory()->getPairs($booking_arr['calendar_id']);
				
				pjFrontEnd::pjActionConfirmSend($option_arr, $booking_arr, $calendar_arr, 'cancel');
				
				pjUtil::redirect($_SERVER['PHP_SELF'] . '?controller=pjFrontEnd&action=pjActionCancel&err=200');
			}
		}else{
			if (isset($_GET['hash']) && isset($_GET['id']))
			{
				$arr = $pjBookingModel
					->select('t1.*, t2.content AS country')
					->join('pjMultiLang', "t2.model='pjCountry' AND t2.foreign_id=t1.c_country_id AND t2.locale=t1.locale_id AND t2.field='name'", 'left outer')
					->find($_GET['id'])
					->getData();
				
				if (count($arr) == 0)
				{
					$this->set('status', 2);
				}else{
					if ($arr['status'] == 'cancelled')
					{
						$this->set('status', 4);
					}else{
						$hash = sha1($arr['id'] . PJ_SALT);
						if ($_GET['hash'] != $hash)
						{
							$this->set('status', 3);
						}else{
	
							$bi_arr = pjBookingItemModel::factory()
								->select("t1.*, t2.content AS title")
								->join('pjMultiLang', sprintf("t2.model=IF(t1.type='item','pjItem','pjPackage') AND t2.foreign_id=t1.foreign_id AND t2.field='title' AND t2.locale='%u'", $arr['locale_id']), 'left outer')
								->where('t1.booking_id', $arr['id'])
								->findAll()
								->getData();
							
							$this->set('bi_arr', $bi_arr);
							$this->set('arr', $arr);
						}
					}
				}
			}else if (!isset($_GET['err'])) {
				$this->set('status', 1);
			}
		}
	}
	
	private static function pjActionConfirmSend($option_arr, $booking_arr, $calendar_arr, $type)
	{
		if (!in_array($type, array('confirm', 'payment', 'cancel')))
		{
			return false;
		}
		$Email = new pjEmail();
		if ($option_arr['o_send_email'] == 'smtp')
		{
			$Email
				->setTransport('smtp')
				->setSmtpHost($option_arr['o_smtp_host'])
				->setSmtpPort($option_arr['o_smtp_port'])
				->setSmtpUser($option_arr['o_smtp_user'])
				->setSmtpPass($option_arr['o_smtp_pass'])
			;
		}
		$Email->setContentType('text/html');
		
		$tokens = pjAppController::getTokens($booking_arr, $option_arr);
		
		switch ($type)
		{
			case 'confirm':
			    $subject_client = !empty(@$calendar_arr['confirm_subject_client']) ? str_replace($tokens['search'], $tokens['replace'], @$calendar_arr['confirm_subject_client']) : '';
			    $message_client = !empty(@$calendar_arr['confirm_tokens_client']) ? pjUtil::textToHtml(str_replace($tokens['search'], $tokens['replace'], @$calendar_arr['confirm_tokens_client'])) : '';
				
			    $subject_admin = !empty(@$calendar_arr['confirm_subject_admin']) ? str_replace($tokens['search'], $tokens['replace'], @$calendar_arr['confirm_subject_admin']) : '';
			    $message_admin = !empty(@$calendar_arr['confirm_tokens_admin']) ? pjUtil::textToHtml(str_replace($tokens['search'], $tokens['replace'], @$calendar_arr['confirm_tokens_admin'])) : '';
				
				# Client
				if (isset($booking_arr['c_email']) && !empty($booking_arr['c_email']) &&
					!empty($subject_client) && !empty($message_client))
				{
					$Email
						->setTo($booking_arr['c_email'])
						->setFrom(!empty($calendar_arr['email']) ? $calendar_arr['email'][0] : $booking_arr['c_email'])
						->setSubject($subject_client)
						->send($message_client);
				}
				
				# Admin
				if (!empty($subject_admin) && !empty($message_admin))
				{
					foreach ($calendar_arr['email'] as $email)
					{
						$Email
							->setTo($email)
							->setFrom($email)
							->setSubject($subject_admin)
							->send($message_admin);
					}
				}
				break;
			case 'payment':
			    $subject_client = !empty(@$calendar_arr['payment_subject_client']) ? str_replace($tokens['search'], $tokens['replace'], @$calendar_arr['payment_subject_client']) : '';
			    $message_client = !empty(@$calendar_arr['payment_tokens_client']) ? pjUtil::textToHtml(str_replace($tokens['search'], $tokens['replace'], @$calendar_arr['payment_tokens_client'])) : '';
				
			    $subject_admin = !empty(@$calendar_arr['payment_subject_admin']) ? str_replace($tokens['search'], $tokens['replace'], @$calendar_arr['payment_subject_admin']) : '';
			    $message_admin = !empty(@$calendar_arr['payment_tokens_admin']) ? pjUtil::textToHtml(str_replace($tokens['search'], $tokens['replace'], @$calendar_arr['payment_tokens_admin'])) : '';
				
				# Client
				if (isset($booking_arr['c_email']) && !empty($booking_arr['c_email']) &&
					!empty($subject_client) && !empty($message_client))
				{
					$Email
						->setTo($booking_arr['c_email'])
						->setFrom(!empty($calendar_arr['email']) ? $calendar_arr['email'][0] : $booking_arr['c_email'])
						->setSubject($subject_client)
						->send($message_client);
				}
				
				# Admin
				if (!empty($subject_admin) && !empty($message_admin))
				{
					foreach ($calendar_arr['email'] as $email)
					{
						$Email
							->setTo($email)
							->setFrom($email)
							->setSubject($subject_admin)
							->send($message_admin);
					}
				}
				break;
				
			case 'cancel':
			    $subject_client = !empty(@$calendar_arr['cancel_subject_client']) ? str_replace($tokens['search'], $tokens['replace'], @$calendar_arr['cancel_subject_client']) : '';
			    $message_client = !empty(@$calendar_arr['cancel_tokens_client']) ? pjUtil::textToHtml(str_replace($tokens['search'], $tokens['replace'], @$calendar_arr['cancel_tokens_client'])) : '';
			
			    $subject_admin = !empty(@$calendar_arr['cancel_subject_admin']) ? str_replace($tokens['search'], $tokens['replace'], @$calendar_arr['cancel_subject_admin']) : '';
			    $message_admin = !empty(@$calendar_arr['cancel_tokens_admin']) ? pjUtil::textToHtml(str_replace($tokens['search'], $tokens['replace'], @$calendar_arr['cancel_tokens_admin'])) : '';
			
				# Client
				if (isset($booking_arr['c_email']) && !empty($booking_arr['c_email']) &&
						!empty($subject_client) && !empty($message_client))
				{
					$Email
						->setTo($booking_arr['c_email'])
						->setFrom(!empty($calendar_arr['email']) ? $calendar_arr['email'][0] : $booking_arr['c_email'])
						->setSubject($subject_client)
						->send($message_client);
				}
			
				# Admin
				if (!empty($subject_admin) && !empty($message_admin))
				{
					foreach ($calendar_arr['email'] as $email)
					{
						$Email
							->setTo($email)
							->setFrom($email)
							->setSubject($subject_admin)
							->send($message_admin);
					}
				}
				break;
		}
	}
}
?>