<?php

namespace App\Libraries\MyUtil;

use App\Libraries\MyUtil\MyUtilLibrary;
use App\Traits\FileTrait;

class ImageLibrary extends MyUtilLibrary
{
    use FileTrait;
    private $_srcPath = "";
    private $_dstPath = "";
    private $_dstFile = "";
    private $_image;
    private $_imageType;
    public function __construct()
    {
        parent::__construct();
    }
    // 이미지의 현재 너비를 반환하는 메소드
    public function getSourcePath(): string
    {
        return $this->_srcPath;
    }
    public function setSourcePath(string $srcPath): void
    {
        $this->_srcPath = $srcPath;
    }
    public function getDestinationPath(): string
    {
        return $this->_dstPath;
    }
    public function setDestinationPath(string $dstPath): void
    {
        $this->_dstPath = $dstPath;
    }
    public function getDestinationFile(): string
    {
        return $this->_dstFile;
    }
    public function setDestinationFile(string $dstFile): void
    {
        $this->_dstFile = $dstFile;
    }

    public function getWidth()
    {
        return imagesx($this->_image);
    }
    // 이미지의 현재 높이를 반환하는 메소드
    public function getHeight()
    {
        return imagesy($this->_image);
    }
    // 이미지 파일을 로드하는 메소드
    private function load($file)
    {
        $imageInfo = getimagesize($file);
        $this->_imageType = $imageInfo[2];
        switch ($this->_imageType) {
            case IMAGETYPE_JPEG:
                $this->_image = imagecreatefromjpeg($file);
                break;
            case IMAGETYPE_GIF:
                $this->_image = imagecreatefromgif($file);
                break;
            case IMAGETYPE_PNG:
                $this->_image = imagecreatefrompng($file);
                break;
            case IMAGETYPE_WEBP:
                $this->_image = imagecreatefromwebp($file);
                break;
        }
    }
    // 이미지 크기를 지정된 너비, 높이로 변경하는 메소드
    private function resize($width, $height)
    {
        $newImage = imagecreatetruecolor($width, $height);
        imagecopyresampled($newImage, $this->_image, 0, 0, 0, 0, $width, $height, $this->getWidth(), $this->getHeight());
        $this->_image = $newImage;
    }
    // 이미지 비율을 유지하면서 크기를 조정하는 메소드
    private function resizeToWidth($width)
    {
        $ratio = $width / $this->getWidth();
        $height = $this->getHeight() * $ratio;
        $this->resize($width, $height);
    }
    private function resizeToHeight($height)
    {
        $ratio = $height / $this->getHeight();
        $width = $this->getWidth() * $ratio;
        $this->resize($width, $height);
    }
    private function scale($scale)
    {
        $width = $this->getWidth() * ($scale / 100);
        $height = $this->getHeight() * ($scale / 100);
        $this->resize($width, $height);
    }
    // 이미지를 저장하는 메소드
    private function save($file, $imageType = IMAGETYPE_WEBP, $compression = 75)
    {
        switch ($imageType) {
            case IMAGETYPE_JPEG:
                imagejpeg($this->_image, $file, $compression);
                break;
            case IMAGETYPE_GIF:
                imagegif($this->_image, $file);
                break;
            case IMAGETYPE_PNG:
                imagepng($this->_image, $file);
                break;
            case IMAGETYPE_WEBP:
            default:
                imagewebp($this->_image, $file, $compression);
                break;
        }
    }
    // 메모리 해제를 위한 메소드
    private function destroy()
    {
        imagedestroy($this->_image);
    }

    public function create(string $file, int $width = 480, int $height = 319): bool
    {
        if (!$this->isFileType($this->getSourcePath(), $file)) {
            log_message("warning", "{$file} Image 형식파일이 아닙니다.");
            return false;
        }
        //저장할 디렉토리 생성
        $this->makeDirectory($this->getDestinationPath());
        // 이미지 파일 로드
        $this->load($this->getSourcePath() . DIRECTORY_SEPARATOR . $file);
        // 200x200으로 이미지 크기 조정
        $this->resize($width, $height);
        // 파일 저장
        $this->save($this->getDestinationPath() . DIRECTORY_SEPARATOR . $this->getDestinationFile());
        // 메모리 해제
        $this->destroy();
        log_message("debug", sprintf(
            "%s %s->%s(W:%s,H:%s) 작업완료)",
            __FUNCTION__,
            $file,
            $this->getDestinationFile(),
            $width,
            $height
        ));
        return true;
    }
}
