// src/xml_serializer_factory.hh - Copyright 2005, 2006, University
//               of Padova, dept. of Pure and Applied
//               Mathematics
//
// This file is part of SGPEMv2.
//
// This is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// SGPEMv2 is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with SGPEMv2; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

#ifndef XML_SERIALIZER_FACTORY_HH
#define XML_SERIALIZER_FACTORY_HH 1

#include "config.h"
#include <sgpemv2/history.hh>
#include <sgpemv2/environment.hh>
#include <sgpemv2/serializer_error.hh>

#include <glibmm/ustring.h>
#include <map>

namespace sgpem
{
  class History;
  class Resource;
  class Process;
  class Thread;
  class Request;
  class SubRequest;
}

namespace sgpem
{
  class XMLSerializerFactory;
  /**
    \brief Creates objects given their class name and an array of their properties
    
    Resources should come first in deserialization, so save pointers to new objects to a backend::Resource into a std::map<Glib::ustring,backend::Resource*>. This will come really handy when deserializing Requests.
   */
  class XMLSerializerFactory
  {
  public:
    typedef std::map<Glib::ustring, Glib::ustring> Parameters;

    /**
      \brief Contructor takes an history as readed data destination
     */
    XMLSerializerFactory(History& hist);

    /**
      \brief A destructor, nothing else
     */
    ~XMLSerializerFactory();

    /**
      \return The data destination history associated with this factory
     */
    History* get_history();


    /**
      \brief Creates objects from their name plus parameters
      
      This method recognizes a class type and calls the appropriate
      creator method, which must also take care of inserting the
      new object in its right container, if necessary.
      
      \throw SerializerError If not all necessary parameters for an object creation are provided
     */
    void factory_method(const Glib::ustring& class_name, Parameters& parameters) throw(SerializerError);
  protected:
  private:
    typedef Environment::resource_key_t      resource_key_t;
    // associate old keys with new ones
    typedef std::map<resource_key_t, resource_key_t> TempMap;

    /**
      Resource factory from given parameters
     */
    History::ResourcePair create_resource(Parameters& parameters);

    /**
      Process factory from given parameters
     */
    Process& create_process(Parameters& parameters);

    /**
      Thread factory from given parameters
     */
    Thread& create_thread(Parameters& parameters);

    /**
      Request factory from given parameters
     */
    Request& create_request(Parameters& parameters);

    /**
      \throw A SerializerError if there's no existing associated resource
      for a given ID parameter (it means the savefile is corrupted).
     */
    SubRequest& create_subrequest(Parameters& parameters);

    // history object to add to resources processes etc...
    History* _hist;

    // memory of last objects to link to
    Process* _last_process;
    Thread*  _last_thread;
    Request* _last_request;

    // take association with old keys an new keys
    // to reslove sub requests
    TempMap _temp_map;
  };
}

#endif
