/*
** This file is part of the ViTE project.
**
** This software is governed by the CeCILL-A license under French law
** and abiding by the rules of distribution of free software. You can
** use, modify and/or redistribute the software under the terms of the
** CeCILL-A license as circulated by CEA, CNRS and INRIA at the following
** URL: "http://www.cecill.info".
** 
** As a counterpart to the access to the source code and rights to copy,
** modify and redistribute granted by the license, users are provided
** only with a limited warranty and the software's author, the holder of
** the economic rights, and the successive licensors have only limited
** liability.
** 
** In this respect, the user's attention is drawn to the risks associated
** with loading, using, modifying and/or developing or reproducing the
** software by the user in light of its specific status of free software,
** that may mean that it is complicated to manipulate, and that also
** therefore means that it is reserved for developers and experienced
** professionals having in-depth computer knowledge. Users are therefore
** encouraged to load and test the software's suitability as regards
** their requirements in conditions enabling the security of their
** systems and/or data to be ensured and, more generally, to use and
** operate it in the same conditions as regards security.
** 
** The fact that you are presently reading this means that you have had
** knowledge of the CeCILL-A license and that you accept its terms.
**
**
** ViTE developers are (for version 0.* to 1.0):
**
**        - COULOMB Kevin
**        - FAVERGE Mathieu
**        - JAZEIX Johnny
**        - LAGRASSE Olivier
**        - MARCOUEILLE Jule
**        - NOISETTE Pascal
**        - REDONDY Arthur
**        - VUCHENER Clément 
**
*/
/*!
 *\file Render_opengl.cpp
 */

#include <sstream>
/* -- */
#include <QLabel>
#include <QPainter>
#include <QPen>
#include <QCloseEvent>
#include <QSettings>
#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(){
    QSettings settings("ViTE", "ViTE");

    if (settings.contains("minimap/x"))
        Minimap::load_session();
    else{
        /* Initialize with default values */
        Session::Minimap::x           = 0;
        Session::Minimap::y           = 0;
        Session::Minimap::width       = 200;
        Session::Minimap::height      = 150;
        Session::Minimap::pen_size    = 3;
        Session::Minimap::pen_color   = Qt::red;
        Session::Minimap::brush_color = QColor::fromRgbF(1, 1, 0, 0.5);
        Session::Minimap::is_closed   = isHidden();
    }

    move  (Session::Minimap::x    , Session::Minimap::y);
    resize(Session::Minimap::width, Session::Minimap::height);

	_is_initialized=false;
}

void Minimap::load_session(){
    QSettings settings("ViTE", "ViTE");

    Session::Minimap::x           = settings.value("minimap/x").value<int>();
    Session::Minimap::y           = settings.value("minimap/y").value<int>();
    Session::Minimap::width       = settings.value("minimap/width").value<int>();
    Session::Minimap::height      = settings.value("minimap/height").value<int>();
    Session::Minimap::pen_size    = settings.value("minimap/pen_size").value<int>();
    Session::Minimap::pen_color   = settings.value("minimap/pen_color").value<QColor>();
    Session::Minimap::brush_color = settings.value("minimap/brush_color").value<QColor>();
    Session::Minimap::is_closed   = settings.value("minimap/is_closed").value<bool>();
}

// \todo Should be called when closing the window too?
void Minimap::store_session(){
    QSettings settings("ViTE", "ViTE");

    settings.setValue("minimap/x"          , Session::Minimap::x);
    settings.setValue("minimap/y"          , Session::Minimap::y);
    settings.setValue("minimap/width"      , Session::Minimap::width);
    settings.setValue("minimap/height"     , Session::Minimap::height);
    settings.setValue("minimap/pen_size"   , Session::Minimap::pen_size);
    settings.setValue("minimap/pen_color"  , Session::Minimap::pen_color);
    settings.setValue("minimap/brush_color", Session::Minimap::brush_color);
    settings.setValue("minimap/is_closed"  , Session::Minimap::is_closed);

    settings.sync();/* Commit changes */
    
}

void Minimap::init(const QImage &image){

    _x = _y = _w = _h = 0;

    _original_image = image;
    
    _minimap_image = _original_image.scaled(QSize(Session::Minimap::width, Session::Minimap::height), Qt::IgnoreAspectRatio);

    if (!Session::Minimap::is_closed)/* If minimap was not closed when user released the last trace, show it */
        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(){
   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 == Session::Minimap::width   &&
           _h == Session::Minimap::height )  )
   {         
        _painter.begin(&buf);
        _pen.setColor(Session::Minimap::pen_color);
        _pen.setWidth(Session::Minimap::pen_size);
        _painter.setPen(_pen);
        _painter.setBrush(QBrush(Session::Minimap::brush_color));
   
        _painter.drawRect ( _x, _y, _w, _h);/* Draw the viewport quad */
        _painter.end();
   }

   setPixmap(buf);
   setScaledContents(true);
   
   if (!pixmap())
       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();/* Take care that close() (via closeEvent()) also modify the Session::Minimap::is_closed attribute */
         Session::Minimap::is_closed = false;
     }
         

    _minimap_image.fill(0);
    buf = QPixmap::fromImage(_minimap_image);
    
    if (buf.isNull())
        return;
    
    setPixmap(buf);

    Session::Minimap::x      = x();
    Session::Minimap::y      = y();
    Session::Minimap::width  = width();
    Session::Minimap::height = height();
    Minimap::store_session();

	_is_initialized=false;

    /* Qt will release automatically _minimap_widget */
}

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

void Minimap::closeEvent(QCloseEvent*){

    Session::Minimap::is_closed = true;
}

void Minimap::resizeEvent(QResizeEvent* event){
    
    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;

    Session::Minimap::width  = width();
    Session::Minimap::height = height();
    _minimap_image           = _original_image.scaled(QSize(Session::Minimap::width, Session::Minimap::height), Qt::IgnoreAspectRatio);

    redraw();
}
