<?php
class FotoJobs extends FileJobs{
	var $iCustomThumbX = 250;
	var $iCustomThumbY = 250;
	var $iMaxForThumbSize = 10000;
	var $iQuality = 80;
	var $iThumbX = 100;
	var $iThumbY = 100;
	var $sExt = 'jpg';
	var $sExtDot = '.jpg';
	static function &getInstance( ){
		static $oInstance = null;
		if( !isset( $oInstance ) ){
			$oInstance = new FotoJobs( );
		}
		return $oInstance;
	}
	function __construct( $iThumbSize = 100 ){
		$this->iThumbX = $iThumbSize;
	}
	function setThumbSize( $iThumbSize = 100 ){
		$this->iThumbX = $iThumbSize;
	}
	function setThumbQuality( $iThumbQuality = 80 ){
		$this->iQuality = $iThumbQuality;
	}
	function setMaxForThumbSize( $iMaxForThumbSize = 10000 ){
		$this->iMaxForThumbSize = $iMaxForThumbSize;
	}
	function copyAndCreateThumb( $sDestDir, $mImgSrc, $sImgOutput, $sOption = null ){
		$iOldSize = $this->iThumbX;
		if( !is_dir( $sDestDir ) ) return null;
		$sImgOutput = $this->throwNameOfFile( $sImgOutput );
		$sImgOutput = $this->changeFileName( $sImgOutput );
		if( $sOption == 'copy' ){
			if( is_file( $mImgSrc ) && filesize( $mImgSrc ) > 0 && $this->checkCorrectFile( $mImgSrc, 'jpg|jpeg|gif|png' ) == 1 ){
				$this->sExt = $this->throwExtOfFile( $mImgSrc );
				$this->sExtDot = isset( $this->sExt ) ? '.' . $this->sExt : null;
				$aNewFiles['bFile'] = $this->checkIsFile( $sImgOutput . $this->sExtDot, $sDestDir );
				if( !copy( $mImgSrc, $sDestDir . $aNewFiles['bFile'] ) ) return null;
			} else return null;
		} elseif( $sOption == 'upload' ){
			if( is_uploaded_file( $mImgSrc['tmp_name'] ) && is_file( $mImgSrc['tmp_name'] ) && filesize( $mImgSrc['tmp_name'] ) > 0 && $this->checkCorrectFile( $mImgSrc['name'], 'jpg|jpeg|gif|png' ) == 1 ){
				$this->sExt = $this->throwExtOfFile( $mImgSrc['name'] );
				$this->sExtDot = isset( $this->sExt ) ? '.' . $this->sExt : null;
				$aNewFiles['bFile'] = $this->uploadFile( $mImgSrc, $sDestDir, $sImgOutput . $this->sExtDot );
			} else return null;
		}
		$sImgPatch = $sDestDir . $aNewFiles['bFile'];
		$aNewFiles['bName'] = $this->throwNameOfFile( $aNewFiles['bFile'] );
		$aNewFiles['sFile'] = $aNewFiles['bName'] . '.' . $this->sExtDot;
		$aImgSize = $this->throwImgSize( $sImgPatch );
		if( defined( 'MAX_DIMENSION_OF_IMAGE' ) && ( $aImgSize['width'] > MAX_DIMENSION_OF_IMAGE || $aImgSize['height'] > MAX_DIMENSION_OF_IMAGE ) ){
			if( $aImgSize['width'] < $this->iMaxForThumbSize && $aImgSize['height'] < $this->iMaxForThumbSize ){
				$iOldAdd = null;
				$this->setThumbSize( 'l'.MAX_DIMENSION_OF_IMAGE );
				$aNewFiles['bFile'] = $this->createThumb( $sImgPatch, $sDestDir, $aNewFiles['bFile'] );
				$this->setThumbSize( $iOldSize );
			} else return null;
		}
		if( $aImgSize['width'] >= $this->iThumbX || $aImgSize['height'] >= $this->iThumbY ){
			if( $aImgSize['width'] < $this->iMaxForThumbSize && $aImgSize['height'] < $this->iMaxForThumbSize ) $aNewFiles['sFile'] = $this->createThumb( $sImgPatch, $sDestDir );
			else return null;
		} else copy( $sImgPatch, $sDestDir . $aNewFiles['sFile'] );
		$aNewFiles['sWidth'] = $this->iThumbX;
		$aNewFiles['sHeight'] = $this->iThumbY;
		$aNewFiles['bWidth'] = $aImgSize['width'];
		$aNewFiles['bHeight'] = $aImgSize['height'];
		$aNewFiles['sName'] = basename( $aNewFiles['sFile'], '.' . $this->sExt );
		$aNewFiles['ext'] = $this->sExt;
		$this->iThumbY = 100;
		$this->setThumbSize( $iOldSize );
		return $aNewFiles;
	}
	function clearAll( ){
		$this->iThumbX = 100;
		$this->iThumbY = 100;
	}
	function throwImgSize( $imgSrc, $sOption = null ){
		$aImg = getImageSize( $imgSrc );
		if( $sOption == 'width' ) return $aImg[0];
		elseif( $sOption == 'height' ) return $aImg[1];
		else return Array( 'width' => $aImg[0], 'height' => $aImg[1] );
	}
	function throwImgWidth( $imgSrc ){
		return $this->throwImgSize( $imgSrc, 'width' );
	}
	function throwImgHeight( $imgSrc ){
		return $this->throwImgSize( $imgSrc, 'height' );
	}
	function createCustomThumb( $sImgSource, $sImgDestDir, $iSize = null, $sImgOutput = false, $bOverwrite = null ){
		if( !is_dir( $sImgDestDir ) || $this->checkCorrectFile( $sImgSource, 'gif|jpeg|jpg|png' ) == 0 ) return null;
		$aImgSize = $this->throwImgSize( $sImgSource );
		if( $aImgSize['width'] < $this->iMaxForThumbSize && $aImgSize['height'] < $this->iMaxForThumbSize ){
			$sImgExt = $this->throwExtOfFile( $sImgSource );
			if( $sImgOutput == false ) $sImgOutput = $this->throwNameOfFile( $sImgSource ) . '.' . $sImgExt;
			if( !isset( $bOverwrite ) ) $sImgOutput = $this->checkIsFile( $sImgOutput, $sImgDestDir );
			$iOldSize = $this->iThumbX;
			if( !isset( $iSize ) || !preg_match( '/^[whls]?[0-9]+$/', $iSize ) ) $this->setThumbSize( $this->iCustomThumbX );
			else $this->setThumbSize( $iSize );
			$sFile = $this->createThumb( $sImgSource, $sImgDestDir, $sImgOutput );
			$this->setThumbSize( $iOldSize );
			return $sFile;
		} else return null;
	}
	function createThumb( $sImgSource, $sImgDestDir, $sImgOutput = false, $iQuality = null, $sOption = null ){
		if( !is_dir( $sImgDestDir ) || $this->checkCorrectFile( $sImgSource, 'gif|jpeg|jpg|png' ) == 0 ) return null;
		if( !isset( $iQuality ) || !is_numeric( $iQuality ) ) $iQuality = $this->iQuality;
		$sImgExt = $this->throwExtOfFile( $sImgSource );
		if( $sImgOutput == false ) $sImgOutput = basename( $sImgSource, '.' . $sImgExt ) . '.' . $sImgExt;
		$sImgOutput = $this->changeFileName( $sImgOutput );
		$sImgTmp = $sImgDestDir . $sImgOutput . "_tmp." . $sImgExt;
		copy( $sImgSource, $sImgTmp );
		$aImgProperties = GetImageSize( $sImgTmp );
		if( !$aImgProperties[2] == 2 ){
			return null;
		} else{
			switch( $sImgExt ){
				case 'gif':
					$mImgCreate = ImageCreateFromGIF( $sImgTmp );
					if( !$mImgCreate ){
						$mImgCreate = ImageCreateFromPNG( $sImgTmp );
						$sImgExt = 'png';
					}
					if( !$mImgCreate ){
						$mImgCreate = ImageCreateFromJPEG( $sImgTmp );
						$sImgExt = 'jpg';
					}
				break;
				case 'jpeg':
				case 'jpg':
					$mImgCreate = ImageCreateFromJPEG( $sImgTmp );
					if( !$mImgCreate ){
						$mImgCreate = ImageCreateFromPNG( $sImgTmp );
						$sImgExt = 'png';
					}
					if( !$mImgCreate ){
						$mImgCreate = ImageCreateFromGIF( $sImgTmp );
						$sImgExt = 'gif';
					}
				break;
				case 'png':
					$mImgCreate = ImageCreateFromPNG( $sImgTmp );
					if( !$mImgCreate ){
						$mImgCreate = ImageCreateFromGIF( $sImgTmp );
						$sImgExt = 'gif';
					}
					if( !$mImgCreate ){
						$mImgCreate = ImageCreateFromJPEG( $sImgTmp );
						$sImgExt = 'jpg';
					}
				break;
			}
			if( is_numeric( $this->iThumbX ) ){
				$iThumbSize = $this->iThumbX;
				$sThumbMode = 'x';
			} else{
				$iThumbSize = substr( $this->iThumbX, 1 );
				$sThumbMode = substr( $this->iThumbX, 0, 1 );
			}
			$iImgCreateX = ImageSX( $mImgCreate );
			$iImgCreateY = ImageSY( $mImgCreate );
			switch( $sThumbMode ){
				case 'x':
					$this->iThumbY = $iImgCreateY * $this->iThumbX / ( $iImgCreateX );
					if( $this->iThumbX / $this->iThumbY < 1 ){
						$this->iThumbY = $this->iThumbX;
						$this->iThumbX = $iImgCreateX * $this->iThumbY / ( $iImgCreateY );
					}
					if( ( $this->iThumbX > $iImgCreateX ) && ( $this->iThumbY > $iImgCreateY ) ){
						$this->iThumbY = $iImgCreateY;
						$this->iThumbX = $iImgCreateX;
						
						$iThumbSize = max( $this->iThumbY, $this->iThumbX );
					}
					$this->iThumbX = ( int )( $this->iThumbX );
					$this->iThumbY = ( int )( $this->iThumbY );
					$mImgDest = imagecreatetruecolor( $iThumbSize, $iThumbSize );
					break;
				case 'w':
					$this->iThumbX = $iThumbSize;
					$this->iThumbY = $iImgCreateY * $iThumbSize / ( $iImgCreateX );
					$this->iThumbX = ( int )( $this->iThumbX );
					$this->iThumbY = ( int )( $this->iThumbY );
					$mImgDest = imagecreatetruecolor( $this->iThumbX, $this->iThumbY );
					break;
				case 'h':
					$this->iThumbY = $iThumbSize;
					$this->iThumbX = $iImgCreateX * $iThumbSize / ( $iImgCreateY );
					$this->iThumbX = ( int )( $this->iThumbX );
					$this->iThumbY = ( int )( $this->iThumbY );
					$mImgDest = imagecreatetruecolor( $this->iThumbX, $this->iThumbY );
					break;
				case 'l':
					if( $iImgCreateX >= $iImgCreateY ){
						$this->iThumbX = $iThumbSize;
						$this->iThumbY = $iImgCreateY * $iThumbSize / ( $iImgCreateX );
						$this->iThumbX = ( int )( $this->iThumbX );
						$this->iThumbY = ( int )( $this->iThumbY );
						$mImgDest = imagecreatetruecolor( $this->iThumbX, $this->iThumbY );
					} else{
						$this->iThumbY = $iThumbSize;
						$this->iThumbX = $iImgCreateX * $iThumbSize / ( $iImgCreateY );
						$this->iThumbX = ( int )( $this->iThumbX );
						$this->iThumbY = ( int )( $this->iThumbY );
						$mImgDest = imagecreatetruecolor( $this->iThumbX, $this->iThumbY );
					}
					break;
				case 's':
					if( $iImgCreateX < $iImgCreateY ){
						$this->iThumbX = $iThumbSize;
						$this->iThumbY = $iImgCreateY * $iThumbSize / ( $iImgCreateX );
						$this->iThumbX = ( int )( $this->iThumbX );
						$this->iThumbY = ( int )( $this->iThumbY );
						$mImgDest = imagecreatetruecolor( $this->iThumbX, $this->iThumbY );
					} else{
						$this->iThumbY = $iThumbSize;
						$this->iThumbX = $iImgCreateX * $iThumbSize / ( $iImgCreateY );
						$this->iThumbX = ( int )( $this->iThumbX );
						$this->iThumbY = ( int )( $this->iThumbY );
						$mImgDest = imagecreatetruecolor( $this->iThumbX, $this->iThumbY );
					}
					break;
			}
			$aValues = Array();
			$aValuesTmp = explode( "\n", str_replace( "\r\n", "\n", file_get_contents( 'templates/colors.less' ) ) );
			foreach( $aValuesTmp as $sValue ){
				if( preg_match( '/^@([a-zA-Z0-9]+):"([0-9a-f]{6})";$/', $sValue, $aMatches ) ){
					$aValues[$aMatches[1]] = $aMatches[2];
				}
			}					
			$color = $aValues['photoBg'];
			$cr = hexdec( substr( $color, 0, 2 ) );
			$cg = hexdec( substr( $color, 2, 2 ) );
			$cb = hexdec( substr( $color, 4, 2 ) );

			switch( $sImgExt ){
				case "png":
					// integer representation of the color black (rgb: 0,0,0)
					$background = imagecolorallocatealpha( $mImgDest, $cr, $cg, $cb, 127 );
					imagealphablending( $mImgDest, false );
					if( $sThumbMode == 'x' ){
						imagefilledrectangle( $mImgDest, 0, 0, $iThumbSize + 1, $iThumbSize + 1, $background );
					} else{
						imagefilledrectangle( $mImgDest, 0, 0, $this->iThumbX + 1, $this->iThumbY + 1, $background );
					}
					// removing the black from the placeholder
					imagecolortransparent( $mImgDest, $background );
					// turning off alpha blending (to ensure alpha channel information is preserved, rather than removed (blending with the rest of the image in the form of black))
					imagealphablending( $mImgDest, true );
					// turning on alpha channel information saving (to ensure the full range of transparency is preserved)
					imagesavealpha( $mImgDest, true );
				break;
				case "gif":
					// integer representation of the color black (rgb: 0,0,0)
					$background = imagecolorallocate( $mImgDest, $cr, $cg, $cb );
					imagefilledrectangle( $mImgDest, 0, 0, $iThumbSize + 1, $iThumbSize + 1, $background );
					// removing the black from the placeholder
					imagecolortransparent( $mImgDest, $background );
				break;
				default:
//					file_put_contents( 'color.log', var_export( Array( $cr, $cg, $cb ), true ) );
					$background = imagecolorallocate( $mImgDest, $cr, $cg, $cb );
					imagefilledrectangle( $mImgDest, 0, 0, $iThumbSize + 1, $iThumbSize + 1, $background );
				break;
			}
			unlink( $sImgTmp );
			$sCreateFunction = 'imagecopyresampled';
			if( !function_exists( $sCreateFunction ) ) $sCreateFunction = 'imagecopyresized';
			if( $sThumbMode == 'x' ){
				$offsetX = ( $iThumbSize - $this->iThumbX ) / 2;
				$offsetY = ( $iThumbSize - $this->iThumbY ) / 2;
			} else{
				$offsetX = 0;
				$offsetY = 0;
			}
			if( $sCreateFunction( $mImgDest, $mImgCreate, $offsetX, $offsetY, 0, 0, $this->iThumbX + 1, $this->iThumbY + 1, $iImgCreateX, $iImgCreateY ) ){
				imagedestroy( $mImgCreate );
				if( !is_file( $sImgDestDir . $sImgOutput ) ){
					touch( $sImgDestDir . $sImgOutput );
					chmod( $sImgDestDir . $sImgOutput, 0666 );
				}
				switch( $sImgExt ){
					case 'gif':
						if( function_exists( "imagegif" ) ) $Image = ImageGIF( $mImgDest, $sImgDestDir . $sImgOutput );
						else{
							if( $iQuality > 0 ) $iQuality = floor( ( $iQuality - 1 ) / 10 );
							$Image = ImagePNG( $mImgDest, $sImgDestDir . $sImgOutput, $iQuality );
						}
						break;
					case 'jpeg':
					case 'jpg':
						$Image = ImageJPEG( $mImgDest, $sImgDestDir . $sImgOutput, $iQuality );
						break;
					case 'png':
						// turning on alpha channel information saving (to ensure the full range of transparency is preserved)
						imagesavealpha( $mImgDest, true );
						$Image = ImagePNG( $mImgDest, $sImgDestDir . $sImgOutput );
						break;
					}
					if( $Image ){
						imagedestroy( $mImgDest );
						return $sImgOutput;
					}
					imagedestroy( $mImgDest );
				} else{
					imagedestroy( $mImgCreate );
					imagedestroy( $mImgDest );
					return null;
				}
				return null;
		}
	}
	function addWatermark( $sFileName, $sWatermarkFileName, $sWatermarkPos, $iQuality ){
		if( $this->checkCorrectFile( $sFileName, 'gif|jpeg|jpg|png' ) == 0 ) return null;
		if( !isset( $iQuality ) || !is_numeric( $iQuality ) ) $iQuality = $this->iQuality;
		$sImgExt = $this->throwExtOfFile( $sFileName );
		$aImgProperties = GetImageSize( $sFileName );
//		if( !$aImgProperties[2] == 2 ) return null;
		switch( $sImgExt ){
			case 'gif':
				$mImgCreate = ImageCreateFromGIF( $sFileName );
				if( !$mImgCreate ){
					$mImgCreate = ImageCreateFromPNG( $sFileName );
					$sImgExt = 'png';
				}
				if( !$mImgCreate ){
					$mImgCreate = ImageCreateFromJPEG( $sFileName );
					$sImgExt = 'jpg';
				}
			break;
			case 'jpeg':
			case 'jpg':
				$mImgCreate = ImageCreateFromJPEG( $sFileName );
				if( !$mImgCreate ){
					$mImgCreate = ImageCreateFromPNG( $sFileName );
					$sImgExt = 'png';
				}
				if( !$mImgCreate ){
					$mImgCreate = ImageCreateFromGIF( $sFileName );
					$sImgExt = 'gif';
				}
			break;
			case 'png':
				$mImgCreate = ImageCreateFromPNG( $sFileName );
				if( !$mImgCreate ){
					$mImgCreate = ImageCreateFromGIF( $sFileName );
					$sImgExt = 'gif';
				}
				if( !$mImgCreate ){
					$mImgCreate = ImageCreateFromJPEG( $sFileName );
					$sImgExt = 'jpg';
				}
			break;
		}

		$photo_width = $aImgProperties[0];
		$photo_height = $aImgProperties[1];

		$photo_image = imagecreatefromjpeg($sFileName);

		ImageAlphaBlending($mImgCreate, true);

		$mImgDest = imagecreatetruecolor($photo_width,$photo_height);
		imagecopyresized($mImgDest,$mImgCreate,0,0,0,0,$photo_width,$photo_height,$photo_width,$photo_height);

		$logo_size = getimagesize($sWatermarkFileName);
		$logo_width = $logo_size[0];
		$logo_height = $logo_size[1];

		$logo_image = ImageCreateFromPNG($sWatermarkFileName);
		
		if( $photo_width >= $logo_width && $photo_height >= $logo_height ){
			switch( $sWatermarkPos ){
				case 'tl':
					$posx = 0;
					$posy = 0;
					break;
				case 'tr':
					$posx = $photo_width - $logo_width;
					$posy = 0;
					break;
				case 'bl':
					$posx = 0;
					$posy = $photo_height - $logo_height;
					break;
				case 'br':
					$posx = $photo_width - $logo_width;
					$posy = $photo_height - $logo_height;
					break;
				default: //center
					$posx = floor( ( $photo_width - $logo_width ) / 2 );
					$posy = floor( ( $photo_height - $logo_height ) / 2 );
					break;
			}
			$result = ImageCopy($mImgDest, $logo_image, $posx, $posy, 0, 0, $logo_width, $logo_height);
		} else{
			$ratio = min( ( $photo_width / $logo_width ), ( $photo_height / $logo_height ) );
			$logo_width_res = floor( $logo_width * $ratio );
			$logo_height_res = floor( $logo_height * $ratio );

			switch( $sWatermarkPos ){
				case 'tl':
					$posx = 0;
					$posy = 0;
					break;
				case 'tr':
					$posx = $photo_width - $logo_width_res;
					$posy = 0;
					break;
				case 'bl':
					$posx = 0;
					$posy = $photo_height - $logo_height_res;
					break;
				case 'br':
					$posx = $photo_width - $logo_width_res;
					$posy = $photo_height - $logo_height_res;
					break;
				default: //center
					$posx = floor( ( $photo_width - $logo_width_res ) / 2 );
					$posy = floor( ( $photo_height - $logo_height_res ) / 2 );
					break;
			}

			$sCreateFunction = 'imagecopyresampled';
			if( !function_exists( $sCreateFunction ) ) $sCreateFunction = 'imagecopyresized';
			$result = $sCreateFunction( $mImgDest, $logo_image, $posx, $posy, 0, 0, $logo_width_res + 1, $logo_height_res + 1, $logo_width, $logo_height );
		}

		ImageDestroy($logo_image);

		if( $result ){
			imagedestroy( $mImgCreate );
			if( !is_file( $sFileName ) ){
				touch( $sFileName );
				chmod( $sFileName, 0666 );
			}
			switch( $sImgExt ){
				case 'gif':
					if( function_exists( "imagegif" ) ) $Image = ImageGIF( $mImgDest, $sFileName );
					else{
						if( $iQuality > 0 ) $iQuality = floor( ( $iQuality - 1 ) / 10 );
						$Image = ImagePNG( $mImgDest, $sFileName, $iQuality );
					}
					break;
				case 'jpeg':
				case 'jpg':
					$Image = ImageJPEG( $mImgDest, $sFileName, $iQuality );
					break;
				case 'png':
					// turning on alpha channel information saving (to ensure the full range of transparency is preserved)
					imagesavealpha( $mImgDest, true );
					$Image = ImagePNG( $mImgDest, $sFileName );
					break;
			}
			if( $Image ){
				imagedestroy( $mImgDest );
				return $sFileName;
			}
			imagedestroy( $mImgDest );
		} else{
			imagedestroy( $mImgCreate );
			imagedestroy( $mImgDest );
			return null;
		}
		return null;
	}
}
?>