/*
 * Example: Configure HDMI output and display a text overlay using the LT API client
 *
 * This example demonstrates how to:
 *      1. Connect to an LT310 device and verify that a given input source is active.
 *      2. Configure an HDMI output to use that input source.
 *      3. Initialize a canvas and draw text on it.
 *      4. Set the HDMI output overlay to display the canvas.
 *
 * Usage:
 *      hdmi_out.exe -source <inputSource> [-text <overlayText>]
 *
 * Arguments:
 *      -source, -s   URL of a valid LT input on the device, for example:
 *                        hdmi-in/0
 *                        sdi-in/1
 *
 *      -text, -t     Optional text to render on the video overlay.
 *                    Default: "Hello, World!"
 *
 * Note:
 *      This code is intended for demonstration purposes. For production use,
 *      ensure proper error handling and resource cleanup.
 *
 * © 2025 Enciris Technologies. All rights reserved.
 */

#include "../../lt.h"
#include <iostream>

#ifdef _WIN32
#include <direct.h>
#endif

void printHelp() {
    std::cout << R"(
Usage:
    hdmi_out.exe -source <sourceURL> [-text <overlayText>]

Arguments:
    -source, -s   URL of a valid LT input on the device (e.g. sdi-in/0)

    -text, -t     Optional text to render on the video overlay (Default: "Hello, World!")

This example routes the selected input to HDMI output 0, creates a canvas with custom text,
and applies the canvas as an overlay on the HDMI output.
)" << std::endl;
}

/**
 * Fatal error handler - logs message and exits application cleanly.
 */
auto logFatal = [](const std::string& msg) -> void {
    throw std::runtime_error("FATAL ERROR: " + msg);
};

/**
 * Main application entry point.
 */
int main(int argc, char** argv)
{
    // Print command line usage if no arguments provided
    if (argc < 2) {
        printHelp();
        return 1;
    }

    try {
        lt::Client client;
        lt::error err;

        // Parse command line options
        std::string sourceURL;
        std::string overlayText = "Hello, World!"; // default text

        for (int i = 1; i < argc; i++) {
            if ((strcmp(argv[i], "-source") == 0 || strcmp(argv[i], "-s") == 0) && i + 1 < argc) {
                sourceURL = argv[++i];
            }
            else if ((strcmp(argv[i], "-text") == 0 || strcmp(argv[i], "-t") == 0) && i + 1 < argc) {
                overlayText = argv[++i];
            }
        }

        // Require source URL
        if (sourceURL.empty()) {
            printHelp();
            return 1;
        }

        // -------------------------------------------------------------------------
        // Check if input selected is active
        // -------------------------------------------------------------------------
        lt::Input input;

        err = client.Get("lt310:/0/"+sourceURL, input);
        if (!err.empty()) {
            logFatal("Failed to get input: " + err);
        }

        if (input.video.signal != "locked") {
            logFatal("Input source is not locked");
        }

        // -------------------------------------------------------------------------
        // Set HDMI output source
        // -------------------------------------------------------------------------
        err = client.Post("lt310:/0/hdmi-out/0", lt::json{ { "source", sourceURL } }, nullptr);
        if (!err.empty()) {
            logFatal(err);
        }
        std::cout << "hdmi-out source set to: " << sourceURL << std::endl;

        // -------------------------------------------------------------------------
        // Get HDMI output parameters
        // -------------------------------------------------------------------------
        lt::Output output;
        err = client.Get("lt310:/0/hdmi-out/0", output);
        if (!err.empty()) {
            logFatal(err);
        }

        // -------------------------------------------------------------------------
        // Initialize the canvas with the same size as HDMI output
        // -------------------------------------------------------------------------
        err = client.Post("lt310:/canvas/0/init", lt::json{ { "size", output.video.size } }, nullptr);
        if (!err.empty()) {
            logFatal(err);
        }

        // -------------------------------------------------------------------------
        // Draw text on the canvas
        // -------------------------------------------------------------------------
        err = client.Post("lt310:/canvas/0/text", lt::json{ { "text", overlayText }, { "fontSize", 200 }, { "size", output.video.size } }, nullptr);
        if (!err.empty()) {
            logFatal(err);
        }

        /* Add your own drawing code here
        * Images (PNG, JPEG, ...)
        * Rectangles
        * Lines
        * Ellipses
        * ...
        */

        // -------------------------------------------------------------------------
        // Apply the canvas as an HDMI overlay
        // -------------------------------------------------------------------------
        err = client.Post("lt310:/0/hdmi-out/0", lt::json{ { "overlay", "canvas/0" } }, nullptr);
        if (!err.empty()) {
            logFatal(err);
        }

        return 0;
    }
    catch (const std::exception& e) {
        std::cerr << e.what() << std::endl;
        return EXIT_FAILURE;
    }
}