#ifndef SERIALIZER_CONTAINER
#define SERIALIZER_CONTAINER


#include "trace/IntervalOfContainer.hpp"

#include <limits>
#include <float.h>
#include "trace/Entitys.hpp"
#include "trace/Container.hpp"
#include <boost/serialization/split_member.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/assume_abstract.hpp>
#include <trace/Serializer.hpp>

#include "trace/Serializer_values.hpp"
#include "trace/Serializer_types.hpp"
#include "trace/Serializer_structs.hpp"

    //Container serialization methods
    BOOST_SERIALIZATION_SPLIT_FREE(::Container)

                template<class Archive>
         void save(Archive & ar, const ::Container& l, const unsigned int)
    {
        Name _name=l.get_name()   ;
        ar & _name;
        Date _creation_time=l.get_creation_time();
        ar & _creation_time;
        Date _destruction_time=l.get_destruction_time();
        ar & _destruction_time;
        int type_uid= Serializer<ContainerType>::Instance().getUid(l.get_type());
        ar & type_uid;
        const Container* _parent=l.get_parent();
        ar & _parent;

        int _uid=Serializer< ::Container >::Instance().getUid(&l);
        ar & _uid;
        //size of the _intervalsOfContainer array;
        int i=l.get_intervalsOfContainer()->size();
       // printf("nb itc dans %s : %d\n", _name.to_string().c_str(), i);
        ar & i;
        //start and stop time of each one of the itc
        std::list<IntervalOfContainer* > ::const_iterator it_end1= l.get_intervalsOfContainer()->end();
        for(std::list<IntervalOfContainer *>::const_iterator it = l.get_intervalsOfContainer()->begin() ;
            it != it_end1;
            it++){
                Date d = (*it)->get_beginning();
                ar & d;
                Date d2=( *it)->get_end();
                ar & d2;
                //printf("on sauve %lf et %lf de %s\n", d.get_value(), d2.get_value(), _name.to_string().c_str());
                std::map<EntityValue* , double>* t=( *it)->get_states_values_map();
                ar & t;
        }

        const std::map<std::string, Value *>*       _extra_fields= l.get_extra_fields();
        ar & _extra_fields;
        const ::Container::Vector * v= l.get_children();
        ar & v;
    }

     template<class Archive>
    void load(Archive & ar, ::Container& l, const unsigned int)
    {

        Name                      _name;
        Date                      _creation_time;
        Date                      _destruction_time;
    const ContainerType            *_type;
    Container                *_parent;
    ::Container::Vector*                    _children;

    std::map<std::string, Value *> *      _extra_fields;

    std::list<IntervalOfContainer* >        _intervalsOfContainer;
        ar & _name;
        ar & _creation_time;
        ar & _destruction_time;
        int type_uid;
        ar & type_uid;
        _type=Serializer<ContainerType>::Instance().getValue(type_uid);
        ar & _parent;
        int _uid;
        ar & _uid;
        Serializer<Container>::Instance().setUid(_uid, &l);
        int itc_size=0;
        ar & itc_size;
        if(itc_size!=0){
            //start and stop time of each one of the it
            for(int i=0 ; i<itc_size; i++){
                    IntervalOfContainer* itc=new IntervalOfContainer();
                    itc->_loaded=0;
                    ar & itc->_beginning;
                    ar & itc->_end;
                    ar & itc->_states_values_map;

                    if(itc->_beginning<Info::Entity::x_min)Info::Entity::x_min=itc->_beginning.get_value();
                    if(itc->_end>Info::Entity::x_max)Info::Entity::x_max=itc->_end.get_value();
                    _intervalsOfContainer.push_back(itc);
            }
        }

        ar & _extra_fields;
        new(&l) Container(_name,_creation_time, const_cast<ContainerType*>(_type), _parent,*_extra_fields);
        l.set_intervalsOfContainer(&_intervalsOfContainer);

        ar & _children;
        ::Container::VectorIt it = _children->begin();
        ::Container::VectorIt it_end = _children->end();
        for (; it != it_end; it++){
            l.add_child(*it);
        }

    }

    #endif
