#ifndef TRACEBUILDER_HPP
#define TRACEBUILDER_HPP
#include <iostream>
#include <string>
#include <queue>
#include <map>

#include <QWaitCondition>
#include <QSemaphore>
#include <QObject>
#include <QMutex>
#include <QThread>
/* -- */

#include "trace/values/Values.hpp"
#include "trace/EntityValue.hpp"
#include "trace/EntityTypes.hpp"
#include "trace/Entitys.hpp"
#include "trace/Trace.hpp"
#include "trace/tree/Node.hpp"
#include "trace/tree/BinaryTree.hpp"
/* -- */
#include "common/common.hpp"
#include "common/Info.hpp" /* Dirty, should be remove */
#include "common/Message.hpp"
#include "common/Errors.hpp"
/* -- */
#include "trace/tree/Interval.hpp"

#include "parser/Parser.hpp"


typedef std::map<const String, Container *, String::less_than > Container_map;
/*
typedef struct Test_struct{
    int _id;
}Test_struct;*/


typedef struct Trace_builder_struct{
    int _id;
    //void (*func)(void* tb,Date, Name alias, String container_type,String, String, String, String, std::map<std::string, Value *> *extra_fields);
    void (*func)(Trace_builder_struct*);
    Date time;
    Name alias;
    String      type;
    String      start_container_type;
    String      end_container_type;
    String      container;
    String      value_string;
    Double      value_double;
    String      start_container;
    String      end_container;
    String      key;
    std::map<std::string, Value *> extra_fields;
        //std::map<std::string, Value *> *extra_fields;
    Trace* _trace;
    Parser* _parser;
    Container_map* _containers;
    Trace_builder_struct(){ /*extra_fields=NULL;*/}

}Trace_builder_struct;

class TraceBuilderThread : public QObject {
    Q_OBJECT

private:
    QWaitCondition* _cond;
    bool _is_finished;
    QSemaphore * _freeSlots;
    QMutex* _mutex;
public:
    TraceBuilderThread(QWaitCondition* cond,  QSemaphore * freeSlots, QMutex* mutex);
    static void define_container_type(Trace_builder_struct* tb_struct);
    static void create_container(Trace_builder_struct* tb_struct);
    static void destroy_container(Trace_builder_struct* tb_struct);
    static void define_event_type(Trace_builder_struct* tb_struct);
    static void define_state_type(Trace_builder_struct* tb_struct);
    static void define_variable_type(Trace_builder_struct* tb_struct);
    static void define_link_type(Trace_builder_struct* tb_struct);
    static void define_entity_value(Trace_builder_struct* tb_struct);
    static void set_state(Trace_builder_struct* tb_struct);
    static void push_state(Trace_builder_struct* tb_struct);
    static void pop_state(Trace_builder_struct* tb_struct);
    static void new_event(Trace_builder_struct* tb_struct);
    static void set_variable(Trace_builder_struct* tb_struct);
    static void add_variable(Trace_builder_struct* tb_struct);
    static void sub_variable(Trace_builder_struct* tb_struct);
    static void start_link(Trace_builder_struct* tb_struct);
    static void end_link(Trace_builder_struct* tb_struct);


  public slots:
  void build_trace(int n, Trace_builder_struct* tb_struct);
  void build_finished();
  bool is_finished();

};


#endif
