<?php
namespace App\Utils\DigitsToLetters;

/**
 * This converter was implemented manually after a Visual Basic example received from the client:
 * From: Sumit Grover, To: Diana Ioana Magadan, Sent: Monday, May 3, 2021 11:12
 * This might be refactored using KWN library.
 * @author Dan Baluta
 */
class SA extends GeneralAbstract
{
	/**
	 * (non-PHPdoc)
	 * @see \App\Utils\DigitsToLetters\GeneralAbstract::getText()
	 */
	public function getText()
	{
		$val  = "";
		$andStr = "";
		$pointStr = "";
		$endStr = "";

		list($wholeNo, $points) = explode(".", $this->value);   // separate whole numbers from points

		$wholeNoText = trim($this->translateWholeNumber($wholeNo));

		if ($wholeNoText) {
			$wholeNoText .= $this->separator.$this->currencyName;   // Saudi Riyal (currency): "السعودي الريال"
		}

		if ($points) {
			if ($wholeNo) {
				$andStr = "و".$this->separator;
			}

			$pointStr = trim($this->translateWholeNumber($points));

			if ($pointStr) {
				$pointStr .= $this->separator.$this->currencySubdivision;	// Halala (subdivision): " هللة"
			}
		}

		$val = sprintf("%s{$this->separator}%s%s{$this->separator}%s", $wholeNoText, $andStr, $pointStr, $endStr);

		return trim($val, $this->separator);
	}


	/**
	 * Translate an integer (recursive function)
	 * @param integer $number
	 * @return string
	 */
	private function translateWholeNumber($number)
	{
		$word = "";

		$signStr = ($number<0) ? "-":"";	// minus: ناقص
		$numberAbs = abs($number);

		// check for 0XX
		$beginsZero = false;
		// check if already translated
		$isDone = false;
		$dblAmt = sprintf("%.2f", $numberAbs);

		if ($dblAmt != 0) {
			// test for zero or digit zero in a nuemric
			if (strpos($numberAbs, "0") === 0) {
				$beginsZero = true;
			}

			$numDigits = strlen($numberAbs);
			$pos = 0;
			// store digit grouping
			$place = "";
			// digit grouping name:hundres,thousand,etc...
			switch ($numDigits) {
				case 1:
					// ones' range
					$word = $this->ones($numberAbs);
					$isDone = true;
				break;
				case 2:
					// tens' range
					$word = $this->tens($numberAbs);
					$isDone = true;
				break;
				case 3:
					// hundreds' range
					$pos = ($numDigits % 3) + 1;
					$place = " مائة ";
				break;
				case 4: case 5: case 6:
					// thousands' range
					$pos = ($numDigits % 4) + 1;
					$place = " ألف ";
				break;
				case 7: case 8: case 9:
					// millions' range
					$pos = ($numDigits % 7) + 1;
					$place = " مليون ";
				break;
				case 10:
					// billions's range
					$pos = ($numDigits % 10) + 1;
					$place = " مليار ";
				break;
				default:
					// add extra case options for anything above Billion...
					$isDone = true;
				break;
			}

			if (!$isDone) {
				// if transalation is not done, continue...(Recursion comes in now!!)
				$word = $this->translateWholeNumber(substr($numberAbs, 0, $pos)) . $place . $this->translateWholeNumber(substr($numberAbs, $pos));

				// check for trailing zeros
				if ($beginsZero) {
					$word = $this->separator . "و" . $this->separator . trim($word, $this->separator);
				}
			}

			// ignore digit grouping names
			if (trim($word)==trim($place)) {
				$word = "";
			}

			// add sign
			if ($word) {
				$word = $signStr.$word;
			}
		}

		return trim($word);
	}

	/**
	 * Translate two-digit numbers: 10 to 90
	 * @param integer $digit
	 * @return NULL|string
	 */
	private function tens($digit)
	{
		$digt = (int)$digit;
		$name = null;

		switch ($digt) {
			case 10:
				$name = "عشرة";
			break;
			case 11:
				$name = "أحد عشر";
			break;
			case 12:
				$name = "اثني عشر";
			break;
			case 13:
				$name = "ثلاثة عشر";
			break;
			case 14:
				$name = "أربعة عشرة";
			break;
			case 15:
				$name = "خمسة عشر";
			break;
			case 16:
				$name = "السادس عشر";
			break;
			case 17:
				$name = "سبعة عشر";
			break;
			case 18:
				$name = "الثامنة عشر";
			break;
			case 19:
				$name = "تسعة عشر";
			break;
			case 20:
				$name = "عشرين";
			break;
			case 30:
				$name = "ثلاثون";
			break;
			case 40:
				$name = "أربعون";
			break;
			case 50:
				$name = "خمسون";
			break;
			case 60:
				$name = "ستون";
			break;
			case 70:
				$name = "سبعون";
			break;
			case 80:
				$name = "ثمانون";
				break;
			case 90:
				$name = "تسعين";
			break;
			default:
				if ($digt > 0) {
					$name = ($this->tens(substr($digit, 0, 1) . "0") . $this->separator) . $this->ones(substr($digit, 1));
				}
			break;
		}

		return $name;
	}

	/**
	 * Translate one-digit numbers: 1 to 9
	 * @param integer $digit
	 * @return string
	 */
	private function ones($digit)
	{
		$digt = (int)$digit;
		$name = "";

		switch ($digt) {
			case 1:
				$name = "واحد";
			break;
			case 2:
				$name = "اثنين";
			break;
			case 3:
				$name = "ثلاثة";
			break;
			case 4:
				$name = "أربعة";
			break;
			case 5:
				$name = "خمسة";
			break;
			case 6:
				$name = "ستة";
			break;
			case 7:
				$name = "سبعة";
			break;
			case 8:
				$name = "ثمانية";
			break;
			case 9:
				$name = "تسع";
			break;
		}

		return $name;
	}

}
