1<?php
2
3namespace Davaxi\Sparkline;
4
5/**
6 * Class PictureTrait.
7 */
8class Picture
9{
10    const DOT_RADIUS_TO_WIDTH = 2;
11
12    /**
13     * @var resource
14     */
15    protected $resource;
16
17    /**
18     * @var int
19     */
20    protected $height;
21
22    /**
23     * @var int
24     */
25    protected $width;
26
27    /**
28     * Picture constructor.
29     * @param int $width
30     * @param int $height
31     */
32    public function __construct(int $width, int $height)
33    {
34        $this->width = $width;
35        $this->height = $height;
36        $this->resource = imagecreatetruecolor($width, $height);
37    }
38
39    /**
40     * @param array $setColor
41     *
42     * @return int
43     */
44    protected function getBackground(array $setColor = []): int
45    {
46        if ($setColor) {
47            return imagecolorallocate(
48                $this->resource,
49                $setColor[0],
50                $setColor[1],
51                $setColor[2]
52            );
53        }
54
55        return imagecolorallocatealpha(
56            $this->resource,
57            0,
58            0,
59            0,
60            127
61        );
62    }
63
64    /**
65     * @param array $lineColor
66     *
67     * @return int
68     */
69    public function getLineColor(array $lineColor): int
70    {
71        return imagecolorallocate(
72            $this->resource,
73            $lineColor[0],
74            $lineColor[1],
75            $lineColor[2]
76        );
77    }
78
79    /**
80     * @param array $backgroundColor
81     */
82    public function applyBackground(array $backgroundColor)
83    {
84        imagesavealpha($this->resource, true);
85        imagefill(
86            $this->resource,
87            0,
88            0,
89            $this->getBackground($backgroundColor)
90        );
91    }
92
93    /**
94     * @param int $lineThickness
95     */
96    public function applyThickness(int $lineThickness)
97    {
98        imagesetthickness($this->resource, $lineThickness);
99    }
100
101    /**
102     * @param array $polygon
103     * @param array $fillColor
104     * @param int $count
105     */
106    public function applyPolygon(array $polygon, array $fillColor, int $count)
107    {
108        if (!$fillColor) {
109            return;
110        }
111        $fillColor = imagecolorallocate($this->resource, $fillColor[0], $fillColor[1], $fillColor[2]);
112        imagefilledpolygon($this->resource, $polygon, $count + 2, $fillColor);
113    }
114
115    /**
116     * @param array $line
117     * @param array $lineColor
118     */
119    public function applyLine(array $line, array $lineColor)
120    {
121        $lineColor = $this->getLineColor($lineColor);
122        foreach ($line as $coordinates) {
123            list($pictureX1, $pictureY1, $pictureX2, $pictureY2) = $coordinates;
124            imageline($this->resource, $pictureX1, $pictureY1, $pictureX2, $pictureY2, $lineColor);
125        }
126    }
127
128    /**
129     * @param int $positionX
130     * @param int $positionY
131     * @param float $radius
132     * @param array $color
133     */
134    public function applyDot(int $positionX, int $positionY, float $radius, array $color)
135    {
136        if (!$color || !$radius) {
137            return;
138        }
139
140        $minimumColor = imagecolorallocate(
141            $this->resource,
142            $color[0],
143            $color[1],
144            $color[2]
145        );
146        $dotDiameter = (int)round($radius * static::DOT_RADIUS_TO_WIDTH);
147        imagefilledellipse(
148            $this->resource,
149            $positionX,
150            $positionY,
151            $dotDiameter,
152            $dotDiameter,
153            $minimumColor
154        );
155    }
156
157    /**
158     * @param int $width
159     * @param int $height
160     *
161     * @return resource
162     */
163    public function generate(int $width, int $height)
164    {
165        $sparkline = imagecreatetruecolor($width, $height);
166        imagealphablending($sparkline, false);
167        imagecopyresampled(
168            $sparkline,
169            $this->resource,
170            0,
171            0,
172            0,
173            0,
174            $width,
175            $height,
176            $this->width,
177            $this->height
178        );
179        imagesavealpha($sparkline, true);
180        imagedestroy($this->resource);
181
182        return $sparkline;
183    }
184}
185