/***********************************************************************
**
**   map.h
**
**   This file is part of KFLog2.
**      Modified for PDA use on many places using conditional compilation
**
************************************************************************
**
**   Copyright (c):  1999, 2000 by Heiner Lamprecht, Florian Ehinger
**
**   This file is distributed under the terms of the General Public
**   Licence. See the file COPYING for more information.
**
**   $Id: map.h,v 1.38 2004/06/18 17:01:35 axel Exp $
**
***********************************************************************/

#ifndef MAP_H
#define MAP_H

#include "targets.h"

#include "cumulusapp.h"

#include <qregion.h>
#include <qwidget.h>
#include <qbitmap.h>
#include <qtimer.h>
#include <qpointarray.h>

#include "wp.h"
#include "airspace.h"
#include "flighttask.h"
#include "waypointcatalog.h"

// class SinglePoint;
class Flight;
class WaypointCatalog;

/**
 * @short Container for @ref Airspace objects with a QRegion
 * @author André Somers
 *
 * Contains the regions of all visible airspaces. The map maintains a list to
 * find the airspace-data when the users selects a airspace in the map.
 * Takes ownership of the region, but not of the airspace!
 */
class AirRegion{
  public:
    QRegion* region;
    Airspace* airspace;
    AirRegion(QRegion * reg, Airspace * air);
    ~AirRegion();
};

/**
 * This class provides basic functions for displaying the map.
 *
 * @author Heiner Lamprecht, Florian Ehinger
 * @version $Id: map.h,v 1.38 2004/06/18 17:01:35 axel Exp $
 */
class Map : public QWidget
{
  Q_OBJECT

  public:
    /**
     * The constructor creates a new Map-object and
     * creates the icon used as a cursor in the map.
     */

    Map(QWidget * parent, const char* name);

    /**
     * Destroys the Map-object.
     */
    virtual ~Map();
  /**
    * Lists the possible map-orientations.
    */
  void setDrawing(bool isEnable);
  /**
   * List of different modes for the maporientation
   * -headUp: the current heading is up, the glider symbol always points upwards.
   * -northUp: default. North is up.
   * -trackUp: the map is oriënted so towards the selected waypoint.
   * Currently, only northUp is supported.
   */
  enum mapMode {headUp=0, northUp=1, trackUp=2};
  /**
   * Write property of int heading.
   */
  virtual void setHeading( const int& _newVal);
  /** Read property of int heading. */
  virtual const int& getHeading();
  /** Write property of int bearing. */
  virtual void setBearing( const int& _newVal);
  /** Read property of int bearing. */
  virtual const int& getBearing();
  /** Write property of mapMode mode. */
  virtual void setMode( const mapMode& _newVal);
  /** Read property of mapMode mode. */
  virtual mapMode getMode() const;
  /** Write property of bool ShowGlider. */
  virtual void setShowGlider( const bool& _newVal);
    /**
     * This function scedules a redraw of the map. It sets two timers:
     * The first timer is set for a small interval, and reset every time sceduleRedraw
     * is called. This allows for several modifications to the map being used for the
     * redraw at once.
     * The second timer is set for a larger interval, and is not reset. It makes sure
     * the redraw occurs once in awhile, even if events modifying the map keep comming
     * in and would otherwise prevent the map from being redrawn.
     *
     * If either of the two timers times out, the status of redrawSceduled is reset
     * and the map is redrawn to reflect the current position and zoomfactor.
     */
    void sceduleRedraw();
    /**
     *  unsceduled immediate redraw
     */
    void draw();
    /**
     * Only updates the glider symbol and the bearing line
     */
    void quickDraw();
    /**
      * This function is used to check if there are airspaces in the proximity of the
      * current position. It shows a warning if there are.
      */
    void checkAirspace(const QPoint&);

    void readConfig();

    /**
     * Returns the instance of the map widget.
     */
    static Map * getInstance() {return instance;};

  public slots:
    void slotNewWind();
    /** */
    void slotRedraw();
    /** */
    void slotRedrawMap();
    /** */
    void slotCenterToFlight();
    /** */
    void slotCenterToTask();
    /** */
    void slotCenterToWaypoint(const unsigned int id);
    /**
      * settings have changed
     */
    void slot_settingschanged();


  /** Slot signalled when user selects another waypointcatalog.  */
  void slotWaypointCatalogChanged(WaypointCatalog* c);
  /** This slot is called to set a new position. The map object determines if it is necessary to recenter the map, or if the glider can just be drawn on a different position. */
  void slot_position(const QPoint& newPos);
  /** Used to zoom the map out. Will scedule a redraw. */
  void slotZoomOut();
  /** Used to zoom in on the map. Will scedule a redraw. */
  void slotZoomIn();
  /** sets a new scale */
  void slotSetScale(const double& newScale);

  signals:
    /** */
    void changed(QSize);
    /** */
    void showFlightPoint(const QPoint pos, const struct flightPoint& point);
    /**
    	*
    	*/
    void showTaskText(FlightTask* task);
    /** */
    void taskPlanningEnd();
    /** */
    void showPoint(const QPoint pos);
    /** */
    void pointClicked(QPoint);
    /** is emited when left button click on the map */
    void waypointSelected(wayPoint *);
    /** is emited when an airspace is entered or left behind */
    void airspaceWarning(const QString&);
    /** is emitted when the map starts and ends a redrawing sequence */
    void isRedrawing(bool);
  protected:
    /**
     * redraw the current map if state == ShiftButton
     */
    virtual void keyReleaseEvent(QKeyEvent* event);
    /**
     * Redefinition of the paintEvent.
     */
    virtual void paintEvent(QPaintEvent* event);
    /**
     * Redefinition of the resizeEvent.
     */
    virtual void resizeEvent(QResizeEvent* event);
    
    /**
     * Redefinition of the mousePressEvent.
     */
    virtual void mousePressEvent(QMouseEvent* event);
    /**
     * Redefinition of the mouseReleaseEvent.
     */
    virtual void mouseReleaseEvent(QMouseEvent* event);


  private:
    /**
     * Mutex to avoid reentrance 
     */
    bool _mutex;
    /**
     * set mutex to avoid reentrance
     */
    void setMutex(bool);
    /**
     * get mutex to avoid reentrance
     */
    bool mutex();
    /**
     * Eventfilter to stop events if redrawing the map. Uses the mutex.
     */
    bool eventFilter(QObject *, QEvent *);
     /**
     * Map drawing can be switched off during startup 
     */
    bool _isEnable;
     /**
     * Flag is set, if a redraw event has to be queued because map
     * drawing is already running.
     */
    bool _isRedrawEvent;
     /**
     * queued resize event is available
     */
    bool _isResizeEvent;
     /**
     * queued size of resize event
     */
    QSize resizeEventSize;
    /**
     * Redraws the map.
     */
    void __redrawMap();
    /**
     * Copies the pixmaps into pixBuffer and calls a paintEvent().
     */
    void __showLayer();
    /**
     * Draws the map. The type of mapobjects to be drawn is controlled
     * via slotConfigureMap.
     * @see #slotConfigureMap
     */
    void __drawMap();
    /**
     */
   // void __drawFlight();
    /**
     * Draws the Task which is currently planned
     *
     */
    void __drawPlannedTask(bool solid = true);
    /**
     * Draws the grid tino the map.
     */
    void __drawGrid();
  /**
   * Puts the waypoints of the active waypoint catalog to the map
   * @arg wpPainter Painter for the waypoints themselves
   * @arg maskP Painter for the mask for bitblt'ing the pixmap.
   */
  void __drawWaypoints(QPainter * wpPainter, QPainter * maskP);
  /**
   * Draws all the landable sites on the the sites buffer
   */
  void __drawLandableSites();
  /**
   * Draws a trail indicating the flightpath taken, if that feature
   * is turned on.
   */
  void __drawTrail(); 

    /**
      * Display Infos about MapItems
      */
    void __displayMapInfo(QPoint current);
    /**
      * Display detailed Infos about MapItems
      */
    void __displayDetailedMapInfo(const QPoint& current);

  /**
    * This function sets the maprotation and redraws the map if the maprotation differs too much from the current maprotation.
    */
  void setMapRot(int newRotation);

    /**
     * calculates the rotation of the glidersymbol based on the mapmode, the heading and the bearing. In degrees counterclockwise.
     */
  int calcGliderRotation();

  /**
   * calculates the maprotation based on the mapmode, the heading and the bearing. In degrees counterclockwise.
   */
  int calcMapRotation();

    /**
     *   search for a waypoint
     *   First look in task itself
     *   Second look in map contents
     */
    bool __getTaskWaypoint(QPoint current, struct wayPoint *wp, QList<wayPoint> &taskPointList);
  /** Draws the glidersymbol on the pixmap */
  void __drawGlider();
  /** Draws a scale on the pixmap. */
  void __drawScale();
  /** Draws the Xsymbol on the pixmap */
  void __drawX();
  /** This function draws a "directionline" on the map if a waypoint has been selected. The QPoint is the projected & mapped coordinate of the positionsymbol on the map, so we don't have to calculate that all over again. */
  void __drawDirectionLine(const QPoint& from);

  // Draws a windvector on the map
  void __drawWindArrow();

    /**
     * This pixmap is used to store the currently displayed map.
     * This painter is about the same size as the map-widget, but is only
     * used for internal buffering the map. Whenever the widget is about
     * to be drawn, this buffer is used to get the content.
     */
    QPixmap pixBuffer;
/**
     * Contains the Map under the CursorA to erase the cursor later
     *
     */
    QPixmap pixCursorBuffer1;
    QPixmap pixCursorBuffer2;
    QPixmap pixCursor1;
    QPixmap pixCursor2;
    QPixmap pixAnimate;
    /**
     * Contains the grid, needed as the basis.
     */
    //QPixmap pixGrid;
    /**
     * Contains the underlying map (contours, rivers, roads, cities, ...)
     */
    //QPixmap pixUnderMap;
    /**
     * The layer containing all aeronautical elements ('landable sites').
     */
    QPixmap pixAero;
    /**
     * The mask for layer containing all aeronautical elements.
     */
    QBitmap bitAeroMask;
    /**
     * Contains the flights.
     */
    //QPixmap pixFlight;   //now misused for the X and the Glider symbols
    /**
     * Planning Task.
     */
    QPixmap pixPlan;
    /**
     * Contains the airspace-structure.
     */
    //QPixmap pixAirspace;
    /**
     * Contains the topography
     */
    QPixmap pixIsoMap;
    /**
     *
     */
    QPixmap pixCursor;
    /*
    * Pixmap to hold waypoints of active WaypointsCatalog
    */
    QPixmap windArrow;

    //QPixmap pixWaypoints;
    /** */
    QBitmap bitMapMask;
    /** */
    //QBitmap bitAirspaceMask;
    /** */
    QBitmap bitFlightMask;
    QBitmap bitPlanMask;
    /** **/
    //QBitmap bitWaypointsMask;
    /** */
    QPoint prePos;
    QPoint prePlanPos;
    QPoint preAnimationPos;
    QPoint preCur1;
    QPoint preCur2;
    int preIndex;

    int mapRot;
    int curMapRot;
    wayPoint  wp;  // actual selected waypoint
    /**
     * Contains the regions of all visible airspaces. The list is needed to
     * find the airspace-data when the users selects a airspace in the map.
     */
    QList<AirRegion> airspaceRegList;

		/**
			* contains planning task points
			* enthält die Punkte!!!
			*/
 //   QList<wayPoint> taskPointList;
		// 0 keine Planung 1 Planung 2 Planung Aufgabe Abgeschlossen
//		enum planning {NoPlanning = 0, Planning = 1, TaskFinished = 2};
		int planning;
		// Index des WP welcher verschoben wird bei planning == 3
		int moveWPindex;
    // indicates if a WP was Added in Snapping Mode (Planning)
		bool lastAdd;
    /** Contains the currently proposed zoomfactor. The actual factor used is stored in the MapMatrix. */
    double zoomFactor;
    // indicates if the mouse is in a snapping area
    bool isSnapping;
    /** reference to the short interval redrawtimer */
    QTimer * redrawTimerShort;
    /** reference to the short interval redrawtimer */
    QTimer * redrawTimerLong;
    /** Determines wether to draw the glidersymbol or not. */
    bool ShowGlider;
    // temp task (snapping)
    // FlightTask tempTask;
    unsigned int zoomProgressive; 
    float zoomProgressiveVal[8]; 

public: // Public attributes
  QPoint preSnapPoint;

protected: // Protected attributes
  /** Contains the current heading. Used for rotating the map in headUp mapmode or rotating the glidersymbol in northUp and trackUp modes. In degrees clockwise. */
  int heading;

  /** Contains the current bearing. Used for rotating the map and glider-symbol in trackUp mode. In degrees clockwise (0=due north, 90 east, etc.) */
  int bearing;

  /** Contains the mapmode.
    * northUp: the top of the map is north
    * headUp: the top of the map is the current flightdirection
    * trackUp: the top of the map is the current bearing to the selected waypoint
    */
  mapMode mode;

  /** Holds the current position. */
  QPoint curPos;
  /** @ee: these pixmaps are pre-loaded to prevent runtime drawing */
  QPixmap _cross;
  QPixmap _glider;
  QString _inside;
  QString _veryNear;
  QString _near;
  static Map * instance;
};

#endif
