#pragma once

#include "rtweekend.h"

// for writing to stdout
#include <iostream>

// for writing to socket
#include <unistd.h>

void correct_gamma(colour& pixel_colour, int samples)
{
    double r = pixel_colour.x();
    double g = pixel_colour.y();
    double b = pixel_colour.z();

    // divide the colour total by the number of samples and gamma-correct for gamma=2.0
    auto scale = 1.0 / samples;
    r = sqrt(scale * r);
    g = sqrt(scale * g);
    b = sqrt(scale * b);

    pixel_colour = colour(r, g, b);
}

void write_colour_to_stream(std::ostream &out, colour pixel_colour, int samples_per_pixel)
{
    correct_gamma(pixel_colour, samples_per_pixel);

    auto r = pixel_colour.x();
    auto g = pixel_colour.y();
    auto b = pixel_colour.z();
    
    // write the translated [0,255] value of each colour component.
    out << static_cast<int>(256 * clamp(r, 0.0, 0.999)) << ' '
        << static_cast<int>(256 * clamp(g, 0.0, 0.999)) << ' '
        << static_cast<int>(256 * clamp(b, 0.0, 0.999)) << '\n';
}

int format_component(double component)
{
    return int(256 * clamp(component, 0.0, 0.999));
}

void write_colour_to_socket(int sockfd, colour pixel_colour, int samples_per_pixel)
{
    correct_gamma(pixel_colour, samples_per_pixel);

    int r = format_component(pixel_colour.x());
    int g = format_component(pixel_colour.y());
    int b = format_component(pixel_colour.z());

    // pack values
    int len = 3;
    char s[len];
    sprintf(s, "%c%c%c", r, g, b);

    int written = write(sockfd, s, len);
    if (written < 0)
    {
        error("ERROR writing colour to socket");
    }
}
