<?php

namespace IZON\Thumber\Services\Impl;

use IZON\IO\Image;
use IZON\Thumber\Image\ImageNameBuilder;
use IZON\Thumber\Image\ImageSize;
use IZON\Thumber\ImageCache\ImageCache;
use IZON\Thumber\ImageConverter\IImageConverterFactory;
use IZON\Thumber\ImageResizer\IImageResizer;
use IZON\Thumber\Services\ThumbnailService;
use IZON\Thumber\Thumber;

/**
 * servis pro zpracovani obrazku, mozna i dalsiho multimedialniho obsahu z galerie
 */
class ThumbnailServiceImpl implements ThumbnailService {
    /**
     *
     * @var IImageResizer
     */
    protected $imageResizer;
    /**
     *
     * @var ImageCache
     */
    protected $imageCache;
    /**
     *
     * @var IImageConverterFactory
     */
    protected $imageConverterFactory;
    /**
     *
     * @var ?string
     */
    protected $format = null;

    /**
     * 
     * @param IImageResizer $imageResizer
     * @param ImageCache $imageCache
     * @param IImageConverterFactory $imageConverterFactory
     */
    function __construct(IImageResizer $imageResizer, ImageCache $imageCache, IImageConverterFactory $imageConverterFactory) {
        $this->imageResizer = $imageResizer;
        $this->imageCache = $imageCache;
        $this->imageConverterFactory = $imageConverterFactory;
    }
    /**
     * 
     * @param string|null $format
     */
    function setFormat(?string $format) {
        $this->format = $format;
    }

    public function getThumber() {
        return new Thumber($this);
    }

    /**
     * 
     * @param Image $sourceImage
     * @param array $parameters parametry pro resizovani
     */
    public function getImageURL(Image $sourceImage, array $parameters = []) {
        $width = $parameters['width'] + 0;
        $height = $parameters['height'] + 0;
        if(!isset($parameters["type"])) {
            $type = IImageResizer::CONTAIN;
        } else {
            $type = $parameters["type"];
        }

        $originaSize = ImageSize::create($sourceImage->getWidth(), $sourceImage->getHeight());
        if($width <= 0 && $height <= 0) {
            $containerSize = $originaSize;
        } else if($width <= 0) {
            $containerSize = ImageSize::createFromHeight($height, $originaSize->getAspectRatio());
        } else if($height <= 0) {
            $containerSize = ImageSize::createFromWidth($width, $originaSize->getAspectRatio());
        } else {
            $containerSize = ImageSize::create($width, $height);
        }

        $newSize = $this->imageResizer->resize($type)->getSize($originaSize, $containerSize);
        $quality = array_key_exists('quality', $parameters) ? $parameters['quality'] : self::QUALITY;


        $pathParts = pathinfo($sourceImage->getFsPath());
        $nameBuilder = new ImageNameBuilder($pathParts['filename'], $sourceImage->getExtension());
        $nameBuilder->setSize($newSize);
        $nameBuilder->setQuality($quality);
        if(!empty($this->format)) {
            $nameBuilder->setFormat($this->format);
        }
        $newName = $nameBuilder->build();

        if($this->imageCache->has($newName)) {
            $path = $this->imageCache->getPath($newName);
            return $path . '?' . filemtime($path);
        }

        $imageConverter = $this->imageConverterFactory->createImageConverter($sourceImage);
        $imageConverter->setSize($newSize);
        $imageConverter->setQuality($quality);
        if(!empty($this->format)) {
            $imageConverter->setFormat($this->format);
        }
        $newImage = $imageConverter->convert($newName);
        $this->imageCache->set($newName, $newImage, true);
        $path = $this->imageCache->getPath($newName);
        return $path . '?' . filemtime($path);
    }

}

