<?php

class ImageGenerator {
    private $person;
    private $text;
    private $song;
    private $white;
    private $template;

    const textFont = 'fonts/NotoSerif-Regular.ttf';
    const timeFont = 'fonts/Corinthia.ttf';
    const personFont = ImageGenerator::textFont;
    const songFont = ImageGenerator::timeFont;
    private $time;

    public function __construct($person, $text, $song, $time) {
        $this->person = $person;
        $this->text = $text;
        $this->song = $song;
        $this->time = $time;
    }

    private function generate() {
        $this->template = $this->getTemplate();
        $this->white = imagecolorallocate($this->template, 255, 255, 255);

        $this->drawPerson();
        $this->drawText();
        $this->drawSong();
        $this->drawTime();
    }

    public function expose()  {
        $this->generate();

        imagejpeg($this->template);
    }

    static function utfText($text){
        $text = trim($text);
        $text = mb_convert_encoding($text, "HTML-ENTITIES", "UTF-8");
        $text = preg_replace('~^(&([a-zA-Z0-9]);)~', htmlentities('${1}'), $text);
        $text = preg_replace(preg_quote("/&ndash;/"), '-', $text);
        $text = preg_replace(preg_quote("/&hellip;/"), '&#8230;', $text);
        $text = preg_replace(preg_quote("/&laquo;/"), '&#171;', $text);
        $text = preg_replace(preg_quote("/&raquo;/"), '&#187;', $text);
        $text = preg_replace(preg_quote("/&mdash;/"), '&#8212;', $text);
        $text = preg_replace(preg_quote("/&ldquo;/"), '&#8220;', $text);
        $text = preg_replace(preg_quote("/&rdquo;/"), '&#8221;', $text);
        $text = preg_replace(preg_quote("/&eacute;/"), '&#233;', $text);
        $text = preg_replace(preg_quote("/ /"), ' ', $text);
//        $text = str_replace("&ndash;", "–", $text);
        return ($text);
    }

    private function getTemplate(){
        return imagecreatefromjpeg("template.jpg");
    }

    private function drawPerson() {
        $color = $this->white;
        $font = ImageGenerator::personFont;
        $this->centerText(70, 310, $color, $font, $this->person);
    }

    private function drawText() {
        $color = imagecolorallocate($this->template, 71, 97, 203);
        $fontSize = 65;
        $font = ImageGenerator::textFont;
        $utfText = $this->utfText($this->text);
        $text = "\"".$utfText."\"";

        $this->fitText(450, imagesx($this->template) - 400, 470, 100, $color, $font, $text);
    }

    private function drawSong() {
        $color = $this->white;
        $fontSize = 120;
        $font = ImageGenerator::songFont;
        $text = "\"" .$this->song. "\" песня";

        $this->centerText($fontSize, 1050, $color, $font, $text);
    }

    private function drawTime() {
        $color = $this->white;
        $fontSize = 100;
        $font = ImageGenerator::timeFont;

        $time = date("j.m.Y", $this->time);
        $text = "на ".$time."г.";

        $this->centerText($fontSize, 1170, $color, $font, $text);
    }

    private function centerText($fontSize, $y, $color, $font, $text) {
        $utfText = $this->utfText($text);
        $box = imagettfbbox($fontSize, 0, $font, $utfText);
        $center = (imagesx($this->template) / 2) - (($box[2] - $box[0]) / 2);
        imagettftext($this->template, $fontSize, 0, $center, $y, $color, $font, $utfText);
    }

    private function fitText($regionY, $regionWidth, $regionHeight, $fontSize, $color, $font, $utfText) {
        do {
            $box = imagettfbbox($fontSize, 0, $font, $utfText);
            $rightBottomX = $box[2];
            $rightBottomY = $box[3];
//            print_r($box);

            if ($rightBottomX > $regionWidth || $rightBottomY > $regionHeight) {
                $fontSize -= 1;
            } else {
                break;
            }
        } while(true);

        $this->centerText($fontSize, $regionY, $color, $font, $utfText);

    }
//        $imageWidth = imagesx($this->template);
//        $imageHeight = imagesy($this->template);

//        $x = ($imageWidth / 2) - (($box[2] - $box[0]) / 2);
}
