/*
 * 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_conveyer
							{
								
								/**
								 * @author kcf <vidofnir@folksprak.org>
								 */
								const kind : string = "conveyer";
								
								
								/**
								 * @author kcf <vidofnir@folksprak.org>
								 */
								export type type_conveyer =
									{
										direction : mod_direction.type_direction;
									}
								;
								
								
								/**
								 * @author kcf <vidofnir@folksprak.org>
								 */
								function create
									(
										direction : mod_direction.type_direction
									)
									: type_conveyer
									{
										return {
											"direction": direction,
										};
									}
								
								
								/**
								 * @author kcf <vidofnir@folksprak.org>
								 */
								export function create_extended
									(
										direction : mod_direction.type_direction
									)
									: mod_actuator.type_actuator
									{
										return lib_call.wrap(kind, create(direction));
									}
								
								
								/**
								 * @author kcf <vidofnir@folksprak.org>
								 */
								function example
									(
									)
									: type_conveyer
									{
										return create(0);
									}
								
								
								/**
								 * @author kcf <vidofnir@folksprak.org>
								 */
								export function direction_read
									(
										conveyer : type_conveyer
									)
									: mod_direction.type_direction
									{
										return conveyer.direction;
									}
								
								
								/**
								 * @author kcf <vidofnir@folksprak.org>
								 */
								function rotate
									(
										conveyer : type_conveyer,
										increment : int = +1
									)
									: void
									{
										conveyer.direction = mod_direction.add(conveyer.direction, increment);
									}
								
								
								/**
								 * @author kcf <vidofnir@folksprak.org>
								 */
								function use
									(
										conveyer : type_conveyer,
										token : mod_token.type_token
									)
									: void
									{
										mod_token.move(token, conveyer.direction);
									}
								
								
								/**
								 * @author kcf <vidofnir@folksprak.org>
								 */
								function export_
									(
										conveyer : type_conveyer
									)
									: any
									{
										return {
											"direction": mod_direction.export_(conveyer.direction),
										};
									}
								
								
								/**
								 * @author kcf <vidofnir@folksprak.org>
								 */
								function import_
									(
										conveyer_ : any
									)
									: type_conveyer
									{
										return (
											create
												(
													mod_direction.import_(conveyer_["direction"])
												)
										);
									}
								
								
								/**
								 * @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"])),
										}
									)
								;
								
							}
						
					}
				
			}
	
	}

