//
// .NAME:
//  GenAppService
//
// .AUTHOR:
//  Gilberto Camara, Baudoin Raoult and Fernando Ii
//     ECMWF, December 1997
//
// .SUMMARY:
//  Describes the GenAppService class, which handles
//  the communication with GenApp for the purposes of
//  user interface definitions.
//
//  PlotMod delegates all interface definition (such
//  as Printer Setup and Preferences) to GenApp, which
//  already has the facilities for creating menus.
//
//  This is a "singleton" class.
//
// .CLIENTS:
//  SuperPage, as called by the main menu (SuperPageWidget)
//
// .RESPONSABILITY:
//  This class will provide support for the communication
//  with GenApp for the purposes of user interface definitions
//
//  Each new object of this class will, on its constructor:
//  - create a GenApp "EDIT, DEFINITION" request
//    which will allow GenApp to edit this definition
//  - store a copy of a callback procedure to be called
//  - call GenApp (using the MvServiceTask facilities)
//
//  When the "endofTask" function is returned by "event",
//  the object will perform the callback action
//
//
// .COLLABORATORS:
//  MvServiceTask, GenApp
//
// .ASCENDENT:
//  MvClient
//
// .DESCENDENT:
//
//
// .REFERENCES:
//  This class is based on the general facilities for
//  process communication used in METVIEW, especially the
//  MvClient and MvServiceTask facilities. Please refer
//  to these classes (or have a chat with Baudoin) for
//  more information.
//
//  This class implements a "singleton" as suggested
//  by Myers, "More Effective C+", page 130.
//

#pragma once

#include "MvServiceTask.h"
#include "MvTask.h"
#include "MvCallback.hpp"

#include <map>

// allows more than one request to GenApp simultaneously
typedef std::map<MvServiceTask*, MvCallbackBase*> CallbackMap;

class GenAppService : public MvClient
{
public:
    static GenAppService& Instance();
    // access to class singleton

    // -- Destructor

    ~GenAppService();

    // -- Methods

    virtual void endOfTask(MvTask*);
    // perform actions after receiving response from GenApp

    bool CallGenApp(MvCallbackBase*, MvRequest&);
    // call GenApp to perform editing actions

private:
    // -- Constructors

    GenAppService();  // no external access point

    CallbackMap callbackMap_;
    // contains for each task the related callback
};


// -- CallGenAppService
//
//    external function called by the PlotMod classes
//    to ask GenApp to edit a request
//
//    INPUT : An object,
//            a callback procedure
//            an input request
//
//    NOTE:   The request verb MUST exist on the object list

template <class T>
bool CallGenAppService(T& object,
                       void (T::*proc)(MvRequest&),
                       MvRequest& request)
{
    bool result = GenAppService::Instance().CallGenApp(new MvCallback<T>(object, proc), request);

    return result;
}
