<?php
error_reporting(E_ALL & ~E_WARNING & ~E_NOTICE & ~E_DEPRECATED);
ob_start();
session_start();
if((($_SERVER['SERVER_ADDR']==$_SESSION['demo_server_ip']) && ((!empty($_SERVER['HTTP_CLIENT_IP']) ? $_SERVER['HTTP_CLIENT_IP'] : (!empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? explode(',', $_SERVER['HTTP_X_FORWARDED_FOR'])[0] : $_SERVER['REMOTE_ADDR']))!=$_SESSION['demo_developer_ip']) && ($_SESSION['id_user']==$_SESSION['demo_user_id'])) || ($_SESSION['svt_si']!=session_id())) {
    http_response_code(403);
    die('Forbidden');
}
ini_set("memory_limit",-1);
ini_set('max_execution_time', 9999);
ini_set('max_input_time', 9999);
require_once(dirname(__FILE__).'/../../db/connection.php');
require_once(dirname(__FILE__).'/../functions.php');
$id_virtualtour = $_SESSION['id_virtualtour_sel'];
$id_user = $_SESSION['id_user'];
$settings = get_settings();
$id_room = (int)$_POST['id_room'];
if(!check_elem_ownership($id_user,$id_virtualtour,'room',$id_room)) {
    ob_end_clean();
    echo json_encode(array("status"=>"error"));
    die();
}
$polygons_json = $_POST['polygons'];
$polygons = json_decode($polygons_json, true);
if (json_last_error() !== JSON_ERROR_NONE || empty($polygons)) {
    http_response_code(400);
    die('Invalid polygon data provided.');
}
$panorama_image = $_POST['panorama_image'];
$s3_params = check_s3_tour_enabled($id_virtualtour);
$s3_enabled = false;
$s3Client = null;
if(!empty($s3_params)) {
    $s3_bucket_name = $s3_params['bucket'];
    $s3_url = init_s3_client($s3_params);
    if($s3_url!==false) {
        $s3_enabled = true;
    }
}
session_write_close();
$panorama_image_new = 'pano_'.time().'.jpg';
if($s3_enabled) {
    $path_panorama = "s3://$s3_bucket_name/viewer/panoramas/$panorama_image";
    $path_panorama_new = "s3://$s3_bucket_name/viewer/panoramas/$panorama_image_new";
    $path_panorama_original = "s3://$s3_bucket_name/viewer/panoramas/original/$panorama_image";
    $path_panorama_original_new = "s3://$s3_bucket_name/viewer/panoramas/original/$panorama_image_new";
} else {
    $path_panorama = dirname(__FILE__).'/../../viewer/panoramas/'.$panorama_image;
    $path_panorama_new = dirname(__FILE__).'/../../viewer/panoramas/'.$panorama_image_new;
    $path_panorama_original = dirname(__FILE__).'/../../viewer/panoramas/original/'.$panorama_image;
    $path_panorama_original_new = dirname(__FILE__).'/../../viewer/panoramas/original/'.$panorama_image_new;
}
list($width, $height) = getimagesize($path_panorama);
$out = imagecreatefromjpeg($path_panorama);
$blurred_image = create_full_blurred_image($path_panorama, $width, $height);
foreach ($polygons as $polygon) {
    $points = [];
    foreach ($polygon as $point) {
        $points[] = intval($point['x']);
        $points[] = intval($point['y']);
    }
    if (count($points) < 6) continue;
    $perimeter = getPolygonCropCorners($points, 2);
    $poly_X = $perimeter[0]['min'];
    $poly_Y = $perimeter[1]['min'];
    $poly_width = $perimeter[0]['max'] - $perimeter[0]['min'];
    $poly_height = $perimeter[1]['max'] - $perimeter[1]['min'];
    if ($poly_width <= 0 || $poly_height <= 0) continue;
    $mask = imagecreatetruecolor($poly_width, $poly_height);
    $black = imagecolorallocate($mask, 0, 0, 0);
    $white = imagecolorallocate($mask, 255, 255, 255);
    imagefill($mask, 0, 0, $black);
    $points_translated = [];
    for ($i = 0; $i < count($points); $i += 2) {
        $points_translated[] = $points[$i] - $poly_X;
        $points_translated[] = $points[$i+1] - $poly_Y;
    }
    imagefilledpolygon($mask, $points_translated, count($points_translated) / 2, $white);
    $feather_amount = min($poly_width, $poly_height) * 0.01;
    for ($i = 0; $i < $feather_amount; $i++) {
        imagefilter($mask, IMG_FILTER_GAUSSIAN_BLUR);
    }
    for ($x = 0; $x < $poly_width; $x++) {
        for ($y = 0; $y < $poly_height; $y++) {
            $mask_brightness = (imagecolorat($mask, $x, $y) >> 16) & 0xFF;
            if ($mask_brightness == 0) {
                continue;
            }
            $global_x = $poly_X + $x;
            $global_y = $poly_Y + $y;
            $blurred_rgb = imagecolorat($blurred_image, $global_x, $global_y);
            $original_rgb = imagecolorat($out, $global_x, $global_y);
            if ($mask_brightness == 255) {
                imagesetpixel($out, $global_x, $global_y, $blurred_rgb);
                continue;
            }
            $r_blur = ($blurred_rgb >> 16) & 0xFF;
            $g_blur = ($blurred_rgb >> 8) & 0xFF;
            $b_blur = $blurred_rgb & 0xFF;
            $r_orig = ($original_rgb >> 16) & 0xFF;
            $g_orig = ($original_rgb >> 8) & 0xFF;
            $b_orig = $original_rgb & 0xFF;
            $alpha = $mask_brightness / 255.0;
            $r_final = $r_orig * (1 - $alpha) + $r_blur * $alpha;
            $g_final = $g_orig * (1 - $alpha) + $g_blur * $alpha;
            $b_final = $b_orig * (1 - $alpha) + $b_blur * $alpha;
            $final_color = imagecolorallocate($out, $r_final, $g_final, $b_final);
            imagesetpixel($out, $global_x, $global_y, $final_color);
        }
    }
    imagedestroy($mask);
}
imagedestroy($blurred_image);
imageinterlace($out, true);
imagejpeg($out, $path_panorama_new, 100);
imagedestroy($out);

if(file_exists($path_panorama_new)) {
    copy($path_panorama_original, $path_panorama_original_new);
    if($s3_enabled && $settings['aws_s3_type']=='digitalocean') {
        try {
            $s3Client->putObjectAcl(['Bucket' => $s3_bucket_name, 'Key' => "viewer/panoramas/$panorama_image_new", 'ACL' => 'public-read']);
        } catch (\Aws\S3\Exception\S3Exception $e) {}
        try {
            $s3Client->putObjectAcl(['Bucket' => $s3_bucket_name, 'Key' => "viewer/panoramas/original/$panorama_image_new", 'ACL' => 'public-read']);
        } catch (\Aws\S3\Exception\S3Exception $e) {}
    }
    $mysqli->close();
    $mysqli = new mysqli(DATABASE_HOST, DATABASE_USERNAME, DATABASE_PASSWORD, DATABASE_NAME);
    if (mysqli_connect_errno()) { echo mysqli_connect_error(); exit(); }
    $mysqli->query("SET NAMES 'utf8mb4';");
    $mysqli->query("UPDATE svt_rooms SET panorama_image='$panorama_image_new',multires_status=0,blur=1 WHERE id=$id_room;");
    $panorama_image_gt = $panorama_image_new;
    include("../../services/generate_thumb.php");
    include("../../services/generate_pano_mobile.php");
    generate_multires(false,$id_virtualtour);
    ob_end_clean();
    header('Content-Type: application/json');
    echo json_encode(['status'=>'success', 'new_image'=>$panorama_image_new]);
    exit();
} else {
    ob_end_clean();
    http_response_code(500);
    header('Content-Type: application/json');
    echo json_encode(['status'=>'error', 'message'=>'Failed to create the new image.']);
    exit();
}

function create_full_blurred_image($source, $width, $height) {
    $srcImage = imagecreatefromjpeg($source);
    $size = [
        'sm' => ['w' => intval($width / 4), 'h' => intval($height / 4)],
        'md' => ['w' => intval($width / 2), 'h' => intval($height / 2)],
    ];
    $sm = imagecreatetruecolor($size['sm']['w'], $size['sm']['h']);
    imagecopyresampled($sm, $srcImage, 0, 0, 0, 0, $size['sm']['w'], $size['sm']['h'], $width, $height);
    for ($x = 1; $x <= 6; $x++) {
        imagefilter($sm, IMG_FILTER_GAUSSIAN_BLUR);
    }
    $md = imagecreatetruecolor($size['md']['w'], $size['md']['h']);
    imagecopyresampled($md, $sm, 0, 0, 0, 0, $size['md']['w'], $size['md']['h'], $size['sm']['w'], $size['sm']['h']);
    imagedestroy($sm);
    for ($x = 1; $x <= 6; $x++) {
        imagefilter($md, IMG_FILTER_GAUSSIAN_BLUR);
    }
    imagecopyresampled($srcImage, $md, 0, 0, 0, 0, $width, $height, $size['md']['w'], $size['md']['h']);
    imagedestroy($md);
    return $srcImage;
}

function getPolygonCropCorners($points, $numCoords) {
    $perimeter = array();
    for ( $i = 0; $i < count($points); $i++ ) {
        $axisIndex = $i % $numCoords;
        if (count($perimeter) < $axisIndex+1) {
            $perimeter[] = array();
        }
        $min = isset($perimeter[$axisIndex]['min']) ? $perimeter[$axisIndex]['min'] : $points[$i];
        $max = isset($perimeter[$axisIndex]['max']) ? $perimeter[$axisIndex]['max'] : $points[$i];
        $perimeter[$axisIndex]['min'] = min($min, $points[$i] - 2);
        $perimeter[$axisIndex]['max'] = max($max, $points[$i] + 2);
    }
    return $perimeter;
}

?>