<?php
/**
 * @package       RSform!Pro
 * @copyright (C) 2015 www.rsjoomla.com
 * @license       GPL, http://www.gnu.org/copyleft/gpl.html
 */

// no direct access
defined('_JEXEC') or die;

use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\Factory;
use Joomla\CMS\Language\Text;
use Joomla\CMS\Table\Table;
use Joomla\CMS\HTML\HTMLHelper;
use Joomla\Utilities\IpHelper;
use Joomla\CMS\Form\Form;
use Joomla\CMS\Uri\Uri;

define('RSFORM_FIELD_PAYMENT_EWAY', 501);

/**
 * RSForm! Pro system plugin
 */
class plgSystemRsfpewaypayment extends CMSPlugin
{
	/**
	 * @var int
	 */
	protected $componentId = RSFORM_FIELD_PAYMENT_EWAY;
	/**
	 * @var string
	 */
	protected $componentValue = 'eway';

	protected $autoloadLanguage = true;

	public function onRsformBackendAfterCreateFieldGroups(&$fieldGroups, $self)
	{
		$formId = Factory::getApplication()->input->getInt('formId');
		$exists = RSFormProHelper::componentExists($formId, RSFORM_FIELD_PAYMENT_EWAY);

		$fieldGroups['payment']->fields[] = (object) array(
			'id' 	=> RSFORM_FIELD_PAYMENT_EWAY,
			'name' 	=> Text::_('RSFP_EWAY_COMPONENT'),
			'icon'  => 'rsficon rsficon-coin-dollar',
			'exists' => $exists ? $exists[0] : false
		);
	}

	public function onRsformBackendAfterCreateComponentPreview($args = array())
	{
		if ($args['ComponentTypeName'] == $this->componentValue)
		{
			$args['out'] = '<span class="rsficon rsficon-coin-dollar" style="font-size:24px;margin-right:5px"></span>  ' . $args['data']['LABEL'];
		}
	}

	public function onRsformDefineHiddenComponents(&$hiddenComponents)
	{
		$hiddenComponents[] = $this->componentId;
	}

	public function onRsformBackendAfterShowFormEditTabsTab()
	{
		echo '<li><a href="javascript: void(0);" id="eway"><span class="rsficon rsficon-coin-dollar"></span><span class="inner-text">' . Text::_('RSFP_EWAY_PAYMENT') . '</span></a></li>';
	}

	public function onRsformFormSave($form)
	{
		try
		{
			$app 			 = Factory::getApplication();
			$data            = $app->input->get('eway', array(), 'array');
			$data['form_id'] = $form->FormId;
			$row             = $this->getTable();

			if (!$row)
			{
				return false;
			}

			if (!$row->bind($data))
			{
				return false;
			}

			$row->check();

			if (!$row->store())
			{
				$app->enqueueMessage($row->getError(), 'error');
			}
		}
		catch (Exception $e)
		{
			$app->enqueueMessage($e->getMessage(), 'error');
		}
	}

	protected function getTable()
	{
		return Table::getInstance('RSForm_Eway', 'Table');
	}

	public function onRsformBackendFormCopy($args)
	{
		$formId = $args['formId'];
		$newFormId = $args['newFormId'];

		if ($row = $this->getTable())
		{
			if ($row->load($formId))
			{
				$row->form_id = $newFormId;

				$row->check();

				return $row->store();
			}
		}
	}

	public function onRsformBackendAfterShowFormEditTabs()
	{
		$formId = Factory::getApplication()->input->getInt('formId', 0);
		$lang   = Factory::getLanguage();
		$row    = $this->getTable();

		if (!$row)
		{
			return;
		}

		$row->load($formId);
		$row->merge_vars = @unserialize($row->merge_vars);
		if ($row->merge_vars === false)
		{
			$row->merge_vars = array();
		}

		// Fields
		$fields = array();
		if ($array = $this->_getFields($formId))
		{
			$fields[] = HTMLHelper::_('select.option', '', Text::_('RSFP_EWAY_IGNORE'));
			foreach ($array as $field)
			{
				$fields[] = HTMLHelper::_('select.option', $field, $field);
			}
		}

		// Merge Vars
		$merge_vars = array(
			'cardholder'                => Text::_('RSFP_EWAY_CARDHOLDER'),
			'creditcard'                => Text::_('RSFP_EWAY_CREDITCARD'),
			'expmonth'                  => Text::_('RSFP_EWAY_EXPIRATION_MONTH'),
			'expyear'                   => Text::_('RSFP_EWAY_EXPIRATION_YEAR'),
			'cscnumber'                 => Text::_('RSFP_EWAY_CSC'),
			'payment_InvoiceDescription' => Text::_('RSFP_EWAY_PAYMENT_INVOICEDESCRIPTION'),
			'customer_Reference'        => Text::_('RSFP_EWAY_CUSTOMER_REFERENCE'),
			'customer_Title'            => Text::_('RSFP_EWAY_CUSTOMER_TITLE'),
			'customer_FirstName'        => Text::_('RSFP_EWAY_CUSTOMER_FIRSTNAME'),
			'customer_LastName'         => Text::_('RSFP_EWAY_CUSTOMER_LASTNAME'),
			'customer_CompanyName'      => Text::_('RSFP_EWAY_CUSTOMER_COMPANYNAME'),
			'customer_JobDescription'   => Text::_('RSFP_EWAY_CUSTOMER_JOBDESCRIPTION'),
			'customer_Street1'          => Text::_('RSFP_EWAY_CUSTOMER_STREET1'),
			'customer_Street2'          => Text::_('RSFP_EWAY_CUSTOMER_STREET2'),
			'customer_City'             => Text::_('RSFP_EWAY_CUSTOMER_CITY'),
			'customer_State'            => Text::_('RSFP_EWAY_CUSTOMER_STATE'),
			'customer_PostalCode'       => Text::_('RSFP_EWAY_CUSTOMER_POSTALCODE'),
			'customer_Country'          => Text::_('RSFP_EWAY_CUSTOMER_COUNTRY'),
			'customer_Email'            => Text::_('RSFP_EWAY_CUSTOMER_EMAIL'),
			'customer_Phone'            => Text::_('RSFP_EWAY_CUSTOMER_PHONE'),
			'customer_Mobile'           => Text::_('RSFP_EWAY_CUSTOMER_MOBILE'),
			'customer_Comments'         => Text::_('RSFP_EWAY_CUSTOMER_COMMENTS'),
			'customer_Fax'              => Text::_('RSFP_EWAY_CUSTOMER_FAX'),
			'customer_Url'              => Text::_('RSFP_EWAY_CUSTOMER_URL')
		);

		$lists['ew_fields'] = array();
		if (is_array($merge_vars))
		{
			foreach ($merge_vars as $merge_var => $title)
			{
				$lists['ew_fields'][$merge_var] = HTMLHelper::_('select.genericlist', $fields, 'eway[merge_vars][' . $merge_var . ']', null, 'value', 'text', isset($row->merge_vars[$merge_var]) ? $row->merge_vars[$merge_var] : null);
			}
		}
		?>
		<div id="ewaydiv">
			<table class="table table-bordered">
				<?php
				if (is_array($merge_vars))
				{
					foreach ($merge_vars as $merge_var => $title)
					{
						?>
						<tr>
							<td nowrap="nowrap" width="80" align="right" class="key"><?php echo $title ?></td>
							<td nowrap="nowrap">
								<?php
								echo $lists['ew_fields'][$merge_var];

								if ($lang->hasKey('RSFP_EWAY_' . $merge_var . '_DESC'))
								{
									echo '<p>' . Text::_('RSFP_EWAY_' . $merge_var . '_DESC') . '</p>';
								}
								?>
							</td>
						</tr>
						<?php
					}
				}
				?>
			</table>
		</div>
		<?php
	}

	public function onRsformBackendAfterShowConfigurationTabs($tabs)
	{
		$tabs->addTitle(Text::_('RSFP_EWAY_LABEL'), 'form-eway');
		$tabs->addContent($this->showConfigurationScreen());
	}

	private function loadFormData()
	{
		$data 	= array();
		$db 	= Factory::getDbo();

		$query = $db->getQuery(true)
			->select('*')
			->from($db->qn('#__rsform_config'))
			->where($db->qn('SettingName') . ' LIKE ' . $db->q('eway.%', false));
		if ($results = $db->setQuery($query)->loadObjectList())
		{
			foreach ($results as $result)
			{
				$data[$result->SettingName] = $result->SettingValue;
			}
		}

		return $data;
	}

	protected function showConfigurationScreen()
	{
		ob_start();

		Form::addFormPath(__DIR__ . '/forms');

		$form = Form::getInstance( 'plg_system_rsfpewaypayment.configuration', 'configuration', array('control' => 'rsformConfig'), false, false );
		$form->bind($this->loadFormData());

		?>
		<div id="page-eway" class="form-horizontal">
			<?php
			foreach ($form->getFieldsets() as $fieldset)
			{
				if ($fields = $form->getFieldset($fieldset->name))
				{
					foreach ($fields as $field)
					{
						// This is a workaround because our fields are named "eway." and Joomla! uses the dot as a separator and transforms the JSON into [eway][apikey] instead of [eway.apikey].
						echo str_replace('"rsformConfig[eway][', '"rsformConfig[eway.', $form->renderField($field->fieldname));
					}
				}
			}
			?>
		</div>
		<?php

		$contents = ob_get_contents();
		ob_end_clean();

		return $contents;
	}

	public function onRsformGetPayment(&$items, $formId)
	{
		if ($components = RSFormProHelper::componentExists($formId, $this->componentId))
		{
			$data = RSFormProHelper::getComponentProperties($components[0]);

			$item        = new stdClass();
			$item->id    = $components[0];
			$item->value = $this->componentValue;
			$item->text  = $data['LABEL'];
			
			if ($tax = RSFormProHelper::getConfig('eway.taxvalue'))
			{
				$item->tax = $tax;
				$item->tax_type = RSFormProHelper::getConfig('eway.taxtype') == '0' ? 'percent' : 'fixed';

			}

			// add to array
			$items[] = $item;
		}
	}

	/**
	 * @param $payValue
	 * @param $formId
	 * @param $SubmissionId
	 * @param $price
	 * @param $products
	 * @param $code
	 *
	 * @throws Exception
	 */
	public function onRsformDoPayment($payValue, $formId, $SubmissionId, $price, $products, $code)
	{
		// execute only for our plugin
		if ($payValue != $this->componentValue)
		{
			return;
		}

		if ($price > 0)
		{
			$db    = Factory::getDbo();
			$post  = $_POST['form'];
			$query = $db->getQuery(true);
			$query->select('*')
				->from($db->qn('#__rsform_eway'))
				->where($db->qn('form_id') . ' = ' . $db->q($formId));
			$db->setQuery($query);
			if ($row = $db->loadObject())
			{
				$row->merge_vars = @unserialize($row->merge_vars);
				if ($row->merge_vars === false)
				{
					$row->merge_vars = array();
				}

				/**
				 * Get the calculated price (with tax)
				 */
				if ($tax = RSFormProHelper::getConfig('eway.taxvalue'))
				{
					$price = $this->calcTax($price, RSFormProHelper::getConfig('eway.taxvalue'), RSFormProHelper::getConfig('eway.taxtype'));
				}

				$vars          = array();
				$vars['price'] = $price;
				foreach ($row->merge_vars as $tag => $field)
				{
					if (empty($tag))
					{
						continue;
					}

					if (!isset($post[$field]))
					{
						$post[$field] = '';
					}

					if (is_array($post[$field]))
					{
						$post[$field] = implode(',', $post[$field]);
					}

					$vars[$tag] = $post[$field];
				}

				// Make the payment
				require_once JPATH_ADMINISTRATOR . '/components/com_rsform/helpers/eway/include_eway.php';

				$apiKey      = RSFormProHelper::getConfig('eway.username');
				$apiPassword = RSFormProHelper::getConfig('eway.password');
				$apiEndpoint = \Eway\Rapid\Client::MODE_PRODUCTION;

				if (!(bool) RSFormProHelper::getConfig('eway.test'))
				{
					$apiEndpoint = \Eway\Rapid\Client::MODE_SANDBOX;
				}

				$client = \Eway\Rapid::createClient($apiKey, $apiPassword, $apiEndpoint);

				$payment = array(
					'TotalAmount'   => 100 * number_format($price, 2, '.', ''),
					'InvoiceNumber' => substr($code, 0, 16),
					'InvoiceReference' => 'Form #' . $formId . ' Submission #' . $SubmissionId,
					'InvoiceDescription' => $vars['payment_InvoiceDescription'],
					'CurrencyCode'  => RSFormProHelper::getConfig('payment.currency')
				);

				$transaction = array(
					'Payment'         => $payment,
					'RedirectUrl'     => Uri::root() . 'index.php?option=com_rsform&formId=' . $formId . '&task=plugin&plugin_task=eway.return&internalCode=' . $code,
					'TransactionType' => \Eway\Rapid\Enum\TransactionType::PURCHASE,
					'Capture'         => true,
					'CustomerIP'      => IpHelper::getIp(),
					'Customer'        => array(
						'Reference'         => $vars['customer_Reference'],
						'Title'             => $vars['customer_Title'],
						'FirstName'         => $vars['customer_FirstName'],
						'LastName'          => $vars['customer_LastName'],
						'CompanyName'       => $vars['customer_CompanyName'],
						'JobDescription'    => $vars['customer_JobDescription'],
						'Street1'           => $vars['customer_Street1'],
						'Street2'           => $vars['customer_Street2'],
						'City'              => $vars['customer_City'],
						'State'             => $vars['customer_State'],
						'PostalCode'        => $vars['customer_PostalCode'],
						'Country'           => strtolower($vars['customer_Country']),
						'Email'             => $vars['customer_Email'],
						'Phone'             => $vars['customer_Phone'],
						'Mobile'            => $vars['customer_Mobile'],
						'Comments'          => $vars['customer_Comments'],
						'Fax'               => $vars['customer_Fax'],
						'Url'               => $vars['customer_Url']
					)
				);

				// Get a new instance of the Eway object. This is used so that we can programmatically change values sent to Eway through the "Scripts" areas.
				$eway = RSFormProEway::getInstance();

				// If any options have already been set, use this to override the ones used here
				$eway->merge($transaction);

				$response = $client->createTransaction(\Eway\Rapid\Enum\ApiMethod::TRANSPARENT_REDIRECT, $eway->args);
				$errors = $response->getErrors();

				if (empty($errors))
				{
					$data = array(
						'EWAY_CARDNAME'        => $vars['cardholder'],
						'EWAY_CARDNUMBER'      => $vars['creditcard'],
						'EWAY_CARDEXPIRYMONTH' => $vars['expmonth'],
						'EWAY_CARDEXPIRYYEAR'  => $vars['expyear'],
						'EWAY_CARDCVN'         => $vars['cscnumber'],
						'EWAY_ACCESSCODE'      => $response->AccessCode,
						'EWAY_PAYMENTTYPE'     => 'Credit Card'
					);

					?>
					<form method="post" action="<?php echo RSFormProHelper::htmlEscape($response->FormActionURL); ?>" id="payment_form">
						<?php foreach ($data as $key => $value)
						{ ?>
							<input type="hidden" name="<?php echo RSFormProHelper::htmlEscape($key); ?>" value="<?php echo RSFormProHelper::htmlEscape($value); ?>" />
						<?php } ?>
					</form>
					<div style="padding: 100px; text-align: center;">
						<p><?php echo Text::_('RSFP_EWAY_PLEASE_WAIT_WHILE_PROCESSING'); ?></p>
						<p><?php echo HTMLHelper::_('image', 'plg_system_rsfpewaypayment/eway.png', Text::_('RSFP_EWAY_PLEASE_WAIT_WHILE_PROCESSING'), null, true); ?></p>
					</div>
					<script type="text/javascript">
						function paymentFormSubmit() {
							window.setTimeout(function () {
								document.getElementById('payment_form').submit();
							}, 5500);
						}
						try {
							window.addEventListener ? window.addEventListener('load', paymentFormSubmit, false) : window.attachEvent('onload', paymentFormSubmit);
						}
						catch (err) {
							paymentFormSubmit();
						}
					</script>
					<?php
					Factory::getApplication()->close();
				}
				else
				{
					foreach ($errors as $errorCode)
					{
						Factory::getApplication()->enqueueMessage(Text::_('RSFP_EWAY_' . $errorCode), 'error');
					}
				}
			}
		}
	}

	/**
	 * @param $args
	 */
	public function onRsformFrontendBeforeStoreSubmissions($args)
	{
		$formId = (int) $args['formId'];
		$post   = &$args['post'];

		// Do we have a Choose Payment field?
		$choosePayment = RSFormProHelper::componentExists($formId, RSFORM_FIELD_PAYMENT_CHOOSE);
		if (!$choosePayment)
		{
			return;
		}

		// Check that we're paying through eWay
		$properties = RSFormProHelper::getComponentProperties($choosePayment[0]);
		$fieldName = $properties['NAME'];
		if (!isset($post[$fieldName]))
		{
			return;
		}

		$payValue = $post[$fieldName];
		if (is_array($payValue))
		{
			$payValue = implode('', $payValue);
		}

		if ($payValue != $this->componentValue)
		{
			return;
		}

		// Get fields to remove sensitive data from
		$db     = Factory::getDbo();
		$query  = $db->getQuery(true);
		$query->select('*')
			->from($db->qn('#__rsform_eway'))
			->where($db->qn('form_id') . ' = ' . $db->q($formId));
		$db->setQuery($query);
		if ($row = $db->loadObject())
		{
			$row->merge_vars = @unserialize($row->merge_vars);
			if ($row->merge_vars === false)
			{
				$row->merge_vars = array();
			}

			foreach ($row->merge_vars as $tag => $field)
			{
				if (empty($tag) || empty($field))
				{
					continue;
				}

				if ($tag == 'creditcard' || $tag == 'expmonth' || $tag == 'expyear' || $tag == 'cscnumber')
				{
					$post[$field] = '';
				}
			}
		}
	}

	/**
	 * @throws Exception
	 */
	public function onRsformFrontendSwitchTasks()
	{
		$input  = Factory::getApplication()->input;
		$formId = $input->getInt('formId', 0);

		if ($input->getString('plugin_task', '') == 'eway.return')
		{
			$this->ewayReturn($formId, $input->get('AccessCode', '', 'raw'), $input->getString('internalCode', ''));
		}
	}

	// Parse the response
	/**
	 * @param $formId
	 * @param $accessCode
	 *
	 * @throws Exception
	 */
	protected function ewayReturn($formId, $accessCode, $internalCode)
	{
		$app = Factory::getApplication();

		require_once JPATH_ADMINISTRATOR . '/components/com_rsform/helpers/eway/include_eway.php';
		$apiEndpoint = \Eway\Rapid\Client::MODE_PRODUCTION;

		if (!(bool) RSFormProHelper::getConfig('eway.test'))
		{
			$apiEndpoint = \Eway\Rapid\Client::MODE_SANDBOX;
		}

		$client   = \Eway\Rapid::createClient(RSFormProHelper::getConfig('eway.username'), RSFormProHelper::getConfig('eway.password'), $apiEndpoint);
		$response = $client->queryTransaction($accessCode);

		if (isset($response->Transactions[0]))
		{
			$transactionStatus = $response->Transactions[0]->getAttribute('TransactionStatus');
			$transactionId	   = $response->Transactions[0]->getAttribute('TransactionID');
		}
		else
		{
			$transactionStatus 	= null;
			$transactionId 		= null;
		}

		$errors    = $response->getErrors();
		$confirmed = false;

		if (empty($errors) && $transactionStatus)
		{
			$db    = Factory::getDbo();
			$query = $db->getQuery(true);
			$query->select($db->qn('SubmissionId'))
				->from($db->qn('#__rsform_submissions', 's'))
				->where($db->qn('s.FormId') . ' = ' . $db->q($formId))
				->where('MD5(CONCAT(' . $db->qn('s.SubmissionId') . ',' . $db->qn('s.DateSubmitted') . ')) = ' . $db->q($internalCode));
			$db->setQuery($query);
			if ($SubmissionId = $db->loadResult())
			{
				$query->clear();
				$query->update($db->qn('#__rsform_submission_values'))
					->set($db->qn('FieldValue') . ' = ' . $db->q(1))
					->where($db->qn('FieldName') . ' = ' . $db->q('_STATUS'))
					->where($db->qn('FormId') . ' = ' . $db->q($formId))
					->where($db->qn('SubmissionId') . ' = ' . $db->q($SubmissionId));
				$db->setQuery($query);
				$db->execute();

				// Add $transactionId to _TRANSACTION_ID field
				if (!empty($transactionId))
				{
					$query->clear();
					$query->update($db->qn('#__rsform_submission_values'))
						->set($db->qn('FieldValue') . ' = ' . $db->q($transactionId))
						->where($db->qn('FieldName') . ' = ' . $db->q('_TRANSACTION_ID'))
						->where($db->qn('FormId') . ' = ' . $db->q($formId))
						->where($db->qn('SubmissionId') . ' = ' . $db->q($SubmissionId));
					$db->setQuery($query);
					$db->execute();
				}

				$confirmed = true;
				$app->triggerEvent('onRsformAfterConfirmPayment', array($SubmissionId));
			}
		}

		$log = array();
		if (!empty($errors))
		{
			foreach ($errors as $error)
			{
				$log[] = Text::_('RSFP_EWAY_' . \Eway\Rapid::getMessage($error));
			}
		}

		if (!$transactionStatus && isset($response->Transactions[0]))
		{
			$errors = explode(',', $response->Transactions[0]->ResponseMessage);
			foreach ($errors as $error)
			{
				$log[] = Text::_('RSFP_EWAY_' . \Eway\Rapid::getMessage($error));
			}
		}

		$reason = '';
		if (!empty($log))
		{
			$reason = implode('<br />', $log);
		}

		// Get session object
		$session = Factory::getSession();

		// Get data from session
		$formparams = $session->get('com_rsform.formparams.formId' . $formId);

		if ($formparams && $formparams->redirectUrl)
		{
			// Mark form as processed
			$formparams->formProcessed = true;

			// Store new session data
			$session->set('com_rsform.formparams.formId' . $formId, $formparams);

			$message = array(
				'type' => $confirmed ? 'Notice' : 'error',
				'message' => $confirmed ? Text::sprintf('PLG_SYSTEM_RSFPEWAY_TRANSACTION_SUCCESSFUL', substr($internalCode, 0,16)) : $reason
			);

			// Redirect
			$app->enqueueMessage($message['message'], $message['type']);
			$app->redirect($formparams->redirectUrl);
		}
	}

	/**
	 * @param $formId
	 *
	 * @return mixed
	 */
	protected function _getFields($formId)
	{
		$db    = Factory::getDbo();
		$query = $db->getQuery(true)
			->select($db->qn('p.PropertyValue'))
			->from($db->qn('#__rsform_components', 'c'))
			->join('LEFT', $db->qn('#__rsform_properties', 'p') . ' ON (' . $db->qn('c.ComponentId') . '=' . $db->qn('p.ComponentId') . ')')
			->where($db->qn('c.FormId') . '=' . $db->q($formId))
			->where($db->qn('p.PropertyName') . '=' . $db->q('NAME'))
			->order($db->qn('c.Order') . ' ' . $db->escape('ASC'));

		return $db->setQuery($query)->loadColumn();
	}

	/**
	 * @param $formId
	 */
	public function onRsformFormDelete($formId)
	{
		if ($row = $this->getTable())
		{
			$row->delete($formId);
		}
	}

	/**
	 * @param $form
	 * @param $xml
	 * @param $fields
	 */
	public function onRsformFormBackup($form, $xml, $fields)
	{
		if ($row = $this->getTable())
		{
			if ($row->load($form->FormId))
			{
				$row->check();

				$data = $row->getProperties();
				unset($data['form_id']);

				$xml->add('eway');
				foreach ($data as $property => $value)
				{
					$xml->add($property, $value);
				}
				$xml->add('/eway');
			}
		}
	}

	/**
	 * @param $form
	 * @param $xml
	 * @param $fields
	 */
	public function onRsformFormRestore($form, $xml, $fields)
	{
		if (isset($xml->eway))
		{
			$data = array(
				'form_id' => $form->FormId
			);

			foreach ($xml->eway->children() as $property => $value)
			{
				$data[$property] = (string) $value;
			}

			$row = $this->getTable();
			$row->save($data);
		}
	}

	public function onRsformBackendFormRestoreTruncate()
	{
		Factory::getDbo()->truncateTable('#__rsform_eway');
	}

	public function calcTax($price, $amount, $type)
	{
		$price = (float) $price;
		$amount = (float) $amount;

		switch ($type)
		{
			case false:
				$price = $price + (($price * $amount) / 100);
				break;

			case true:
				$price = $price + $amount;
				break;
		}

		return $price;
	}

	public function onRsformAfterCreatePlaceholders($args)
	{
		if ($choosePayment = RSFormProHelper::componentExists($args['form']->FormId, RSFORM_FIELD_PAYMENT_CHOOSE))
		{
			$properties = RSFormProHelper::getComponentProperties($choosePayment[0]);
			$fieldName = $properties['NAME'];

			if (!isset($args['submission']->values[$fieldName]))
			{
				return;
			}

			if ($args['submission']->values[$fieldName] != $this->componentValue)
			{
				return;
			}

			$grandTotal = $this->calcTax($args['submission']->values['rsfp_Total'], RSFormProHelper::getConfig('eway.taxvalue'), RSFormProHelper::getConfig('eway.taxtype'));

			$placeholders = &$args['placeholders'];
			$values       = &$args['values'];

			$placeholders[] = '{grandtotal}';
			$values[]       = $this->number_format($grandTotal);

			$placeholders[] = '{tax}';
			$values[]       = $this->number_format($grandTotal - (float) $args['submission']->values['rsfp_Total']);
		}
	}

	public function onRsformAfterCreateQuickAddPlaceholders(& $placeholders, $componentId)
	{
		if ($componentId == $this->componentId)
		{
			$placeholders['display'][] = '{grandtotal}';
			$placeholders['display'][] = '{tax}';
		}

		return $placeholders;
	}

	private function number_format($val)
	{
		return number_format((float) $val, RSFormProHelper::getConfig('payment.nodecimals'), RSFormProHelper::getConfig('payment.decimal'), RSFormProHelper::getConfig('payment.thousands'));
	}
}

class RSFormProEway
{
	public $args = array();

	public static function getInstance() {
		static $inst;
		if (!$inst) {
			$inst = new RSFormProEway;
		}

		return $inst;
	}

	public function merge($transaction)
	{
		foreach ($transaction as $key => $values)
		{
			if (is_array($values))
			{
				if (!isset($this->args[$key]))
				{
					$this->args[$key] = array();
				}

				$this->args[$key] = array_merge($values, $this->args[$key]);
			}
			else
			{
				$this->args[$key] = $values;
			}
		}
	}
}