<?php
	function function_feed($value)
	{
		return (
			function ($function) use (&$value)
			{
				return $function($value);
			}
		);
	}
	
	function function_compose($function1, $function2)
	{
		return (
			function ($value) use (&$function1, &$function2)
			{
				return ($function2($function1($value)));
			}
		);
	}
	
	function function_chain($functions)
	{
		return (
			function ($value) use (&$functions)
			{
				/*
				return array_reduce($functions, function ($x, $y) {call_user_func("function_compose", $x, $y);}, $value);
				 */
				return ((count($functions) == 0) ? $value : function_feed($functions[0]($value))(function_chain(array_slice($functions, 1))));
			}
		);
	}
	
	function object_from_array($key_name)
	{
		return (
			function ($list) use (&$key_name)
			{
				$object = [];
				foreach ($list as $element)
				{
					$key = $element[$key_name];
					$object[$key] = $element;
				}
				return $object;
			}
		);
	}
	
	function object_attribute($name)
	{
		return (
			function ($object) use (&$name)
			{
				return $object[$name];
			}
		);
	}
	
	function object_map($function)
	{
		return (
			function ($object) use (&$function)
			{
				$object_ = [];
				foreach ($object as $key => $value)
				{
					$object_[$key] = $function($value);
				}
				return $object_;
			}
		);
	}
	
	function fetch($structure, $field, $fallback = null, $escalation = 1)
	{
		if (array_key_exists($field, $structure))
		{
			return $structure[$field];
		}
		else
		{
			switch ($escalation)
			{
				case 0:
				{
					return $fallback;
					// break;
				}
				case 1:
				{
					return $fallback;
					// break;
				}
				case 2:
				{
					throw (sprintf("field '%s' missing in structure!", $field));
					return $fallback;
					// break;
				}
				default:
				{
					throw (sprintf("unhandled escalation level %u", $escalation));
					// break;
				}
			}
		}
	}
	
	function compose($names)
	{
		array_map
		(
			function ($name)
			{
				include("source/content/" . $name . ".html.php");
			},
			$names
		);
	}
	
	function mark($core, $classes)
	{
		global $configuration;
		if ($configuration["replace_fs_umlauts"])
		{
			if (in_array("lang_fs", $classes) and !in_array("letter", $classes))
			{
				$core = str_replace
				(
					["ö","ü"],
					["oy","uy"],
					$core
				);
			}
		}
		return ('<span class="' . implode(" ", $classes) . '">' . $core . '</span>');
	}
	
	function format($string, $classes = ["type_word", "lang_fs"])
	{
		if ($string == NULL)
		{
			$string = "--";
		}
		else
		{
			$string = preg_replace("/\/([^\/]*)\//", mark("$1", ["ipa"]), $string);
			$string = preg_replace("/_([^_]*)_/", "<u>$1</u>", $string);
			$string = preg_replace("/\'([^\']*)\'/", mark("$1", $classes), $string);
		}
		return $string;
	}
	
	function _foo($fieldname)
	{
		return (
			function ($row) use (&$fieldname)
			{
				global $configuration;
				return ["original" => $row[$fieldname]["fs"], "translated" => $row[$fieldname][$configuration["target"]]];
			}
		);
	}
	
	function _baz($words, $type, $language)
	{
		return ((count($words) == 0) ? "?" : implode(", ", array_map(function ($word) use (&$type,&$language) {return mark($word, [$type, "lang_" . $language]);}, $words)));
	}
	
	function _bar($type = "type_word")
	{
		return (
			function ($value) use (&$type)
			{
				global $configuration;
				$output = "";
				$output .= _baz($value["original"], $type, "fs");
				$output .= " ~ ";
				$output .= _baz($value["translated"], $type, $configuration["target"]);
				return $output;
			}
		);
	}
	
	function format_single($type, $language)
	{
		return (
			function ($piece) use (&$type, &$language)
			{
				return mark($piece, [$type, "lang_" . $language]);
			}
		);
	}
	
	function format_list($type, $language)
	{
		return (
			function ($pieces) use (&$type, &$language)
			{
				return ((count($pieces) == 0) ? "?" : implode(", ", array_map(format_single($type, $language), $pieces)));
			}
		);
	}
	
	function format_correlation($type, $language_from = "fs", $language_to = null)
	{
		global $configuration;
		if ($language_to == null) $language_to = $configuration["target"];
		return (
			function ($source) use (&$type, &$language_from, &$language_to)
			{
				$output = "";
				$output .= format_list($type, $language_from)($source[$language_from]);
				$output .= " ~ ";
				$output .= format_list($type, $language_to)($source[$language_to]);
				return $output;
			}
		);
	}
	
	function proposal()
	{
 ?>
		<div class="note note_error">
			<span class="note_content">
				<p>This section is only a proposal yet; not part of the draft.</p>
			</span>
		</div>
<?php
	}
 ?>