
/***************************************************************************
 *
 * Project:  OpenCPN
 * Purpose:  Chart Canvas
 * Author:   David Register
 *
 ***************************************************************************
 *   Copyright (C) 2010 by David S. Register                               *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,  USA.         *
 **************************************************************************/

#ifndef __CHCANV_H__
#define __CHCANV_H__

#include "bbox.h"

#include <wx/datetime.h>
#include <wx/treectrl.h>
#include "wx/dirctrl.h"
#include <wx/sound.h>
#include <wx/grid.h>
#include <wx/wxhtml.h>

#include "chart1.h"                 // for enum types
#include "ocpndc.h"
#include "undo.h"

#include "ocpCursor.h"
#include "GoToPositionDialog.h"
#include "DetailSlider.h"
#include "RolloverWin.h"
#include "timers.h"
#include "emboss_data.h"
#include "S57Sector.h"
#include "gshhs.h"

class wxGLContext;
class GSHHSChart;
class IDX_entry;
class ocpnCompass;

//    Useful static routines
void ShowAISTargetQueryDialog(wxWindow *parent, int mmsi);

//--------------------------------------------------------
//    Screen Brightness Control Support Routines
//
//--------------------------------------------------------

int InitScreenBrightness(void);
int RestoreScreenBrightness(void);
int SetScreenBrightness(int brightness);


//    Set up the preferred quilt type
#define QUILT_TYPE_2

//----------------------------------------------------------------------------
//    Forward Declarations
//----------------------------------------------------------------------------
      class Route;
      class TCWin;
      class RoutePoint;
      class SelectItem;
      class wxBoundingBox;
      class ocpnBitmap;
      class WVSChart;
      class MyFrame;
      class ChartBaseBSB;
      class ChartBase;
      class AIS_Target_Data;
      class S57ObjectTree;
      class S57ObjectDesc;
      class RolloverWin;
      class Quilt;
      class PixelCache;
      class ChInfoWin;
      class glChartCanvas;
      class CanvasMenuHandler;
      class ChartStack;
      class Piano;
      class canvasConfig;
      class MUIBar;

enum                                //  specify the render behaviour of SetViewPoint()
{
    CURRENT_RENDER,                 // use the current render type
    FORCE_SUBSAMPLE                 // force sub-sampled render, with re-render timer
};

//          Cursor region enumerator
enum
{
      CENTER,
      MID_RIGHT,
      MID_LEFT,
      MID_TOP,
      MID_BOT,
};

typedef enum ownship_state_t
{
      SHIP_NORMAL        = 0,
      SHIP_LOWACCURACY,
      SHIP_INVALID
}_ownship_state_t;

enum {
      ID_S57QUERYTREECTRL =            10000,
      ID_AISDIALOGOK
};

enum {
    ID_PIANO_DISABLE_QUILT_CHART = 32000, ID_PIANO_ENABLE_QUILT_CHART
};

enum {
    NORTH_UP_MODE,
    COURSE_UP_MODE,
    HEAD_UP_MODE
};

//----------------------------------------------------------------------------
// ChartCanvas
//----------------------------------------------------------------------------
class ChartCanvas: public wxWindow
{
     friend class glChartCanvas;
public:
      ChartCanvas(wxFrame *frame, int canvasIndex);
      ~ChartCanvas();

      void SetupGlCanvas( );

      //    Methods
      void OnKeyDown(wxKeyEvent &event);
      void OnKeyUp(wxKeyEvent &event);
      void OnKeyChar(wxKeyEvent &event);
      void OnPaint(wxPaintEvent& event);
      void PaintCleanup();
      void Scroll(int dx, int dy);
      void OnToolLeftClick( wxCommandEvent& event );
      
      bool MouseEventOverlayWindows( wxMouseEvent& event );
      bool MouseEventChartBar( wxMouseEvent& event );
      bool MouseEventSetup( wxMouseEvent& event, bool b_handle_dclick = true );
      bool MouseEventProcessObjects( wxMouseEvent& event );
      bool MouseEventProcessCanvas( wxMouseEvent& event );
      void SetCanvasCursor( wxMouseEvent& event );
      void OnKillFocus( wxFocusEvent& WXUNUSED(event) );
      void OnSetFocus( wxFocusEvent& WXUNUSED(event) );
      
      void PopupMenuHandler(wxCommandEvent& event);
      bool IsPrimaryCanvas(){ return (m_canvasIndex == 0); }
      
      bool SetUserOwnship();
      
      double GetCanvasRangeMeters();
      void SetCanvasRangeMeters( double range );
      
      void EnablePaint(bool b_enable);
      virtual bool SetCursor(const wxCursor &c);
      virtual void Refresh( bool eraseBackground = true, const wxRect *rect = (const wxRect *) NULL );
      virtual void Update();

      void LostMouseCapture(wxMouseCaptureLostEvent& event);
      
      void CancelMouseRoute();
      void SetDisplaySizeMM( double size );
      double GetDisplaySizeMM(){ return m_display_size_mm; }
      
      bool SetVPScale(double sc, bool b_refresh = true);
      bool SetVPProjection(int projection);
      bool SetViewPoint ( double lat, double lon);
      bool SetViewPointByCorners( double latSW, double lonSW, double latNE, double lonNE );
      bool SetViewPoint(double lat, double lon, double scale_ppm, double skew, double rotation,
                        int projection = 0, bool b_adjust = true, bool b_refresh = true);
      void ReloadVP ( bool b_adjust = true );
      void LoadVP ( ViewPort &vp, bool b_adjust = true );

      ChartStack *GetpCurrentStack(){ return m_pCurrentStack; }
      void SetGroupIndex( int index, bool autoswitch = false );
      bool CheckGroup( int igroup );
      void canvasRefreshGroupIndex( void );
      void canvasChartsRefresh( int dbi_hint );
      
      void CheckGroupValid( bool showMessage = true, bool switchGroup0 = true);

      void UpdateCanvasS52PLIBConfig();
      
      void TriggerDeferredFocus();
      void OnDeferredFocusTimerEvent( wxTimerEvent &event);
      void OnRouteFinishTimerEvent( wxTimerEvent& event );

      void ClearS52PLIBStateHash(){ m_s52StateHash = 0; }
      void SetupCanvasQuiltMode( void );
      void ApplyCanvasConfig(canvasConfig *pcc);
      
      void SetVPRotation(double angle){ VPoint.rotation = angle; }
      double GetVPRotation(void) { return GetVP().rotation; }
      double GetVPSkew(void) { return GetVP().skew; }
      double GetVPTilt(void) { return GetVP().tilt; }
      void ClearbFollow(void);
      void SetbFollow(void);
      void TogglebFollow( void );
      void JumpToPosition( double lat, double lon, double scale );
      void SetFirstAuto( bool b_auto ){m_bFirstAuto = b_auto; }
      
      void GetDoubleCanvasPointPix(double rlat, double rlon, wxPoint2DDouble *r);
      void GetDoubleCanvasPointPixVP( ViewPort &vp, double rlat, double rlon, wxPoint2DDouble *r );
      bool GetCanvasPointPix( double rlat, double rlon, wxPoint *r );
      bool GetCanvasPointPixVP( ViewPort &vp, double rlat, double rlon, wxPoint *r );
      
      void GetCanvasPixPoint(double x, double y, double &lat, double &lon);
      void WarpPointerDeferred(int x, int y);
      void UpdateShips();
      void UpdateAIS();
      void UpdateAlerts();                          // pjotrc 2010.02.22

      bool IsMeasureActive(){ return m_bMeasure_Active; }
      wxBitmap &GetTideBitmap(){ return m_cTideBitmap; }
      
      void UnlockQuilt();
      void SetQuiltMode(bool b_quilt);
      bool GetQuiltMode(void);
      std::vector<int> GetQuiltIndexArray(void);
      bool IsQuiltDelta(void);
      void SetQuiltChartHiLiteIndex(int dbIndex);
      int GetQuiltReferenceChartIndex(void);
      double GetBestStartScale(int dbi_hint, const ViewPort &vp);
      void ConfigureChartBar();
      
      int GetNextContextMenuId();

      TCWin *getTCWin(){ return pCwin; }
      
      bool StartTimedMovement( bool stoptimer=true );
      void DoTimedMovement( );
      void DoMovement( long dt );
      void StopMovement( );

      void SetColorScheme(ColorScheme cs);
      ColorScheme GetColorScheme(){ return m_cs;}

      void CanvasApplyLocale();

      //    Accessors
      int GetCanvasWidth(){ return m_canvas_width;}
      int GetCanvasHeight(){ return m_canvas_height;}
      float GetVPScale(){return GetVP().view_scale_ppm;}
      float GetVPChartScale(){return GetVP().chart_scale;}
      double GetCanvasScaleFactor(){return m_canvas_scale_factor;}
      double GetCanvasTrueScale(){return m_true_scale_ppm;}
      double GetAbsoluteMinScalePpm(){ return m_absolute_min_scale_ppm; }
      ViewPort &GetVP();
      ViewPort *GetpVP(){ return &VPoint; }
      void SetVP(ViewPort &);
      ChartBase* GetChartAtCursor();
      ChartBase* GetOverlayChartAtCursor();
      Piano *GetPiano(){ return m_Piano; }
      int GetPianoHeight();
      
      bool isRouteEditing( void ){ return m_bRouteEditing && m_pRoutePointEditTarget; }
      bool isMarkEditing( void ){ return m_bMarkEditing && m_pRoutePointEditTarget; }
      
      GSHHSChart* GetWorldBackgroundChart() { return pWorldBackgroundChart; }
      void ResetWorldBackgroundChart() { pWorldBackgroundChart->Reset(); }

      void  SetbTCUpdate(bool f){ m_bTCupdate = f;}
      bool  GetbTCUpdate(){ return m_bTCupdate;}
      void  SetbShowCurrent(bool f){ m_bShowCurrent = f;}
      bool  GetbShowCurrent(){ return m_bShowCurrent;}
      void  SetbShowTide(bool f){ m_bShowTide = f;}
      bool  GetbShowTide(){ return m_bShowTide;}
      double GetPixPerMM(){ return m_pix_per_mm;}

      void SetOwnShipState(ownship_state_t state){ m_ownship_state = state;}
      void SetCursorStatus( double cursor_lat, double cursor_lon );
      void GetCursorLatLon(double *lat, double *lon);

      bool PanCanvas(double dx, double dy);
      void StopAutoPan(void);

      void ZoomCanvas(double factor, bool can_zoom_to_cursor=true, bool stoptimer=true );
      void ZoomCanvasSimple(double factor);
      void DoZoomCanvas(double factor,  bool can_zoom_to_cursor = true);

      void RotateCanvas( double dir );
      void DoRotateCanvas( double rotation );
      void DoTiltCanvas( double tilt );

      void ShowAISTargetList(void);

      void ShowGoToPosition(void);
      void HideGlobalToolbar();
      void ShowGlobalToolbar();

      ChartBase *GetLargestScaleQuiltChart();
      ChartBase *GetFirstQuiltChart();
      ChartBase *GetNextQuiltChart();
      int GetQuiltChartCount();
      void InvalidateAllQuiltPatchs(void);
      void SetQuiltRefChart(int dbIndex);
      std::vector<int> GetQuiltCandidatedbIndexArray(bool flag1 = true, bool flag2 = true);
      std::vector<int> GetQuiltExtendedStackdbIndexArray();
      std::vector<int> GetQuiltEclipsedStackdbIndexArray();
      int GetQuiltRefChartdbIndex(void);
      void InvalidateQuilt(void);
      double GetQuiltMaxErrorFactor();
      bool IsChartQuiltableRef(int db_index);
      bool IsChartLargeEnoughToRender( ChartBase* chart, ViewPort& vp );
      int GetCanvasChartNativeScale();
      int FindClosestCanvasChartdbIndex(int scale);
      void UpdateCanvasOnGroupChange(void);
      void SetUpMode( int mode);
      void ToggleLookahead( );
      void SetShowGPS( bool show );
 
      void ShowObjectQueryWindow( int x, int y, float zlat, float zlon);
      void ShowMarkPropertiesDialog( RoutePoint* markPoint );
      void ShowRoutePropertiesDialog(wxString title, Route* selected);
      void ShowTrackPropertiesDialog( Track* selected );
      void DrawTCWindow(int x, int y, void *pIDX);
      
      void UpdateGPSCompassStatusBox( bool b_force_new );
      ocpnCompass *GetCompass(){ return m_Compass; }
      
      wxColour GetFogColor(){ return m_fog_color; }      
      
      void ShowChartInfoWindow(int x, int dbIndex);
      void HideChartInfoWindow(void);
    
      void StartMeasureRoute();
      void CancelMeasureRoute();

      bool DoCanvasUpdate( void );
      void SelectQuiltRefdbChart( int db_index, bool b_autoscale = true );
      void SelectQuiltRefChart( int selected_index );
      double GetBestVPScale( ChartBase *pchart );
      void selectCanvasChartDisplay( int type, int family);
      void RemoveChartFromQuilt( int dbIndex );
      
      void HandlePianoClick( int selected_index, int selected_dbIndex );
      void HandlePianoRClick( int x, int y, int selected_index, int selected_dbIndex );
      void HandlePianoRollover( int selected_index, int selected_dbIndex );
      void UpdateCanvasControlBar( void );
      void FormatPianoKeys( void );
      void PianoPopupMenu ( int x, int y, int selected_index, int selected_dbIndex );
      void OnPianoMenuDisableChart(wxCommandEvent& event);
      void OnPianoMenuEnableChart(wxCommandEvent& event);
      bool IsPianoContextMenuActive(){ return m_piano_ctx_menu != 0; }
      void SetCanvasToolbarItemState( int tool_id, bool state );
      bool DoCanvasCOGSet( void );
      void UpdateFollowButtonState( void );
      void ApplyGlobalSettings();
      void SetShowGPSCompassWindow( bool bshow );

      void FreezePiano(){ m_pianoFrozen = true; }
      void ThawPiano(){ m_pianoFrozen = false; }

      //Todo build more accessors
      bool        m_bFollow;
      wxCursor    *pCursorPencil;
      wxCursor    *pCursorArrow;
      wxCursor    *pCursorCross;
      wxCursor    *pPlugIn_Cursor;
      TCWin       *pCwin;
      wxBitmap    *pscratch_bm;
      bool        m_brepaint_piano;
      double      m_cursor_lon, m_cursor_lat;
      Undo        *undo;
      wxPoint     r_rband;
      double      m_prev_rlat;
      double      m_prev_rlon;
      RoutePoint  *m_prev_pMousePoint;
      Quilt       *m_pQuilt;
      bool        m_bShowNavobjects;
      int         m_canvasIndex;
      int         m_groupIndex;
      int          m_routeState;
      ChartBase   *m_singleChart;
      int         m_upMode;
      bool        m_bLookAhead;
      double      m_VPRotate;
      
      void DrawBlinkObjects( void );

      void StartRoute(void);
      void FinishRoute(void);
      
      void InvalidateGL();
      
#ifdef ocpnUSE_GL
      glChartCanvas *GetglCanvas(){ return m_glcc; }
#endif      

      void JaggyCircle(ocpnDC &dc, wxPen pen, int x, int y, int radius);
      
      bool CheckEdgePan( int x, int y, bool bdragging, int margin, int delta );

      Route       *m_pMouseRoute;
      bool        m_FinishRouteOnKillFocus;
      bool        m_bMeasure_Active;
      bool        m_bMeasure_DistCircle;
      wxString    m_active_upload_port;
      bool        m_bAppendingRoute;
      int         m_nMeasureState;
      Route       *m_pMeasureRoute;
      MyFrame     *parent_frame;
      wxString    FindValidUploadPort();
      CanvasMenuHandler  *m_canvasMenu;
      int GetMinAvailableGshhgQuality() { return pWorldBackgroundChart->GetMinAvailableQuality(); }
      int GetMaxAvailableGshhgQuality() { return pWorldBackgroundChart->GetMaxAvailableQuality(); }
      Route  *GetSelectedRoute() const { return m_pSelectedRoute; }
      Track  *GetSelectedTrack() const { return m_pSelectedTrack; }
      RoutePoint  *GetSelectedRoutePoint() const { return m_pFoundRoutePoint; }

      ocpnFloatingToolbarDialog *RequestNewCanvasToolbar(bool bforcenew = true);
      void UpdateToolbarColorScheme( ColorScheme cs );
      void SetAISCanvasDisplayStyle(int StyleIndx);
      void TouchAISToolActive( void );
      void UpdateAISTBTool( void );
      void SetToolbarScaleFactor( double scale_factor){ m_toolbar_scalefactor = scale_factor; }
      ocpnFloatingToolbarDialog *GetToolbar(){ return m_toolBar; }
      void SetToolbarConfigString( wxString& config){ m_toolbarConfig = config; }
      wxString GetToolbarConfigString(){ return m_toolbarConfig; }
      
      void SetToolbarPosition( wxPoint position );
      wxPoint GetToolbarPosition();
      void SetToolbarOrientation( long orient );
      long GetToolbarOrientation();
      
      void SubmergeToolbar(void);
      void SurfaceToolbar(void);
      void ToggleToolbar( bool b_smooth = false );
      bool IsToolbarShown();
      void DestroyToolbar();
      
      void SelectChartFromStack(int index,  bool bDir = false,  ChartTypeEnum New_Type = CHART_TYPE_DONTCARE, ChartFamilyEnum New_Family = CHART_FAMILY_DONTCARE);
      void SelectdbChart( int dbindex );
      
      void ShowTides(bool bShow);
      void ShowCurrents(bool bShow);
      
      void DoCanvasStackDelta( int direction );

      void ProcessNewGUIScale();
      
      bool GetShowDepthUnits(){ return m_bShowDepthUnits; }
      void SetShowDepthUnits( bool show ){ m_bShowDepthUnits = show; }
      bool GetShowGrid(){ return m_bDisplayGrid; }
      void SetShowGrid( bool show ){ m_bDisplayGrid = show; }
      bool GetShowOutlines(){ return m_bShowOutlines; }
      void SetShowOutlines( bool show ){ m_bShowOutlines = show; }
      bool GetShowChartbar(){ return true; }
      bool GetToolbarEnable(){ return m_bToolbarEnable; }
      void SetToolbarEnable( bool show );
      wxRect GetMUIBarRect();
      void SetMUIBarPosition();
      void DestroyMuiBar();
      void CreateMUIBar();
      
      
      void ToggleChartOutlines(void);
      void ToggleCanvasQuiltMode( void );
      
      wxString GetScaleText(){ return m_scaleText; }
      double GetScaleValue(){ return m_scaleValue; }
      
      bool        m_b_paint_enable;

      bool GetShowENCText(){ return m_encShowText; }
      void SetShowENCText( bool show );
      
      bool GetShowENCDepth(){ return m_encShowDepth; }
      void SetShowENCDepth( bool show );
      
      bool GetShowENCLightDesc(){ return m_encShowLightDesc; }
      void SetShowENCLightDesc( bool show );
      
      bool GetShowENCBuoyLabels(){ return m_encShowBuoyLabels; }
      void SetShowENCBuoyLabels( bool show );

      bool GetShowENCLights(){ return m_encShowLights; }
      void SetShowENCLights( bool show );
      
      int GetENCDisplayCategory(){ return m_encDisplayCategory; }
      void SetENCDisplayCategory( int category );

      bool GetShowENCAnchor(){ return m_encShowAnchor; }
      void SetShowENCAnchor( bool show );

      bool GetShowENCDataQual(){ return m_encShowDataQual; }
      void SetShowENCDataQual( bool show );
      
      int GetUpMode(){ return m_upMode; }
      bool GetLookahead(){ return m_bLookAhead; }

      bool GetShowAIS(){ return m_bShowAIS; }
      void SetShowAIS( bool show );
      bool GetAttenAIS(){ return m_bShowAISScaled; }
      void SetAttenAIS( bool show );
      
      MUIBar *GetMUIBar(){ return m_muiBar; }
     
      void SetAlertString( wxString str){ m_alertString = str;}
      wxString GetAlertString(){ return m_alertString; }
      
      wxRect GetScaleBarRect(){ return m_scaleBarRect; }
      void RenderAlertMessage( wxDC &dc, const ViewPort &vp);

      std::vector<int>      m_tile_noshow_index_array;
      std::vector<int>      m_tile_yesshow_index_array;
      std::vector<int>      m_quilt_noshow_index_array;

      bool IsTileOverlayIndexInYesShow( int index );
      bool IsTileOverlayIndexInNoShow( int index );
      void AddTileOverlayIndexToNoShow( int index );
      
      std::vector<int> GetQuiltNoshowIindexArray(){ return m_quilt_noshow_index_array; }
private:
      int AdjustQuiltRefChart();

      bool UpdateS52State();
      
      void CallPopupMenu( int x, int y );
      
      bool IsTempMenuBarEnabled();
      bool InvokeCanvasMenu(int x, int y, int seltype);
      
      ViewPort    VPoint;
      void        PositionConsole(void);
      
      wxColour PredColor();
      wxColour ShipColor();

      void ComputeShipScaleFactor(float icon_hdt,
                                  int ownShipWidth, int ownShipLength, 
                                  wxPoint &lShipMidPoint,
                                  wxPoint &GpsOffsetPixels, wxPoint lGPSPoint,
                                  float &scale_factor_x, float &scale_factor_y);

      void ShipDrawLargeScale( ocpnDC& dc, wxPoint lShipMidPoint );
      void ShipIndicatorsDraw( ocpnDC& dc, int img_height,
                               wxPoint GPSOffsetPixels, wxPoint lGPSPoint);
                               
      ChInfoWin   *m_pCIWin;

      bool        m_bShowCurrent;
      bool        m_bShowTide;
      int         cursor_region;
      bool        m_bTCupdate;
      wxString    m_scaleText;
      double      m_scaleValue;
      bool        m_bShowScaleInStatusBar;
      wxRect      bbRect;

      wxPoint     LastShipPoint;
      wxPoint     LastPredPoint;
      bool        m_bDrawingRoute;
      bool        m_bRouteEditing;
      bool        m_bMarkEditing;
	  bool		  m_bRoutePoinDragging;
      bool        m_bIsInRadius;
      bool        m_bMayToggleMenuBar;

      RoutePoint  *m_pRoutePointEditTarget;
      RoutePoint  *m_lastRoutePointEditTarget;
      SelectItem  *m_pFoundPoint;
      bool        m_bChartDragging;
      Route       *m_pSelectedRoute;
      Track       *m_pSelectedTrack;
      wxArrayPtrVoid *m_pEditRouteArray;
      RoutePoint  *m_pFoundRoutePoint;

      int         m_FoundAIS_MMSI;

      wxCursor    *pCursorLeft;
      wxCursor    *pCursorRight;
      wxCursor    *pCursorUp;
      wxCursor    *pCursorDown;

      wxCursor    *pCursorUpLeft;
      wxCursor    *pCursorUpRight;
      wxCursor    *pCursorDownLeft;
      wxCursor    *pCursorDownRight;

      int         popx, popy;

      wxBitmap    *pThumbDIBShow;
      wxBitmap    *pThumbShowing;

      bool        bShowingCurrent;
      bool        bShowingTide;

      double       m_canvas_scale_factor;    // converter....
                                             // useage....
                                             // true_chart_scale_on_display = m_canvas_scale_factor / pixels_per_meter of displayed chart
                                             // also may be considered as the "pixels-per-meter" of the canvas on-screen
      double      m_pix_per_mm;     // pixels per millimeter on the screen
      double      m_display_size_mm;
      
      double      m_absolute_min_scale_ppm;

      bool singleClickEventIsValid;
      wxMouseEvent singleClickEvent;

      std::vector<s57Sector_t> extendedSectorLegs;
      wxFont m_overzoomFont;
      int m_overzoomTextWidth;
      int m_overzoomTextHeight;

      //    Methods
      void OnActivate(wxActivateEvent& event);
      void OnSize(wxSizeEvent& event);
      void MouseTimedEvent(wxTimerEvent& event);
      void MouseEvent(wxMouseEvent& event);
      void ShipDraw(ocpnDC& dc);
      void DrawArrow(ocpnDC& dc, int x, int y, double rot_angle, double scale);
      void OnRolloverPopupTimerEvent ( wxTimerEvent& event );
      void FindRoutePointsAtCursor( float selectRadius, bool setBeingEdited );

      void RotateTimerEvent(wxTimerEvent& event);
      void PanTimerEvent(wxTimerEvent& event);
      void MovementTimerEvent(wxTimerEvent& );
      void MovementStopTimerEvent( wxTimerEvent& );
      void OnCursorTrackTimerEvent(wxTimerEvent& event);

      void DrawAllTracksInBBox( ocpnDC& dc, LLBBox& BltBBox );
      void DrawActiveTrackInBBox( ocpnDC& dc, LLBBox& BltBBox );
      void DrawAllRoutesInBBox(ocpnDC& dc, LLBBox& BltBBox );
      void DrawActiveRouteInBBox(ocpnDC& dc, LLBBox& BltBBox );
      void DrawAllWaypointsInBBox(ocpnDC& dc, LLBBox& BltBBox );
      void DrawAnchorWatchPoints( ocpnDC& dc );
      double GetAnchorWatchRadiusPixels(RoutePoint *pAnchorWatchPoint);

      void DrawAllTidesInBBox(ocpnDC& dc, LLBBox& BBox);
      void DrawAllCurrentsInBBox(ocpnDC& dc, LLBBox& BBox);
      void RebuildTideSelectList( LLBBox& BBox );
      void RebuildCurrentSelectList( LLBBox& BBox );
      

      void RenderAllChartOutlines(ocpnDC &dc, ViewPort& vp);
      void RenderChartOutline(ocpnDC &dc, int dbIndex, ViewPort& vp);
      void RenderRouteLegs ( ocpnDC &dc );

      void AlertDraw(ocpnDC& dc);                // pjotrc 2010.02.22

      void GridDraw(ocpnDC& dc); // Display lat/lon Grid in chart display
      void ScaleBarDraw( ocpnDC& dc );

      void DrawOverlayObjects ( ocpnDC &dc, const wxRegion& ru );

      emboss_data *EmbossDepthScale();
      emboss_data *CreateEmbossMapData(wxFont &font, int width, int height, const wxString &str, ColorScheme cs);
      void CreateDepthUnitEmbossMaps(ColorScheme cs);
      wxBitmap CreateDimBitmap(wxBitmap &Bitmap, double factor);

      void CreateOZEmbossMapData(ColorScheme cs);
      emboss_data *EmbossOverzoomIndicator ( ocpnDC &dc);
      void SetOverzoomFont();

//      void CreateCM93OffsetEmbossMapData(ColorScheme cs);
//      void EmbossCM93Offset ( wxMemoryDC *pdc);

      void DrawEmboss ( ocpnDC &dc, emboss_data *pemboss );

 
      void ShowBrightnessLevelTimedPopup( int brightness, int min, int max );
      
      //    Data
      int         m_canvas_width, m_canvas_height;

      int         xr_margin;                          // chart scroll margins, control cursor, etc.
      int         xl_margin;
      int         yt_margin;
      int         yb_margin;


      wxPoint     last_drag;

      wxMemoryDC  *pmemdc;

      int         warp_x, warp_y;
      bool        warp_flag;


      wxTimer     *pPanTimer;       // This timer used for auto panning on route creation and edit
      wxTimer     *pMovementTimer;       // This timer used for smooth movement in non-opengl mode
      wxTimer     *pMovementStopTimer; // This timer used to stop movement if a keyup event is lost
      wxTimer     *pCurTrackTimer;  // This timer used to update the status window on mouse idle
      wxTimer     *pRotDefTimer;    // This timer used to control rotaion rendering on mouse moves
      wxTimer     *m_DoubleClickTimer;
      wxTimer      m_routeFinishTimer;
      
      wxTimer     m_RolloverPopupTimer;

      int         m_wheelzoom_stop_oneshot;
      int         m_last_wheel_dir;
      wxStopWatch m_wheelstopwatch;
      double      m_zoom_target;
      
      int         m_curtrack_timer_msec;
      int         m_rollover_popup_timer_msec;

      GSHHSChart  *pWorldBackgroundChart;

      ChartBaseBSB *pCBSB;
      wxBitmap    *pss_overlay_bmp;
      wxMask      *pss_overlay_mask;

      wxRect      ship_draw_rect;
      wxRect      ship_draw_last_rect;
      wxRect      ais_draw_rect;
      wxRect      alert_draw_rect;          // pjotrc 2010.02.22

      wxBitmap    *proute_bm;          // a bitmap and dc used to calculate route bounding box
      wxMemoryDC  m_dc_route;         // seen in mouse->edit->route


      emboss_data *m_pEM_Feet;                // maps for depth unit emboss pattern
      emboss_data *m_pEM_Meters;
      emboss_data *m_pEM_Fathoms;

      emboss_data *m_pEM_OverZoom;
//      emboss_data *m_pEM_CM93Offset;	// Flav



      double      m_true_scale_ppm;

      ownship_state_t   m_ownship_state;

      ColorScheme m_cs;

      wxBitmap    m_bmTideDay;
      wxBitmap    m_bmTideDusk;
      wxBitmap    m_bmTideNight;
      wxBitmap    m_bmCurrentDay;
      wxBitmap    m_bmCurrentDusk;
      wxBitmap    m_bmCurrentNight;
      wxBitmap    m_cTideBitmap;
      wxBitmap    m_cCurrentBitmap;
      
      RolloverWin *m_pRouteRolloverWin;
      RolloverWin *m_pTrackRolloverWin;
      RolloverWin *m_pAISRolloverWin;
      
      TimedPopupWin *m_pBrightPopup;
      
      wxImage     m_os_image_red_day;
      wxImage     m_os_image_red_dusk;
      wxImage     m_os_image_red_night;
      wxImage     m_os_image_grey_day;
      wxImage     m_os_image_grey_dusk;
      wxImage     m_os_image_grey_night;
      wxImage     m_os_image_yellow_day;
      wxImage     m_os_image_yellow_dusk;
      wxImage     m_os_image_yellow_night;
      
      wxImage     *m_pos_image_red;
      wxImage     *m_pos_image_grey;
      wxImage     *m_pos_image_yellow;
      
      wxImage     *m_pos_image_user;
      wxImage     *m_pos_image_user_grey;
      wxImage     *m_pos_image_user_yellow;
      
      wxImage     *m_pos_image_user_day;
      wxImage     *m_pos_image_user_dusk;
      wxImage     *m_pos_image_user_night;
      wxImage     *m_pos_image_user_grey_day;
      wxImage     *m_pos_image_user_grey_dusk;
      wxImage     *m_pos_image_user_grey_night;
      wxImage     *m_pos_image_user_yellow_day;
      wxImage     *m_pos_image_user_yellow_dusk;
      wxImage     *m_pos_image_user_yellow_night;
      
      wxImage     m_ship_pix_image;             //cached ship draw image for high overzoom
      int         m_cur_ship_pix;
      bool        m_cur_ship_pix_isgrey;
      ColorScheme m_ship_cs;


      ViewPort    m_cache_vp;
      wxBitmap    *m_prot_bm;
      wxPoint     m_roffset;

      bool        m_b_rot_hidef;

      SelectItem  *m_pRolloverRouteSeg;
      SelectItem  *m_pRolloverTrackSeg;

      double      m_wheel_lat, m_wheel_lon;
      int         m_wheel_x,m_wheel_y;

      ViewPort    m_bm_cache_vp;
      wxBitmap    m_working_bm;           // Used to build quilt in OnPaint()
      wxBitmap    m_cached_chart_bm;      // A cached copy of the fully drawn quilt

      bool        m_bbrightdir;
      int         m_brightmod;

      bool        m_bzooming, m_bzooming_to_cursor;
      IDX_entry   *m_pIDXCandidate;

//#ifdef ocpnUSE_GL
      glChartCanvas *m_glcc;
//#endif

      //Smooth movement member variables
      wxPoint     m_pan_drag;
      int         m_panx, m_pany, m_modkeys;
      double      m_panspeed;
      bool        m_bmouse_key_mod;
      double      m_zoom_factor, m_rotation_speed;
      int         m_mustmove;


      wxDateTime m_last_movement_time;

      
      int         m_AISRollover_MMSI;
      bool        m_bsectors_shown;
      bool        m_bedge_pan;
      double      m_displayed_scale_factor;
      
      wxColour    m_fog_color;      
      bool        m_disable_edge_pan;
      wxFont      *m_pgridFont;
      
      bool        m_dragoffsetSet;

      ocpnFloatingToolbarDialog *m_toolBar;
      double      m_toolbar_scalefactor;
      wxString    m_toolbarConfig;
      wxPoint     m_toolbarPosition;
      long        m_toolbarOrientation;
      
      bool        m_bautofind;
      bool        m_bFirstAuto;
      double      m_vLat, m_vLon;
      ChartStack  *m_pCurrentStack;
      Piano       *m_Piano;
      bool        m_bpersistent_quilt;
      
      wxMenu      *m_piano_ctx_menu;
      int         menu_selected_dbIndex, menu_selected_index;
      
      ocpnCompass *m_Compass;
      bool         m_bShowGPS;
      
      wxRect       m_mainlast_tb_rect;
      int          m_restore_dbindex;
      int          m_restore_group;

      MUIBar       *m_muiBar;
      wxSize       m_muiBarHOSize;
      
      bool         m_bShowOutlines;
      bool         m_bDisplayGrid;
      bool         m_bShowDepthUnits;
      bool         m_bToolbarEnable;
      bool         m_bShowAIS;
      bool         m_bShowAISScaled;
      
      // S52PLib state storage
      long         m_s52StateHash;
      bool         m_encShowText;
      bool         m_encShowDepth;
      bool         m_encShowLightDesc;
      bool         m_encShowBuoyLabels;
      int          m_encDisplayCategory;
      bool         m_encShowLights;
      bool         m_encShowAnchor;
      bool         m_encShowDataQual;
      
      wxTimer      m_deferredFocusTimer;
      float        m_focus_indicator_pix;
      bool         m_bENCGroup;
      bool         m_last_TBviz;
      
      double       m_OSoffsetx, m_OSoffsety;
      bool         m_MouseDragging;

      wxString     m_alertString;
      wxRect       m_scaleBarRect;
      bool         m_bShowCompassWin;
      bool         m_pianoFrozen;


DECLARE_EVENT_TABLE()
};

// CUSTOMIZATION - FORMAT MINUTES

wxString minutesToHoursDays(float timeInMinutes);

// END OF CUSTOMIZATION - FORMAT MINUTES

/*!
 * Compatibility
 */

#ifndef wxCLOSE_BOX
#define wxCLOSE_BOX 0x1000
#endif
#ifndef wxFIXED_MINSIZE
#define wxFIXED_MINSIZE 0
#endif


#endif
