<?php
declare(strict_types = 1);

/**
 * Création des vignettes.
 *
 * @license https://www.gnu.org/licenses/gpl-3.0.html
 * @link https://www.igalerie.org/
 */

$gets = ['crop', 'file', 'item', 'key', 'orientation', 'quality', 'size', 'type'];
$_GET['crop'] = $_GET['crop'] ?? '';
require_once(__DIR__ . '/includes/prepend.php');

// Vérification du format des paramètres.
if (!preg_match('`^([a-z])?\d{1,12}\-[a-f\d]{32}\.([a-z]{3,4})$`i', $_GET['file'] ?? '', $file)
 || !preg_match('`^(.{1,255})(\.[a-z0-9]{3,4})$`i', $_GET['item'] ?? '', $item)
 || !preg_match('`^[a-f0-9]{32}$`', $_GET['key'] ?? '')
 || !preg_match('`^\d{1,3}$`', $_GET['quality'] ?? '')
 || !preg_match('`^(\d{2,4})(?:x(\d{2,4}))?$`', $_GET['size'] ?? '', $max_size)
 || !preg_match('`^([\d,]{7,32})?$`', $_GET['crop'] ?? '')
 || !in_array($_GET['type'] ?? '', ['cat', 'item', 'pending']))
{
	die(App::httpResponse(400));
}

// Vérification de la clé de sécurité.
$key_params =
[
	$_GET['file'], $_GET['item'], $_GET['quality'], $_GET['size'], $_GET['type'], $_GET['crop']
];
if (isset($_GET['orientation']))
{
	if (!preg_match('`^\d$`', $_GET['orientation']))
	{
		die(App::httpResponse(400));
	}
	$key_params[] = $_GET['orientation'];
}
if (!Security::fileKeyVerify($key_params, $_GET['key']))
{
	die(App::httpResponse(403));
}

// Emplacement des fichiers.
if ($item[2] == '.vid')
{
	$file_source = GALLERY_ROOT . '/cache/captures/' . $item[1] . '.jpg';
}
else if (isset($file[1]) && $file[1] == 'e')
{
	$hash = App::hashFilename($item[1], ['ext']);
	$file_source = GALLERY_ROOT . '/cache/external/' . $hash;
}
else
{
	$file_source = $_GET['type'] == 'pending'
		? GALLERY_ROOT . '/pending/' . $_GET['item']
		: CONF_ALBUMS_PATH . '/' . $_GET['item'];
}

// On crée la vignette si elle n'existe pas.
if (!file_exists($file_thumb = GALLERY_ROOT . '/cache/thumbs/' . $_GET['file']))
{
	// On vérifie la présence de GD.
	if (!function_exists('imagetypes'))
	{
		die('GD is not activated.');
	}

	// On vérifie l'existence du fichier.
	if (!file_exists($file_source))
	{
		die('File does not exist.');
	}

	// Récupération des propriétés de l'image.
	if (!$i = Image::getTypeSize($file_source))
	{
		die('Invalid image.');
	}

	// Images externes.
	if (isset($file[1]) && $file[1] == 'e')
	{
		$i['filetype'] = 2;
	}

	// Création de l'image GD.
	$gd_image = GD::createFrom($file_source);
	if (is_string($gd_image))
	{
		die($gd_image);
	}
	if (is_bool($gd_image))
	{
		die(sprintf('Cannot create image (%s).', $i['filetype']));
	}

	// Orientation.
	$metadata = new Metadata($file_source);
	$orientation = (int) $metadata->getExifValue('orientation');
	GD::orientation($gd_image, $orientation);
	if (in_array($orientation, [5, 6, 7, 8]))
	{
		$width = $i['width'];
		$i['width'] = $i['height'];
		$i['height'] = $width;
	}

	// Dimensions de la vignette.
	$max_width = (int) $max_size[1];
	$max_height = (int) ($max_size[2] ?? $max_size[1]);

	// Vignette personnalisée (rognage spécifique + redimensionnement).
	if ($_GET['crop'])
	{
		$crop = explode(',', $_GET['crop']);
		$crop =
		[
			'x' => (int) $crop[0],
			'y' => (int) $crop[1],
			'w' => (int) $crop[2],
			'h' => (int) $crop[3]
		];

		$src_coords = $crop;

		if (isset($max_size[2]))
		{
			$dst_size = ['w' => $max_width, 'h' => $max_height];
			$src_coords = Image::getCroppedSource(
				$crop['w'], $crop['h'], $dst_size['w'], $dst_size['h']
			);
			$src_coords['x'] += $crop['x'];
			$src_coords['y'] += $crop['y'];
		}
		else
		{
			$dst_size = Image::getResizedSize($crop['w'], $crop['h'], $max_width, $max_height);
		}
	}

	// Vignette rognée (rognage + redimensionnement).
	else if (isset($max_size[2]))
	{
		$dst_size = ['w' => $max_width, 'h' => $max_height];
		$src_coords = Image::getCroppedSource(
			$i['width'], $i['height'], $dst_size['w'], $dst_size['h']
		);
	}

	// Vignette standard (redimensionnement simple).
	else
	{
		$dst_size = Image::getResizedSize($i['width'], $i['height'], $max_width, $max_height);
	}

	GD::resize($gd_image,
		$src_coords['x'] ?? 0, $src_coords['y'] ?? 0,
		$src_coords['w'] ?? $i['width'], $src_coords['h'] ?? $i['height'],
		0, 0,
		$dst_size['w'] ?? $i['width'], $dst_size['h'] ?? $i['height']
	);

	// Enregistrement de l'image GD.
	GD::file($gd_image, $file_thumb, Item::getTypeFile($file[2]), (int) $_GET['quality']);
}

// Lecture du fichier.
Image::read($file_thumb);
?>