<?php

namespace App\Traits;

use App\Entities\Mangboard\BoardEntity;
use App\Libraries\MyStorage\MangboardStorage;

trait ImageTrait
{
    private $_image;
    private $_imageType;

    final protected function getWidth_ImageTrait()
    {
        return imagesx($this->_image);
    }
    // 이미지의 현재 높이를 반환하는 메소드
    final protected function getHeight_ImageTrait()
    {
        return imagesy($this->_image);
    }
    // 이미지 파일을 로드하는 메소드
    final protected function load_ImageTrait($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;
        }
    }
    // 이미지 크기를 지정된 너비, 높이로 변경하는 메소드
    final protected function resize_ImageTrait($width, $height)
    {
        $newImage = imagecreatetruecolor($width, $height);
        imagecopyresampled(
            $newImage,
            $this->_image,
            0,
            0,
            0,
            0,
            $width,
            $height,
            $this->getWidth_ImageTrait(),
            $this->getHeight_ImageTrait()
        );
        $this->_image = $newImage;
    }
    // 이미지 비율을 유지하면서 크기를 조정하는 메소드
    final protected function resizeToWidth_ImageTrait($width)
    {
        $ratio = $width / $this->getWidth_ImageTrait();
        $height = $this->getHeight_ImageTrait() * $ratio;
        $this->resize_ImageTrait($width, $height);
    }
    final protected function resizeToHeight_ImageTrait($height)
    {
        $ratio = $height / $this->getHeight_ImageTrait();
        $width = $this->getWidth_ImageTrait() * $ratio;
        $this->resize_ImageTrait($width, $height);
    }
    final protected function scale($scale)
    {
        $width = $this->getWidth_ImageTrait() * ($scale / 100);
        $height = $this->getHeight_ImageTrait() * ($scale / 100);
        $this->resize_ImageTrait($width, $height);
    }
    // 이미지를 저장하는 메소드
    final protected function save_ImageTrait($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;
        }
    }
    // 메모리 해제를 위한 메소드
    final protected function destroy_ImageTrait()
    {
        imagedestroy($this->_image);
    }

    public function create_small_ImageTrait(BoardEntity $board_entity, MangboardStorage $storage, $target_name = "small", int $width = 480, int $height = 319): void
    {
        $fileInfo = pathinfo($storage->getFullPath() . DIRECTORY_SEPARATOR . $storage->getOriginName(), PATHINFO_ALL);
        $target_file_name = sprintf("%s_%s.%s", $fileInfo['filename'], $target_name, $fileInfo['extension']);
        if (!$this->isFileType_FileTrait($fileInfo['extension'])) {
            throw new \Exception("{$storage->getOriginName()} Image 형식파일이 아닙니다.");
        }
        // 이미지 파일 로드
        $this->load_ImageTrait($storage->getFullPath() . DIRECTORY_SEPARATOR . $storage->getOriginName());
        // 200x200으로 이미지 크기 조정
        $this->resize_ImageTrait($width, $height);
        // 파일 저장
        $this->save_ImageTrait($storage->getFullPath() . DIRECTORY_SEPARATOR . $target_file_name);
        // 메모리 해제
        $this->destroy_ImageTrait();
        log_message("debug", sprintf(
            "%s %s->%s(W:%s,H:%s) 작업완료)",
            __FUNCTION__,
            $storage->getOriginName(),
            $target_file_name,
            $width,
            $height
        ));
        log_message("notice", sprintf(
            "%s -> %s 게시물의 %s번째:%s 작은이미지 생성 완료",
            __FUNCTION__,
            $board_entity->getTitle(),
            $storage->getOriginSequence(),
            $target_file_name
        ));
    }
}
