<?php

/**
 * R&S Imagination Suite
 *
 * blah fasel description
 *
 * @author Darius A. Zylka <rs@regen-sonne.de>
 * @copyright (c) 2009 Darius A. Zylka
 * @version 1.0
 * @package phImaginator
 */


/**
 * Main class
 *
 * @package phImaginator
 *
 */
class phImaginator {

	const POSITION_LEFT = 1;
	const POSITION_CENTER = 2;
	const POSITION_RIGHT = 4;
	const POSITION_TOP = 8;
	const POSITION_MIDDLE = 16;
	const POSITION_BOTTOM = 32;

	const POSITION_LEFT_TOP = 64;
	const POSITION_RIGHT_TOP = 128;
	const POSITION_LEFT_BOTTOM = 256;
	const POSITION_RIGHT_BOTTOM = 512;

	const POSITION_ALL = 1024;

	const FITTING_WIDTH = 2048;
	const FITTING_HEIGHT = 4096;
	const FITTING_BOTH = 8192;

	const TRANSITION_LINEAR = 1;
	const TRANSITION_LOGARITHMIC = 2;
	const TRANSITION_EXPONENTIAL = 3;

	/**
	 * An array with all image data like resources, width, height, filename
	 *
	 * @access public
	 * @var array
	 */
	public $imageSourceCollection = array();

	/**
	 * Incremental counter of all added images
	 *
	 * @access private
	 * @var integer
	 */
	private $resource_counter = 0;

	/**
	 * Holds the additional file name for the generated images
	 *
	 * @access private
	 * @var string
	 */
	private $nameAppend = false;
	private $namePrepend = false;


	/**
	 * Constructor
	 * Includes the module interface and the module parent class
	 *
	 */
	public function __construct() {
		require_once 'phImaginator.Module.interface.php';
		require_once 'phImaginator.Universal.class.php';

		//phImaginator_Universal::setGlobalConstants();
	}

	/**
	 * Adds new images resources
	 *
	 * @access public
	 * @param mixed $source An array containing files or directories or a string with a file or directory name
	 */
	public function add($source) {
		if (is_array($source)) {
			foreach ($source as $source_file) {
				$this->addSource($source_file);
			}
		} else {
			$this->addSource($source);
		}
	}

	/**
	 * Checks if given resource is a file or a directory
	 *
	 * @access private
	 * @param string $source A file or directory name
	 */
	private function addSource($source) {
		if (is_file($source)) {
			$this->addImage($source);
		} else if (is_dir($source) && $dh = opendir($source)) {
			$source .= (substr($source, -1, 1) != '/') ? '/' : '';

			while (($file = readdir($dh)) !== false) {
				$sourcefile = $source . $file;

				if (is_file($sourcefile)) {
			            $this->addImage($sourcefile);
				}
			}
			closedir($dh);
		}
	}

	/**
	 * Generates an image resource and adds it to the collection
	 *
	 * @access private
	 * @param string $source_file
	 * @uses $imageSourceCollection
	 */
	private function addImage($source_file) {
		list($width, $height, $type) = getimagesize($source_file);

		switch ($type) {
			case IMAGETYPE_JPEG:
				$resource = imagecreatefromjpeg($source_file);

				break;

			case IMAGETYPE_PNG:
				$resource = imagecreatefrompng($source_file);
				imagesavealpha($resource, true);

				break;

			case IMAGETYPE_GIF:
				$resource = imagecreatefromgif($source_file);

				break;

			default:
				break;
		}

		if (isset($resource) && is_resource($resource)) {
			++$this->resource_counter;

			$fileinfo = pathinfo($source_file);

			$this->imageSourceCollection[$this->resource_counter] = array(
				'width' => $width,
				'height' => $height,
				'resource' => $resource,
				'id' => $this->resource_counter,
				'type' => $type,
				'fileinfo' => $fileinfo
			);
		}
	}

	/**
	 * Includes the module class file and calls its desired method
	 *
	 * @access public
	 * @param string $action Name of the class and its desired method
	 * @param array $params Given parameters
	 */
	public function __call($action, $params) {
		$classCall = explode('_', $action);
		$class = $classCall[0];
		$method = $classCall[1];

		if (!is_object($this->$class)) {
			require_once 'phImaginator.' . $class . '.class.php';
			$className = 'phImaginator_' . $class;
		}

		if ($className::ifRunCollected()) {
			$className::assignImageSourceCollection($this->imageSourceCollection);
			$className::$method($params);
		} else {
			if (is_array($this->imageSourceCollection)) {
				foreach ($this->imageSourceCollection as $id => &$source_data) {
//					$className::$method($source_data, $params);
//					$tmp_params = $params;
					phImaginator_Universal::setCurrentResource($source_data);
//					array_unshift($params, &$source_data);
					call_user_func_array(array($className, $method), $params);

//					$params = $tmp_params;
				}
			}
		}

		return $this;
	}

	/**
	 * Adds an additional name for the generated image files
	 *
	 * @access public
	 * @param string $nameAdd Prefix for the new file name
	 * @uses $nameAdd
	 */
	public function nameAdd($namePrepend = false, $nameAppend = false) {
		$this->nameAppend = $nameAppend;
		$this->namePrepend = $namePrepend;
	}

	/**
	 * Walks through the collection and calls the saving method for each element
	 *
	 * @access public
	 * @param mixed $imagetype One of the Exif Imagetype Constants
	 * @param integer $quality A value between 0 (high compression level, pure quality) and 100 (no compression, best possible quality)
	 * @uses $imageSourceCollection
	 */
	public function save($imagetype = false, $quality = 85, $destination = false) {
		if (is_array($this->imageSourceCollection)) {
			foreach ($this->imageSourceCollection as $source_data) {
				$this->saveImage($source_data, $imagetype, $quality, $destination);
			}
		}
	}

	/**
	 * Writes the image to file system
	 *
	 * @access private
	 * @param array $source_data
	 * @param mixed $imagetype One of the Exif Imagetype Constants
	 * @param quality $quality
	 */
	private function saveImage($source_data, $imagetype = false, $quality = 85, $destination = false) {
		$source_data['type'] = (!$imagetype) ? $source_data['type'] : $imagetype;

		$destination = ($destination) ? $destination : $source_data['fileinfo']['dirname'];

		switch ($source_data['type']) {

			case IMAGETYPE_JPEG:
				imagejpeg($source_data['resource'], $destination . DIRECTORY_SEPARATOR . $this->namePrepend . $source_data['fileinfo']['filename'] . $this->nameAppend . '.jpg', $quality);

				break;

			case IMAGETYPE_PNG:
				imagealphablending($source_data['resource'], false);
				imagesavealpha($source_data['resource'], true);

				$q = (-$quality + 100) * 0.1;
				$quality = floor(($q > 9) ? 9 : $q);

				imagepng($source_data['resource'], $destination . DIRECTORY_SEPARATOR . $this->namePrepend . $source_data['fileinfo']['filename'] . $this->nameAppend . '.png', $quality);

				break;

			case IMAGETYPE_GIF:
				imagegif($source_data['resource'], $destination . DIRECTORY_SEPARATOR . $this->namePrepend . $source_data['fileinfo']['filename'] . $this->nameAppend . '.gif');

				break;
		}
	}

	/**
	 * Sets the font informations for usage in modules
	 *
	 * @param string $fontFile Path and name to the TTF file
	 * @param integer $size Font size
	 * @param mixed $color An array or hex value for the color (array(R, G, B) or #RRGGBB)
	 * @param integer $lucency An value between 0 and 100 for the lucency of the written text
	 */
	public function setFont($fontFile, $size = false, $color = false, $lucency = false) {
		phImaginator_Universal::setFont($fontFile, $size, $color, $lucency);
	}
}




?>