<?php
if (!defined("ROOT_PATH"))
{
	header("HTTP/1.1 403 Forbidden");
	exit;
}
class pjAppController extends pjBaseAppController
{
	public $models = array();
	public $defaultRoom = 'admin_room_id';

    public function pjActionCheckInstall()
    {
        $this->setLayout('pjActionEmpty');

        $result = array('status' => 'OK', 'code' => 200, 'text' => 'Operation succeeded', 'info' => array());
        $folders = array('app/web/upload');
        foreach ($folders as $dir)
        {
            if (!is_writable($dir))
            {
                $result['status'] = 'ERR';
                $result['code'] = 101;
                $result['text'] = 'Permission requirement';
                $result['info'][] = sprintf('Folder \'<span class="bold">%1$s</span>\' is not writable. You need to set write permissions (chmod 777) to directory located at \'<span class="bold">%1$s</span>\'', $dir);
            }
        }

        return $result;
    }
	
    /**
     * Sets some predefined role permissions and grants full permissions to Admin.
     */
    public function pjActionAfterInstall()
    {
        $this->setLayout('pjActionEmpty');

        $result = array('status' => 'OK', 'code' => 200, 'text' => 'Operation succeeded', 'info' => array());

        $pjAuthRolePermissionModel = pjAuthRolePermissionModel::factory();
        $pjAuthUserPermissionModel = pjAuthUserPermissionModel::factory();

        $permissions = pjAuthPermissionModel::factory()->findAll()->getDataPair('key', 'id');

        $roles = array(1 => 'admin', 2 => 'editor');
        foreach ($roles as $role_id => $role)
        {
            if (isset($GLOBALS['CONFIG'], $GLOBALS['CONFIG']["role_permissions_{$role}"])
                && is_array($GLOBALS['CONFIG']["role_permissions_{$role}"])
                && !empty($GLOBALS['CONFIG']["role_permissions_{$role}"]))
            {
                $pjAuthRolePermissionModel->reset()->where('role_id', $role_id)->eraseAll();

                foreach ($GLOBALS['CONFIG']["role_permissions_{$role}"] as $role_permission)
                {
                    if($role_permission == '*')
                    {
                        // Grant full permissions for the role
                        foreach($permissions as $key => $permission_id)
                        {
                            $pjAuthRolePermissionModel->setAttributes(compact('role_id', 'permission_id'))->insert();
                        }
                        break;
                    }
                    else
                    {
                        $hasAsterix = strpos($role_permission, '*') !== false;
                        if($hasAsterix)
                        {
                            $role_permission = str_replace('*', '', $role_permission);
                        }

                        foreach($permissions as $key => $permission_id)
                        {
                            if($role_permission == $key || ($hasAsterix && strpos($key, $role_permission) !== false))
                            {
                                $pjAuthRolePermissionModel->setAttributes(compact('role_id', 'permission_id'))->insert();
                            }
                        }
                    }
                }
            }
        }
        pjAuthRoleModel::factory()->setAttributes(array('id' => 3, 'role' => 'Client', 'is_backend' => 'F', 'T'))->insert();
        
		// Grant full permissions to Admin
        $user_id = 1; // Admin ID
        $pjAuthUserPermissionModel->reset()->where('user_id', $user_id)->eraseAll();
        foreach($permissions as $key => $permission_id)
        {
            $pjAuthUserPermissionModel->setAttributes(compact('user_id', 'permission_id'))->insert();
        }
        
        pjPaymentOptionModel::factory()->where('payment_method', 'world_pay')->eraseAll();

        return $result;
    }
    
    public function isEditor()
	{
		return $this->getRoleId() == 2;
	}
	public function isClient()
	{
	    return $this->getRoleId() == 3;
	}
	
    public function beforeFilter()
    {
        parent::beforeFilter();

        if(!in_array($this->_get->toString('controller'), array('pjFront')))
        {
            $this->appendJs('pjAdminCore.js');
            // TODO: DELETE unnecessary files
            #$this->appendCss('reset.css');
            //$this->appendCss('pj-all.css', PJ_FRAMEWORK_LIBS_PATH . 'pj/css/');
            if(in_array($this->_get->toString('controller'), array('pjAdminRooms')) && in_array($this->_get->toString('action'), array('pjActionUpdate')))
            {
                $this->appendCss('pj-all.css', PJ_FRAMEWORK_LIBS_PATH . 'pj/css/');
                $this->appendJs('jquery-ui.min.js', PJ_THIRD_PARTY_PATH . 'jquery_ui/');
                $this->appendCss('jquery-ui.min.css', PJ_THIRD_PARTY_PATH . 'jquery_ui/');
            }
            $this->appendCss('admin.css');
        }
        if ($this->_get->toString('controller') == 'pjAdminPrices' && @$this->_get->toString('action') == 'pjActionIndex')
        {
            if ($this->_get->check('room_id') && $this->_get->toInt('room_id') > 0)
            {
                $_SESSION[$this->defaultRoom] = (int) $this->_get->toInt('room_id');
            }
            
            $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')
                ->where('t1.calendar_id', $this->getForeignId())
                ->orderBy('`name` ASC')
                ->findAll()
                ->getData()
                );
            
            if ($this->getForeignIdPrice() !== FALSE)
            {
                foreach ($this->tpl['room_arr'] as $room)
                {
                    if ($room['id'] == $this->getForeignIdPrice())
                    {
                        $this->option_arr['o_bf_adults_max'] = $room['adults'];
                        $this->option_arr['o_bf_children_max'] = $room['children'];
                        $this->set('option_arr', $this->option_arr);
                        break;
                    }
                }
            }
        }
        
        if ($this->_get->toString('controller') != 'pjInstaller') {
        	$this->notConfirmed();	
        }
        return true;
    }
    
    public function getForeignId()
    {
    	return 1;
    }
    
	public function getForeignIdPrice()
	{
		return isset($_SESSION[$this->defaultRoom]) && (int) $_SESSION[$this->defaultRoom] > 0 ? (int) $_SESSION[$this->defaultRoom] : false;
	}
    
    public static function jsonDecode($str)
	{
		$Services_JSON = new pjServices_JSON();
		return $Services_JSON->decode($str);
	}
	
	public static function jsonEncode($arr)
	{
		$Services_JSON = new pjServices_JSON();
		return $Services_JSON->encode($arr);
	}
	
	public static function jsonResponse($arr)
	{
		header("Content-Type: application/json; charset=utf-8");
		echo pjAppController::jsonEncode($arr);
		exit;
	}

	public function getLocaleId()
	{
		return isset($_SESSION[$this->defaultLocale]) && (int) $_SESSION[$this->defaultLocale] > 0 ? (int) $_SESSION[$this->defaultLocale] : 1;
	}
	
	public function getDirection()
	{
		$dir = 'ltr';
		if($this->getLocaleId() != false)
		{
			$locale_arr = pjLocaleModel::factory()->find($this->getLocaleId())->getData();
			$dir = $locale_arr['dir'];
		}
		return $dir;
	}
	
	public function getRoomPrice($room_id, $date_from, $date_to, $night_mode=true, $adults=null, $children=null)
    {
    	list($startY, $startM, $startD) = explode("-", $date_from);
    	$from = strtotime($date_from);
    	$to = strtotime($date_to);
    	
    	$dateFrom = new DateTime($date_from);
    	$dateTo = new DateTime($date_to);
    	$nights= $dateTo->diff($dateFrom)->format("%a");
    	
    	if (!$night_mode)
    	{
    		$nights += 1;
    	}
    	list($txtDayOfWeek, $startDay) = explode("-", date("D-w", $from));
    	$isoDayOfWeek = $startDay > 0 ? $startDay : 7;
    	
    	
    	$pjPriceModel = pjPriceModel::factory();
    	$price_arr = $pjPriceModel
    		->where('t1.foreign_id', $room_id)
    		
			->where('t1.date_from <=', $date_to)
			->where('t1.date_to >=', $date_from)
			->findAll()
			->getData();
    	
		$default_price_arr = $pjPriceModel
			->reset()
			->where('t1.foreign_id', $room_id)
			->where("(t1.date_from IS NULL)")
			->where("(t1.date_to IS NULL)")
			->findAll()
			->getData();
		
    	foreach ($price_arr as $k => $item)
    	{
			$price_arr[$k]['ts_from'] = strtotime($item['date_from']);
			$price_arr[$k]['ts_to'] = strtotime($item['date_to']);
    	}
    	$mask = array(1 => 'mon', 2 => 'tue', 3 => 'wed', 4 => 'thu', 5 => 'fri', 6 => 'sat', 7 => 'sun');

    	# Discounts
    	$discount_price = 0;
    	$pjDiscountPackageModel = pjDiscountPackageModel::factory();
    	$pjDiscountPackageItemModel = pjDiscountPackageItemModel::factory();
    	
		$d_arr = $pjDiscountPackageItemModel
			->select('t1.price AS total_price, t2.start_day, t2.end_day, t2.date_from, t2.date_to')
			->join('pjDiscountPackage', 't2.id=t1.package_id', 'inner')
			->where('t1.adults', $adults)
			->where('t1.children', $children)
			->where('t2.room_id', $room_id)
			->where('t2.date_from <=', $date_from)
			->where('t2.date_to >=', $date_to)
			->orderby('t2.date_from ASC')
			->findAll()
			->getData();
		
		if (empty($d_arr))
		{
			$d_arr = $pjDiscountPackageModel
				->select('t1.total_price, t1.start_day, t1.end_day, t1.date_from, t1.date_to')
				->where('t1.room_id', $room_id)
				->where('t1.date_from <=', $date_from)
				->where('t1.date_to >=', $date_to)
				->orderby('t1.date_from ASC')
				->findAll()
				->getData();
		}

    	if (!empty($d_arr))
		{
			$endDay = date("w", $to);
    		$_end = $endDay > 0 ? $endDay : 7;
    		$_start = $isoDayOfWeek;
			$tmp = $d_arr;
			$br = 0;
			foreach ($tmp as $k => $d_arr)
			{
				$d_start = $d_arr['start_day'] > 0 ? $d_arr['start_day'] : 7;
				$d_end = $d_arr['end_day'] > 0 ? $d_arr['end_day'] : 7;
				if ((float) $d_arr['total_price'] > 0 && ($br == 0 || ($_start == $d_start && $_end == $d_end)))
				{
		    		$discount_price = (float) $d_arr['total_price'];
		    		$discountPackageStart = strtotime($d_arr['date_from']);
					$discountPackageEnd = strtotime($d_arr['date_to']);
					
					$discount_ts = array();
					$discount_pretty = array();
					$d_start = $d_arr['start_day'];
					$d_end = $d_arr['end_day'];
					
					$scenario_1 = ($discountPackageEnd - $discountPackageStart > $to - $from);
					$scenario_2 = ($discountPackageEnd - $discountPackageStart < $to - $from);
					$scenario_3 = ($discountPackageEnd - $discountPackageStart == $to - $from);

					$daysAreInsufficient = (($to - $from)/86400 < ($discountPackageEnd - $discountPackageStart)/86400 && ($discountPackageEnd - $discountPackageStart)/86400 <= 7);

					if ($d_start != 7 && $d_end != 7
						&& (($scenario_1 && !$daysAreInsufficient)
							xor ($scenario_2 && !$daysAreInsufficient)
							xor ($scenario_3 && $discountPackageStart == $from && $discountPackageEnd == $to)
							)
					)
					{
						$d_start = $d_start > 0 ? $d_start : 7;
						$d_end = $d_end > 0 ? $d_end : 7;
						
						if ($d_start == $d_end)
						{
							$d_end -= 1;
							if ($d_end == 0)
							{
								$d_end += 7;
							}
						}
						
						$index = -1;
						$is_open = false;
						for ($i = $discountPackageStart; $i <= $discountPackageEnd; $i = strtotime('+1 day', $i))
						{
							$weekday = date("w", $i);
							$weekday = $weekday > 0 ? $weekday : 7;
							//if ($weekday == $d_start && ($discountPackageEnd - $i)/86400 +1 >= 7 - $d_start)
							if ($weekday == $d_start)
							{
								$is_open = true;
								$index += 1;
								$discount_pretty[$index] = array();
								$discount_ts[$index] = array();
							}
							
							if ($is_open)
							{
								if($i==$to && $night_mode){
								} else {
									$discount_pretty[$index][] = date("d.m.Y - l", $i);
									$discount_ts[$index][] = $i;
								}
							}
	
							if ($weekday == $d_end)
							{
								$is_open = false;
							}
						}
					}
					
					$br++;
				}
			}
		}
		
		# Discounts
    	$price = $discount = 0;
    	$j = $isoDayOfWeek;
    	$season = $pricePerNight = array();
    	#---
    	$ins = array();
		if (isset($discount_ts))
		{
			foreach ($discount_ts as $d_key => $times)
			{
				foreach ($times as $_k => $_v)
				{
					$ins[$d_key][$_k] = 0;
				}
			}
		}
    	foreach (range(1, $nights) as $i)
    	{
    		$date = mktime(0, 0, 0, $startM, $startD + ($i - 1), $startY);
    		
    		if (isset($discount_ts))
    		{
	    		foreach ($discount_ts as $d_key => $times)
	    		{
	    			if ($date >= min($times) && $date <= max($times))
	    			{
	    				$ins[$d_key][ array_search($date, $times) ] = 1;
	    				break;
	    			}
	    		}
    		}
    	}

    	$discount_multiple = 0;
		if ($discount_price > 0 && isset($discount_ts) && !empty($discount_ts) && !empty($ins))
		{
			foreach ($ins as $ii)
			{
				if (!in_array(0, $ii))
				{
					$discount_multiple += 1;
				}
			}
		}
    	#---
    	foreach (range(1, $nights) as $i)
    	{
    		if ($j > 7)
    		{
    			$j = 1;
    		}
    		$date = mktime(0, 0, 0, $startM, $startD + ($i - 1), $startY);
    		
    		$in = false;
    		if (isset($discount_ts) && !empty($ins))
    		{
	    		foreach ($discount_ts as $d_key => $times)
	    		{
	    			if ($date >= min($times) && $date <= max($times) && !in_array(0, $ins[$d_key]))
	    			{
	    				$in = true;
	    				break;
	    			}
	    		}
    		}

    		# Season price
    		foreach ($price_arr as $k => $item)
    		{
    			if ($date >= $item['ts_from'] && $date <= $item['ts_to'])
    			{
    				if (!is_null($adults) && (int) $adults > -1 && $adults != $item['adults'])
    				{
    					continue;
    				}
    				if (!is_null($children) && (int) $children > -1 && $children != $item['children'])
    				{
    					continue;
    				}
    				if (isset($discountPackageStart) && isset($discountPackageEnd) &&
    					$date >= $discountPackageStart && $date <= $discountPackageEnd &&
    					$in)
    				{
    				} else{
    					$price += $item[$mask[$j]];
    				}
    				$pricePerNights[$i] = $item[$mask[$j]];
    				$season[$i] = true;
    				break;
    			}
    		}
    		# Default price (season)
    		if (!isset($season[$i]))
    		{
	    		foreach ($price_arr as $k => $item)
	    		{
	    			if ($date >= $item['ts_from'] && $date <= $item['ts_to'])
	    			{
	    				if (isset($discountPackageStart) && isset($discountPackageEnd) &&
	    					$date >= $discountPackageStart && $date <= $discountPackageEnd &&
	    					$in)
	    				{
	    				} else{
	    					$price += $item[$mask[$j]];
	    				}
	    				$pricePerNights[$i] = $item[$mask[$j]];
	    				$season[$i] = true;
	    				break;
	    			}
	    		}
    		}
    		# Default price (adults, children)
    		if (!isset($season[$i]))
    		{
    			foreach ($default_price_arr as $k => $item)
	    		{
	    			if (!is_null($adults) && (int) $adults > -1 && $adults != $item['adults'])
    				{
    					continue;
    				}
    				if (!is_null($children) && (int) $children > -1 && $children != $item['children'])
    				{
    					continue;
    				}
    				if (isset($discountPackageStart) && isset($discountPackageEnd) &&
    					$date >= $discountPackageStart && $date <= $discountPackageEnd &&
    					$in)
    				{
    				} else{
    					$price += $item[$mask[$j]];
    				}
    				$pricePerNights[$i] = $item[$mask[$j]];
    				$season[$i] = true;
    				break;
	    		}
    		}
    		# Default price (general)
    		if (!isset($season[$i]))
    		{
	    		foreach ($default_price_arr as $k => $item)
	    		{
	    			if ((int) $item['adults'] === 0 && (int) $item['children'] === 0)
	    			{
	    				if (isset($discountPackageStart) && isset($discountPackageEnd) &&
	    					$date >= $discountPackageStart && $date <= $discountPackageEnd &&
	    					$in)
	    				{
	    				} else {
	    					$price += $item[$mask[$j]];
	    				}
	    				$pricePerNights[$i] = $item[$mask[$j]];
	    				$season[$i] = true;
	    				break;
	    			}
	    		}
    		}
    		$j++;
    	}
    	$pjDiscountFreeModel = pjDiscountFreeModel::factory();
		
		$free_arr = $pjDiscountFreeModel
			->select('t1.min_length, t1.max_length, t1.free_nights')
			->where('t1.room_id', $room_id)
			->where('t1.date_from <=', $date_to)
			->where('t1.date_to >=', $date_from)
			->where('t1.min_length <=', $nights)
			->where('t1.max_length >=', $nights)
			->limit(1)
			->findAll()
			->getData()
		;
		
		if (!empty($free_arr))
		{
			$free_arr = $free_arr[0];
			for ($i = $nights; $i > $nights - (int) $free_arr['free_nights']; $i--)
			{
				$discount += $pricePerNights[$i];
    		}
		}

		$price += $discount_price * $discount_multiple;
    	$price -= $discount;
    	$price = $price > 0 ? $price : 0;
    	return $price;
    }
    
	public static function getTokens($booking_arr, $option_arr)
    {
    	$room_arr = $extra_arr = array();
    	
    	if (isset($booking_arr['rooms']) && !empty($booking_arr['rooms']))
    	{
    		foreach ($booking_arr['rooms'] as $room)
    		{
    			$room_arr[] = sprintf("%u x %s", $room['cnt'], $room['name']);
    		}
    	}
    	
    	if (isset($booking_arr['extras']) && !empty($booking_arr['extras']))
    	{
    		foreach ($booking_arr['extras'] as $extra)
    		{
    		    $extra_arr[] = pjSanitize::clean($extra['name']);
    		}
    	}
    	
    	$rooms = join("; ", $room_arr);
    	$extras = join("; ", $extra_arr);
		$pt = __('personal_titles', true);
		
		if ((int)$booking_arr['client_id'] > 0) {
			$client_arr = pjClientModel::factory()
		        ->select("t1.*, t2.email as c_email, t2.name as c_name, t2.phone as c_phone")
				->join('pjAuthUser', 't2.id=t1.foreign_id', 'left outer')
			    ->find($booking_arr['client_id'])
	    		->getData();
	    	if ($client_arr) {
	    		unset($client_arr['id']);
	    		unset($client_arr['foreign_id']);
	    		unset($client_arr['calendar_id']);
	    		unset($client_arr['c_notes']);
	    		$booking_arr = array_merge($booking_arr, $client_arr);
	    	}
		}
		
		$hash = sha1($booking_arr['id'].$booking_arr['created'].PJ_SALT);
		$cancelURL = $option_arr['o_cancel_booking_url'];
		$cancelURL .= '#!/Cancel/id:' . $booking_arr['id'] . '/hash:' . $hash;
		$cancelURL = '<a href="'.$cancelURL.'">'.$cancelURL.'</a>';
		
		$c_arrival = date($option_arr['o_time_format'], strtotime($booking_arr['c_arrival']));
		$payment_titles = pjPayments::getPaymentTitles($booking_arr['calendar_id'], $booking_arr['locale_id']);
		$payment_method = $booking_arr['payment_method'];
		if (isset($payment_titles[$booking_arr['payment_method']])) {
			$payment_method = $payment_titles[$booking_arr['payment_method']];
		}
		
    	$search = array(
    		'{Title}', '{Name}', '{Phone}', '{Email}',
    		'{ArrivalTime}', '{Notes}', '{Company}', '{Address}', '{City}',
    		'{State}', '{Zip}', '{Country}',
    		'{PaymentMethod}', '{Deposit}',
    		'{SecurityDeposit}', '{Rooms}', '{Extras}',
    		'{Tax}', '{Total}', '{RoomPrice}', '{ExtraPrice}', '{Discount}',
    		'{DateFrom}', '{DateTo}', '{BookingID}',
    		'{CancelURL}'
    	);
		$replace = array(
			@$pt[$booking_arr['c_title']], pjSanitize::clean($booking_arr['c_name']), pjSanitize::clean($booking_arr['c_phone']), pjSanitize::clean($booking_arr['c_email']),
			$c_arrival, pjSanitize::clean($booking_arr['c_notes']), pjSanitize::clean($booking_arr['c_company']), pjSanitize::clean($booking_arr['c_address']), pjSanitize::clean($booking_arr['c_city']),
			$booking_arr['c_state'], $booking_arr['c_zip'], @$booking_arr['country'],
			$payment_method, 
			pjCurrency::formatPrice($booking_arr['deposit']),
			pjCurrency::formatPrice($booking_arr['security']), 
			$rooms, $extras,
			pjCurrency::formatPrice($booking_arr['tax']), 
			pjCurrency::formatPrice($booking_arr['total']), 
			pjCurrency::formatPrice($booking_arr['room_price']), 
			pjCurrency::formatPrice($booking_arr['extra_price']), 
			pjCurrency::formatPrice($booking_arr['discount']),
			pjDateTime::formatDate($booking_arr['date_from'], 'Y-m-d', $option_arr['o_date_format']), pjDateTime::formatDate($booking_arr['date_to'], 'Y-m-d', $option_arr['o_date_format']), $booking_arr['uuid'],
			$cancelURL
		);
		return compact('search', 'replace');
    }
    
    public static function getClientTokens($option_arr, $client_id, $salt, $locale_id)
    {
        $country = NULL;
        $client = pjClientModel::factory()->find($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='".$locale_id."'", 'left outer')
            ->find($client['c_country'])->getData();
            if (!empty($country_arr))
            {
                $country = $country_arr['country_title'];
            }
        }
        $search = array(
            '{Title}', '{Name}', '{Phone}', '{Email}', '{Password}',
            '{Notes}', '{Company}', '{Address}', '{City}', '{State}', '{Zip}', '{Country}');
        $replace = array(
            @$client['c_title'], pjSanitize::clean(@$auth_client['name']), pjSanitize::clean(@$auth_client['phone']), pjSanitize::clean(@$auth_client['email']), @$auth_client['password'],
            @$client['c_notes'], pjSanitize::clean(@$client['c_company']), pjSanitize::clean(@$client['c_address']), pjSanitize::clean(@$client['c_city']), pjSanitize::clean(@$client['c_state']), pjSanitize::clean(@$client['c_zip']), $country);
            return compact('search', 'replace');
    }
    
	public static function getDiscount($data, $room_ids)
	{
		if (!isset($data['code']) || empty($data['code']))
		{
			return array('status' => 'ERR', 'code' => 100, 'text' => 'Voucher code couldn\'t be empty.');
		}
		$arr = pjDiscountCodeModel::factory()
			->where('t1.promo_code', $data['code'])
			->whereIn('room_id', $room_ids)
			->findAll()
			->getData();
			
		if (empty($arr))
		{
			return array('status' => 'ERR', 'code' => 101, 'text' => 'Voucher not found.');
		}
		
		$rooms = array();
		foreach ($arr as $item)
		{
			if (strtotime($item['date_from']) <= strtotime($data['date_to']) && strtotime($item['date_to']) >= strtotime($data['date_from']))
			{
				$rooms[$item['room_id']] = array(
					'voucher_type' => $item['type'],
					'voucher_discount' => $item['discount']
				);
			}
		}
		if (empty($rooms))
		{
			return array('status' => 'ERR', 'code' => 102, 'text' => '');
		}
		
		return array(
			'status' => 'OK',
			'code' => 200,
			'text' => 'Voucher code has been applied.',
			'voucher_code' => $data['code'],
			'voucher_rooms' => $rooms
		);
	}

	public static function getMonthStatus($calendar_id, $month, $year)
	{
		$numOfDays = date("t", mktime(0, 0, 0, $month, 1, $year));
		$_arr = array();
		foreach (range(1, $numOfDays) as $i)
		{
			$_arr[date("Y-m-d", mktime(0, 0, 0, $month, $i, $year))] = array('code' => 1, 'text' => 'free');
		}
		//TODO
		return $_arr;
	}
	
	public function calPrices($booking_rooms, $date_from, $date_to, $voucher_arr, $extras, $nights, $option_arr, $from)
	{
		$_persons = 0;
		$room_price = $extra_price = $total = $security = $tax = $deposit = $discount = 0;
		$rooms_price_stack = array();
		
		if(isset($booking_rooms) && $from == 'front')
		{
			foreach ($booking_rooms as $room_id => $room_arr)
			{
				$rooms_price_stack[$room_id] = array();
				foreach ($room_arr as $index => $room_info)
				{
					$amount = $this->getRoomPrice($room_id, $date_from, $date_to, ($option_arr['o_price_based_on'] == 'nights'), $room_info['adults'], $room_info['children']);
					$room_price += $amount;
					$discount += pjUtil::getDiscount($amount, $room_id, $voucher_arr);
					$_persons += $room_info['adults'] + $room_info['children'];
					$rooms_price_stack[$room_id][$index] = $amount;
				}
			}
		}else{
			foreach ($booking_rooms as $room_info)
			{
				$amount = $this->getRoomPrice($room_info['room_id'], $date_from, $date_to, ($option_arr['o_price_based_on'] == 'nights'), $room_info['adults'], $room_info['children']);
				$room_price += $amount;
				$discount += pjUtil::getDiscount($amount, $room_info['room_id'], $voucher_arr);
				$_persons += $room_info['adults'] + $room_info['children'];
				pjBookingRoomTempModel::factory()->reset()->set('id', $room_info['id'])->modify(array('price' => $amount));
			}
		}
		
		if (isset($extras['extra_id']) && is_array($extras['extra_id']) && count($extras['extra_id']) > 0)
		{
			foreach ($extras['extra_id'] as $extra_id => $extra_str)
			{
				list($_per, $_price) = explode("|", $extra_str);
				switch ($_per)
				{
					case 'day':
						$extra_price += $_price * $nights;
						break;
					case 'booking':
						$extra_price += $_price;
						break;
					case 'person':
						$extra_price += $_price * $_persons;
						break;
					case 'day_person':
						$extra_price += $_price * $nights * $_persons;
						break;
				}
			}
		}else{
			if (isset($extras) && is_array($extras) && count($extras) > 0)
			{
				foreach ($extras as $extra)
				{
				    if(isset($extra['per']))
				    {
    					switch ($extra['per'])
    					{
    						case 'day':
    							$extra_price += $extra['price'] * $nights;
    							break;
    						case 'booking':
    							$extra_price += $extra['price'];
    							break;
    						case 'person':
    							$extra_price += $extra['price'] * $_persons;
    							break;
    						case 'day_person':
    							$extra_price += $extra['price'] * $nights * $_persons;
    							break;
    					}
				    }
				}
			}
		}
		$total = $extra_price + $room_price;
		$total -= $discount;
		$total > 0 ? $total : 0;
		if ((float) $option_arr['o_tax'] > 0 && $total > 0)
		{
			$tax = ($total * (float) $option_arr['o_tax']) / 100;
			$total += $tax;
		}
			
		if ((float) $option_arr['o_security'] > 0 && $total > 0)
		{
			$security = (float) $option_arr['o_security'];
		}
			
		if (isset($option_arr['o_require_all_within'])
				&& (int) $option_arr['o_require_all_within'] > 0
				&& strtotime(date("Y-m-d")) + (int) $option_arr['o_require_all_within'] * 86400 >= strtotime($date_from))
		{
			$deposit = $total;
		} else {
			switch ($option_arr['o_deposit_type'])
			{
				case 'percent':
					$deposit = ($total * $option_arr['o_deposit']) / 100;
					break;
				case 'amount':
					$deposit = $option_arr['o_deposit'];
					break;
			}
		}
		$deposit += $security;
		
		$result['room_price'] = $room_price;
		$result['extra_price'] = $extra_price;
		$result['total'] = $total;
		$result['security'] = $security;
		$result['tax'] = $tax;
		$result['deposit'] = $deposit;
		$result['discount'] = $discount;
		$result['rooms_price_stack'] = $rooms_price_stack;
		
		$result['room_price_f'] = pjCurrency::formatPrice($room_price);
		$result['extra_price_f'] = pjCurrency::formatPrice($extra_price);
		$result['total_f'] = pjCurrency::formatPrice($total);
		$result['security_f'] = pjCurrency::formatPrice($security);
		$result['tax_f'] = pjCurrency::formatPrice($tax);
		$result['deposit_f'] = pjCurrency::formatPrice($deposit);
		$result['discount_f'] = pjCurrency::formatPrice($discount);
		
		return $result;
	}
	
	protected static function getAdminEmail()
	{
	    $arr = pjAuthUserModel::factory()->select('t1.email')->find(1)->getData();
	    
	    return $arr ? $arr['email'] : NULL;
	}
	protected static function getAdminPhone()
	{
	    $arr = pjAuthUserModel::factory()->select('t1.phone')->find(1)->getData();
	    
	    return $arr ? $arr['phone'] : NULL;
	}
	
	protected function notConfirmed()
	{
		if ($this->option_arr['o_allow_pending_time'] == 1) {
			pjBookingModel::factory()
				->where('`status`', 'pending')
				->where(sprintf("UNIX_TIMESTAMP(NOW()) >= UNIX_TIMESTAMP(DATE_ADD(`created`, INTERVAL %u MINUTE))", $this->option_arr['o_pending_time']))
				->modifyAll(array('status' => 'not_confirmed'));
		}
	}
}
?>