#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <vector>
#include <opencv2/opencv.hpp>

// Struktur für die eingelesenen Rechteckdaten
struct PcbRect {
    double cx;
    double cy;
    double width;
    double height;
};

int main() {
    const std::string imgInputFile = "input.tiff";
    const std::string txtInputFile = "rechtecke.txt";
    const std::string outputFile = "ausgabe.tiff";

    // 1. Originalbild laden (in Farbe konvertieren, damit wir ROT zeichnen können)
    cv::Mat src = cv::imread(imgInputFile, cv::IMREAD_COLOR);
    if (src.empty()) {
        std::cerr << "Fehler: Konnte Bild " << imgInputFile << " nicht oeffnen!" << std::endl;
        return 1;
    }

    // 2. Textdatei parsen
    std::ifstream txtFile(txtInputFile);
    if (!txtFile.is_open()) {
        std::cerr << "Fehler: Konnte " << txtInputFile << " nicht oeffnen!" << std::endl;
        return 1;
    }

    std::vector<PcbRect> rectangles;
    std::string line;
    bool dataSection = false;

    while (std::getline(txtFile, line)) {
        // Daten beginnen nach der Trennlinie
        if (line.find("---") != std::string::npos) {
            dataSection = true;
            continue;
        }
        // Ende der Tabelle bei der Gleichheitszeichen-Linie
        if (dataSection && line.find("===") != std::string::npos) {
            break;
        }

        if (dataSection && !line.empty()) {
            std::stringstream ss(line);
            int id;
            double cx, cy, w, h;
            
            // Spalten einlesen: ID, Zentrum_X, Zentrum_Y, Breite, Hoehe
            if (ss >> id >> cx >> cy >> w >> h) {
                rectangles.push_back({cx, cy, w, h});
            }
        }
    }
    txtFile.close();

    std::cout << rectangles.size() << " Messpunkte aus Textdatei geladen." << std::endl;

    // 3. Rechtecke in das Bild einzeichnen
    // OpenCV Farbformat ist BGR: Blau=0, Gruen=0, Rot=255
    cv::Scalar redColor(0, 0, 255); 
    int thickness = 2; // Linienstärke des Rahmens in Pixeln

    for (const auto& rect : rectangles) {
        // Da die Radien aus der Distanztransformation ermittelt wurden,
        // berechnen wir die linke obere Ecke des maximalen In-Rechtecks:
        int xTopLeft = cvRound(rect.cx - (rect.width / 2.0));
        int yTopLeft = cvRound(rect.cy - (rect.height / 2.0));
        int w = cvRound(rect.width);
        int h = cvRound(rect.height);

        // Erstelle OpenCV Rechteck-Objekt
        cv::Rect cvRect(xTopLeft, yTopLeft, w, h);

        // Sicherstellen, dass das Rechteck innerhalb der Bildgrenzen liegt
        cvRect &= cv::Rect(0, 0, src.cols, src.rows);

        // Rechteck zeichnen
        cv::rectangle(src, cvRect, redColor, thickness);
        
        // Optional: Einen kleinen Punkt im exakten Zentrum zeichnen
        cv::circle(src, cv::Point(cvRound(rect.cx), cvRound(rect.cy)), 2, redColor, -1);
    }

    // 4. Als neue TIFF-Datei speichern
    if (cv::imwrite(outputFile, src)) {
        std::cout << "Datei erfolgreich mit roten Rahmen als '" << outputFile << "' gespeichert." << std::endl;
    } else {
        std::cerr << "Fehler beim Schreiben der Ausgabedatei!" << std::endl;
        return 1;
    }

    return 0;
}
