/**
 *
 * @file src/render/Minimap.cpp
 *
 * @copyright 2008-2024 Bordeaux INP, CNRS (LaBRI UMR 5800), Inria,
 *                      Univ. Bordeaux. All rights reserved.
 *
 * @author Camille Ordronneau
 * @author Johnny Jazeix
 * @author Mathieu Faverge
 * @author Olivier Lagrasse
 * @author Augustin Degomme
 *
 * @date 2024-07-17
 */
/*!
 *\file Render_opengl.cpp
 */

#include <sstream>
/* -- */
#include <QLabel>
#include <QPainter>
#include <QPen>
#include <QCloseEvent>
#include <QResizeEvent>
#include <QSize>
/* -- */
#include "common/common.hpp"
#include "common/Session.hpp"
#include "common/Message.hpp"
/* -- */
#include "render/Minimap.hpp"

using namespace std;

#define message *Message::get_instance() << "(" << __FILE__ << " l." << __LINE__ << "): "

/***********************************
 *
 *
 *
 * Constructor and destructor.
 *
 *
 *
 **********************************/

Minimap::Minimap() :
    _x(0), _y(0), _w(0), _h(0), _is_initialized(false) {
    MinimapSettings &ms = Session::getSessionMinimap();

    move(ms._x, ms._y);
    resize(ms._width, ms._height);
}

void Minimap::init(const QImage &image) {
    MinimapSettings &ms = Session::getSessionMinimap();

    _original_image = image;

    _minimap_image = _original_image.scaled(QSize(ms._width,
                                                  ms._height),
                                            Qt::IgnoreAspectRatio);

    /* If minimap was not closed when user released the last trace, show it */
    if (!ms._is_closed)
        show();

    _is_initialized = true;
}

void Minimap::update(const int x, const int y, const int w, const int h) {

    _x = x;
    _y = y;
    _w = w;
    _h = h;

    redraw();
}

void Minimap::redraw() {
    MinimapSettings &ms = Session::getSessionMinimap();
    QPixmap buf;

    buf = QPixmap::fromImage(_minimap_image);

    if (buf.isNull())
        return;

    /* If the viewport quad does not match the entire
     minimap frame, draw it */
    if (!((_x == 0) && (_y == 0) && (_w == ms._width) && (_h == ms._height))) {
        _painter.begin(&buf);
        _pen.setColor(ms._pen_color);
        _pen.setWidth(ms._pen_size);
        _painter.setPen(_pen);
        _painter.setBrush(QBrush(ms._brush_color));

        _painter.drawRect(_x, _y, _w, _h); /* Draw the viewport quad */
        _painter.end();
    }

    setPixmap(buf);
    setScaledContents(true);

#if defined(HAVE_QT5_15)
    bool pixmap_test = pixmap(Qt::ReturnByValue).isNull();
#else
    bool pixmap_test = pixmap()->isNull();
#endif

    if (pixmap_test) {
        message << tr("No Pixmap set for the minimap").toStdString() << Message::endw;
    }
}

void Minimap::release() {
    QPixmap buf;

    if (!isHidden()) { /* If minimap is no hidden, close it */
        close();
    }

    Session::getSessionMinimap().save(x(), y(), width(), height(), isHidden());

    _minimap_image.fill(0);
    buf = QPixmap::fromImage(_minimap_image);

    if (buf.isNull())
        return;

    setPixmap(buf);

    _is_initialized = false;
}

bool Minimap::is_initialized() {
    return _is_initialized;
}

void Minimap::closeEvent(QCloseEvent *) {
    Session::getSessionMinimap()._is_closed = true;
}

void Minimap::resizeEvent(QResizeEvent *event) {
    MinimapSettings &ms = Session::getSessionMinimap();

    const float width_factor = (float)event->size().width() / (float)event->oldSize().width();
    const float height_factor = (float)event->size().height() / (float)event->oldSize().height();

    _x *= width_factor;
    _w *= width_factor;
    _y *= height_factor;
    _h *= height_factor;

    ms._width = width();
    ms._height = height();
    _minimap_image = _original_image.scaled(QSize(ms._width,
                                                  ms._height),
                                            Qt::IgnoreAspectRatio);

    redraw();
}
