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

//
// .NAME:
//  SuperPage
//
// .AUTHOR:
//  Gilberto Camara and Fernando Ii
//
// .SUMMARY:
//  Defines a concrete SuperPage class for the page hierarchy in PlotMod.
//  The SuperPage class is an example a Component class
//  of the Composite "pattern".
//
//  Its methods allow for the insertion and removal of nodes and
//  on a tree structure, and also for the drawing method.
//
//
// .DESCRIPTION:
//  Refer to the "Design Patterns" book, page 163 for more details
//
//
// .DESCENDENT:
//
//
// .RELATED:
//  PlotMod, DataObject, SubPage, Text, Legend
//  Builder, Visitor, Device, DataUnit
//
// .ASCENDENT:
//  Presentable
//

#pragma once

#include <memory>

#include "Device.h"
#include "Preferences.h"
#include "Presentable.h"

#ifndef NOMETVIEW_QT
class uPlotBase;
#endif

class SuperPage : public Presentable
{
public:
    // Constructors
    SuperPage(const MvRequest& inRequest);
    SuperPage(const SuperPage&);

    Presentable* Clone() const override { return new SuperPage(*this); }

    // Destructor
    ~SuperPage() override;

    // Methods
    // Overriden from Presentable class

    // Create a reply request for creation
    void CreateReply(MvRequest& replyRequest) override;

    // Respond to a drop action
    void Drop(PmContext& context) override;

    // Set print option: All subpages or visible ones only
    void PrintAllV1(bool) override;
    bool PrintAll() override;

    // Return my Name
    std::string Name() override;

    //	virtual Cached SuperPageName()
    //		{ return this->Name(); }

    std::string MacroPlotIndexName(bool useIndex = false) override;

    // Returns a pointer to the icon data base
    MvIconDataBase& IconDataBase() const override
    {
        return *(iconDataBase_.get());
    }

    //	virtual void    Close();
    // Close all objects associated with the SuperPage

    void RemoveAllData() override
    {
        RemoveAllDataChildren();
    }

    void Draw() override;
    // Draws the superpage and all its children

    void DrawProlog() override;
    void DrawTrailerWithReq(MvRequest&) override;

    bool IsVisible() override { return true; }

    // Implements the visitor pattern
    void Visit(Visitor& v) override;

    // Returns the device associated to the superpage
    virtual Device& GetDevice() const
    {
        return *myDevice_;
    }

    // Creates the device for the superpage
    virtual void SetDeviceInfo(const MvRequest&);
    virtual void SetDeviceInfo();

    // Indicates the size of the superpage
    PaperSize GetMySize() override;

    // Retrieve all requests for the whole tree.
    // The requests have already been built and saved internally, but
    // they are not updated automatically if the layers
    // visibility/order/transparency are modified by the uPlot Sidebar.
    // Boolean checkIconStatus = false means use the saved requests;
    // otherwise, rebuild the requests by analysing the whole tree.
    void GetAllRequests(MvRequest&, bool checkIconStatus = false) override;

    // Rebuild the request by analisying the icon features: order,
    // visibility and transparency.
    void SortRequest(MvRequest&, MvRequest&, bool save_layer = true);

    // Generate a description of the superpage's device
    virtual void DescribeDevice(ObjectInfo& myDescription);

    // Generate a description of the superpage
    void DescribeYourself(ObjectInfo& myDescription) override;

    // Insert Visdef in the database
    void InsertVisDef(MvRequest&, bool);

    // Call EraseDraw for all children
    //   virtual void EraseDraw ( int visdefId = 0 );

    //	virtual void UpdateWidget ( MvRequest& inRequest, const int treeNodeId, int& newTreeNodeId );
    // Update SuperPage Widget

    // Retrieve Text lists: title and annotation
    // If there is no Text Title here, search up the tree (i.e the Root).
    // If there is no Text Annotation, do not need to search up the tree,
    // because this type of icon is not mandatory to have.
    bool RetrieveTextTitle(MvIconList&) override;
    void RetrieveTextAnnotation(MvIconList&) override;

    // Retrieve the Legend
    // If failed, retrieves the root's Legend (default)
    bool RetrieveLegend(MvIcon&) override;

    // Zoom methods
    // virtual void ZoomRequest ( int id, const Location& zoomCoord );
    void ZoomRequestByDef(int id, const std::string&) override;
    void ZoomRequestByLevel(int id, int izoom) override;

    // Layer methods
    bool UpdateLayerTransparency(int, int) override;
    bool UpdateLayerVisibility(int, bool) override;
    bool UpdateLayerStackingOrder(int, int) override;

    // --  Internal methods

    //	void  SetMacroType ( MacroType type )
    //		{ macroType_ = type; }
    // Indicates what is the type of macro

    //	void  SetZoomPageId ( int id )
    //		{ zoomPageId_ = id; }

    // Generate a new macro file based on the plot displayed on the screen
    void GenerateMacro() override;

    // Provide a list of the names of the pages
    std::string ListMyPages();

    //	void PrintingFinished ( MvRequest& );
    // Complete the printing job - tell the user

    //	void SaveInFile();
    // Save the contents of the superpage in a file

    void PendingDrawingsAdd() override
    {
        pendingDrawings_++;
    }

    void PendingDrawingsRemove() override
    {
        pendingDrawings_--;
    }

    //	virtual bool DrawingIsFinished()
    //		{ return  (  pendingDrawings_ == 0 ) &&
    //			  (  hasNewpage_  == true  ); }

    // Returns the number of SuperPages for this SuperPage
    int PageIndex() override
    {
        return superPageIndex_;
    }

    // Returns the number of paper pages
    int PaperPageIndex() const override
    {
        return paperPageIndex_;
    }

    // Sets the number of paper pages
    void PaperPageIndexV1(int paperPageIndex) override
    {
        paperPageIndex_ = paperPageIndex;
    }

    // Increments and returns the number of pictures printed
    virtual int IncrementPrintIndex();

    //        virtual void NeedsRedrawing ( bool yesno );

    //        virtual bool NeedsRedrawing ();

    //        virtual void RedrawIfWindow(int visdefId = 0);
    // Sets redrawing flags and does AddTask if needed.

    void RemoveIcon(MvIcon&) override;

    //	virtual void SetInputPresentableId ( int );

    //	virtual void SetBackgroundDraw ( bool );

    //	virtual bool GetBackgroundDraw ()
    //		{ return backDrawEnabled_; }

    //	virtual void PrintInfo ();

    // Dealing with Export plotting
    // Save a copy of the plotting. Set sync to true to make sure
    // that the file will be created before returning to the caller.
    bool ExportPlot(MvRequest*, bool sync = false) override;

    // Get the appropriate requests from the Display Window to
    // be used by ecCharts
    MvRequest ExportToEcCharts() override;

    // Dealing with Print plotting
    // Recreate the plotting and send it to a given printer
    void PrintFile(MvRequest&) override;

    // Insert one Page
    Page* InsertOnePage(MvRequest&) override;
    void InsertOnePageV1(Page*);

    // Dealing with Contents tools
    void contentsRequest(MvRequest&) override;

#ifndef NOMETVIEW_QT
    static void setPlotApplication(uPlotBase* pa)
    {
        plotApplication_ = pa;
    }

#ifdef METVIEW_WEATHER_ROOM
    void plotWeatherRoom(bool checkSync = false);
#endif

#endif

private:
    // Copy Constructor and Operator=
    SuperPage& operator=(const SuperPage&);

    void InsertOnePageInner(Page*);

    // Members
    PaperSize size_;                                // size of superpage in paper coords (cms)
    std::string macroFileName_;                     // name of the macro file which is produced
    std::unique_ptr<MvIconDataBase> iconDataBase_;  // icon data base (one per superpage)
    std::unique_ptr<Device> myDevice_;              // device (plot media)
    Preferences preferences_;                       // preferences associated to the superpage

    int pageIndex_;  // number of pages used in Macro generation

    int superPageIndex_;  // number of Super Pages for this SuperPage,
                          // incremented when receives New Page in a macro
    int paperPageIndex_;  // number of paper pages used for this SuperPage

    //	bool			  backDrawEnabled_; // true if background drawing is enabled

    static int nrSuperPages_;  // Total number of superpages currently active;
    int printIndex_;           // Number of pictures printed

#ifndef NOMETVIEW_QT
    static uPlotBase* plotApplication_;
#endif
};
