<?php

namespace App\Helpers;

use App\AlbumSources\IAlbumSource;
use App\Photo;

class ImageHelper
{
    public function flipImage($imageResource, $flipHorizontal, $flipVertical)
    {
        imagesetinterpolation($imageResource, $this->getInterpolationMethod());

        if ($flipHorizontal && $flipVertical)
        {
            return imageflip($imageResource, IMG_FLIP_BOTH);
        }
        else if ($flipHorizontal)
        {
            return imageflip($imageResource, IMG_FLIP_HORIZONTAL);
        }
        else if ($flipVertical)
        {
            return imageflip($imageResource, IMG_FLIP_VERTICAL);
        }

        return false;
    }

    public function generateThumbnail($gdImageResource, Photo $photo, $thumbnailInfo)
    {
        $thumbnailWidth = intval($thumbnailInfo['width']);
        $thumbnailHeight = intval($thumbnailInfo['height']);

        // If image is portrait, restrict the height by the relevant aspect ratio
        $isPortrait = false;
        if ($photo->height > $photo->width)
        {
            $aspectRatio = $photo->height / $photo->width;
            $thumbnailWidth = intval($thumbnailInfo['height']) / $aspectRatio;
            $thumbnailHeight = intval($thumbnailInfo['height']);
            $isPortrait = true;
        }

        $thumbnailImageResource = imagescale($gdImageResource, $thumbnailWidth, $thumbnailHeight, $this->getInterpolationMethod());

        // If portrait, create a new canvas and paint the new picture in the centre
        if ($isPortrait)
        {
            $newThumbnailImageResource = imagecreatetruecolor($thumbnailInfo['width'], $thumbnailInfo['height']);

            // Fill in white so the space outside the portrait image is not black!
            $whiteColour = imagecolorallocate($newThumbnailImageResource, 255, 255, 255);
            imagefill($newThumbnailImageResource, 0, 0, $whiteColour);
            imagecolordeallocate($newThumbnailImageResource, $whiteColour);

            // Work out the centre position
            // TODO: this may be worth implementing as a configuration option (e.g. portrait thumbnails: left-align, centre, right-align)
            $leftX = ($thumbnailInfo['width'] - $thumbnailWidth) / 2;

            imagecopy($newThumbnailImageResource, $thumbnailImageResource, $leftX, 0, 0, 0, $thumbnailWidth, $thumbnailHeight);
            imagedestroy($thumbnailImageResource);

            $thumbnailImageResource = $newThumbnailImageResource;
        }

        // TODO make the /tmp folder configurable
        $tempName = tempnam(sys_get_temp_dir(), 'btw_thumb_');
        $tempNameWithExtension = ($tempName . '.jpg');
        rename($tempName, $tempNameWithExtension);

        // TODO make thumbnail quality configurable
        imagejpeg($thumbnailImageResource, $tempNameWithExtension, 90);
        imagedestroy($thumbnailImageResource);

        return $tempNameWithExtension;
    }

    public function openImage($imagePath, &$imageInfo)
    {
        $imageInfo = @getimagesize($imagePath);
        if ($imageInfo === false)
        {
            throw new \Exception(sprintf('The image "%s" does not appear to be a valid image, or cannot be read', pathinfo($imagePath, PATHINFO_FILENAME)));
        }

        $im = false;
        $type = $imageInfo[2];
        $allowedTypes = [
            IMG_GIF,
            IMG_PNG,
            IMG_JPEG,
            IMG_WBMP
        ];

        if (!in_array($type, $allowedTypes))
        {
            return false;
        }

        switch ($type)
        {
            case IMG_GIF:
                $im = imagecreatefromgif($imagePath);
                break;

            case IMG_JPEG:
                $im = imagecreatefromjpeg($imagePath);
                break;

            case IMG_PNG:
                $im = imagecreatefrompng($imagePath);
                break;

            case IMG_WBMP:
                $im = imagecreatefromwbmp($imagePath);
                break;
        }

        return $im;
    }

    public function rotateImage($imageResource, $angle)
    {
        imagesetinterpolation($imageResource, $this->getInterpolationMethod());

        return imagerotate($imageResource, $angle, 0);
    }

    public function saveImage($imageResource, $imagePath, $imageInfo)
    {
        switch ($imageInfo[2])
        {
            case IMG_GIF:
                imagegif($imageResource, $imagePath);
                break;

            case IMG_JPEG:
                imagejpeg($imageResource, $imagePath);
                break;

            case IMG_PNG:
                imagepng($imageResource, $imagePath);
                break;

            case IMG_WBMP:
                imagewbmp($imageResource, $imagePath);
                break;
        }
    }

    private function getInterpolationMethod()
    {
        return IMG_SINC;
    }
}