/*
 * Inscoper NBO Example: Export NBO-XML
 * ====================================
 * This example demonstrates how to serialize an NBO object tree to an XML string
 * or to an XML file, and how validation is applied on export.
 *
 * Prerequisites:
 * -------------
 * 1. Installation: the include directory of the release must be on the include
 *    paths, and the application must link against the NBO library.
 */

// --8<-- [start:main_logic]
#include <NBO/NBO/BinData.h>
#include <NBO/NBO/Denomination_Type.h>
#include <NBO/NBO/Image.h>
#include <NBO/NBO/ImageID_Type.h>
#include <NBO/NBO/NonNegativeLong_Type.h>
#include <NBO/NBO/StageLabel.h>

#include <filesystem>
#include <iostream>
#include <memory>

using namespace Inscoper;

int main() {
    // Build a small tree: an image carrying three stage positions
    NBO::Image image;

    NBO::ImageID_TypePtr imageId = std::make_shared<NBO::ImageID_Type>();
    imageId->set("Image:1");
    image.setID(imageId);

    NBO::Denomination_TypePtr name = std::make_shared<NBO::Denomination_Type>();
    name->set("Field 1");
    image.setName(name);

    const float positions[3][2] = {{0.0f, 0.0f}, {120.5f, 0.0f}, {241.0f, 0.0f}};
    for (int index = 0; index < 3; ++index) {
        NBO::StageLabelPtr stageLabel = std::make_shared<NBO::StageLabel>();
        stageLabel->setName("Position " + std::to_string(index));
        stageLabel->setX(positions[index][0]);
        stageLabel->setY(positions[index][1]);
        image.addToStageLabel_List(stageLabel);
    }

    // Step 1: Serialize to a string
    std::cout << image.toXmlString() << std::endl;

    // Step 2: Serialize to a file
    std::filesystem::path outputPath = std::filesystem::temp_directory_path() / "image.xml";
    image.toXmlFile(outputPath.string());
    std::cout << "Written to " << outputPath.string() << std::endl;

    // Step 3: Control validation on export
    // Export validates the document by default: an element missing a required
    // attribute throws InscoperNBOValidationException, and attributes that carry a
    // schema default are written explicitly. Pass false to write exactly what was
    // set, at the cost of producing a document that may not be schema-valid.
    NBO::BinData binData;
    binData.setBigEndian(true);
    NBO::NonNegativeLong_TypePtr length = std::make_shared<NBO::NonNegativeLong_Type>();
    length->set(12);
    binData.setLength(length);

    std::cout << binData.toXmlString() << std::endl;       // validated: Compression="none"
    std::cout << binData.toXmlString(false) << std::endl;  // as set: Compression is omitted

    return 0;
}
// --8<-- [end:main_logic]
