/*
 * viking -- GPS Data and Topo Analyzer, Explorer, and Manager
 *
 * Copyright (C) 2003-2005, Evan Battaglia <gtoevan@gmx.net>
 * Copyright (c) 2011-2013, Rob Norris <rw_norris@hotmail.com>
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */

#ifndef _VIKING_TRWLAYER_H
#define _VIKING_TRWLAYER_H

#include "viklayer.h"
#include "vikviewport.h"
#include "vikwaypoint.h"
#include "viktrack.h"
#include "viklayerspanel.h"

G_BEGIN_DECLS

#define VIK_TRW_LAYER_TYPE            (vik_trw_layer_get_type ())
#define VIK_TRW_LAYER(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), VIK_TRW_LAYER_TYPE, VikTrwLayer))
#define VIK_TRW_LAYER_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), VIK_TRW_LAYER_TYPE, VikTrwLayerClass))
#define IS_VIK_TRW_LAYER(obj)         (G_TYPE_CHECK_INSTANCE_TYPE ((obj), VIK_TRW_LAYER_TYPE))
#define IS_VIK_TRW_LAYER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), VIK_TRW_LAYER_TYPE))

typedef enum {
  VIK_TRW_LAYER_SUBLAYER_TRACKS,
  VIK_TRW_LAYER_SUBLAYER_WAYPOINTS,
  VIK_TRW_LAYER_SUBLAYER_TRACK,
  VIK_TRW_LAYER_SUBLAYER_WAYPOINT,
  VIK_TRW_LAYER_SUBLAYER_ROUTES,
  VIK_TRW_LAYER_SUBLAYER_ROUTE
} trw_subtype_enum;

typedef enum {
  GPX_V1_0 = 0,
  GPX_V1_1,
  // ATM V1.1 is implicitly Garmin...
  //GPX_V1_1_GARMIN,
} gpx_version_t;

typedef struct _VikTrwLayerClass VikTrwLayerClass;
struct _VikTrwLayerClass
{
  VikLayerClass object_class;
};


GType vik_trw_layer_get_type ();

typedef struct _VikTrwLayer VikTrwLayer;

typedef struct {
  gchar *description;
  gchar *author;
  //gboolean has_time;
  gchar *timestamp; // TODO: Consider storing as proper time_t.
  gchar *keywords; // TODO: handling/storing a GList of individual tags?
  gchar *url;
  gchar *url_name; // AKA url_text
} VikTRWMetadata;

VikTRWMetadata *vik_trw_metadata_new();
void vik_trw_metadata_free ( VikTRWMetadata *metadata );
VikTRWMetadata *vik_trw_layer_get_metadata ( VikTrwLayer *vtl );
void vik_trw_layer_set_metadata ( VikTrwLayer *vtl, VikTRWMetadata *metadata );

gpx_version_t vik_trw_layer_get_gpx_version ( VikTrwLayer *vtl );
void vik_trw_layer_set_gpx_version ( VikTrwLayer *vtl, gpx_version_t value );
gchar *vik_trw_layer_get_gpx_header ( VikTrwLayer *vtl );
void vik_trw_layer_set_gpx_header ( VikTrwLayer *vtl, gchar* value );
gchar *vik_trw_layer_get_gpx_extensions ( VikTrwLayer *vtl );
void vik_trw_layer_set_gpx_extensions ( VikTrwLayer *vtl, gchar *value);

GQueue* vik_trw_layer_get_laps ( VikTrwLayer *vtl );
void vik_trw_layer_set_laps ( VikTrwLayer *vtl, GQueue *value );

void vik_trwlayer_uninit ();

gboolean vik_trw_layer_find_date ( VikTrwLayer *vtl, const gchar *date_str, VikCoord *position, VikViewport *vvp, gboolean do_tracks, gboolean select );

/* These are meant for use in file loaders (gpspoint.c, gpx.c, etc).
 * These copy the name, so you should free it if necessary. */
void vik_trw_layer_filein_add_waypoint ( VikTrwLayer *vtl, gchar *name, VikWaypoint *wp );
void vik_trw_layer_filein_add_track ( VikTrwLayer *vtl, gchar *name, VikTrack *tr );

void vik_trw_layer_tidy_tracks ( VikTrwLayer *vtl, guint speed, gboolean recalc_bounds );

gint vik_trw_layer_get_property_tracks_line_thickness ( VikTrwLayer *vtl );

void vik_trw_layer_add_waypoint ( VikTrwLayer *vtl, gchar *name, VikWaypoint *wp );
void vik_trw_layer_add_track ( VikTrwLayer *vtl, gchar *name, VikTrack *t );
void vik_trw_layer_add_route ( VikTrwLayer *vtl, gchar *name, VikTrack *t );

// Waypoint returned is the first one
VikWaypoint *vik_trw_layer_get_waypoint ( VikTrwLayer *vtl, const gchar *name );

// Track returned is the first one
VikTrack *vik_trw_layer_get_track ( VikTrwLayer *vtl, const gchar *name );
gboolean vik_trw_layer_delete_track ( VikTrwLayer *vtl, VikTrack *trk );
gboolean vik_trw_layer_delete_route ( VikTrwLayer *vtl, VikTrack *trk );

void vik_trw_layer_center_view_track ( VikTrwLayer *vtl, VikTrack *trk, VikViewport *vvp, VikLayersPanel *vlp );
gboolean vik_trw_layer_auto_set_view ( VikTrwLayer *vtl, VikViewport *vvp );
gboolean vik_trw_layer_find_center ( VikTrwLayer *vtl, VikCoord *dest );
GHashTable *vik_trw_layer_get_tracks ( VikTrwLayer *vtl );
GHashTable *vik_trw_layer_get_routes ( VikTrwLayer *vtl );
GHashTable *vik_trw_layer_get_waypoints ( VikTrwLayer *vtl );
gboolean vik_trw_layer_is_empty ( VikTrwLayer *vtl );
VikTrack *vik_trw_layer_get_only_track ( VikTrwLayer *vtl );
LatLonBBox vik_trw_layer_get_bbox ( VikTrwLayer *vtl );

gboolean vik_trw_layer_new_waypoint ( VikTrwLayer *vtl, GtkWindow *w, const VikCoord *def_coord );

VikCoordMode vik_trw_layer_get_coord_mode ( VikTrwLayer *vtl );

gboolean vik_trw_layer_uniquify ( VikTrwLayer *vtl, VikLayersPanel *vlp );

void vik_trw_layer_reset ( VikTrwLayer *vtl, VikViewport *vvp );
void vik_trw_layer_delete_all_waypoints ( VikTrwLayer *vtl );
void vik_trw_layer_delete_all_tracks ( VikTrwLayer *vtl );
void vik_trw_layer_delete_all_routes ( VikTrwLayer *vtl );
void trw_layer_cancel_tps_of_track ( VikTrwLayer *vtl, VikTrack *trk );

void vik_trw_layer_goto_track_prev_point ( VikTrwLayer *vtl );
void vik_trw_layer_goto_track_next_point ( VikTrwLayer *vtl );

// Functions for editing primarily from the Select Tool
void vik_trw_layer_insert_tp_beside_current_tp ( VikTrwLayer *vtl, gboolean before );
void vik_trw_layer_delete_trackpoint_selected ( VikTrwLayer *vtl );
void vik_trw_layer_delete_waypoint ( VikTrwLayer *vtl, VikWaypoint *wpt );

void vik_trw_layer_reset_waypoints ( VikTrwLayer *vtl );

void vik_trw_layer_draw_highlight ( VikTrwLayer *vtl, VikViewport *vvp );
void vik_trw_layer_draw_highlight_item ( VikTrwLayer *vtl, VikTrack *trk, VikWaypoint *wpt, VikViewport *vvp );
void vik_trw_layer_draw_highlight_items ( VikTrwLayer *vtl, GHashTable *trks, GHashTable *wpts, VikViewport *vvp );

// E.g for creating a list of tracks with the corresponding layer it is in
//  (thus a selection of tracks may be from differing layers)
typedef struct {
  VikTrack *trk;
  VikTrwLayer *vtl;
} vik_trw_and_track_t;

typedef GList* (*VikTrwlayerGetTracksAndLayersFunc) (VikLayer*, gpointer);
GList *vik_trw_layer_build_track_list_t ( VikTrwLayer *vtl, GList *tracks );

// For creating a list of waypoints with the corresponding layer it is in
//  (thus a selection of waypoints may be from differing layers)
typedef struct {
  VikWaypoint *wpt;
  VikTrwLayer *vtl;
} vik_trw_waypoint_list_t;

typedef GList* (*VikTrwlayerGetWaypointsAndLayersFunc) (VikLayer*, gpointer);
GList *vik_trw_layer_build_waypoint_list_t ( VikTrwLayer *vtl, GList *waypoints );

GdkPixbuf* get_wp_sym_small ( gchar *symbol );

/* Exposed Layer Interface function definitions */
// Intended only for use by other trw_layer subwindows
void trw_layer_verify_thumbnails ( VikTrwLayer *vtl );
// Other functions only for use by other trw_layer subwindows
gchar *trw_layer_new_unique_sublayer_name ( VikTrwLayer *vtl, gint sublayer_type, const gchar *name );
void trw_layer_waypoint_rename ( VikTrwLayer *vtl, VikWaypoint *wp, const gchar *new_name );
void trw_layer_calculate_bounds_waypoints ( VikTrwLayer *vtl );
void trw_layer_calculate_bounds_tracks ( VikTrwLayer *vtl );
void trw_layer_waypoint_properties_changed ( VikTrwLayer *vtl, VikWaypoint *wp );
void trw_layer_wpwin_set ( VikTrwLayer *vtl, VikWaypoint *wp, gpointer wpwin );
gboolean trw_layer_modified ( VikTrwLayer *vtl );

gboolean vik_trw_layer_get_tracks_visibility ( VikTrwLayer *vtl );
gboolean vik_trw_layer_get_routes_visibility ( VikTrwLayer *vtl );
gboolean vik_trw_layer_get_waypoints_visibility ( VikTrwLayer *vtl );

gboolean vik_trw_layer_get_prefer_gps_speed ( VikTrwLayer *vtl );

void vik_trw_layer_set_filename ( VikTrwLayer *vtl, const gchar* filename );
const gchar* vik_trw_layer_get_filename ( VikTrwLayer *vtl );

void trw_layer_update_treeview ( VikTrwLayer *vtl, VikTrack *trk, gboolean do_sort );

void trw_layer_dialog_shift ( VikTrwLayer *vtl, GtkWindow *dialog, VikCoord *coord, gboolean vertical );

void trw_layer_tpwin_init ( VikTrwLayer *vtl );
gboolean trw_layer_tpwin_is_shown ( VikTrwLayer *vtl );

void trw_layer_replace_external ( VikTrwLayer *vtl, const gchar *external_file );
void trw_ensure_layer_loaded ( VikTrwLayer *trw );

typedef struct {
  VikTrack *trk; // input
  gpointer uuid; // output
} trku_udata;
gboolean trw_layer_track_find_uuid ( const gpointer id, const VikTrack *trk, gpointer udata );

typedef struct {
  VikWaypoint *wp; // input
  gpointer uuid;   // output
} wpu_udata;
gboolean trw_layer_waypoint_find_uuid ( const gpointer id, const VikWaypoint *wp, gpointer udata );

void trw_layer_zoom_to_show_latlons ( VikTrwLayer *vtl, VikViewport *vvp, struct LatLon maxmin[2] );

GHashTable *vik_trw_layer_get_tracks_iters ( VikTrwLayer *vtl );
GHashTable *vik_trw_layer_get_routes_iters ( VikTrwLayer *vtl );
GHashTable *vik_trw_layer_get_waypoints_iters ( VikTrwLayer *vtl );

void vik_trw_layer_trackpoint_draw ( VikTrwLayer *vtl, VikViewport *vvp, VikTrack *trk, VikTrackpoint *tpt );

#define VIK_SETTINGS_LIST_DATE_FORMAT "list_date_format"

typedef enum _VikTRWDataType
{
 VIKING_WAYPOINT = 0,
 VIKING_TRACK,
} VikTRWDataTypeT;

G_END_DECLS

#endif
