/*
** 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 Command_window.cpp
 */

#include <vector>
#include <stack>
#include <iostream>
#include <sstream>
/* -- */
#include <QTreeWidgetItem>
#include <QGLWidget>
#include <QTextEdit>
#include <QPushButton>
#include <QRadioButton>
#include <QProcess>
/* -- */
#include "common/common.hpp"
/* -- */
#include "interface/resource.hpp"
#include "interface/Interface.hpp"
#include "interface/Interface_graphic.hpp"
/* -- */
#include "common/Message.hpp"
/* -- */
#include "core/Core.hpp"
/* -- */
#include "trace/values/Values.hpp"
#include "trace/tree/Interval.hpp"
#include "trace/tree/Node.hpp"
#include "trace/tree/BinaryTree.hpp"
#include "trace/EntityValue.hpp"
#include "trace/EntityTypes.hpp"
#include "trace/Entitys.hpp"
// #include "trace/tree/Interval.hpp"
#include "trace/Trace.hpp"
/* -- */
#include "Command_window.hpp"


using namespace std;
 // Should use the Core and not the interface graphic to remove a lot of widget from the graphical interface
Command_window::Command_window( QWidget *parent, Interface_graphic * i) : QMainWindow(parent){
    setupUi(this);
    //    _trace = T;
    //    CKFP(_ui_layout = this->findChild<QVBoxLayout *>("verticalLayout_5"),"Cannot find the vertical layout in the ui file");
    _console = i;

    CKFP(_ui_cmd_box = this->findChild<QLineEdit*>("command"), "Cannot find the command box in the .ui file");

    CKFP(_ui_start_box = this->findChild<QLineEdit*>("startTime"), "Cannot find the beginning argument box in the .ui file");

    CKFP(_ui_end_box = this->findChild<QLineEdit*>("endTime"), "Cannot find the end argument box in the .ui file");

    CKFP(_ui_filter_box = this->findChild<QLineEdit*>("filter"), "Cannot find the filter argument box in the .ui file");

    CKFP(_ui_tree_box = this->findChild<QTreeWidget*>("_nodes_selected"), "Cannot find the tree argument box in the .ui file");
}

void Command_window::set_trace( Trace * t){
    _trace = t;
}

void Command_window::init_window() {
    // We set the names of the containers for the tree widget
    _nodes_selected->clear();
    set_container_names();
}

// By default, cmd = useless
void Command_window::on_execute_button_clicked(){

    const QString cmd = _ui_cmd_box->text();
    QString start_time = _ui_start_box->text();
    QString end_time = _ui_end_box->text();
    QString filter = _ui_filter_box->text();

    if(start_time == "" ||
       start_time == "t0")
        start_time = "0";
    if(end_time == "" ||
       end_time == "t1")
        end_time = QString::fromStdString(_trace->get_max_date().to_string());
    if(filter == "" ||
       filter < nullptr)
        filter = "0";

    set_selected_nodes();

    if(cmd=="PROC"){
        start_time = "0";
        end_time = QString::fromStdString(_trace->get_max_date().to_string());
        filter = "0";
    }
    else if(cmd == "DATE"){
        filter = "0";
        _selected_containers.clear();
    }
    else if(cmd == "SMALL"){
        _selected_containers.clear();
        start_time = "0";
        end_time = QString::fromStdString(_trace->get_max_date().to_string());
    }
    else if(cmd == "RECT")
        filter = "0";
    else if(cmd == "PROCREST"){
        start_time = "0";
        end_time = QString::fromStdString(_trace->get_max_date().to_string());
    }
    else if (cmd == "lapinou"){
        show_error();
    }
    else if( cmd == "TIME"){
        _selected_containers.clear();
    }


    _trace->set_selected_container(&_selected_containers);
    _trace->set_interval_constrained(new Interval(start_time.toDouble(),end_time.toDouble()));
    _trace->set_filter(filter.toDouble());

    _console->get_console()->launch_action(Core::_STATE_RENDER_UPDATE);
    _console->get_console()->draw_trace(_console->get_filename(),Core::_DRAW_OPENGL);


}



void Command_window::set_container_names() {

  const Container::Vector *root_containers = _trace->get_root_containers();

    if(root_containers->empty()) {
        *Message::get_instance() << "No containers in this trace" << Message::ende;
        return;
    }
    // Add the root container names
    QList<QTreeWidgetItem *> items;
    QFlags<Qt::ItemFlag>     flg=Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsTristate;

    for (const auto &root_container : *root_containers) {
        string           name = root_container->get_Name().to_string();
        QStringList      temp(QString::fromStdString(name));
        QTreeWidgetItem *current_node = new QTreeWidgetItem((QTreeWidgetItem *)nullptr, temp);

        current_node->setFlags(flg);
        current_node->setCheckState(0,Qt::Unchecked);
        items.append(current_node);

        // Recursivity to add the children names
        set_container_names_rec(current_node, root_container);
    }

    (*(items.begin()))->setExpanded(true);
    _nodes_selected->insertTopLevelItems(0, items);
}

void Command_window::set_container_names_rec(QTreeWidgetItem *current_node, const Container *current_container) {
    const Container::Vector *children = current_container->get_children();
    QFlags<Qt::ItemFlag>     flg      = Qt::ItemIsUserCheckable | Qt::ItemIsSelectable | Qt::ItemIsEnabled/* | Qt::ItemIsTristate*/;

    for (const auto &it : *children) {
        // We create the node and we do the recursivity
        string name = it->get_Name().to_string();
        QStringList temp(QString::fromStdString(name));
        QTreeWidgetItem *node = new QTreeWidgetItem(current_node, temp);
        node->setFlags(flg);
        node->setCheckState(0,Qt::Unchecked);
        set_container_names_rec(node ,it);
    }
}


void Command_window::set_selected_nodes()
{
    // We delete the previous selected containers
    if(!_selected_containers.empty())
    {
        _selected_containers.clear();
    }

    // We fill the new selected containers
    // TODO : Use the tree instead of the list
    QTreeWidgetItemIterator it(_nodes_selected);
    while (*it)
    {
        if ((*it)->checkState(0) == Qt::Checked)
        {
            _selected_containers.push_back(_trace->search_container((*it)->text(0).toStdString()));
        }
        it ++;
    }
}


void Command_window::show_error(){
//     switch(fork()){
//     case -1 :
//         return;
//     case 0 :
//         execvp("xpenguins",NULL);
//     default :
//         break;
//     }
}
/*
Command_window::~Command_window (){
    delete _ui_layout;
    delete _ui_cmd_box;
    delete _ui_start_box;
    delete _ui_end_box;
    delete _ui_filter_box;
    delete _ui_tree_box;
}
*/
