<?php
/**
 * DooGdImage class file.
 *
 * @author Leng Sheng Hong <darkredz@gmail.com>
 * @link http://www.doophp.com/
 * @copyright Copyright &copy; 2009 Leng Sheng Hong
 * @license http://www.doophp.com/license
 */

/**
 * A helper class that helps to manage images, upload, resize, create thumbnails, crop images, etc.
 *
 * @author Leng Sheng Hong <darkredz@gmail.com>
 * @version $Id: DooGdImage.php 1000 2009-08-19 21:37:38
 * @package doo.helper
 * @since 1.1
 */
class DooGdImage {
    
    /**
     * Path to store the uploaded image files
     * @var string
     */
    public $uploadPath;

    /**
     * Path to store the resized/processed image files(thumbnails/watermarks)
     * @var string
     */
    public $processPath;

    /**
     * Suffix name for the generated thumbnail image files, eg. 203992029_thumb.jpg
     * @var string
     */
    public $thumbSuffix = '_thumb';

    /**
     * Suffix name for the generated watermarked image files, eg. 203992029_water.jpg
     * @var string
     */
    public $waterSuffix = '_water';

    /**
     * Suffix name for the cropped image files, eg. 203992029_crop.jpg
     * @var string
     */
    public $cropSuffix = '_crop';

	/**
	 * Suffix name for the rotate image files, eg 203992029_rotated.jpg
	 */
	public $rotateSuffix = '_rotated';

    /**
     * Determine whether to save the processed images
     * @var bool
     */
    public $saveFile = true;

    /**
     * The file name of the TTF font to be used with watermarks.
     * @var string
     */
    public $ttfFont;

    /**
     * Generated image type. gif, png, jpg
     * @var string
     */
    public $generatedType = 'jpg';

    /**
     * Generated image quality. For png & jpg only
     * @var string
     */
    public $generatedQuality = 100;

    /**
     * Determine whether to use time + unique value as a file name for the uploaded images.
     * @var bool
     */
    public $timeAsName = true;

    /**
     * Construtor for DooGdImage
     *
     * @param string $uploadPath Path of the uploaded image
     * @param string $processPath Path to save the processes images
     * @param bool $saveFile To save the processed images
     */
    public function  __construct($uploadPath='', $processPath='', $saveFile=true, $timeAsName=true){
        $this->uploadPath = $uploadPath;
        $this->processPath = $processPath;
        $this->saveFile = $saveFile;
        $this->timeAsName = $timeAsName;
    }

    /**
     * Set the TTF Font type for water mark processing.
     * @param string $ttfFontFile the TTF font file name
     * @param string $path Path to the font
     */
    public function setFont($ttfFontFile, $path=''){
        $this->ttfFont = $path . $ttfFontFile;
    }

    /**
     * Creates an image object based on the file type.
     *
     * @param mixed The variable to store the image resource created.
     * @param string $type Image type, gif, png, jpg
     * @param string $file File name of the image
     * @return resource
     */
    protected function createImageObject(&$img, $type, $file){
        switch($type){
            case 1:
                $img = imagecreatefromgif($file);
                break;
            case 2:
                $img = imagecreatefromjpeg($file);
                break;
            case 3:
                $img = imagecreatefrompng($file);
                break;
            default:
                return false;
        }
        return $img;
    }

    /**
     * Creates an image from a resouce based on the generatedType
     * 
     * @param resource $img The image resource
     * @param string $file File name to be stored.
     * @return bool
     */
    protected function generateImage(&$img, $file=null){
        switch($this->generatedType){
            case 'gif':
                return imagegif($img, $file);
                break;
            case 'jpg':
                return imagejpeg($img, $file, $this->generatedQuality);
                break;
            case 'png':
                if($this->generatedQuality>9)
                        $quality = 9;
                else
                    $quality = $this->generatedQuality;
                return imagepng($img, $file, $quality);
                break;
            default:
                return false;
        }
    }

    /**
     * Crops an image.
     * 
     * @param string $file Image file name
     * @param int $cropWidth Width to be cropped
     * @param int $cropHeight Height to be cropped
     * @param int $cropStartX Position x to start cropping
     * @param int $cropStartY Position y to start cropping
     * @param string $rename New file name for the processed image file to be saved.
     * @return bool|string Returns the generated image file name. Return false if failed.
     */
    public function crop($file, $cropWidth, $cropHeight, $cropStartX=0, $cropStartY=0, $rename=''){
        $file = $this->uploadPath . $file;
        $imginfo = $this->getInfo($file);

        if($rename=='')
            $newName = substr($imginfo['name'], 0, strrpos($imginfo['name'], '.')) . $this->cropSuffix .'.'. $this->generatedType;
        else
            $newName = $rename .'.'. $this->generatedType;

        //create image object based on the image file type, gif, jpeg or png
        $this->createImageObject($img, $imginfo['type'], $file);

        if(!$img) return false;

        $cropimg = imagecreatetruecolor($cropWidth,$cropHeight);
        $width = $imginfo['width'];
        $height = $imginfo['height'];

        //Crop now
        imagecopyresampled($cropimg, $img, 0, 0, $cropStartX, $cropStartY, $width, $height, $width, $height);

        if($this->saveFile){
            //delete if exist
            if(file_exists($this->processPath . $newName))
                unlink($this->processPath . $newName);
            $this->generateImage($cropimg, $this->processPath . $newName);
            imagedestroy($cropimg);
            imagedestroy($img);
            return $this->processPath . $newName;
        }
        else{
            $this->generateImage($cropimg);
            imagedestroy($cropimg);
            imagedestroy($img);
        }

        return true;
    }

	/**
	 * Rotate an image Clockwise by specified amount
	 *
	 * @param string $file Image file name
	 * @param int $rotateBy Amount to rotate the image by in clockwise direction
	 * @param string $rename New file name for the processed image file to be saved
	 * @return bool|string Returns the generated image file name. Return false if failed
	 */
	public function rotate($file, $rotateBy, $rename='') {

		$file = $this->uploadPath . $file;
		$imginfo = $this->getInfo($file);

		if($rename=='') {
            $newName = substr($imginfo['name'], 0, strrpos($imginfo['name'], '.')) . $this->rotateSuffix .'.'. $this->generatedType;
		} else {
            $newName = $rename .'.'. $this->generatedType;
		}

		// create image object based on the image file type, gif, jpeg or png
        $this->createImageObject($img, $imginfo['type'], $file);

        if(!$img) return false;

		// Rotate the image. We take roation away from 360 as image rotate rotates Counter Clockwise
		$img = imagerotate($img, (360 - intval($rotateBy)), 0);

		if($this->saveFile){
            //delete if exist
            if(file_exists($this->processPath . $newName)) {
                unlink($this->processPath . $newName);
			}
            $this->generateImage($img, $this->processPath . $newName);
            imagedestroy($img);
            return $this->processPath . $newName;
        }
        else{
            $this->generateImage($img);
            imagedestroy($img);
        }

        return true;
	}


    /**
     * Resize/Generates thumbnail from an existing image file.
     * 
     * @param string $file The image file name.
     * @param int $width Width of the thumbnail
     * @param int $height Height of the thumbnail
     * @param string $rename New file name for the processed image file to be saved.
     * @return bool|string Returns the generated image file name. Return false if failed.
     */
    public function createThumb($file, $width=128, $height=128, $rename=''){
        $file = $this->uploadPath . $file;
        $imginfo = $this->getInfo($file);
        
        if($rename=='')
            $newName = substr($imginfo['name'], 0, strrpos($imginfo['name'], '.')) . $this->thumbSuffix .'.'. $this->generatedType;
        else
            $newName = $rename .'.'. $this->generatedType;

        //create image object based on the image file type, gif, jpeg or png
        $this->createImageObject($img, $imginfo['type'], $file);

        if(!$img) return false;

        $width  = ($width > $imginfo['width']) ? $imginfo['width'] : $width;
        $height = ($height > $imginfo['height']) ? $imginfo['height'] : $height;
        $oriW = $imginfo['width'];
        $oriH = $imginfo['height'];

        //maintain ratio
        if($oriW*$width > $oriH*$height)
            $height = round($oriH * $width/$oriW);
        else
            $width = round($oriW * $height/$oriH);

        //For GD version 2.0.1 only
        if (function_exists('imagecreatetruecolor')){
            $newImg = imagecreatetruecolor($width, $height);
            imagecopyresampled($newImg, $img, 0, 0, 0, 0, $width, $height, $imginfo['width'], $imginfo['height']);
        }
        else{
            $newImg = imagecreate($width, $height);
            imagecopyresampled($newImg, $img, 0, 0, 0, 0, $width, $height, $imginfo['width'], $imginfo['height']);
        }

        if($this->saveFile){
            //delete if exist
            if(file_exists($this->processPath . $newName))
                unlink($this->processPath . $newName);
            $this->generateImage($newImg, $this->processPath . $newName);
            imagedestroy($newImg);
            imagedestroy($img);
            return $this->processPath . $newName;
        }
        else{
            $this->generateImage($newImg);
            imagedestroy($newImg);
            imagedestroy($img);
        }
        
        return true;
    }

    /**
     * Create a square thumbnail (resize adaptively)
     *
     * @param string $file The image file name.
     * @param int $size Width/height of the thumbnail
     * @param string $rename New file name for the processed image file to be saved.
     * @return bool|string Returns the generated image file name. Return false if failed.
     */
    public function createSquare($file, $size, $rename=''){
        return $this->adaptiveResize($file, $size, $size, $rename);
    }

    /**
     * Adaptively Resizes the Image
     *
     * Resize the image to as close to the provided dimensions as possible, and then crops the
     * remaining overflow (from the center) to get the image to be the size specified
     *
     * @param string $file The image file name.
     * @param int $width
     * @param int $height
     * @param string $rename New file name for the processed image file to be saved.
     * @return bool|string Returns the generated image file name. Return false if failed.
     */
    public function adaptiveResize($file, $width, $height, $rename='') {
        $file = $this->uploadPath . $file;
        $imginfo = $this->getInfo($file);
        
        if($rename=='')
            $newName = substr($imginfo['name'], 0, strrpos($imginfo['name'], '.')) . $this->thumbSuffix .'.'. $this->generatedType;
        else
            $newName = $rename .'.'. $this->generatedType;

        //create image object based on the image file type, gif, jpeg or png
        $this->createImageObject($img, $imginfo['type'], $file);

        if(!$img) return false;

        if($imginfo['height'] == $imginfo['width']){
            $resizeWidth = $width;
            $resizeHeight = $height;
        }
        else if($imginfo['height'] > $imginfo['width']){
            $resizeWidth = $width;
            $resizeHeight = ($imginfo['height']/$imginfo['width'])*$resizeWidth;
        }else{
            $resizeHeight = $height;
            $resizeWidth = ($imginfo['width']/$imginfo['height'])*$resizeHeight;
        }

        //For GD version 2.0.1 only
        if (function_exists('imagecreatetruecolor')){
            $newImg = imagecreatetruecolor($width, $height);
            imagecopyresampled($newImg, $img, ($width-$resizeWidth)/2, ($height-$resizeHeight)/2, 0, 0, $resizeWidth, $resizeHeight, $imginfo['width'], $imginfo['height']);
        }
        else{
            $newImg = imagecreate($width, $height);
            imagecopyresampled($newImg, $img, ($width-$resizeWidth)/2, ($height-$resizeHeight)/2, 0, 0, $resizeWidth, $resizeHeight, $imginfo['width'], $imginfo['height']);
        }

        if($this->saveFile){
            //delete if exist
            if(file_exists($this->processPath . $newName))
                unlink($this->processPath . $newName);
            $this->generateImage($newImg, $this->processPath . $newName);
            imagedestroy($newImg);
            imagedestroy($img);
            return $this->processPath . $newName;
        }
        else{
            $this->generateImage($newImg);
            imagedestroy($newImg);
            imagedestroy($img);
        }

        return true;
    }


	    public function adaptiveResizeCropExcess($file, $width=128, $height=128, $rename=''){
        $file = $this->uploadPath . $file;

        $imginfo = $this->getInfo($file);

        if($rename=='')
            $newName = substr($imginfo['name'], 0, strrpos($imginfo['name'], '.')) . $this->thumbSuffix .'.'. $this->generatedType;
        else
            $newName = $rename .'.'. $this->generatedType;

        //create image object based on the image file type, gif, jpeg or png
        $this->createImageObject($img, $imginfo['type'], $file);

        if(!$img) return false;

		if (($imginfo['width'] / $imginfo['height']) > ($width / $height) ) {	
			$srcY = 0;
			$srcH = $imginfo['height'];
			$srcW = round($width / ($height / $imginfo['height']));
			$srcX = round(($imginfo['width'] / 2) - ($srcW / 2));
		} else {
			$srcX = 0;
			$srcW = $imginfo['width'];
			$srcH = round($height / ($width / $imginfo['width']));
			$srcY = round(($imginfo['height'] / 2) - ($srcH / 2));
		}

        //For GD version 2.0.1 only
        if (function_exists('imagecreatetruecolor')){
            $newImg = imagecreatetruecolor($width, $height);

            imagecopyresampled($newImg, $img, 0, 0, $srcX, $srcY, $width, $height, $srcW, $srcH);
        }
        else{
            $newImg = imagecreate($width, $height);
            imagecopyresampled($newImg, $img, 0, 0, $srcX, $srcY, $width, $height, $srcW, $srcH);
        }

        if($this->saveFile){
            //delete if exist
            if(file_exists($this->processPath . $newName))
                unlink($this->processPath . $newName);
            $this->generateImage($newImg, $this->processPath . $newName);
            imagedestroy($newImg);
            imagedestroy($img);
            return $this->processPath . $newName;
        }
        else{
            $this->generateImage($newImg);
            imagedestroy($newImg);
            imagedestroy($img);
        }

        return true;
    }


	/**
     * Resizes the Image and keep it proportioned
     *
     * Resize the image to fit within specified area while maintaining the image ratio.
	 *
	 * There are 3 modes of operation which are
	 *  - To resize so width matches specification and height it auto determined (set width but leave height as null)
	 *  - To resize so height matches spectification and width is auto determined (set width to null and height to desired height)
	 *  - To resize so image fits within the area defined by width and height (set both width and height)
     *
     * @param string $file The image file name.
     * @param int $width The maximum width of the new image (or null if only setting height)
     * @param int $height The maximum height of the new image (or null if only setting width)
     * @param string $rename New file name for the processed image file to be saved.
     * @return bool|string Returns the generated image file name. Return false if failed.
     */
	public function ratioResize($file, $width=null, $height=null, $rename='') {

		$file = $this->uploadPath . $file;
        $imginfo = $this->getInfo($file);

        if($rename=='')
            $newName = substr($imginfo['name'], 0, strrpos($imginfo['name'], '.')) . $this->thumbSuffix .'.'. $this->generatedType;
        else
            $newName = $rename .'.'. $this->generatedType;

		if ($width === null && $height === null) {
			return false;
		} elseif ($width !== null && $height === null) {
			$resizeWidth = $width;
			$resizeHeight = ($width / $imginfo['width']) * $imginfo['height'];
		} elseif ($width === null && $height !== null) {
			$resizeWidth = ($height / $imginfo['height']) * $imginfo['width'];
			$resizeHeight = $height;
		} else {
			if ($imginfo['width'] > $imginfo['height']) {
				$resizeWidth = $width;
				$resizeHeight = ($width / $imginfo['width']) * $imginfo['height'];
			} else {
				$resizeWidth = ($height / $imginfo['height']) * $imginfo['width'];
				$resizeHeight = $height;
			}
		}

		//create image object based on the image file type, gif, jpeg or png
        $this->createImageObject($img, $imginfo['type'], $file);
		if(!$img) return false;

        if (function_exists('imagecreatetruecolor')){
            $newImg = imagecreatetruecolor($resizeWidth, $resizeHeight);
            imagecopyresampled($newImg, $img, 0, 0, 0, 0, $resizeWidth, $resizeHeight, $imginfo['width'], $imginfo['height']);
        }
        else{
            $newImg = imagecreate($resizeWidth, $resizeHeight);
            imagecopyresampled($newImg, $img, ($width-$resizeWidth)/2, ($height-$resizeHeight)/2, 0, 0, $resizeWidth, $resizeHeight, $imginfo['width'], $imginfo['height']);
        }
		
		imagedestroy($img);

        if($this->saveFile){
            //delete if exist
            if(file_exists($this->processPath . $newName))
                unlink($this->processPath . $newName);
            $this->generateImage($newImg, $this->processPath . $newName);
            imagedestroy($newImg);
            return $this->processPath . $newName;
        }
        else{
            $this->generateImage($newImg);
            imagedestroy($newImg);
        }

        return true;

	}

    /**
     * Add water mark text to an image.
     * 
     * @param string $file Image file name
     * @param string $text Text to be added as water mark
     * @param int $maxWidth Maximum width of the processed image
     * @param int $maxHeight Maximum height of the processed image
     * @param string $rename New file name for the processed image file to be saved.
     * @return bool|string Returns the generated image file name. Return false if failed.
     */
    public function waterMark($file, $text, $maxWidth, $maxHeight, $rename=''){
        $file = $this->uploadPath . $file;
        $imginfo = $this->getInfo($file);

        if($rename=='')
            $newName = substr($imginfo['name'], 0, strrpos($imginfo['name'], '.')) . $this->waterSuffix .'.'. $this->generatedType;
        else
            $newName = $rename .'.'. $this->generatedType;

        //create image object based on the image file type, gif, jpeg or png
        $this->createImageObject($img, $imginfo['type'], $file);

        if(!$img) return false;

        $width  = ($maxWidth > $imageInfo['width']) ? $imageInfo['width'] : $maxWidth;
        $height = ($maxHeight > $imageInfo['height']) ? $imageInfo['height'] : $maxHeight;
        $oriW	= $imageInfo['width'];
        $oriH	= $imageInfo['height'];

        if ($oriW*$width > $oriH*$height)
            $height = round($oriH*$width/$oriW);
        else
            $width = round($oriW*$height/$oriH);

        if (function_exists('imagecreatetruecolor')){
            $new = imagecreatetruecolor($width, $height);
            imagecopyresampled($new, $img, 0, 0, 0, 0, $width, $height, $imageInfo['width'], $imageInfo['height']);
        }
        else{
            $new = imagecreate($width, $height);
            imagecopyresampled($new, $img, 0, 0, 0, 0, $width, $height, $imageInfo['width'], $imageInfo['height']);
        }

        $white = imagecolorallocate($new, 255, 255, 255);
        $black = imagecolorallocate($new, 0, 0, 0);
        $alpha = imagecolorallocatealpha($new, 230, 230, 230, 40);

        imagefilledrectangle($new, 0, $height-26, $width, $height, $alpha);
        imagefilledrectangle($new, 13, $height-20, 15, $height-7, $black);
        imageTTFText($new, 4.9, 0, 20, $height-14, $black, $this->ttfFont, $text[0]);
        imageTTFText($new, 4.9, 0, 20, $height-6, $black, $this->ttfFont, $text[1]);

        if ($this->saveFile){
            if (file_exists($this->processPath . $newName))
                unlink($this->processPath . $newName);
            $this->generateImage($newImg, $this->processPath . $newName);
            imagedestroy($new);
            imagedestroy($img);
            return $this->processPath . $newName;
        }
        else{
            $this->generateImage($newImg);
            imagedestroy($new);
            imagedestroy($img);
        }

        return true;
    }

	/**
	 * Embed a watermark image onto a given image.
	 *
	 * @param string $file Image file name
	 * @param string $watermarkImgPath Full path to watermark image
	 * @param string|int $posX Position of watermark horizontally: left | middle | right  OR > 0 to position Xpx from left or < 0 to position Xpx from right
	 * @param string|int $posY Position of watermark vertically: top  | middle | bottom OR > 0 to position Xpx from top  or < 0 to position Xpx from bottom
	 * @param string $rename New file name for the processed image file to be saved
	 * @return bool|string Returns the generated image file name. Return false if failed
	 */
	public function waterMarkImage($file, $watermarkImgPath, $posX='right', $posY='bottom', $rename='') {
		$file = $this->uploadPath . $file;
        $imgInfo = $this->getInfo($file);
		$watermarkImgInfo = $this->getInfo($watermarkImgPath);

        if($rename=='')
            $newName = substr($imgInfo['name'], 0, strrpos($imgInfo['name'], '.')) . $this->waterSuffix .'.'. $this->generatedType;
        else
            $newName = $rename .'.'. $this->generatedType;

		$destX = 0;
		$destY = 0;

		if ($posX === 'left') {
			$destX = 0;
		} elseif ($posX === 'right') {
			$destX = $imgInfo['width'] - $watermarkImgInfo['width'];
		} elseif ($posX === 'middle') {
			$destX = ($imgInfo['width'] - $watermarkImgInfo['width']) / 2;
		} elseif ($posX > 0) {
			$destX = $posX;
		} elseif ($posX < 0) {
			$destX = $imgInfo['width'] - $watermarkImgInfo['width'] + $posX;
		}

		if ($posY === 'top') {
			$destY = 0;
		} elseif ($posY === 'bottom') {
			$destY = $imgInfo['height'] - $watermarkImgInfo['height'];
		} elseif ($posY === 'middle') {
			$destY = ($imgInfo['height'] - $watermarkImgInfo['height']) / 2;
		} elseif ($posY > 0) {
			$destY = $posY;
		} elseif ($posY < 0) {
			$destY = $imgInfo['height'] - $watermarkImgInfo['height'] + $posX;
		}

        //create image object based on the image file type, gif, jpeg or png
        $this->createImageObject($img, $imgInfo['type'], $file);
		$this->createImageObject($watermarkImg, $watermarkImgInfo['type'], $watermarkImgPath);

        if(!$img || !$watermarkImg) return false;

		if (function_exists('imagecreatetruecolor')){
            $new = imagecreatetruecolor($imgInfo['width'], $imgInfo['height']);
            imagecopyresampled($new, $img, 0, 0, 0, 0, $imgInfo['width'], $imgInfo['height'], $imgInfo['width'], $imgInfo['height']);
        }
        else{
            $new = imagecreate($imgInfo['width'], $imgInfo['height']);
            imagecopyresampled($new, $img, 0, 0, 0, 0, $imgInfo['width'], $imgInfo['height'], $imgInfo['width'], $imgInfo['height']);
        }
		imagedestroy($img);
		
		imagecopy($new, $watermarkImg, $destX, $destY, 0, 0, $watermarkImgInfo['width'], $watermarkImgInfo['height']);
		imagedestroy($watermarkImg);

		if ($this->saveFile){
            if (file_exists($this->processPath . $newName))
                unlink($this->processPath . $newName);
            $this->generateImage($new, $this->processPath . $newName);
			imagedestroy($new);
            return $this->processPath . $newName;
        }
        else{
            $this->generateImage($new);
			imagedestroy($new);
        }

        return true;
	}

	/**
	 * Centers an image in the middle of a container image. Useful when you want to align an image horizontally and vertically
	 * for example a landscape image in a square box.
	 *
	 * @param string $file Image file name
	 * @param integer $width The width of the new image
	 * @param integer $height The height of the new image
	 * @param array $bgcolor Array defining the background color array(RED, GREEN, BLUE) eg. (0, 255, 0) for bright green
	 * @param string $rename New file name for the processed image file to be saved
	 * @return bool|string Returns the generated image file name. Return false if failed
	 */
	public function centerImageInContrainer($file, $width, $height, $bgcolor, $rename='') {

		$file = $this->uploadPath . $file;
        $imginfo = $this->getInfo($file);

        if($rename=='')
            $newName = substr($imginfo['name'], 0, strrpos($imginfo['name'], '.')) . $this->thumbSuffix .'.'. $this->generatedType;
        else
            $newName = $rename .'.'. $this->generatedType;

		//create image object based on the image file type, gif, jpeg or png
        $this->createImageObject($img, $imginfo['type'], $file);
		if(!$img) return false;

        //For GD version 2.0.1 only
        if (function_exists('imagecreatetruecolor')){
            $newImg = imagecreatetruecolor($width, $height);
        } else {
            $newImg = imagecreate($width, $height);
        }

		$bgColor = imagecolorallocate($newImg, $bgcolor[0], $bgcolor[1], $bgcolor[2]);
		imagefilledrectangle($newImg, 0, 0, $width, $height, $bgColor);

		imagecopyresampled($newImg, $img, ($width-$imginfo['width'])/2, ($height-$imginfo['height'])/2, 0, 0, $imginfo['width'], $imginfo['height'], $imginfo['width'], $imginfo['height']);

		imagedestroy($img);

        if($this->saveFile){
            //delete if exist
            if(file_exists($this->processPath . $newName))
                unlink($this->processPath . $newName);
            $this->generateImage($newImg, $this->processPath . $newName);
            imagedestroy($newImg);
            return $this->processPath . $newName;
        }
        else{
            $this->generateImage($newImg);
            imagedestroy($newImg);
        }

        return true;
	}

    /**
     * Get the file name of an image's thumbnail.
     * @param string $file Image file name
     * @return string
     */
    public function getThumb($file){
        $thumbName = substr($file, 0, strrpos($file, '.')) . $this->thumbSuffix .'.'. $this->generatedType;
        $file = $this->processPath . $thumbName;
        if(!file_exists($file))
            return;
        return $file;
    }

    /**
     * Get the file name of an image's watermark.
     * @param string $file Image file name
     * @return string
     */
    public function getWaterMark($file){
        $markName = substr($file, 0, strrpos($file, ".")) . $this->waterSuffix .'.'. $this->generatedType;
        $file = $this->processPath . $markName;
        if (!file_exists($file))
            return;
        return $file;
    }

    /**
     * Tries to remove the images along with its thumbnails & watermarks
     *
     * @param string|array $file Image file name(s)
     * @return string
     */
    public function removeImage($file){
        if(is_array($file)){
            foreach($file as $f){
                $oriName   = $this->processPath . $f;
                $thumbName	= $this->processPath . substr($f, 0, strrpos($f, '.')) . $this->thumbSuffix .'.'. $this->generatedType;
                $markName  = $this->processPath . substr($f, 0, strrpos($f, '.')) . $this->waterSuffix .'.'. $this->generatedType;

                if(file_exists($thumbName))
                    unlink($thumbName);

                if(file_exists($markName))
                    unlink($markName);

                if(file_exists($oriName))
                    unlink($oriName);
            }
        }
        else{
            $oriName   = $this->processPath . $file;
            $thumbName	= $this->processPath . substr($file, 0, strrpos($file, '.')) . $this->thumbSuffix .'.'. $this->generatedType;
            $markName  = $this->processPath . substr($file, 0, strrpos($file, '.')) . $this->waterSuffix .'.'. $this->generatedType;

            if(file_exists($thumbName))
                unlink($thumbName);

            if(file_exists($markName))
                unlink($markName);

            if(file_exists($oriName))
                unlink($oriName);
        }
    }


    /**
     * Get the info of an image
     *
     * @param string $file Image file name
     * @return array Returns info in array consists of width, height, type, name & filesize.
     */
    public function getInfo($file){
        $data = getimagesize($file);
        $img['width'] = $data[0];
        $img['height'] = $data[1];
        $img['type'] = $data[2];
        $img['name'] = basename($file);
        $img['filesize'] = filesize($file);
        return $img;
    }

    /**
     * Save the uploaded image(s) in HTTP File Upload variables
     * 
     * @param string $filename The file field name in $_FILES HTTP File Upload variables
     * @param string $rename Rename the uploaded file (without extension)
     * @return string|array The file name of the uploaded image.
     */
    public function uploadImage($filename, $rename=''){
        $img = !empty($_FILES[$filename]) ? $_FILES[$filename] : null;
        if($img==Null)return;

		if (!file_exists($this->uploadPath)) {
			Doo::loadHelper('DooFile');
			$fileManager = new DooFile(0777);
			$fileManager->create($this->uploadPath);
		}

        if(is_array($img['name'])===False){
            $pic = strrpos($img['name'], '.');
            $ext = strtolower(substr($img['name'], $pic+1));

            if ($this->timeAsName){
                $newName = time().'-'.mt_rand(1000,9999) . '.' . $ext;
            }else{
                $newName = $img['name'];
            }

            if($rename=='')
                $imgPath = $this->uploadPath . $newName;
            else
                $imgPath = $this->uploadPath . $rename . '.' . $ext;

            if (move_uploaded_file($img['tmp_name'], $imgPath)){
                return ($rename=='')? $newName : $rename. '.' . $ext;
            }
        }
        else{
            $uploadImagesPath = array();
            foreach($img['error'] as $k=>$error){
                if(empty($img['name'][$k])) continue;
                if ($error == UPLOAD_ERR_OK) {
                   $pic = strrpos($img['name'][$k], '.');
                   $ext = strtolower(substr($img['name'][$k], $pic+1));

                   if($this->timeAsName){
                       $newName = time().'-'.mt_rand(1000,9999) . '_' . $k . '.' . $ext;
                   }else{
                       $newName = $img['name'][$k];
                   }

                   if($rename=='')
                       $imgPath = $this->uploadPath . $newName;
                   else
                       $imgPath = $this->uploadPath . $rename . '_' . $k . '.' . $ext;

                   if (move_uploaded_file($img['tmp_name'][$k], $imgPath)){
                       $uploadImagesPath[] = $newName;
                   }
                }else{
                   return false;
                }
            }
            return $uploadImagesPath;
        }
    }

    /**
     * Get the uploaded images' format type
     *
     * @param string $filename The file field name in $_FILES HTTP File Upload variables
     * @return string|array The image format type of the uploaded image.
     */
    public function getUploadFormat($filename){
        if(!empty($_FILES[$filename])){
            $type = $_FILES[$filename]['type'];
            if(is_array($type)===False){
                if(!empty($type))
                    return str_replace('image/', '', $type);
            }
            else{
                $typelist = array();
                foreach($type as $t){
                    $typelist[] = str_replace('image/', '', $t);
                }
                return $typelist;
            }
        }
    }

    /**
     * Checks if image mime type of the uploaded file(s) is in the allowed list
     * @param string $filename The file field name in $_FILES HTTP File Upload variables
     * @param array $allowType Allowed image format type. Default: JPEGs, GIFs and PNGs
     * @return bool Returns true if image mime type is in the allowed list.
     */
    public function checkImageType($filename, $allowType=array('jpg','jpeg','pjpeg','gif','png','x-png')){
        $type = $this->getUploadFormat($filename);
        if(is_array($type)===False)
            return in_array($type, $allowType);
        else{
            foreach($type as $t){
                if($t===Null || $t==='') continue;
                if(!in_array($t, $allowType)){
                    return false;
                }
            }
            return true;
        }
    }

    /**
     * Checks if image extension of the uploaded file(s) is in the allowed list.
     *
     * @param string $filename The file input field name in $_FILES HTTP File Upload variables
     * @param array $allowExt Allowed file extensions. Default: jpg, jpeg, gif, png
     * @return bool Returns true if file extension is in the allowed list.
     */
    public function checkImageExtension($filename, $allowExt=array('jpg','jpeg','gif','png')){
        if(!empty($_FILES[$filename])){
            $name = $_FILES[$filename]['name'];
            if(is_array($name)===False){
                $n = strrpos($name, '.');
                $ext = strtolower(substr($name, $n+1));
                return in_array($ext, $allowExt);
            }
            else{
                foreach($name as $nm){
                    $n = strrpos($nm, '.');
                    $ext = strtolower(substr($nm, $n+1));
                    if(!in_array($ext, $allowExt)){
                        return false;
                    }
                }
                return true;
            }
        }
    }

    /**
     * Checks if image file size does not exceed the max file size allowed.
     *
     * @param string $filename The file input field name in $_FILES HTTP File Upload variables
     * @param int $maxSize Allowed max file size in kilo bytes.
     * @return bool Returns true if file size does not exceed the max file size allowed.
     */
    public function checkImageSize($filename, $maxSize){
        if(!empty($_FILES[$filename])){
            $size = $_FILES[$filename]['size'];
            if(is_array($size)===False){
                if(($size/1024)>$maxSize){
                    return false;
                }
            }
            else{
                foreach($size as $s){
                    if(($s/1024)>$maxSize){
                        return false;
                    }
                }
            }
            return true;
        }
    }

}
