<?php namespace Intellex\Manicure;

use Intellex\Manicure\Plugin\PluginInterface;
use Intellex\Manicure\Source\SourceInterface;

/**
 * Class Engine
 * The engine behind the manicure.
 *
 * @package Intellex\Manicure
 */
class Engine {

	/** @var SourceInterface The original image. */
	private $original;

	/** @var SourceInterface The resulting image. */
	private $result;

	/**
	 * Engine constructor.
	 *
	 * @param SourceInterface $source The original source, which we want to transform.
	 */
	public function __construct(SourceInterface $source) {
		$this->result = $this->original = $source;
	}

	/**
	 * Apply plugins.
	 *
	 * @param PluginInterface|PluginInterface[] $plugins The plugin to apply.
	 *
	 * @return $this The instance of engine, for chaining.
	 */
	public function apply($plugins) {
		foreach ((array) $plugins as $plugin) {
			$this->result = $plugin->apply($this->result);
		}

		return $this;
	}

	/**
	 * Quickly apply plugins using array representation of them.
	 *
	 * @param array $map The rules, in format [ [ PluginName, arg1, arg2, ... ], ... ].
	 *
	 * @return Engine The instance of engine, for chaining.
	 */
	public function quickApply(array $map) {
		$plugins = [];

		foreach ($map as $params) {
			$plugin = array_shift($params);

			// Default namespace
			if (!class_exists($plugin)) {
				$plugin = "\\Intellex\\Manicure\\Plugin\\{$plugin}";
			}

			$reflection = new \ReflectionClass($plugin);
			$plugins[] = $reflection->newInstanceArgs($params);
		}

		return $this->apply($plugins);
	}

	/** @return SourceInterface The original image. */
	public function getOriginal() {
		return $this->original;
	}

	/** @return SourceInterface The resulting image. */
	public function getResult() {
		return $this->result;
	}

}
