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

defined('_JEXEC') or die;

class RSFormProScripting
{
	public static function compile(&$subject, $replace, $with)
	{
		$placeholders = array_combine($replace, $with);
		$formId = isset($placeholders['{global:formid}']) ? $placeholders['{global:formid}'] : null;
		
		$placeholderPattern = '({[a-zA-Z0-9\_\- ]+:[a-zA-Z_]+})';
		$innerPattern 		= '((?:(?!{/?if).)*?)';
		$comparisonPattern  = '(<=|&lt;=|>=|&gt;=|<-|&lt;-|->|-&gt;|<>|&lt;&gt;|<|&lt;|>|&gt;|!=|===|==|=)';
		
		// {Placeholder1:value} > {Placeholder2:value}
		$pattern = '#{if\s?' . $placeholderPattern . '\s?' . $comparisonPattern . '?\s?' . $placeholderPattern . '?\s?}' . $innerPattern . '{/if}#s';
		while (preg_match($pattern, $subject, $match)) {
			$placeholder = trim($match[1]);
			$operand	 = htmlspecialchars_decode(trim($match[2]));
			$compare 	 = trim($match[3]);
			$content 	 = $match[4];
			$value		 = !isset($placeholders[$placeholder]) ? '' : $placeholders[$placeholder];
			$compare	 = !isset($placeholders[$compare]) ? '' : $placeholders[$compare];
			
			$result = static::doComparison($value, $compare, $operand, $formId);
			
			// if empty value remove whole line
			// else show line but remove pseudo-code
			$subject = preg_replace($pattern,
									$result ? addcslashes($content, '$') : '',
									$subject,
									1);
		}
		
		// {Placeholder1:value} > 1
		$pattern = '#{if\s?' . $placeholderPattern . '\s?' . $comparisonPattern . '?\s?' . $innerPattern . '?\s?}' . $innerPattern . '{/if}#s';
		while (preg_match($pattern, $subject, $match)) {
			$placeholder = trim($match[1]);
			$operand	 = htmlspecialchars_decode(trim($match[2]));
			$compare	 = trim($match[3], '\'" ');
			$content 	 = $match[4];
			$value		 = !isset($placeholders[$placeholder]) ? '' : $placeholders[$placeholder];
			
			$result = static::doComparison($value, $compare, $operand, $formId);
			
			// if empty value remove whole line
			// else show line but remove pseudo-code
			$subject = preg_replace($pattern,
									$result ? addcslashes($content, '$') : '',
									$subject,
									1);
		}
		
		// 1 < {Placeholder1:value}
		$pattern = '#{if\s?' . $innerPattern . '\s?' . $comparisonPattern . '?\s?' . $placeholderPattern . '?\s?}' . $innerPattern . '{/if}#s';
		while (preg_match($pattern, $subject, $match)) {
			$placeholder = trim($match[1]);
			$operand	 = htmlspecialchars_decode(trim($match[2]));
			$compare	 = trim($match[3], '\'" ');
			$content 	 = $match[4];
			$value		 = !isset($placeholders[$placeholder]) ? '' : $placeholders[$placeholder];
			
			$result = static::doComparison($value, $compare, $operand, $formId);
			
			// if empty value remove whole line
			// else show line but remove pseudo-code
			$subject = preg_replace($pattern,
									$result ? addcslashes($content, '$') : '',
									$subject,
									1);
		}
	}
	
	protected static function doComparison($value, $compare, $operand, $formId)
	{
		switch ($operand)
		{
			default:
				$result = $value;
			break;
			
			case '<=':
				$result = $value <= $compare;
			break;
			
			case '>=':
				$result = $value >= $compare;
			break;
			
			case '<>':
				$result = $value <> $compare;
			break;
			
			case '<':
				$result = $value < $compare;
			break;
			
			case '>':
				$result = $value > $compare;
			break;
			
			case '!=':
				$result = $value != $compare;
			break;
			
			case '=':
			case '==':
				$result = $value == $compare;
			break;
			
			case '===':
				$result = $value === $compare;
			break;
			
			case '<-':
				$result = self::inclusion($value, $compare, $formId, 'left');
			break;
			
			case '->':
				$result = self::inclusion($value, $compare, $formId, 'right');
			break;
		}
		
		return $result;
	}
	
	public static function inclusion($value, $compare, $formId, $direction) {
		// let's make sure we have the formId defined
		if (is_null($formId)) return false;
		
		$form = RSFormProHelper::getForm($formId);
		$separator = str_replace(array('\n', '\r', '\t'), array("\n", "\r", "\t"), $form->MultipleSeparator);
		
		$values = explode($separator, $value);
		$compares = explode(',', $compare);
		
		$intersect = array_intersect($values, $compares);
		
		return ($direction == 'left' ? count($intersect) == count($compares) : count($intersect) == count($values));
	}
}