/***************************** 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 *************************************/

#pragma once

#include "MvFwd.h"
#include "MvRequest.h"
#include "MagicsObserver.h"

class MvStopWatch;

class PlotMod : protected magics::MagicsObserver
{
public:
    // Access to singleton object
    static PlotMod& Instance();
    static void Instance(PlotMod*);

    PlotMod();
    ~PlotMod() override = default;

    // Returns running mode: true: interactive, false: batch
    bool IsInteractive() { return isInteractive_; }

    // Window mode functions
    bool IsWindow(const char*);                  // Check a given driver
    bool IsWindow() const { return isWindow_; }  // Inquire current status

    // Check/initialize request came from a Macro
    void CalledFromMacro(bool flag) { calledFromMacro_ = flag; }
    bool CalledFromMacro() { return calledFromMacro_; }
    bool CalledFirstFromMacro() { return calledFirstFromMacro_; }
    bool CalledFromMacro(MvRequest&);

    // Output Format methods
    MvRequest OutputFormatInfo();         // Get output info
    MvRequest OutputFormat();             // Get request
    MvRequest MakeDefaultOutputFormat();  // Get default
    void OutputFormat(MvRequest&);        // Initialize
    const char* Destination()             // "SCREEN","PRINTER","PREVIEW"
    {
        return plotDestination_.c_str();
    }
    const char* PrinterName()  // name of the printer
    {
        return printerName_.c_str();
    }

    bool isMagicsErrorIgnored() const { return magicsErrorIgnored_; }
    bool setMagicsErrorIgnored(bool b)
    {
        auto prev = magicsErrorIgnored_;
        magicsErrorIgnored_ = b;
        return prev;
    }

    // Timing methods
    void watchStart(const char*);    // Starts and names the session
    void watchLaptime(const char*);  // Prints the laptime since the previous call to
                                     // watchLaptime() or from watchStart()
    void watchStop();                // Stops and prints a report

    virtual std::string currentWorkDir() const { return {}; }
    virtual void addWeatherSymbol(const MvRequest&) = 0;

protected:
    // from MagicsObserver
    void warningMessage(const std::string&) override;
    void errorMessage(const std::string&) override;
    void infoMessage(const std::string&) override;
    void progressMessage(const std::string&) override {}

    bool isInteractive_{false};
    bool isWindow_{false};  // output on screen?
    bool magicsErrorIgnored_{false};
    MvRequest outFormat_;          // output format info
    std::string plotDestination_;  // "SCREEN","PRINTER","PREVIEW"."FILE"
    std::string printerName_;      // name of the printer
    MvStopWatch* watch_{nullptr};  // timing debug

    // If request came from a Macro then both variables are initialised to
    // true. In the interactive mode, after calling the ploting routine for
    // the first time, variable calledFromMacro_ is updated to false.
    // This is needed because uPlot should treat all the icons dropped
    // afterwards as interactive mode, instead of batch mode.
    bool calledFromMacro_{false};       // request came from Macro?
    bool calledFirstFromMacro_{false};  // request came from Macro?

    static PlotMod* plotModInstance_;
};
