/*
 * Verrückte Turing-Maschinen — A turing complete game
 * Copyright (C) 2016-2018 kcf <vidofnir@folksprak.org>
 * 
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

namespace mod_vtm
	{
		
		export namespace mod_model
			{
				
				export namespace mod_actuator
					{
						
						export namespace mod_reader
							{
								
								/**
								 * @author kcf <vidofnir@folksprak.org>
								 */
								const kind : string = "reader";
								
								
								/**
								 * @author kcf <vidofnir@folksprak.org>
								 */
								export type type_reader =
									{
										"direction": mod_direction.type_direction,
										"symbol_links": mod_symbol.type_symbol,
										"symbol_rechts": mod_symbol.type_symbol,
									}
								;
								
								
								/**
								 * @author kcf <vidofnir@folksprak.org>
								 */
								 function create
									(
										direction : mod_direction.type_direction,
										symbol_links : mod_symbol.type_symbol,
										symbol_rechts : mod_symbol.type_symbol
									)
									: type_reader
									{
										return {
											"direction": direction,
											"symbol_links": symbol_links,
											"symbol_rechts": symbol_rechts,
										};
									}
								
								
								/**
								 * @author kcf <vidofnir@folksprak.org>
								 */
								export function create_extended
									(
										direction : mod_direction.type_direction,
										symbol_links : mod_symbol.type_symbol,
										symbol_rechts : mod_symbol.type_symbol
									)
									: mod_actuator.type_actuator
									{
										return lib_call.wrap(kind, create(direction, symbol_links, symbol_rechts));
									}
								
								
								/**
								 * @author kcf <vidofnir@folksprak.org>
								 */
								function example
									(
									)
									: type_reader
									{
										return create(0, 0, 1);
									}
								
								
								/**
								 * @author kcf <vidofnir@folksprak.org>
								 */
								export function direction_read
									(
										reader : type_reader
									)
									: mod_direction.type_direction
									{
										return reader.direction;
									}
								
								
								/**
								 * @author kcf <vidofnir@folksprak.org>
								 */
								export function symbol_links_read
									(
										reader : type_reader
									)
									: mod_symbol.type_symbol
									{
										return reader.symbol_links;
									}
								
								
								/**
								 * @author kcf <vidofnir@folksprak.org>
								 */
								export function symbol_rechts_read
									(
										reader : type_reader
									)
									: mod_symbol.type_symbol
									{
										return reader.symbol_rechts;
									}
								
								
								/**
								 * @author kcf <vidofnir@folksprak.org>
								 */
								function rotate
									(
										reader : type_reader,
										increment : int = +1
									)
									: void
									{
										reader.direction = mod_direction.add(reader.direction, increment);
									}
								
								
								/**
								 * @author kcf <vidofnir@folksprak.org>
								 */
								function use
									(
										reader : type_reader,
										token : mod_token.type_token
									)
									: void
									{
										const symbol_ : lib_errormonade.type_errormonade<mod_symbol.type_symbol> = mod_token.read(token);
										let summand : mod_direction.type_direction;
										if (lib_errormonade.filled(symbol_))
											{
												const symbol : mod_symbol.type_symbol = lib_errormonade.read(symbol_);
													 if (symbol === reader.symbol_links)
													{
														mod_token.shift(token);
														summand = +2;
													}
												else if (symbol === reader.symbol_rechts)
													{
														mod_token.shift(token);
														summand = -2;
													}
												else
													{
														summand = 0;
													}
											}
										else
											{
												summand = 0;
											}
										const direction : mod_direction.type_direction = mod_direction.add(reader.direction, summand);
										mod_token.move(token, direction);
									}
								
								
								/**
								 * @author kcf <vidofnir@folksprak.org>
								 */
								function export_
									(
										reader : type_reader
									)
									: any
									{
										return {
											"direction": mod_direction.export_(reader.direction),
											"symbol_links": mod_symbol.export_(reader.symbol_links),
											"symbol_rechts": mod_symbol.export_(reader.symbol_rechts),
										};
									}
								
								
								/**
								 * @author kcf <vidofnir@folksprak.org>
								 */
								function import_
									(
										raw : any
									)
									: type_reader
									{
										return (
											create
												(
													mod_direction.import_(raw["direction"]),
													mod_symbol.import_(raw["symbol_links"]),
													mod_symbol.import_(raw["symbol_rechts"])
												)
										);
									}
								
								
								/**
								 * @author kcf <vidofnir@folksprak.org>
								 */
								lib_trait.attend<signature_actuator>
									(
										trait_actuator,
										kind,
										{
											"example": () => lib_call.wrap(kind, example()),
											"rotate": (actuator, increment) => rotate(lib_call.unwrap(actuator), increment),
											"use": (actuator, token) => use(lib_call.unwrap(actuator), token),
											"export": (actuator) => ({"kind": kind, "data": export_(actuator.data)}),
											"import": (raw) => lib_call.wrap(kind, import_(raw["data"])),
										}
									)
								;
								
							}
						
					}
				
			}
		
	}

