<?php
class Expense extends AppModel
{
	var $name = 'Expense';
	public $hasOne = 'GroupSettings';

	function setGroupExpenseValidation()
	{

		$this->validate = array(
			'title' => array(

				'notBlank' => array(
					'rule' => 'notBlank',
					'message' =>  __('TITLE_NOT_EMPTY_MAX_CHAR')
				),
				'between' => array(
					'rule' => array('maxLength', '50'),
					'message' =>  __('TITLE_NOT_EMPTY_MAX_CHAR')
				)
			),
			'YourName' => array(

				'notBlank' => array(
					'rule' => 'notBlank',
					'message' => __('YOUR_NAME_NOT_EMPTY_MAX_CHAR')
				),
				'between' => array(
					'rule' => array('maxLength', PARTICIPENT_NAME_LENGTH),
					'message' =>  __('YOUR_NAME_NOT_EMPTY_MAX_CHAR')
				),
                'noForbiddenChars' => array(
                    'rule' => ['custom', '/^[^,|]*$/'],
                    'message' => __('LBL_PARTICIPENT_NAME_ERROR')
                )
			),
			'participants' => array(

				'notBlank' => array(
					'rule' => array('participantLengthCheck', PARTICIPENT_NAME_LENGTH),
					'message' =>  __('PARTICIPANT_NOT_EMPTY_MAX_CHAR')
				),
				'duplicacy' => array(
					'rule' => array('participantDuplicacyCheck', 'YourName'),
					'message' =>  __('PARTICIPANT_DUPCICATE')
				)

			),
			'emails' => array(

				'notBlank' => array(
					'rule' => array('validEmailCheck'),
					'message' =>  __('EMAIL_IS_NOT_VALIE')
				)

			),
			'currency' => array(

				'notBlank' => array(
					'rule' => 'notBlank',
					'message' => __('CURRENCY_NOT_EMPTY_MAX_CHAR')
				),
				'between' => array(
					'rule' => array('maxLength', '3'),
					'message' =>  __('CURRENCY_NOT_EMPTY_MAX_CHAR')
				)
			),
			'captcha' => array(

				'notBlank' => array(
					'rule' => 'notBlank',
					'message' => __('CAPTCHA_NOT_EMPTY_MAX_CHAR')
				),
				'between' => array(
					'rule' => array('maxLength', '5'),
					'message' =>  __('CAPTCHA_NOT_EMPTY_MAX_CHAR')
				)
			)
		);
	}


	function setFamilyExpenseValidation()
	{

		$this->validate = array(
			'title' => array(

				'notBlank' => array(
					'rule' => 'notBlank',
					'message' =>  __('TITLE_NOT_EMPTY_MAX_CHAR')
				),
				'between' => array(
					'rule' => array('maxLength', '50'),
					'message' =>  __('TITLE_NOT_EMPTY_MAX_CHAR')
				)
			),

			'currency' => array(

				'notBlank' => array(
					'rule' => 'notBlank',
					'message' => __('CURRENCY_NOT_EMPTY_MAX_CHAR')
				),
				'between' => array(
					'rule' => array('maxLength', '3'),
					'message' =>  __('CURRENCY_NOT_EMPTY_MAX_CHAR')
				)
			),
			'emails' => array(

				'notBlank' => array(
					'rule' => array('validEmailCheck'),
					'message' =>  __('EMAIL_IS_NOT_VALIE')
				)

			),
			'captcha' => array(

				'notBlank' => array(
					'rule' => 'notBlank',
					'message' => __('CAPTCHA_NOT_EMPTY_MAX_CHAR')
				),
				'between' => array(
					'rule' => array('maxLength', '5'),
					'message' =>  __('CAPTCHA_NOT_EMPTY_MAX_CHAR')
				)
			)
		);
	}


	function setGroupExpenseModifyValidation()
	{

		$this->validate = array(
			'title' => array(

				'notBlank' => array(
					'rule' => 'notBlank',
					'message' =>  __('TITLE_NOT_EMPTY_MAX_CHAR')
				),
				'between' => array(
					'rule' => array('maxLength', '50'),
					'message' =>  __('TITLE_NOT_EMPTY_MAX_CHAR')
				),
                'noForbiddenChars' => array(
                    'rule' => ['custom', '/^[^,|]*$/'],
                    'message' => __('LBL_PARTICIPENT_NAME_ERROR')
                )
			),
			'currency' => array(

				'notBlank' => array(
					'rule' => 'notBlank',
					'message' => __('CURRENCY_NOT_EMPTY_MAX_CHAR')
				),
				'between' => array(
					'rule' => array('maxLength', '3'),
					'message' =>  __('CURRENCY_NOT_EMPTY_MAX_CHAR')
				)
			)
		);
	}

	/*public $hasMany = array(
			'Participant' => array(
					'className' => 'Participant',
					'conditions' => array('Participant.expense_id' => 'Expense.id'),
					'order' => 'Participant.create_date ASC'
			),
			'GroupExpense' => array(
				'className' =>'GroupExpense',
					'conditions' => array('GroupExpense.expense_id' => 'Expense.id'),
					'order' => 'GroupExpense.create_date ASC') ,
			'Meal' => array(
					'className' =>'Meal',
						'conditions' => array('Meal.expense_id' => 'Expense.id'),
						'order' => 'Meal.date ASC')  
			 
	);*/

	public function setORMForGroupExpense()
	{
		$this->bindModel(array('hasMany' => array(
			'Participant' => array(
				'className' => 'Participant',
				'conditions' => array('Participant.expense_id' => 'Expense.id'),
				'order' => 'Participant.create_date ASC'
			),
			'GroupExpense' => array(
				'className' => 'GroupExpense',
				'conditions' => array('GroupExpense.expense_id' => 'Expense.id'),
				'order' => 'GroupExpense.create_date ASC'
			)

		)));
	}

	public function setORMForFamilyExpense()
	{
		$this->bindModel(array('hasMany' => array(

			'FamilyExpense' => array(
				'className' => 'FamilyExpense',
				'conditions' => array('FamilyExpense.expense_id' => 'Expense.id'),
				'order' => 'FamilyExpense.create_date ASC'
			)

		)));
	}

	public function setORMForMess()
	{

		$this->bindModel(array('hasMany' => array(
			'Participant' => array(
				'className' => 'Participant',
				'conditions' => array('Participant.expense_id' => 'Expense.id'),
				'order' => 'Participant.create_date ASC'
			),
			'GroupExpense' => array(
				'className' => 'GroupExpense',
				'conditions' => array('GroupExpense.expense_id' => 'Expense.id'),
				'order' => 'GroupExpense.create_date ASC'
			),
			'Meal' => array(
				'className' => 'Meal',
				'conditions' => array('Meal.expense_id' => 'Expense.id'),
				'order' => 'Meal.date ASC'
			)

		)));
	}

	public function getGroupExpenseInfoByURL($unique_url)
	{

		$expenseType = substr($unique_url, 0, 1);
		if ($expenseType == "2" || $expenseType == "7") {
			$this->setORMForMess();
		} else {
			$this->setORMForGroupExpense();
		}
		$this->unbindModel(
			array(
				'hasOne' => array('GroupSettings')
			)
		);
		return $this->find('first', array('conditions' => array('BINARY(Expense.unique_url)' => $unique_url)));
	}

	public function getFamilyExpenseInfoByURL($unique_url)
	{

		$this->setORMForFamilyExpense();
		$this->unbindModel(
			array(
				'hasOne' => array('GroupSettings')
			)
		);
		return $this->find('first', array('conditions' => array('BINARY(Expense.unique_url)' => $unique_url)));
	}

	public function participantLengthCheck($check, $limit)
	{

		$result = true;

		$value = trim($check["participants"]);
		if ($value != "") {
			$valueArray = explode(",", $value);

			foreach ($valueArray as $key => $value) {
				if (mb_strlen($value, 'UTF-8') > $limit) {
					$result = false;
					break;
				}
			}
		}

		return $result;
	}


	public function validEmailCheck($check)
	{

		$result = true;

		$value = trim($check["emails"]);
		if ($value != "") {
			if (filter_var($value, FILTER_VALIDATE_EMAIL) === false) {
				$result = false;
			}
		}

		return $result;
	}


	public function participantDuplicacyCheck($check, $yourName)
	{
		$result = true;


		$value = trim($check["participants"]);
		if ($value != "") {
			$valueArray = explode(",", $value);
			foreach ($valueArray as $key => $value) {
				$valueArray[$key] = trim(strtolower($value));
			}

			$length = count($valueArray);
			$unique_array = array_unique($valueArray);
			if (count($unique_array) != $length) {
				$result = false;
			} else {
				foreach ($valueArray as $key => $value) {
					if (trim(strtolower($value)) == trim(strtolower($this->data["Expense"][$yourName]))) {
						$result = false;
						break;
					}
				}
			}
		}

		return $result;
	}

	function modifyExpense($expenseFormArray)
	{

		$result = null;

		$form["id"] = trim($expenseFormArray["id"]);
		$form["title"] = trim($expenseFormArray["title"]);
		$form["currency"] = trim($expenseFormArray["currency"]);
		$form["description"] = trim($expenseFormArray["description"]);
		$form["version"] = trim($expenseFormArray["version"]);
		if (isset($expenseFormArray["default_meal"])) {
			$form["default_meal"] = trim($expenseFormArray["default_meal"]);
			$fileds = array('id', 'title', 'currency', 'description', 'update_date', 'update_user', 'default_meal', 'version');
		} else {
			$fileds = array('id', 'title', 'currency', 'description', 'update_date', 'update_user', 'version');
		}
		$form["update_date"] = time();
		$form["update_user"] = "system";





		$data["Expense"] = $form;
		if (!$this->save($data, false, $fileds)) {
			$result["22"] = "expense not has been saved successfully";
		}

		return $result;
	}

	function createExpense($expenseFormArray, $isRemote, $archieved = false)
	{

		$result = "";

		$form["unique_url"] = "NEW";
		$form["title"] = trim($expenseFormArray["title"]);
		$form["currency"] = trim($expenseFormArray["currency"]);
		$form["description"] = trim($expenseFormArray["description"]);
		$form["language"] = $expenseFormArray["language"];
		$form["expense_type"] = $expenseFormArray["expense_type"];	   // 1 = Group expense		
		$form["source"] = $expenseFormArray["source"]; //1=web,2=mobile,3=facebook

		$form["create_date"] = $expenseFormArray["create_date"]; //

		if (!empty($expenseFormArray["create_user"])) {
			$form["create_user"] = $expenseFormArray["create_user"];
		} else {
			$form["create_user"] = "system";
		}

		$form["update_date"] = time();
		$form["update_user"] = "system";

		$form["ip"] = $expenseFormArray["ip"];;
		$form["user_agent"] = $expenseFormArray["user_agent"];;
		//$form["email"] = trim($expenseFormArray["email"]);
		$form["version"] = "0";
		$form["status"] = "1";

		if ($form["expense_type"] == "2") {
			$form["default_meal"] = "0.5|1.0|1.0";
		} else {
			$form["default_meal"] = "";
		}

        if (!empty($expenseFormArray["user_id"])) {
            $form["user_id"] = $expenseFormArray["user_id"];
        }

		//insert into the table group_expenses	 
		if ($form["expense_type"] == "1" || $form["expense_type"] == "2") {

			$fileds = array(
				'unique_url',
				'title',
				'currency',
				'description',
				'language',
				'expense_type',
				'source',
				'create_user',
				'create_date',
				'update_date',
				'update_user',
				'status',
				'default_meal',
				'ip',
				'user_agent',
				'version',
                'user_id'
			);
			if ($archieved) {
				$fileds[] = 'id';
				$form['unique_url'] = $expenseFormArray["unique_url"];
				$form['id'] = $expenseFormArray["id"];
			}

			$data["Expense"] = $form;

			if ($this->save($data, false, $fileds)) {
				$id =  $this->id;
				if ($id != "") {
					$this->id = $id;
					if ($archieved) {
						$this->insertParticipantsByRemote($id, $expenseFormArray["participants"]);
						$result = $id . "," . $expenseFormArray["unique_url"];
					} else {
						$unique_url_id = $expenseFormArray["expense_type"] . $this->getUniqueURLById(time()) . $this->getUniqueURLById($id) . trim($expenseFormArray["secret_key"]);
						//update group_expenses
						if ($this->saveField("unique_url", $unique_url_id)) {
							//insert into participant table
							if ($isRemote == false) {
								$this->insertParticipants($id, $expenseFormArray["your_name"], $expenseFormArray["participants"]);
							} else {
								$this->insertParticipantsByRemote($id, $expenseFormArray["participants"]);
							}
							$result = $id . "," . $unique_url_id;
						}
					}
				}
			}
		}
        else if ($form["expense_type"] == "3") {
			$fileds = array(
				'unique_url',
				'title',
				'currency',
				'description',
				'language',
				'expense_type',
				'source',
				'create_user',
				'create_date',
				'update_date',
				'update_user',
				'status',
				'default_meal',
				'ip',
				'user_agent',
				'version',
                'user_id'
			);

			if ($archieved) {
				$fileds[] = 'id';
				$form['unique_url'] = $expenseFormArray["unique_url"];
				$form['id'] = $expenseFormArray["id"];
			}
			$data["Expense"] = $form;

			if ($this->save($data, false, $fileds)) {

				$id =  $this->id;

				if ($id != "") {
					$this->id = $id;
					if ($archieved) {
						$result = $id . "," . $expenseFormArray["unique_url"];
					} else {
						$unique_url_id = $expenseFormArray["expense_type"] . $this->getUniqueURLById(time()) . $this->getUniqueURLById($id) . trim($expenseFormArray["secret_key"]);
						//update group_expenses
						if ($this->saveField("unique_url", $unique_url_id)) {
							//insert into participant table
							//if($isRemote == false){
							//$this->insertParticipants($id, $expenseFormArray["your_name"],$expenseFormArray["participants"]);
							$result = $id . "," . $unique_url_id;
							//} else {
							//$this->insertParticipantsByRemote($id,$expenseFormArray["participants"]);
							//$result = $id.",".$unique_url_id;
							//}					

						}
					}
				}
			}
		}

		return $result;
	}



	/* function updateExpense($expenseFormArray){
		
		$result = "";
		
		$form["id"] =$expenseFormArray["id"];
		$form["title"] = $expenseFormArray["title"];
		$form["currency"] = $expenseFormArray["currency"];		 
		$form["description"] = $expenseFormArray["description"];
		$form["language"] = $expenseFormArray["language"];
		$form["is_secret"] = $expenseFormArray["is_secret"];
		$form["secret_key"] = $expenseFormArray["secret_key"];		 
		$form["update_date"] = time();
		$form["update_user"] = "system";
		$form["version"] =  $expenseFormArray["version"];
		
		$fileds = array('title','currency','description',
				'language','is_secret','secret_key','update_date','update_user');
		
		
		$data["Expense"] = $form;
			
		//update few fields of group_expenses table
		if($this->save($data,false,$fileds)){
			$result = 1;
		}
		
		return $result;
	} */



	function insertParticipants($id, $creator_name, $participants)
	{

		$data = array();

		$form["Participant"][0]["participant_id"] = "1" . "_" . "0";
		$form["Participant"][0]["expense_id"] = $id;
		$form["Participant"][0]["name"] = $creator_name;
		$form["Participant"][0]["is_creator"] = 1;

		$i = 1;
		if ($participants != "") {

			$participant_array = explode(",", $participants);

			foreach ($participant_array as $single_participant) {
				if ($single_participant != "") {

					$form["Participant"][$i]["participant_id"] = "1" . "_" . $i;
					$form["Participant"][$i]["expense_id"] = $id;
					$form["Participant"][$i]["name"] = $single_participant;
					$form["Participant"][$i]["is_creator"] = 0;
					$i = $i + 1;
				}
			}
		}

		App::import('model', 'Participant');
		$participant = new Participant();
		$participant->saveMany($form["Participant"]);
	}

	function insertParticipantsByRemote($id, $participantList)
	{

		$i = 0;

		foreach ($participantList as $key => $value) {
			$form["Participant"][$i]["participant_id"] = $value["participant_id"];
			$form["Participant"][$i]["expense_id"] = $id;
			$form["Participant"][$i]["name"] = $value["name"];
			$form["Participant"][$i]["is_creator"] = $value["is_creator"];
			$i = $i + 1;
		}

		App::import('model', 'Participant');
		$participant = new Participant();
		$participant->saveMany($form["Participant"]);
	}

	function findExpenseInfoByIds($expenseIdList)
	{

		$data = NULL;
		if (!empty($expenseIdList) && count($expenseIdList) > 0) {
			$str = implode(",", $expenseIdList);

			$this->hasMany = array();

			$result =  $this->find('all', array(
				'conditions' => array(
					'Expense.id in (' . $str . ')'
				),
				'order' => 'Expense.create_date DESC'
			));

			if (!empty($result)) {
				$data["expenseList"] = $result;
				App::import('model', 'Participant');
				$participant = new Participant();
				$participantInfo = $participant->find('all', array('conditions' => array(
					'Participant.expense_id in (' . $str . ') ',
					'is_creator' => '1'
				)));

				$data["participantList"] = $participantInfo;
			}
		}

		// $log = $this->getDataSource()->getLog(false, false);
		// debug($log);

		return $data;
	}


	function getUniqueURLById($in, $to_num = false, $pad_up = false)
	{

		$index = "abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
		$base = strlen($index);

		if ($to_num) {
			// Digital number <<-- alphabet letter code
			$in = strrev($in);
			$out = 0;
			$len = strlen($in) - 1;
			for ($t = 0; $t <= $len; $t++) {
				$bcpow = bcpow($base, $len - $t);
				$out = $out + strpos($index, substr($in, $t, 1)) * $bcpow;
			}

			if (is_numeric($pad_up)) {
				$pad_up--;
				if ($pad_up > 0) {
					$out -= pow($base, $pad_up);
				}
			}
		} else {
			// Digital number -->> alphabet letter code
			if (is_numeric($pad_up)) {
				$pad_up--;
				if ($pad_up > 0) {
					$in += pow($base, $pad_up);
				}
			}

			$out = "";
			for ($t = floor(log10($in) / log10($base)); $t >= 0; $t--) {
				$a = floor($in / bcpow($base, $t));
				$out = $out . substr($index, $a, 1);
				$in = $in - ($a * bcpow($base, $t));
			}
			$out = strrev($out); // reverse
		}

		return $out;
	}
}
