<?php namespace Newsletter\Builder\RequiredVar;

abstract class RequiredVar {

	/** string The string type. */
	const STRING = 'string';

	/** string The multiline text. */
	const TEXT = 'text';

	/** string The module from the CMS. */
	const MODULE = 'module';

	/** @var string The name of the PHP variable. */
	protected $name;

	/** @var string The title of the variable, for user. */
	protected $title;

	/** @var array The additional options for this type. */
	protected $options;

	/**
	 * RequiredVar constructor.
	 *
	 * @param string $name    The name name of the variable.
	 * @param string $title   The title of the variable, as shown to the user.
	 * @param string $type    The main type of the variable: STRING, TEXT or MODULE.
	 * @param array  $options The additional options for this type.
	 *
	 * @return RequiredVar The created variable.
	 */
	public static function create($name, $title, $type, $options = []) {

		// Make sure the type is in a proper format
		$type = static::from($type);

		// Instantiate a proper type
		$className = '\\' . implode('\\', [ 'Newsletter', 'Builder', 'RequiredVar', ucfirst($type) . 'RequiredVar' ]);
		$instance = new $className();

		// Set up
		$instance->name = $name;
		$instance->title = $title;
		$instance->options = $options;

		return $instance;
	}

	/**
	 * Parse the string representation of a type to a type.
	 *
	 * @param string $type The type to find.
	 *
	 * @return string The found type.
	 */
	public static function from($type) {
		$list = [ static::STRING, static::TEXT, static::MODULE ];
		foreach ($list as $item) {
			if (strtolower($item) === strtolower($type)) {
				return $item;
			}
		}

		return static::STRING;
	}

	/** @return string The name of the PHP variable. */
	public function getName() {
		return $this->name;
	}

	/** @return string The title of the variable, for user. */
	public function getTitle() {
		return $this->title;
	}

	/** @return array The additional options for this type. */
	public function getOptions() {
		return $this->options;
	}

	/**
	 * Parse the value to a template value.
	 *
	 * @param mixed $input The original value.
	 *
	 * @return mixed The parsed value, which will be sent to the template.
	 */
	abstract function parse($input);

	/** @return String The type of the required var. */
	abstract function getType();

}