<?php

if (! defined('BASEPATH')) exit('No direct script access allowed');

/**
 * Library to manage the sending of the email
 */
class MailLib
{
	const ENABLE_DEBUG = 'enable_debug';

	private $sended; // Sended email counter

	// Properties for storing the configuration
	private $email_number_to_sent;
	private $email_number_per_time_range;
	private $email_time_range;
	private $email_from_system;

	private $_ci; // Codeigniter instance

	/**
	 * Class constructor
	 */
	public function __construct()
	{
		// Set the counter to 0
		$this->sended = 0;

		// Get CI instance
		$this->_ci =& get_instance();

		// The second parameter is used to avoiding name collisions in the config array
		$this->_ci->config->load('mail', true);

		// CI Email library
		$this->_ci->load->library('email');

		// Initializing email library with the loaded configurations
		$this->_ci->email->initialize($this->_ci->config->config['mail']);

		// Set the configuration properties with the standard configuration values
		$this->email_number_to_sent = $this->getEmailCfgItem('email_number_to_sent');
		$this->email_number_per_time_range = $this->getEmailCfgItem('email_number_per_time_range');
		$this->email_time_range = $this->getEmailCfgItem('email_time_range');
		$this->email_from_system = $this->getEmailCfgItem('email_from_system');
		$this->alias_from_system = $this->getEmailCfgItem('alias_from_system');
	}

	/**
	 * Sends a single email
	 */
	public function send($from, $to, $subject, $message, $alias = '', $cc = null, $bcc = null, $altMessage = '', $bulk = false, $autogenerated = false)
	{
		// If it is configured then log mail info into the CI error logs
		if ($this->getEmailCfgItem(self::ENABLE_DEBUG) === true)
		{
			$this->_ci->load->library('LogLib'); // Loads logging library

			// Log them all!
			$this->_ci->loglib->logError('From: '.$from);
			$this->_ci->loglib->logError('To: '.$to);
			$this->_ci->loglib->logError('Subject: '.$subject);
			$this->_ci->loglib->logError('Message: '.$message);
			$this->_ci->loglib->logError('Alias: '.$alias);
			$this->_ci->loglib->logError('CC: '.$cc);
			$this->_ci->loglib->logError('BCC: '.$bcc);
			$this->_ci->loglib->logError('Alternative message: '.$altMessage);
		}

		// If from is not specified then use the standard one
		if (is_null($from) || $from == '')
		{
			$from = $this->email_from_system;
			// If alias is not specified then use the standard one
			if (is_null($alias) || $alias == '')
			{
				$alias = $this->alias_from_system;
			}
		}
		if (defined('MAIL_FROM') && MAIL_FROM != '')
		{
			$from = MAIL_FROM;
			if (is_null($alias) || $alias == '')
			{
				$alias = $this->alias_from_system;
			}
		}

		$this->_ci->email->from($from, $alias);

		// Check if the email address of the debug recipient is a valid one
		$recipient = $to;
		$recipientCC = $cc;
		$recipientBCC = $bcc;
		if (defined('MAIL_DEBUG') && MAIL_DEBUG != '')
		{
			// if is it valid use it!!!
			$recipient = MAIL_DEBUG;
			if ($recipientCC != '')
				$recipientCC = MAIL_DEBUG;
			if ($recipientBCC != '')
				$recipientBCC = MAIL_DEBUG;
		}

		$this->_ci->email->to($recipient);
		if (!is_null($recipientCC)) $this->_ci->email->cc($recipientCC);
		if (!is_null($recipientBCC)) $this->_ci->email->bcc($recipientBCC);
		$this->_ci->email->subject($subject);
		$this->_ci->email->message($message);
		if (!isEmptyString($altMessage)) $this->_ci->email->set_alt_message($altMessage);

		if($bulk)
			$this->_ci->email->set_header('Precedence', 'bulk');
		if($autogenerated)
			$this->_ci->email->set_header('Auto-Submitted', 'auto-generated');

		// Avoid printing on standard output ugly error messages
		$result = @$this->_ci->email->send();

		// If the email was succesfully sended then increment the counter
		// and checks if it has to wait until the sending of the next
		if ($result)
		{
			$this->sended++;
			$this->wait();
		}

		return $result;
	}

	/**
	 * Overrides configuration parameters
	 * If the given parameters are not null or empty strings then they are used to override
	 * the following properties of this object:
	 * - email_number_to_sent
	 * - email_number_per_time_range
	 * - email_time_range
	 * - email_from_system
	 */
	public function overrideConfigs($numberToSent, $numberPerTimeRange, $emailTimeRange, $emailFromSystem)
	{
		if (is_numeric($numberToSent)) $this->email_number_to_sent = $numberToSent;

		if (is_numeric($numberPerTimeRange)) $this->email_number_per_time_range = $numberPerTimeRange;

		if (is_numeric($emailTimeRange)) $this->email_time_range = $emailTimeRange;

		if (!isEmptyString($emailFromSystem) && filter_var($emailFromSystem, FILTER_VALIDATE_EMAIL))
		{
			$this->email_from_system = $emailFromSystem;
		}
	}

	/**
	 * Returns value of property email_number_to_sent
	 */
	public function getEmailNumberToSent()
	{
		return $this->email_number_to_sent;
	}

	/**
	 * Validates an email address
	 */
	public function validateEmailAddress($emailAddress)
	{
		$valid = false;

		if (!isEmptyString($emailAddress))
		{
			$valid = filter_var($emailAddress, FILTER_VALIDATE_EMAIL);
		}

		return $valid;
	}

	/**
	 * Checks if it has to wait until the sending of the next
	 */
	private function wait()
	{
		if ($this->sended == $this->email_number_per_time_range)
		{
			$this->sended = 0;
			sleep($this->email_time_range); // Wait!!!
		}
	}

	/**
	 * Gets an item from the email configuration array
	 */
	private function getEmailCfgItem($itemName)
	{
		return $this->_ci->config->item($itemName, EMAIL_CONFIG_INDEX);
	}
}
