<?php
/*
	Stempora Web Framework
	Copyright (c) 2002-2014 Stempora. 
	All rights reserved.
		web:  www.stempora.com
		mail: support@stempora.com				
*/

//use Image\ImageException;

//namespace core\Image;

//use core\Image\ImageConst;

/**
* description
*
* @library	
* @author	
* @since	
*/
class Image {

		/**
		* description
		*
		* @var type
		*
		* @access type
		*/
		var $debug = 0;
		/**
		* description
		*
		* @var type
		*
		* @access type
		*/
		var $processed = null;
		/**
		* description
		*
		* @var type
		*
		* @access type
		*/
		var $data = null;
		
		

	/*
		
	*/

		public static function newInstance(){
			return new self();
		}

		/**
		* description
		*
		* @param
		*
		* @return
		*
		* @access
		*/
		function Read($path) {

			$tmp = $this->__get($path);
			$this->data = $tmp["image"];
			$this->data_type = $tmp["type"];		

			return $this;
		}

		/**
		* description
		*
		* @param
		*
		* @return
		*
		* @access
		*/
		function ReadString($data) {
				//imagecreatefromstring() 
		}
		

		function __get($path)  {

			//debug($path);
			
			$info = GetImageSize($path);

			switch ($info["2"]) {
				case IMAGETYPE_GIF:
					$img = imagecreatefromgif($path);
				break;

				case IMAGETYPE_PNG:
					$img = imagecreatefrompng($path);
				break;

				case IMAGETYPE_JPEG:
					$img = imagecreatefromjpeg($path);
				break;
			}

			return array(
				"image"	=> $img , 
				"type"	=> $info[2]
			);
			
		}


		/**
		* description
		*
		* @param
		*
		* @return
		*
		* @access
		*/
		function destroy() {
			imagedestroy($this->data);

			if ($this->processed) {
				imagedestroy($this->processed);
			}			
		}
				
		/**
		* description
		*
		* @param
		*
		* @return
		*
		* @access
		*/
		function Save($path , $quality = 90 , $chmod = 0777) {

			if (!$quality) {
				$quality = 90;
			}

			
			//switch ($this->data_type) {
			switch (strtolower(CFile::Extension($path))) {
				
				//case IMAGETYPE_GIF:
				case "gif":
					return $this->SaveGif($path , $chmod);
				break;

				//case IMAGETYPE_PNG:
				case "png":
					return $this->SavePNG($path, $quality , $chmod);
				break;

				//case IMAGETYPE_JPEG:
				case "jpeg":
				case "jpg":
					return $this->SaveJpeg($path , $quality , $chmod);
				break;
			}

			return $this;

		}
		
		/**
		* description
		*
		* @param
		*
		* @return
		*
		* @access
		*/
		function SaveGif($path , $chmod = 0777) {
			imagegif(
				$this->processed ? $this->processed :$this->data , 
				$path 
			);

			chmod ( $path , $chmod);
			return $this;
		}
		
		/**
		* description
		*
		* @param
		*
		* @return
		*
		* @access
		*/
		function SavePNG($path , $quality = 90  , $chmod = 0777) {

			if (!$quality) {
				$quality = 90;
			}

			imagepng(
				$this->processed ? $this->processed :$this->data , 
				$path
			);

			chmod ( $path , $chmod);
			return $this;
		}
		
		/**
		* description
		*
		* @param
		*
		* @return
		*
		* @access
		*/
		function SaveJpeg($path , $quality = 90 , $chmod = 0777) {
			imagejpeg(
				$this->processed ? $this->processed :$this->data , 
				$path ,
				$quality
			);

			chmod ( $path , $chmod);

			if ($this->debug) {
//				debug($path);
//				debug($info,1);
			}

			return $this;
		}
		

		/**
		* description
		*
		* @param
		*
		* @return
		*
		* @access
		*/
		function Restore(){
			$this->processed = $this->data;
			return $this;
		}

		/**
		* description
		*
		* @param
		*
		* @return
		*
		* @access
		*/
		function ResizeByWidth($width) {

			$this->__freeProcessed();

			$ratio = imagesx($this->data ) / imagesy($this->data);

			
			$height = $width / $ratio;

			$this->__newImage($width , $height); 

			imageCopyResampled(
				$this->processed , 
				$this->data , 
				0 , 
				0 , 
				0 ,
				0 ,
				$width , 
				$height , 

				imagesx($this->data),
				imagesy($this->data)
			);

			return $this;

		}

		/**
		* description
		*
		* @param
		*
		* @return
		*
		* @access
		*/
		function ResizeByHeight($height) {

			$this->__freeProcessed();

			$ratio = imagesx($this->data ) / imagesy($this->data);
			
			$width = $height * $ratio;

			$this->__newImage($width , $height); 

			imageCopyResampled(
				$this->processed , 
				$this->data , 
				0 , 
				0 , 
				0 ,
				0 ,
				$width , 
				$height , 

				imagesx($this->data),
				imagesy($this->data)
			);

			return $this;

		}

		/**
		* description
		*
		* @param
		*
		* @return
		*
		* @access
		*/
		function ResizeScale($width = null , $height = null) {
			if ($width) {
				return $this->ResizeByWidth($width);
			} elseif ($height) {
				return $this->ResizeByHeight($height);
			} else {
				throw new Exception("Image:ResizeScale($width , $height); must have one parameter set");
			}			
		}
		

		/**
		* description
		*
		* @param
		*
		* @return
		*
		* @access
		*/
		function ResizeFit($width , $height) {

			$sourceWidth = imagesx($this->data);
			$sourceHeight = imagesy($this->data);

			$pRatio = $width / $height;
			$sRatio = $sourceWidth / $sourceHeight;


			if ($pRatio > $sRatio) {
				return $this->ResizeByHeight($height);
			} elseif ($pRatio < $sRatio) {
				return $this->ResizeByWidth($width);
			} else {
				//same ratios
				return $this->Resize($width , $height);
			}
			
			
		}
		
		

		/**
		* description
		*
		* @param
		*
		* @return
		*
		* @access
		*/
		function Resize($width , $height) {

			$this->__freeProcessed();


			$this->__newImage($width , $height); 

			imageCopyResampled(
				$this->processed , 
				$this->data , 
				0 , 
				0 , 
				0 ,
				0 ,
				$width , 
				$height , 

				imagesx($this->data),
				imagesy($this->data)
			);

			return $this;
				
		}
		
		/**
		* description
		*
		* @param
		*
		* @return
		*
		* @access
		*/
		function ScaleCrop($width , $height , $posX = "left", $posY = "top") {

			if (!$posX)
				$posX = "left";

			if (!$posY) 
				$posY = "top";

			if ($this->debug) {
//				debug("W:" . $width . "H" . $height);
			}
			
			

			$this->__freeProcessed();
			$this->__newImage($width , $height); 

			$sourceWidth = imagesx($this->data);
			$sourceHeight = imagesy($this->data);


			$pRatio = $width / $height;
			$sRatio = $sourceWidth / $sourceHeight;

			if ($pRatio == $sRatio) {
				$sx = 0; 
				$sy = 0; 
				$sw = $sourceWidth;
				$sh = $sourceHeight;
			} elseif ($pRatio > $sRatio) {			//checked and works fine
				$sx = 0;
				$sy = 0;
				$sw = $sourceWidth;
				$sh = $sourceWidth / $pRatio;
			} else {

				$sx = 0;
				$sy = 0;
				$sh = $sourceHeight;
				$sw = $sourceHeight * $pRatio;
			}

			//position 
			switch ($posX) {
				case "left":
					//do nothing default
				break;

				case "right":
					if ($sw < $sourceWidth) {
						$sx = ($sourceWidth - $sw);
					}

				break;

				case "center":
					if ($sw < $sourceWidth) {
						$sx = ($sourceWidth - $sw) / 2;
					}					
				break;
			}

			switch ($posY) {
				case "top":
					//default
				break;

				case "bottom":
					if ($sh < $sourceHeight) {
						$sy = ($sourceHeight - $sh);
					}
				break;

				case "center":
					if ($sh < $sourceHeight) {
						$sy = ($sourceHeight - $sh) /2;
					}					
				break;
			}


			imageCopyResampled(
				$this->processed , 
				$this->data , 
				0 , 
				0 , 
				$sx ,
				$sy ,
				$width , 
				$height , 

				$sw,
				$sh
			);

			//var_dump($sw, $sx, $cropLeft, $cropTop);

			return $this;
		}


		/**
		* description
		*
		* @param
		*
		* @return
		*
		* @access
		*/
		function Crop($width , $height , $x , $y , $c_width , $c_height) {

			$this->__freeProcessed();
			$this->__newImage($width , $height); 

		
			ImageCopyResampled(
				$this->processed,
				$this->data,
				0,
				0,
				$x,
				$y,
				$width,
				$height,
				$c_width,
				$c_height
			);

			return $this;
		}
		
		
		/**
		* description
		*
		* @param
		*
		* @return
		*
		* @access
		*/
		function Watermark($file , $posX = "left" , $posY = "bottom") {

			if (!$posX)
				$posX = "left";

			if (!$posY) 
				$posY = "bottom";

			if ($file) {
				$watermark = $this->__get($file);
	
				$wW = imagesx($watermark["image"]);
				$wY = imagesy($watermark["image"]);
				$sX = imagesx($this->processed);
				$sY = imagesy($this->processed);

				switch ($posX) {
					case "left":
						$sdX = 0;
					break;

					case "right":
						$sdX = $sX - $wW;
					break;

					case "center":
						$sdX = ($sX / 2) - ($wW/2);
					break;
				}

				switch ($posY) {
					case "top":
						$sdY = 0;
					break;

					case "bottom":
						$sdY = $sY - $wY;
					break;

					case "center":
						$sdY = ($sY / 2) - ($wY/2);
					break;

				}
				
				imagecopyresampled ( 
					
					$this->processed,
					$watermark["image"] , 
									
					$sdX , 
					$sdY , 
					0 , 
					0 , 
					$wW,
					$wY,
					$wW,
					$wY
				);


				imagedestroy($watermark["image"]);
			}
			
			return $this;


		}
		


		/**
		* description
		*
		* @param
		*
		* @return
		*
		* @access
		*/
		function __freeProcessed() {

			if (is_resource($this->processed)) {
				imagedestroy($this->processed);
			}
		}

		
		/**
		* description
		*
		* @param
		*
		* @return
		*
		* @access
		*/
		function __newImage($width , $height) {

			$this->processed = imagecreatetruecolor($width , $height);

	        $white = imagecolorallocatealpha ($this->processed, 255, 255, 255, 127);

			imagefill($this->processed, 0, 0, $white);
			imagesavealpha( $this->processed, true );				
			imagealphablending($this->processed , true);

			//saving transparency to the new image
			if ( ($this->data_type  == IMAGETYPE_GIF) || ($this->data_type ==  IMAGETYPE_PNG) ) {
				$trnprt_indx = imagecolortransparent($this->data);

				if ($trnprt_indx >= 0) {
					$trnprt_color    =  imagecolorsforindex($this->data,  $trnprt_indx);
					$trnprt_indx    =   imagecolorallocate($this->processed, $trnprt_color['red'], $trnprt_color['green'], $trnprt_color['blue']);

					imagefill($this->processed, 0, 0,  $trnprt_indx);
					imagecolortransparent($this->processed, $trnprt_indx);
				}

			}

		}


		/**
		* description
		*
		* @param
		*
		* @return
		*
		* @access
		*/
		function enableDebug() {
			
			$this->debug = 1;
	
			return $this;
		}
		
		
}


final class ImageConst {

	const FLIP_HORIZONTAL	= 1;
	const FLIP_VERTICAL		= 2;
	const FLIP_BOTH			= 3;

	const MAX_WIDTH			= 2500;
	const MAX_HEIGHT		= 2500;

}


class ImageException extends Exception {
}


?>