<?php


class img
{
	private $source_name = false;
	private $source_w = 0;
	private $source_h = 0;
	private $source_type = false;
	private $source_mime = false;
	
	private $error_message = false;
	
	private $rst_w = 0;
	private $rst_h = 0;
	private $rst_type = false;
	private $rst_mime = false;
	
	private $crop_x = 0;	// кордината x начальной точки на исходном изображении
	private $crop_y = 0;	// кордината y начальной точки на исходном изображении
	private $crop_w = 0;		//	ширина нового изображения
	private	$crop_h = 0;		//	высота нового изображения

	
	private $flag_resize = false;
	private $flag_crop = false;
	private $flag_watermark = false;
	
	
	private $FILE_MIMES = array(
								'image/pjpeg'=>"jpeg",
								'image/jpeg'=>"jpeg",
								'image/jpg'=>"jpeg",
								'image/png'=>"png",
								'image/x-png'=>"png",
								'image/gif'=>"gif");
	//private $alpha = 100;
	private $quality = 100;
	
	
//	var $rst_name =false;
	//var $more_resize = false;	//	увеличивать изображение
	

		//	загружаем изображение
	public function __construct($name){
		
			// файла нет, возвращаем объект с ошибкой
		if ( !file_exists($name) ){
			$this -> make_error( sprintf(E_IMG_FILE_NOT_FOUND,$name) );
			return false;
		}
			//	файл не изображение, возвращаем объект с ошибкой
		$info = getimagesize($name);
		if ( empty( $info[0]) ){
			$this -> make_error( sprintf(E_IMG_FILE_IS_NO_IMAGE,$name)  );
			return false;
		}
			//	с таким изображением работать система не может
		
		$type = $this -> mime_to_type($info['mime']);
		
		if ( !function_exists('imagecreatefrom'.$type) ){
			$this -> make_error( sprintf(E_IMG_FILE_BAD_TYPE,$name)  );
			return false;
		}
			//	устанавливаем параметры по умолчанию
		$this -> source_name = $name;
		$this -> width = $this -> source_w = $this -> rst_w = $info[0];
		$this -> height = $this -> source_h = $this -> rst_h =  $info[1];
		$this -> mime = $this -> rst_mime = $this -> source_mime = $info['mime'];
		$this -> type = $this -> source_type =  $type;
		$this -> rst_type =  $type;
	}
	
		//	тип нового файла
	public function set_type($v){
		if ( empty($v) ){
			$this -> make_error( E_IMG_EMPTY_TYPE );
			return false;	
		}
		if ( !function_exists('image'.$v) ){
			$this -> make_error( sprintf(E_IMG_FILE_BAD_TYPE,$v) );
			return false;
		}
		$this -> rst_mime = $this -> type_to_mime($v);
		if ( !function_exists('image'.$v) ){
			$this -> make_error( sprintf(E_IMG_BAD_MIME,$v) );
			return false;
		}
		$this -> rst_type = $v;
		return true;
	}
	
		//	имя нового файла
	public function set_name($v){
		if ( empty($v) ){
			$this -> make_error( E_IMG_EMPTY_NAME );
			return false;	
		}
		
		if ( preg_match('#[^a-z0-9\-=._]#i',$v,$res) ){
		 
			$this -> make_error(E_IMG_BAD_NAME);
			return false;	
		}
		$this -> rst_name = $v;
		return true;	
	}
	
		//	задаём папку для сохранения результата
	public function set_path($v){
		if ( empty($v) ){
			$this -> make_error( E_IMG_EMPRY_PATH );
			return false;
		}
		if ( !is_dir($v) ){
			$this -> make_error( sprintf(E_IMG_BAD_PATH,$v) );
			return false;
		}
		
		if ( !is_writable($v) ){
			$this -> make_error( sprintf(E_IMG_PATH_WRITE_ACCESS,$v) );
			return false;
		}
		$this -> rst_path = $v;
		return true;
	}
	
	
	

	/**
	* Вычисляет размеры нового изображения
	*	
	* @project cms
	* @class img
	* @name resize
	* @param w int ширина нового изображения
	* @param h int высота нового изображения
	* @param strict bool жёсткое или пропорциональное вычисление размеров изображения
	* @return bool
	*/
	public function resize($w=0,$h=0,$strict = false){
		$this -> flag_resize = true;
		
			//	жёсткий ресайз
		if ( $strict ){
			
			$w =  intval($w);
			$h =  intval($h);
				//	шо за ресайз без размеров изображения
			if ( empty($w) || empty($h) ){
				$this -> make_error(E_IMG_EMPTY_SIZE);
				return false;
			}
			$this -> rst_w = $w;
			$this -> rst_h = $h;
			return true;
		}
		
		$w = empty($w) ? $this -> source_w : intval($w);
		$h = empty($h) ? $this -> source_h : intval($h);
		
			//	размеры нового изображения будут превышать размеры текущего
		if ( $w>=$this -> source_w  &&  $h>=$this -> source_h ){
			return false;
		}
		
			//	выясним на сколько нужно сжать изображение
		$koof_w = round($this -> source_w / $w );
		$koof_h = round($this -> source_h / $h );
		$koof_max = max($koof_w,$koof_h);
		$this -> rst_w = round( $this -> source_w / $koof_max);
		$this -> rst_h = round( $this -> source_h / $koof_max);
			//	ресайз не требуется
		if ( $this -> rst_w==$this -> source_w && $this -> rst_h==$this -> source_h ){
			return false;
		}
		
		
		return true;
	}
	
	
	
	
	public function crop($x,$y,$w,$h){
		$this -> crop_x = intval($x);
		$this -> crop_y = intval($y);
		$this -> crop_w = intval($w);
		$this -> crop_h = intval($h);
		$this -> flag_crop = true;
		return true;
	}
	

	

		//	сохраняем результат
	public function save(){
		
			//	установка параметров привела к ошибке
		if ( false!==$this -> error() ){
			return false;
		}
			
		
			//	загружаем исходник для работы
		$func_name = 'imagecreatefrom'.$this -> source_type;
		$source  =  $func_name($this -> source_name);
		

			//	делаем ресайз
		if ( false!==$this -> flag_resize ){
		
			
			$target = imagecreatetruecolor($this -> rst_w , $this -> rst_h);
			  //  добавим пингам немного прозрачности
		  imagealphablending($target, false);
      imagesavealpha($target, true);
			imagecopyresampled(
					$target, 
					$source, 0,0,0,0,
					$this -> rst_w,$this -> rst_h,$this -> source_w,$this -> source_h  
			);
			
			$source = $target;
		}
			
				//	делаем кроп
		if ( false!==$this -> flag_crop ){
		  
			$target = imagecreatetruecolor($this -> crop_w , $this -> crop_h);
			imagecopy(
					$target, 
					$source, 0, 0,$this -> crop_x, $this -> crop_y, $this -> crop_w, $this -> crop_h
			);	
			$source = $target;
		}
		
			//	делаем водяной знак
		if ( false!==$this -> flag_watermark ){
			//	тут наносим водяные знаки на изображение
			
		}
		
			//	выводим результат
		$func_name = 'image'.$this -> rst_type;
		if ( $this -> rst_type=='png' ){
		  $this -> quality =  round($this -> quality / 10)-1;
		}
	
	 
		if ( empty($this -> rst_name) ){
		 
			header("Content-type:  ".$this -> rst_mime); 
			if ( !$func_name($target,false,$this -> quality) ){
				$this -> make_error( E_IMG_CREATE_FALSE );
			}
			
		}else{
		
			if ( !$func_name($target,$this -> rst_path.'/'.$this -> rst_name,$this -> quality) ){
				$this -> make_error( E_IMG_CREATE_FALSE );
			}
			
		}
		imagedestroy($target);
		//imagedestroy($source);
		return true;
	}
	
	public function make_error($msg){
		$this -> error_message =  $msg;	
	}
	
	public function error(){
		return $this -> error_message;
	}
	
	
		//	переводим mime-type изображения в его формат
	private function mime_to_type($v){
	
		if (!empty($this -> FILE_MIMES[$v]) ){
			return $this -> FILE_MIMES[$v];
		}else{
			return false;
		}
	}
	
			//	получаем mime-type изображения по его расширению
	private function type_to_mime($i){
		foreach( $this -> FILE_MIMES as $k=>$v ){
			if ( $i==$v ){
				return  $k;
			}
		}
		return false;
	}
	
}

?>
