/***************************** 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:
//  Page
//
// .AUTHOR:
//  Gilberto Camara and Fernando Ii
//
// .SUMMARY:
//  Defines a concrete Page class for the page hierarchy in PlotMod.
//  The Page 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
//
#ifndef Page_H
#define Page_H

#include "Presentable.h"
#include "PlotModView.h"
#include "GraphicsEngine.h"
#include "PmProjection.h"
#include "DrawingPriority.h"
#include "ZoomStacks.h"
#include "MatchingInfo.h"

class Page : public Presentable {

public:

   // Constructors
   Page(MvRequest& pageRequest);
   Page(const Page&);
   virtual Presentable* Clone() const { return new Page(*this); }

   // Destructor
   ~Page();

   // Methods
   // Overriden from Presentable class

   // Return my name
   virtual string Name();

   virtual bool IsVisible()
      { return true; }

   // Draw me and all my children
   virtual void Draw ();

   //  draws the presentable
   virtual void DrawProlog ();

   // Draw page header
   virtual void DrawPageHeader ();

   // Register to draw trailer later
   virtual void RegisterDrawTrailer ();

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

   // Return the graphics engine (one per page)
   virtual GraphicsEngine& GetGraphicsEngine() const
      { return *engine_; }

   // Accept a visitor
   virtual void Visit ( Visitor& v );

#if 0
	virtual void DrawBackground ( Canvas& canvas, bool emptyBack = false );
	// Draw the background (ask my view to do it )
	// Obs: draws shared background, not to be used on PostScript

	virtual void DrawForeground ( Canvas& canvas, bool emptyFore = false );
	// Draw the foreground (ask my view to do it )
	// Obs: draws shared foreground, not to be used on PostScript

//D	virtual void DrawFrame ( Canvas& canvas );
	// Draw the frame (ask my view to do it )

	virtual void DrawNewPage ( Canvas& canvas );
	// Draw the frame (ask my view to do it )
#endif

	// Zoom request given a new location to be added to the stack
	//virtual void ZoomRequest ( const Location& zoomCoord );

	// Zoom request given an index from the stack
	virtual void ZoomRequest ( int izoom );

    // Zoom request given a string containing the zoom info
    virtual void ZoomRequest ( const string& zoomInfo );

	// Retrieve zoom information
	virtual void ZoomInfo(int& zoomNumberOfLevels, int& zoomCurrentLevel);

	// Replace the geographical area and plot the result
	//virtual void ReplaceArea ( const Location& zoomCoord, int zoom=-1 );

	// Generate a description of the page
	virtual void DescribeYourself ( ObjectInfo& );

#if 0
	virtual void NeedsRedrawing(bool yesno);
	// Sets all subpages to the same state (bool yesno) of page.

        virtual bool NeedsRedrawing();
	// Checks all subpages, returns true if one of then are true.
  
        virtual void RedrawIfWindow(int visdefId = 0);
        // Sets redrawing flags and does AddTask if needed.

	virtual void SetPageSize ( double top, double left, double bottom, double right );
	// Update Page's size
#endif

   virtual void ContentsDataUnit( int dataUnitId )
      { dataUnitId_ = dataUnitId; }

   virtual int ContentsDataUnit()
      { return  dataUnitId_; }

   virtual string MacroPlotIndexName(bool = true)
      { return myParent_->MacroPlotIndexName(true); }

   virtual void DropShouldStay( bool drop )
      { dropShouldStay_ = drop; }

   virtual bool DropShouldStay()
      { return  dropShouldStay_; }

   // Local methods
   // Insert a new data unit (used in response to a drop action)
   bool InsertDataUnit ( int, long, long, MatchingInfo&, int& );

   // Insert a new visdef ( used in response to a drop action )
   void InsertVisDef ( MvRequest&, MvIconList& );

   // Insert a new visdef that came from a drop in the Plot window.
   // If visdef was dropped alone, first check if it has already being in use.
   // If yes, replace it. If not, remove all the old visdefs and then applied
   // this new one.
   // If visdef was dropped together with a dataunit, add visdef to that dataunit.
   void InsertVisDefFromWindow ( MvRequest&, MvIconList& );

   // Insert visdefs to dataunit
   bool InsertVisDefToDataUnit (MvRequest&, MvIcon&);

   // Insert visdefs to the presentable
   void InsertVisDefToPresentable( MvRequest& );

   // Remove icon from tree structure
   virtual void RemoveIcon ( MvIcon& );

   // Remove all data icon from tree structure
   virtual void RemoveAllData ();

   // Create rows*columns subpages
   void CreateSubpages();

   ZoomStacks* GetZoomStacks()
      { return &zoomStacks_; }

   void InitZoomStacks()
      { zoomStacks_.ClearAll(); }

   // Remove Page relationships from the DataBase
   void RemovePageFromDataBase();

#if 0
	bool RemoveSubPage ( SubPage* );
	// Remove SubPage from SubPages list

	void UpdateChildList ();
	// Look for Subpages with no data, remove then if they are not visible

	int FirstVisible() const { return firstVisible_; }
	// Return number of first visible page ( for Scroll interface )
#endif

	// Return number of visible subpages
	int NumberOfVisible() { return visibleCount_; }

//	Location GetDrawingArea ()
//		{ return drawingArea_; }

//	void SetDrawingArea ( Location drawingArea )
//		{ drawingArea_ = drawingArea; }

//U	void EraseBackDraw ();
//U	void EraseForeDraw ();

	// Set/Get the projection associated to the canvas
	virtual void SetProjection ( const MvRequest& viewRequest );

	PmProjection* GetProjection ()
		{ return ( projection_.get() ); }

	// Return TRUE if there is a projection associated to the page
	bool HasProjection ()
		{ return (projection_.get() != NULL); }

	// Return TRUE if zooming is allowed for this projection
	bool CanDoZoom ();

	void SetDrawPriority( MvRequest& drawPriorRequest )
		{ drawingPriority_.SetPriority ( drawPriorRequest ); }

	DrawingPriority& GetDrawPriority ()
		{ return drawingPriority_; }

	virtual PlotModView& GetView() const
		{ return *myView_; }

   void SetView(auto_ptr<PlotModView>& newView)
      { myView_ = newView; } 

	int FirstPrintable ();

	virtual int PaperPageNumber ( int );

	// return list of canvas used by Page children
//	virtual CanvasList GetCanvases();

	// Return pointer to the canvas associated to the first device with the fewest
	//  number of canvas. Also returns the associated subpage request.
	Canvas* GetNextCanvas(MvRequest& subpageReq);

	// Remove from child list
	bool RemovePresentable ( Presentable* );

#if 0
	virtual void InputCoordinates ( const Location& , int );

	// Call the ToolPlus point script
	virtual void ExecuteToolPlusPointScript ( const Location& );

	// Call the ToolPlus area script
	virtual void ExecuteToolPlusAreaScript ( const Location& );

	virtual void SetInputPresentableId ( int presID )
		{ myParent_->SetInputPresentableId ( presID ); }

	virtual MvRequest& Request();
	// Returns a reference to the object's associated request

        virtual list<bool> ReadyChilds();

	virtual void PrintInfo();

	virtual void  StartMapEditor();
	// Initiate a map editor

	virtual void SaveView();
	// Save View in the disk.
#endif

   bool CheckValidVisDef( MvIcon&, MvRequest&, MvIconList& );

   // Dealing with Drop
   virtual void DropSimulate ( PmContext& context );

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

   // Update View structure
   virtual void UpdateView( const MvRequest& );

protected:

   //Update certain data units for the new area
   virtual void UpdateDataForZoom( const string& zoomInfo);

private:

   // No copy allowed
   Page& operator=(const Page&);

   // Members
   auto_ptr <PlotModView> myView_;

   auto_ptr <GraphicsEngine> engine_;

   int firstVisible_;
   int visibleCount_;
   int dataUnitId_;

   ZoomStacks zoomStacks_;

   bool dropShouldStay_;

   auto_ptr <PmProjection> projection_;  // projection associated with page
   DrawingPriority drawingPriority_;
};

#endif
