/***************************** LICENSE START ***********************************

 Copyright 2012 ECMWF and INPE. This software is distributed under the terms
 of the Apache License version 2.0. In applying this license, ECMWF does not
 waive the privileges and immunities granted to it by virtue of its status as
 an Intergovernmental Organization or submit itself to any jurisdiction.

 ***************************** LICENSE END *************************************/

#ifndef MvApplication_DEFINED
#define MvApplication_DEFINED

#include <MvRequest.h>

//! Establishes communication with \c event module
/*! This class, together with MvService, form the basis
 *  of Metview Application C++ Framework.
 */

class MvApplication
{
    static MvApplication* app;
    static svc* Service;
    static boolean ProcessReplies;


public:
    //! The standard constructor
    /*! The standard constructor for a non X Window module. It gets the basic parameters
 *  from the configuration file and command line, registers the service \c name
 *  and starts the communication with \c event.
 */
    MvApplication(int& argc, char** argv, const char* name = NULL,
                  void* aparg = NULL, int nopt = 0, option* = NULL);


    static MvApplication& instance() { return *app; }

    void wantPreferences(const char* = NULL);

    //! Starts the module's main loop.
    virtual void run();

    virtual void newPreferences(const MvRequest&) {}
    virtual void addInputCallback(FILE*, inputproc, void*);

    static void setProcessReplies(boolean onOff) { ProcessReplies = onOff; }

    static MvRequest getPreferences(const char* = NULL);
    static MvRequest getExpandedPreferences(const char* = NULL);
    static void setPreferences(const MvRequest&, const char* = NULL);

    //! Sends request \c req to service \c name.
    static void callService(const char* name, const MvRequest& req, void* ref);

    static MvRequest waitService(const char*, const MvRequest&, int&);
    static void callFunction(const char*, const MvRequest&, void*);

    //! Broadcasts the message contained in request \c req.
    static void sendMessage(const MvRequest& req);

    static void recordOn(boolean = true);
    static void setFork(boolean);

    //! Defines the maximum time the module may stay in an idle state before being aborted.
    static void setExitTimeout(int minutes);

    static void destroyService() { destroy_service(Service); }
    static void setKeepAlive(boolean);
    static void setMaximum(int);
    static boolean stopAll(const char*, ...);
    static void notifyIconCreation(const char* icon_name, const char* icon_class);
    static void notifyIconModified(const char* icon_name, const char* icon_class);

    //! Returns the service structure created by the constructor.
    static svc* getService() { return Service; }


    static MvRequest poolFetch(const char* icon_name, const char* icon_class);
    static void poolStore(const char* icon_name, const char* icon_class,
                          const MvRequest&);

    static void poolLink(const char* name1, const char* name2);
};


#ifndef DOXYGEN_SHOULD_SKIP_THIS

//-- obsolete? PlotMod and uPlot use directly MvApplication::setKeepAlive()

class KeepAlive
{
    static int count_;

public:
    KeepAlive()
    {
        if (++count_ == 1)
            MvApplication::setKeepAlive(true);
    }
    ~KeepAlive()
    {
        if (--count_ == 0)
            MvApplication::setKeepAlive(false);
    }
};
#endif

#endif
