<?php

/**
 * Výchozí funkce processeru.
 *
 * @category   Dalten
 * @package    Config
 * @subpackage Processer
 */
class Dalten_Config_Processer_DefaultFunctions
{
	/**
	 * Sečte předané hodnoty.
	 *
	 * @return number Suma hodnot.
	 */
	public function sum()
	{
		return array_sum(func_get_args());
	}

	/**
	 * Vrátí nejvyšší hodnotu.
	 * Pokud je jedna z předaných hodnot pole, jsou použity všechny jeho prvky v první úrovni.
	 *
	 * @return float Nejvyšší hodnota.
	 */
	public function max()
	{
		$values = array();
		foreach (func_get_args() as $arg) {
			$values = array_merge($values, array_map('floatval', (array) $arg));
		}

		return (float) max($values);
	}

	/**
	 * Vyhledá a nahradí předaný vzorec hodnotou.
	 *
	 * @param string $pattern Vzorec (řetězec nebo regulár).
	 * @param string $replace Čím nahradit.
	 * @param string $string  Řetězec.
	 *
	 * @return string Řetězec po nahrazení.
	 */
	public function replace($pattern, $replace, $string)
	{
		return preg_replace('~' . $pattern . '~', $replace, (string) $string);
	}

	/**
	 * Ořízne řetězec na zadanou délku.
	 *
	 * @param string $string Řetězec.
	 * @param int    $start  Offset, odkud začít.
	 * @param int    $length Délka řetězce.
	 *
	 * @return string Oříznutý řetězec.
	 */
	public function substr($string, $start, $length = null)
	{
		$length = ($length) ? (int) $length : mb_strlen($string, 'UTF-8');

		return mb_substr((string) $string, (int) $start, $length, 'UTF-8');
	}

	/**
	 * Naformátuje zadané datum podle zadaného formátu.
	 *
	 * @param string $format Formát (viz PHP manuál).
	 * @param string $date   Datum.
	 *
	 * @return string Zformátované datum.
	 */
	public function date($format, $date)
	{
		// Seznam hodnot považovaných za prázdné.
		static $emptyValues = array(
			'0000-00-00' => false,
			'0000-00-00 00:00:00' => false,
			'0' => false,
		);
		$date = (string) $date;
		if (isset($emptyValues[$date]) || $date === '') {
			return '';
		}

		$format = str_replace('|', ':', (string) $format);

		try {
			$result = new DateTime($date);
		} catch (\Exception $e) {
			// Datum asi byla nějaká prasárna, vrátíme radši null, ať kvůli tomu neshodíme export.
			return null;
		}

		return trim($result->format($format), '"');
	}

	/**
	 * Zjistí, jestli se zadaná hodnota nachází v seznamu předaných hodnot.
	 * Pokud je jedna z předaných hodnot pole, jsou použity všechny jeho prvky v první úrovni.
	 *
	 * @param mixed $needle Co hledat (může být i pole).
	 *
	 * @return int Výsledek hledání.
	 */
	public function inList($needle)
	{
		$values = array();
		$args = func_get_args();
		array_shift($args);
		foreach ($args as $arg) {
			$values = array_merge($values, (array) $arg);
		}

		return (int) in_array($needle, $values);
	}

	/**
	 * Převádí předané souřadnice ze stupňů na float.
	 * Pokud předané souřadnice nejsou ve správném tvaru, vrací null.
	 *
	 * @param string $value Souřadnice ve stupních.
	 *
	 * @return float|null Souřadnice jako float nebo null, pokud je souřadnice v nesprávném formátu.
	 */
	public function degToFloat($value)
	{
		$value = trim($value);
		$parts = array();
		$pattern = '~^(?<degree>[0-9]{1,3}).(?<minute>[0-9]{1,2})\'(?<second>[0-9]+)';
		$pattern .= '(?<milisecond>\.[0-9]+)?"(?<letter>[NSEW])$~u';
		if (preg_match($pattern, $value, $parts)) {
			$valid = true;
			$valid = $valid && ($parts['degree'] >= 0 && $parts['degree'] <= 180);
			$valid = $valid && ($parts['minute'] >= 0 && $parts['minute'] <= 60);
			$valid = $valid && ($parts['second'] >= 0 && $parts['second'] <= 60);
			if ($valid === false) {
				return null;
			}
			if (isset($parts['milisecond']) && $parts['milisecond']) {
				$parts['second'] += floatVal('0' . $parts['milisecond']);
			}
			$return = (int) $parts['degree'];
			$return += $parts['minute'] / 60;
			$return += $parts['second'] / 3600;
			if ($parts['letter'] === 'S' || $parts['letter'] === 'W') {
				$return *= -1;
			}
			return sprintf('%F', $return);
		}

		return null;
	}

	/**
	 * Provede na předaném řetězci urlencode a vrátí jej.
	 *
	 * @param string $string String k urlencode.
	 *
	 * @return string urlencoded string.
	 */
	public function urlEncode($string)
	{
		return urlencode($string);
	}

	/**
	 * Provede na předaném řetězci rawurlencode a vrátí jej.
	 *
	 * @param string $string String k rawurlencode.
	 *
	 * @return string rawurlencoded string.
	 */
	public function rawUrlEncode($string)
	{
		return rawurlencode($string);
	}

	/**
	 * Obaluje funkci str_pad. Zarovná řetězec daným počtem znaků.
	 *
	 * @param string $string    Řetězec na zarovnání.
	 * @param int    $padLenght Cílová délka.
	 * @param string $padString Řetězec kterým se zarovnává.
	 *
	 * @return string Zarovnaný řetězec
	 */
	public function strPad($string, $padLenght, $padString)
	{
		return str_pad($string, $padLenght, $padString);
	}

	/**
	 * Obaluje funkci round. Zaokrouhlí číslo.
	 *
	 * @param mixed $number Číslo na zaokrouhlení.
	 *
	 * @return float Zaokrouhlené číslo.
	 */
	public function round($number)
	{
		return round(floatval($number));
	}
}
