<?php
class Brivium_Credits_Model_Credit extends XenForo_Model
{
	/**
	 * Determines if this process is doing a bulk rebuild.
	 *
	 * @var boolean
	 */
	protected $_isBulk = false;
	protected $_waitSubmit = false;
	protected $_defaultData = array();
	protected $_bulkInserts = array();
	protected $_bulkAlerts = array();
	protected $_bulkUpdates = array();
	protected $_bulkInsertLength = 0;
	protected $_bulkAlertLength = 0;
	
	/**
	 * Gets the user model.
	 *
	 * @return XenForo_Model_User
	 */
	protected function _getDefaultData($now)
	{
		if(empty($this->_defaultData)){
			$this->_defaultData = array(
				'user_action_id' 			=>	0,
				'owner_id' 				=>	0,
				'user_event_id' 		=>	0,
				'transaction_date' 		=>	$now,
				'amount' 				=>	0,
				'negate' 				=>	0,
				'multiplier' 			=>	0,
				'multi_amount' 			=>	0,
				'message' 				=>	'',
				'transaction_state' 	=>	'',
				'node_id' 				=>	0,
				'times' 				=>	0,
				'apply_max' 			=>	0,
				'max_time' 				=>	0,
				'event_id' 				=>	0,
				'currency_id' 			=>	0,
				'content_id' 			=>	0,
				'content_type'			=>	'',
				'errorMinimumHandle'	=>	'',
				'user' 					=>	array(),
				'user_action' 			=>	array(),
				'ignore_min_handle' 	=>	false,
				'moderate' 				=>	false,
				'ignore_include' 		=>	false,
				'ignore_maximum' 		=>	false,
				'reverted' 				=>	false,
				'updateUser' 			=>	false,
				'allow_negative' 		=>	false,
				'extraData' 			=>	array()
			);
		}
		return $this->_defaultData;
	}
	
	/**
	 * update user credit
	 *
	 * @param integer $userId
	 * @param string $actionId
	 * @param array $extra 
	 */
	public function updateUserCredit($actionId,$userId, array $extra = array(),&$errorString = '')
	{
		if(!$events = XenForo_Application::get('brcEvents')->$actionId) return false;
		// get event information
		$userModel = $this->getModelFromCache('XenForo_Model_User');
		$now = XenForo_Application::$time;
		$defaultData = $this->_getDefaultData($now);
		$visitor = XenForo_Visitor::getInstance()->toArray();
		$data = array_merge($defaultData, $extra);
		$userActionId 		= $data['user_action_id'];						// user is associated with this event of $user ( default System = 0 )  (int)  
		$ownerId 			= $data['owner_id'];							// not support right now
		$transactionDate 	= $data['transaction_date'];					//  date of transaction (int)
		$amount 			= $data['amount'];								// set amount override event's amount ( if = 0 , amount = event.amount ) (double)
		$negate 			= $data['negate'];								// not support right now
		$message 			= $data['message'];								// comment for this transaction (string)
		$multiplier 		= $data['multiplier'];							// number will calculate with event's multiplier   ( amount = amount + event.multiplier * multiplier )  (int)
		$multiAmount 		= $data['multi_amount'];   						// multipliter Amount  (  amount  = amount x multiAmount )  (int)
		$transactionState 	= $data['transaction_state'];					// Set state for transaction  (string)
		$nodeId 			= $data['node_id'];								// data forum id  (int)
		
		$ignoreInclude 		= $data['ignore_include'];						// ignored check include (forum and user group). (boolen)
		$ignoreMaximum 		= $data['ignore_maximum'];						// ignored check maximum perday and maximum times trigger event.  (boolen)
		$reverted 			= $data['reverted'];							// is reveted event.  (boolen)
		$ignoreMinHandle 	= $data['ignore_min_handle'];					// is ignore min handle.  (boolen)
		$contentId 			= $data['content_id'];							// Content id.  (ex: thread_id, user_id, attachment_id)(int)
		$contentType 		= $data['content_type'];						// is type of content.  (string)
		$extraData 			= $data['extraData'];							// extra data for transactiona and alert  (array)
		$user 				= $data['user'];								// user trigger this event.   (array)
		$userAction 		= $data['user_action'];							// user trigger this event.   (array)
		$eventId 			= $data['event_id'];							// specified event id you want to trigger (not support right now)
		$currencyId 		= $data['currency_id'];							// specified currency id you want to trigger  (int)
		$updateUser 		= $data['updateUser'];							// Update user credit field or not (Using this when you want update manual) (boolen)
		$errorMinimumHandle = $data['errorMinimumHandle'];
		$extraData['reverted'] = $reverted;
		$extraData['ignoreInclude'] = $ignoreInclude;
		
		if(is_array($user) && !empty($user['user_id'])){
			$userId = $userId?$userId:$user['user_id'];
		}else if($userId){
			$user = $userId==$visitor['user_id']?$visitor:$userModel->getFullUserById($userId);
		}else{
			$errorString = new XenForo_Phrase('requested_user_not_found');
			return false;
		}
		if (!$user || !is_array($user) || empty($user['user_id']))
		{
			$errorString = new XenForo_Phrase('do_not_have_permission');
			return false;
		}
		
		if(is_array($userAction) && !empty($userAction['user_id'])){
			$userActionId = $userActionId?$userActionId:$userAction['user_id'];
		}else if($userActionId){
			$userAction = $userActionId==$visitor['user_id']?$visitor:$userModel->getFullUserById($userActionId);
		}else{
			$userAction = $user;
		}
		
		if($currencyId){
			if(!empty($events[$currencyId])){
				if(!empty($events['event_id'])){
					$events = array(
						$currencyId	=> $events[$currencyId]
					);
				}else{
					$events = $events[$currencyId];
				}
			}else{
				$events = array();
			}
		}
		$events = $this->processEvents($events);
		$upgraded = false;
		$currencyObj = XenForo_Application::get('brcCurrencies');
		$actionsObj = XenForo_Application::get('brcActions');
		foreach($events AS $event){
			$amountUpdate = 0;
			$times 				= $data['times']?$data['times']:$event['times']; 			// Maximum times per day  (int)
			$applyMax 			= $data['apply_max']?$data['apply_max']:$event['apply_max'];  // Maximum times After this event has occured.  (int)
			$maxTime 			= $data['max_time']?$data['max_time']:$event['max_time'];   // Timespan in seconds that the above maximum is enforced. (int)
			$moderate 			= $data['moderate']?$data['moderate']:$event['moderate'];   // Timespan in seconds that the above maximum is enforced. (int)
			
			$action = $actionsObj->$event['action_id'];
			
			$allowNegative 		= $data['allow_negative'];
			if(!$allowNegative){
				$allowNegative = !empty($action['allow_negative'])?$action['allow_negative']:false;
			}
			$eventId = !empty($event['event_id'])?$event['event_id']:0;
			$currency = $currencyObj->$event['currency_id'];
			// check event is actived
			if(!$currency['active'])
			{
				$errorString = new XenForo_Phrase('BRC_this_currency_is_not_active_yet');
				continue;
			}
			// check event is actived
			if(!$event['active'])
			{
				$errorString = new XenForo_Phrase('BRC_this_action_is_not_active_yet');
				continue;
			}
			if(!isset($user[$currency['column']]))
			{
				$errorString = new XenForo_Phrase('BRC_field_x_was_not_recognised',array('field'=>$currency['column']));
				continue;
			}
			if(!$ignoreInclude&& !$this->requireInclude($event,$user,$nodeId)){
				$errorString = new XenForo_Phrase('do_not_have_permission');
				continue;
			}
			
			if($actionId=='interest'){
				if($user[$currency['column']]>0){
					$multiplier = $user[$currency['column']];
				}else{
					$errorString = new XenForo_Phrase('BRC_not_valid_amount');
					continue;
				}
			}
			$amountUpdate = $amount;
			if($amountUpdate==0){
				$amountUpdate = $reverted?$event['sub_amount']:$event['amount'];
			}
			
			
			if($multiAmount){
				$amountUpdate *= $multiAmount;
			}
			
			if(!$reverted && !$ignoreMinHandle && $event['extra_min'] && $multiplier < $event['extra_min'] && $event['extra_min_handle']){
				if($event['extra_min_handle']==1){
					$multiplier = 0;
				}else if($event['extra_min_handle']==2){
					$errorString = new XenForo_Phrase('BRC_below_minimum_handling');
					continue;
				}else if($event['extra_min_handle']==3){
					$errorMinimumHandle->setParams(array('min'=>$event['extra_min']));
					if(!$this->_isBulk){
						throw new XenForo_Exception($errorMinimumHandle, true);
					}else{
						return false;
					}
				}
			}
			
			if($event['extra_max'] && $multiplier > $event['extra_max']){
				$multiplier = $multiplier - $event['extra_max'];
			}
			if(!$amountUpdate){
				$errorString = new XenForo_Phrase('BRC_not_valid_amount');
				continue;
			}
			if($multiplier && $multiplier > 0 && $event['multiplier']){
				$amountUpdate = $amountUpdate + $event['multiplier']*$multiplier;
			}
			$this->processCurrencyAmount($event['currency_id'], $amountUpdate, $user);
			if(!$allowNegative && $amountUpdate < 0 && (($user[$currency['column']] + $amountUpdate) < 0)){
			
				if(!empty($action['negative_handle']) && $action['negative_handle']=='prevent_action'){
					if(!$this->_isBulk){
						throw new XenForo_Exception(new XenForo_Phrase('BRC_not_enough_amount',array('amount' => $currencyObj->currencyFormat($amountUpdate,false,$event['currency_id']))), true);
					}else{
						return false;
					}
				}else{
					$errorString = new XenForo_Phrase('BRC_not_enough_amount',array('amount' => $currencyObj->currencyFormat($amountUpdate,false,$event['currency_id'])));
					return false;
				}
			}
			if(!$reverted && !$ignoreMaximum){
				if($applyMax > 0){
					$startTime = 0;
					if($maxTime > 0){
						$maxTimes = $this->countEventOfUser($eventId,$userId,($now - $maxTime));
						if($maxTimes >= $applyMax){
							$errorString = new XenForo_Phrase('BRC_you_can_get_reward_x_times_in_period_of_time_for_y', array('count' => $applyMax,'event'=>$event['title']));
							continue;
						}
					}
				}
				$dayStartTimestamps = XenForo_Locale::getDayStartTimestamps();
				if($times > 0 && $times <= $this->countEventOfUser($eventId,$userId,$dayStartTimestamps['today'])){
					$errorString = new XenForo_Phrase('BRC_you_can_get_reward_x_times_per_day_for_y',array('time'=>$times,'event'=>$event['title']));
					continue;
				}
			}
			$extraData['amount'] = $amountUpdate;
			$extraData['multiAmount'] = $multiAmount;
			$extraData['moderate'] = $moderate;
			$extraData['updateUser'] = $updateUser;
			$alert = false;
			if(XenForo_Model_Alert::userReceivesAlert($user, 'credits', $eventId) && $event['alert']){
				$alert = true;
			}
			
			$upgraded = $this->addUserTransaction($actionId,$eventId, $user, $userAction, $ownerId, $contentId, $contentType, $transactionDate, $amountUpdate, $currency, $multiplier, $negate, $message,$moderate, $transactionState, $extraData,$alert,$updateUser);
		}
		
		if(!$this->_waitSubmit)
			$this->commitUpdate();
		return $upgraded;
	}
	
	public function processCurrencyAmount($currencyId, $amount, &$user)
	{
		return $user;
	}
	public function processEvents($events)
	{
		$listEvents = array();
		if(is_array($events) && empty($events['event_id'])){
			foreach($events AS $event){
				$listEvents += $this->processEvents($event);
			}
		}else{
			if(!empty($events['event_id'])){
				$listEvents[$events['event_id']] = $events;
			}
		}
		return $listEvents;
	}
	
	public function commitUpdate($updateUser = true)
	{
		if(!empty($this->_bulkInserts)){
			$this->_pushToTransaction($this->_bulkInserts);
			$this->_bulkInserts = array();
			$this->_bulkInsertLength = 0;
		}
		if(!empty($this->_bulkAlerts)){
			$this->_pushToAlert($this->_bulkAlerts);
			$this->_bulkAlerts = array();
			$this->_bulkInsertLength = 0;
		}
		if(!empty($this->_bulkUpdates) && $updateUser){
			$this->_updateUserCredits($this->_bulkUpdates);
			$this->_bulkUpdates = array();
			$this->_bulkAlertLength = 0;
		}
		return true;
	}
	
	/**
	 * Add user Transaction Simple with delay option
	 *
	 * @param array $data
	 */
	public function addUserTransaction($actionId,$eventId, $user, $userAction, $ownerId, $contentId, $contentType, $transactionDate, $amount, $currency, $multiplier, $negate, $message, $moderate, $transactionState, $extraData,$alert,$updateUser = false)
	{
		//prd($data);
		$db = $this->_getDb();
		
		$this->insertIntoTransaction($actionId,$eventId,$currency['currency_id'], $user['user_id'], $userAction['user_id'], $ownerId,$contentId, $contentType, $transactionDate, $amount, $multiplier, $negate, $message, $moderate, $transactionState, $extraData);
		if($alert){
			$this->insertIntoAlert($user['user_id'], $userAction['user_id'], $userAction['username'],$eventId,$actionId,$transactionDate,$extraData);
		}
		if(!$moderate || $updateUser){
			if($currency['negative_handle']=='reset' && ($user[$currency['column']] + $amount < 0))$amount = -$user[$currency['column']];
			$this->updateUserCredits($user['user_id'],$amount,$currency['column']);
		}
		
		return true;
	}
	/**
	 * Update user credits
	 *
	 * @param array $data
	 */
	public function updateUserCredits($userId,$amount,$column)
	{
		$db = $this->_getDb();
		$row = ' `'.$column.'` = `'.$column.'` + ' . $db->quote($amount);

		$this->_bulkUpdates[$userId][] = $row;
		return;
	}
	/**
	 * Update user credits
	 *
	 * @param array $data
	 */
	public function _updateUserCredits($records)
	{
		if (is_array($records))
		{
			foreach($records AS $userId=>$record){
				if (is_array($record))
				{
					$record = implode(',', $record);
				}

				if (!$record)
				{
					continue;
				}
				$this->_getDb()->query('
					UPDATE ' . (XenForo_Application::get('options')->BRC_enableUpdateLowPriority ? 'LOW_PRIORITY' : '') . ' xf_user SET
						'. $record .'
					WHERE user_id = ?
				', $userId);
			}
		}else{
			return;
		}
		return true;
	}
	
	public function insertIntoTransaction($actionId,$eventId,$currencyId, $userId, $userActionId, $ownerId,$contentId, $contentType, $transactionDate, $amount, $multiplier, $negate, $message,$moderate, $transactionState, $extraData)
	{
		if(isset($extraData)){
			$extraData = serialize($extraData);
		}
		$db = $this->_getDb();
		$row = '(' . $db->quote($actionId) 
			. ', ' . $db->quote(intval($eventId))
			. ', ' . $db->quote(intval($currencyId))
			. ', ' . $db->quote(intval($userId))
			. ', ' . $db->quote(intval($userActionId)) 
			. ', ' . $db->quote(intval($contentId)) 
			. ', ' . $db->quote($contentType)
			. ', ' . $db->quote($ownerId)
			. ', ' . $db->quote($transactionDate)
			. ', ' . $db->quote($amount) . ', ' . $db->quote($multiplier)
			. ', ' . $db->quote($negate) . ', ' . $db->quote($message)
			. ', ' . $db->quote(intval($moderate))
			. ', ' . $db->quote($transactionState) 
			. ', ' . $db->quote($extraData) . ')';

		$this->_bulkInserts[] = $row;
		$this->_bulkInsertLength += strlen($row);
		
		if ($this->_bulkInsertLength > 500000)
		{	
			$this->_pushToTransaction($this->_bulkInserts);

			$this->_bulkInserts = array();
			$this->_bulkInsertLength = 0;
		}
		return;
	}
	public function insertIntoAlert($alertUserId, $userId, $username, $eventId, $actionId, $transactionDate, array $extraData = null)
	{
		if(isset($extraData)){
			$extraData = serialize($extraData);
		}
		$db = $this->_getDb();
		$row = '(' . $db->quote(intval($alertUserId))
			. ', ' . $db->quote(intval($userId))
			. ', ' . $db->quote($username)
			. ', ' . $db->quote('credit')
			. ', ' . $db->quote(intval($eventId))
			. ', ' . $db->quote($actionId)
			. ', ' . $db->quote($transactionDate)
			. ', ' . $db->quote($extraData)
			. ')';

		$this->_bulkAlerts[] = $row;
		$this->_bulkAlertLength += strlen($row);
		
		if ($this->_bulkInsertLength > 500000)
		{	
			$this->_pushToAlert($this->_bulkAlerts);

			$this->_bulkAlerts = array();
			$this->_bulkInsertLength = 0;
		}
		return;
	}
	
	/**
	 * Runs the actual query to inserts alert.
	 *
	 * @param string|array $record A record (SQL) or array of SQL
	 */
	protected function _pushToAlert($record)
	{
		if (is_array($record))
		{
			$record = implode(',', $record);
		}

		if (!$record)
		{
			return;
		}
		$this->_getDb()->query('
			INSERT INTO xf_user_alert
				(alerted_user_id,user_id,username,content_type,content_id,action,event_date,extra_data)
			VALUES
				' . $record
		);
		return $this->_getDb()->lastInsertId('xf_user_alert', 'alert_id');
	}
	/**
	 * Runs the actual query to inserts transaction.
	 *
	 * @param string|array $record A record (SQL) or array of SQL
	 */
	protected function _pushToTransaction($record)
	{
		if (is_array($record))
		{
			$record = implode(',', $record);
		}

		if (!$record)
		{
			return;
		}
		$this->_getDb()->query('
			INSERT INTO xf_credits_transaction
				(action_id,event_id,currency_id,user_id,user_action_id,content_id,content_type,owner_id,transaction_date,amount,multiplier,negate,message,moderate,transaction_state,extra_data)
			VALUES
				' . $record
		);
		return $this->_getDb()->lastInsertId('xf_credits_transaction', 'transaction_id');
	}
	
	public function updateInterestAmount($userIds){
		if(!$events = XenForo_Application::get('brcEvents')->interest) return false;
		$db = $this->_getDb();
		foreach($events AS $event){
			$currency = XenForo_Application::get('brcCurrencies')->$event['currency_id'];
		
			$db->query('
				UPDATE ' . (XenForo_Application::get('options')->BRC_enableUpdateLowPriority ? 'LOW_PRIORITY' : '') . ' xf_user SET
					`'.$currency['column'].'` = `'.$currency['column'].'` + ? + (`'.$currency['column'].'`*?)
				WHERE user_id IN (' . $db->quote($userIds) . ') AND `'.$currency['column'].'` > 0
			', array($event['amount'],$event['multiplier']));
		}
	}
	
	public function updateDailyRewardAmount($userIds){
		if(!$events = XenForo_Application::get('brcEvents')->dailyReward) return false;
		$db = $this->_getDb();
		foreach($events AS $event){
			$currency = XenForo_Application::get('brcCurrencies')->$event['currency_id'];
		
			$db->query('
				UPDATE ' . (XenForo_Application::get('options')->BRC_enableUpdateLowPriority ? 'LOW_PRIORITY' : '') . ' xf_user SET
					`'.$currency['column'].'` = `'.$currency['column'].'` + ?
				WHERE user_id IN (' . $db->quote($userIds) . ') AND `'.$currency['column'].'` > 0
			', $event['amount']);
		}
	}
	
	/**
	 * alert member
	 *
	 */
	public function createAlert($alertUserId, $userId, $username, $eventId, $actionId, array $extraData = null)
	{
		XenForo_Model_Alert::alert(
			$alertUserId,
			$userId,
			$username,
			'credit',
			$eventId,
			$actionId,
			$extraData
		);
	}
	
	/**
	 * import credits from other field of `xf_user`
	 *
	 */
	public function importCredits($field,$column,$merge = true)
	{
		if (!$this->checkIfExist('xf_user', $field)) {
			return false;
		}
		$merger = '';
		if($merge){
			$merger = ' + `'.$column.'`';
		}
		$this->_getDb()->query('
			UPDATE xf_user SET
				`'.$column.'` = `'.$field.'` '.$merger.'
		');
	}
	/**
	 * Set all trophy point to 0
	 *
	 */
	public function resetTrophyPoints()
	{
		$this->_getDb()->query('
			UPDATE xf_user SET trophy_points = 0
		');
	}
	
	/**
	 * Set all credits to amount
	 *
	 *	@param double $amount
	 */
	public function resetCredit(array $columns,$userIds = array())
	{
		$db = $this->_getDb();
		$where = '1';
		if($userIds){
			if(count($userIds)==1){
				$where = $where . ' AND user_id = ' . $db->quote($userIds);
			}else{
				$where = $where . ' AND user_id IN (' . $db->quote($userIds) . ')';
			}
		}
		$db->update('xf_user',
			$columns,
			$where
		);
	}
	
	/**
	 * Count number event that user trigger in preiod times
	 *
	 *	@param string $eventId
	 *	@param int $userId
	 *	@param int $startTime   from start time to now
	 *	@param int $userActionId
	 */
	public function countEventOfUser($eventId,$userId,$startTime = 0,$userActionId = 0){
		$transactionModel = $this->_getTransactionModel();
		$conditions = array(
			'event_id'	=>	$eventId,
			'user_id'	=>	$userId,
		);
		
		if($userActionId)$conditions['user_action_id'] = $userActionId;
		if($startTime)$conditions['start'] = $startTime;
		return $transactionModel->countTransactions($conditions);
	}
	/**
	 * Count number action that user trigger in preiod times
	 *
	 *	@param string $actionId
	 *	@param int $userId
	 *	@param int $startTime   from start time to now
	 *	@param int $userActionId
	 */
	public function countActionOfUser($actionId,$userId,$startTime = 0,$userActionId = 0,$contentId = 0, $contentType= '' ){
		$transactionModel = $this->_getTransactionModel();
		$conditions = array(
			'action_id'	=>	$actionId,
			'user_id'	=>	$userId,
		);
		
		if($userActionId)$conditions['user_action_id'] = $userActionId;
		if($contentId && $contentType ){
			$conditions['content_id'] = $contentId;
			$conditions['content_type'] = $contentType;
		}
		if($startTime)$conditions['start'] = $startTime;
		return $transactionModel->countTransactions($conditions);
	}
	
	/**
	 * Check if user in group that allowed to trigger events or Forum is in Included Forum
	 *
	 *	@param array|string $events
	 *	@param array|int $user
	 *	@param int $nodeId 
	 */
	public function checkRequireInclude($events,$user = array(),$nodeId = 0){
		if(!$user){
			$user = XenForo_Visitor::getInstance()->toArray();
		}
		if(!is_array($events)){
			$events = XenForo_Application::get('brcEvents')->$events;
		}
		if($events){
			foreach($events AS $eventId=>$event){
				if(is_array($event) && empty($event['event_id'])){
					foreach($event AS $subEvent){
						if(!empty($subEvent['event_id'])){
							if($this->requireInclude($subEvent,$user,$nodeId))return true;
							//$listEvents[$subEvent['event_id']] = $subEvent;
						}
					}
				}else{
					if(!empty($event['event_id'])){
						if($this->requireInclude($event,$user,$nodeId))return true;
						//$listEvents[$event['event_id']] = $event;
					}
				}
			}
		}
		return false;
	}
	
	public function requireInclude(array $event,array $user,$nodeId = 0)
	{
		$check = false;
		$currency = XenForo_Application::get('brcCurrencies')->$event['currency_id'];
		if(!$event['active'] || !$currency['active']) return $check;
		$includeGroups = array();
		if($event['user_groups']==array(0=>0)) $event['user_groups'] = array();
		if($currency['user_groups']==array(0=>0)) $currency['user_groups'] = array();
		if($event['forums']==array(0=>0)) $event['forums'] = array();
		
		if(!empty($event['user_groups']) && !empty($currency['user_groups'])){
			$includeGroups = array_intersect($event['user_groups'],$currency['user_groups']);
			if(!$includeGroups) return false;
		}else{
			$includeGroups = $event['user_groups']?$event['user_groups']:$currency['user_groups'];
		}
		$includeForums = $event['forums'];
		
		if(empty($includeGroups)&& empty($includeForums)) return true;
		if(!empty($includeGroups)){
			$inGroups = array();
			if(isset($user['user_group_id']))$inGroups = $user['user_group_id'];

			if (!empty($user['secondary_group_ids']))
			{
				$inGroups .= ','.$user['secondary_group_ids'];
			}

			$groupCheck = explode(',',$inGroups);

			unset($inGroups);

			foreach ($groupCheck AS $groupId)
			{
				if (in_array($groupId, $includeGroups))
				{
					$check = true;
					break;
				}
			}
		}
		
		if(!empty($includeForums) && $nodeId){
			if (in_array($nodeId, $includeForums)){
				$check = true;
			}
		}
		return $check;
	}
	
	public function processTax($amount,$event){
	
		$userTax = 0;
		$userActionTax = 0;
		
		$taxed = ($amount-$event['amount']) * $event['multiplier'] + $event['amount'];
		if($event['target']=='user'){
			$userTax = $taxed;
		}else if($event['target']=='user_action'){
			$userActionTax = $taxed;
		}else if($event['target']=='both'){
			$userActionTax = $userTax = $taxed/2;
		}
		
		return array(
			$userTax,$userActionTax
		);
	}
	
	
	public function calculateWordAmount($string){
	
		if(XenForo_Application::get("options")->BRC_excludeBlockBbcode){
			$string = preg_replace('#\[(quote|php|html|code)[^\]]*\].*\[/\\1\]#siU', ' ', $string);
		}
		$string = preg_replace('#\[(attach|media|img)[^\]]*\].*\[/\\1\]#siU', ' [\\1] ', $string);
		while ($string != ($newString = preg_replace('#\[([a-z0-9]+)(=[^\]]*)?\](.*)\[/\1\]#siU', '\3', $string)))
		{
			$string = $newString;
		}
		return $this->countWords($string);
	}
	
	public function countWords($string) 
	{
		$count = 0;
		if(XenForo_Application::get("options")->BRC_creditSizeWord){
			$count = count(explode(" ", $string));
		}else{
			$count = utf8_strlen($string);
		}
		return $count;
	}
	
	public function stripBbCode($string) 
	{
		if ($stripQuote)
		{
			$string = preg_replace('#\[(quote)[^\]]*\].*\[/\\1\]#siU', ' ', $string);
		}

		// replaces unviewable tags with a text representation
		$string = preg_replace('#\[(attach|media|img)[^\]]*\].*\[/\\1\]#siU', '[\\1]', $string);

		while ($string != ($newString = preg_replace('#\[([a-z0-9]+)(=[^\]]*)?\](.*)\[/\1\]#siU', '\3', $string)))
		{
			$string = $newString;
		}

		$string = str_replace('[*]', '', $string);
	}
	
	public function totalCredits($column){
		
		if(empty($column) || !$this->checkIfExist('xf_user', $column)){
			return 0;
		}
		return $this->_getDb()->fetchOne('
				SELECT SUM(`'.$column.'`)
				FROM xf_user
			');
	}
	
	public function canAnonymousTransfer(array $viewingUser = null)
	{
		$this->standardizeViewingUserReference($viewingUser);

		if (XenForo_Permission::hasPermission($viewingUser['permissions'], 'BR_CreditsPermission', 'BRC_anonymous_transfer'))
		{
			return true;
		}

		return false;
	}
	
	public function canExportTransaction(array $viewingUser = null)
	{
		$this->standardizeViewingUserReference($viewingUser);

		if (XenForo_Permission::hasPermission($viewingUser['permissions'], 'BR_CreditsPermission', 'BRC_exportTransaction'))
		{
			return true;
		}

		return false;
	}
	
	public function canUseCredits(&$errorPhraseKey = '', array $viewingUser = null)
	{
		$this->standardizeViewingUserReference($viewingUser);

		if (XenForo_Permission::hasPermission($viewingUser['permissions'], 'BR_CreditsPermission', 'useCredits'))
		{
			return true;
		}

		return false;
	}
	
	
	public function footer(){
		return '
		<div id="BRC_CopyrightNotice" class="footerLegal" style="clear:both">
			<div class="pageContent">
				<span class="muted"><a href="http://brivium.com/link-forums/information.109/" title="Credits System" class="concealed" >Credits</a> by Brivium &trade;  &copy; 2012-2013  <a href="http://brivium.com/" class="concealed" title="Brivium Limited">Brivium Limited</a>.</span>
			</div>
		</div>';
	}
	
	public function checkIfExist($table, $field)
	{
		$db = XenForo_Application::get('db');
		if ($db->fetchRow('SHOW columns FROM `' . $table . '` WHERE Field = ?', $field)) {
			return true;
		}
		else {
			return false;
		}
	}
	
	/**
	 * Sets whether this is a bulk. If true, behavior may be modified to be
	 * less asynchronous.
	 *
	 * @param boolean $bulk
	 */
	public function setIsBulk($bulk)
	{
		$this->_isBulk = $bulk;
	}
	
	/**
	 * Sets whether this is a wait. If true, behavior may be modified to be
	 * less asynchronous.
	 *
	 * @param boolean $wait
	 */
	public function setIsWaitSubmit($wait)
	{
		$this->_waitSubmit = $wait;
	}
	
	
	public function setBulkInsertLength($length)
	{
		$this->_bulkInsertLength = $length;
		$this->_bulkAlertLength = $length;
	}
	
	
	/**
	 * Gets the user model.
	 *
	 * @return XenForo_Model_User
	 */
	protected function _getUserModel()
	{
		return $this->getModelFromCache('XenForo_Model_User');
	}
	/**
	 * Gets the action model.
	 *
	 * @return Brivium_Credits_Model_Action
	 */
	protected function _getActionModel()
	{
		return $this->getModelFromCache('Brivium_Credits_Model_Action');
	}
	/**
	 * Gets the transaction model.
	 *
	 * @return Brivium_Credits_Model_Transaction
	 */
	protected function _getTransactionModel()
	{
		return $this->getModelFromCache('Brivium_Credits_Model_Transaction');
	}
	
}