#
#  gpsman --- GPS Manager: a manager for GPS receiver data
#
#  Copyright (c) 2004 Miguel Filgueiras (mig@ncc.up.pt) / Universidade do Porto
#
#    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.
#
#  File: symbols.tcl
#  Last change:  17 June 2004
#

## GPSMan symbols and display options

# names for symbols used by GPSMan (mostly taken from Garmin
#  GPS Interface Specification version 1, rev 2; and from the set
#  used by Lowrance receivers, provided by Brian Baulch)

# default icon dimensions for WP symbols; changing these values
#  implies changing the replacement bitmaps defined before proc
#  InitSymbolImages

set ICONWIDTH 15
set ICONHEIGHT 15

# GPSMan symbol names and their categories (not mutually exclusive)

set SYMBOLS {
    1st_aid
    WP_buoy_white
    WP_dot
    airport
    amusement_park
    anchor
    avn_danger
    avn_faf
    avn_lom
    avn_map
    avn_ndb
    avn_tacan
    avn_vor
    avn_vordme
    avn_vortac
    ball
    beach
    bell
    biker
    boat
    boat_ramp
    border
    bowling
    box_blue
    box_green
    box_red
    bridge
    building
    buoy_amber
    buoy_black
    buoy_blue
    buoy_green
    buoy_green_red
    buoy_green_white
    buoy_orange
    buoy_red
    buoy_red_green
    buoy_red_white
    buoy_violet
    buoy_white
    buoy_white_green
    buoy_white_red
    camping
    capitol_city
    car
    car_rental
    car_repair
    casino
    castle
    cemetery
    chapel
    church
    circle_x
    civil
    controlled
    crossing
    dam
    danger
    deer
    diamond_green
    diamond_red
    diver_down_2
    diver_down_1
    dollar
    dot
    drinking_water
    duck
    MOB
    RV_park
    elevation
    exit
    exit_no_serv
    factory
    fastfood
    fish
    fitness
    flag
    flag_pin_blue
    flag_pin_green
    flag_pin_red
    freeway
    fuel
    fuel_store
    geocache
    geocache_fnd
    geo_name_land
    geo_name_man
    geo_name_water
    glider
    golf
    heliport
    horn
    house
    house_2
    ice_skating
    info
    intersection
    is_highway
    knife_fork
    ladder
    landing
    large_city
    large_ramp_int
    large_exit_ns
    levee
    light
    lodging
    many_fish
    many_tracks
    mark_x
    medium_city
    mile_marker
    military
    mine
    monument
    mountains
    movie
    mug
    museum
    ntl_highway
    null
    null_2
    oil_field
    parachute
    park
    parking
    pharmacy
    phone
    picnic
    pin_blue
    pin_green
    pin_red
    pizza
    police
    post_office
    private
    radio_beacon
    ramp_int
    restricted
    restrooms
    scenic
    school
    seaplane
    shopping_cart
    short_tower
    showers
    skiing
    skull
    small_city
    snow_skiing
    soft_field
    square_green
    square_red
    st_highway
    stadium
    store
    street_int
    summit
    swimming
    take_off
    tall_tower
    theater
    toll
    tow_truck
    traceback
    tracks
    trail_head
    tree
    truck_stop
    tunnel
    ultralight
    us_highway
    weight_station
    wreck
    zoo
}

set UNKNOWNSYMBOLS ""

set SYMBOLSCATS {general land water aviation}

set SYMBOLSFOR(general) {
    WP_dot  danger skull  bell flag flag_pin_blue
    flag_pin_green  flag_pin_red traceback dollar
    null null_2 ball dot  mark_x circle_x diamond_green diamond_red
    square_green  square_red box_blue  box_green  box_red
    pin_blue  pin_green  pin_red}

set SYMBOLSFOR(land) {
    1st_aid    info
    small_city    medium_city    large_city    capitol_city
    car     car_rental    car_repair  tow_truck   biker
    restrooms    pharmacy    phone   post_office   police
    tunnel   bridge    dam  levee    mountains  elevation  summit  ladder
    trail_head   tracks    many_tracks
    tree    deer    duck    fish  many_fish
    parking    house  house_2  building  lodging
    park   castle    monument    church chapel  cemetery
    museum    zoo    theater   casino
    scenic  airport  factory  mine  oil_field
    knife_fork    fastfood     mug    pizza  movie 
    school    shopping_cart   store   stadium
    amusement_park    beach         swimming    showers    skiing
    golf   bowling    fitness  snow_skiing   ice_skating
    picnic    camping    drinking_water   geocache    geocache_fnd
    RV_park   fuel    fuel_store  horn     exit    exit_no_serv
    large_exit_ns     mile_marker   border
    toll    freeway     ntl_highway  is_highway    st_highway    us_highway
    street_int    ramp_int    large_ramp_int   crossing
    truck_stop    weight_station
    parachute     glider   ultralight tall_tower     short_tower
    take_off      landing
    geo_name_land    geo_name_man    geo_name_water
    civil   military}

set SYMBOLSFOR(water) {
    anchor    boat    boat_ramp      fish   many_fish
    fuel    light    MOB    beach    swimming    wreck dam     mile_marker
    radio_beacon    WP_buoy_white    buoy_amber
    buoy_black    buoy_blue    buoy_green    buoy_green_red
    buoy_green_white    buoy_orange    buoy_red    buoy_red_green
    buoy_red_white    buoy_violet    buoy_white    buoy_white_green
    buoy_white_red    diver_down_1    diver_down_2}

set SYMBOLSFOR(aviation) {
    airport     heliport    private   seaplane    soft_field    landing
    take_off    radio_beacon   avn_danger avn_faf  avn_lom  avn_map    avn_ndb
    avn_tacan    avn_vor    avn_vordme    avn_vortac
    controlled   restricted    intersection
    parachute     glider   ultralight tall_tower     short_tower}

# GPSMan display options

set DISPOPTS {symbol s_name s_comment name comment}

# images that must be defined because the symbols are used by GPSMan
#  must have an internal definition as a 15x15 bit map
# there is a frame image as a 17x17 bit map
# this must be changed if $ICONWIDTH or $ICONHEIGHT changes

set DEFINEIMGS {WP_dot diamond_green diamond_red MOB interr}

array set INTERNALIMG {
    frame,dims    17x17
    frame,fg      red
    frame {
#define fr_width 17
#define fr_height 17
static unsigned char fr_bits[] = {
   0xff, 0xff, 0x01, 0xff, 0xff, 0x01, 0x03, 0x80, 0x01, 0x03, 0x80, 0x01,
   0x03, 0x80, 0x01, 0x03, 0x80, 0x01, 0x03, 0x80, 0x01, 0x03, 0x80, 0x01,
   0x03, 0x80, 0x01, 0x03, 0x80, 0x01, 0x03, 0x80, 0x01, 0x03, 0x80, 0x01,
   0x03, 0x80, 0x01, 0x03, 0x80, 0x01, 0x03, 0x80, 0x01, 0xff, 0xff, 0x01,
   0xff, 0xff, 0x01};
    }
    SYMBOL,dims   15x15
    WP_dot,fg     red
    WP_dot {
#define dot_width 15
#define dot_height 15
static unsigned char dot_bits[] = {
   0xc0, 0x01, 0xf0, 0x07, 0xfc, 0x1f, 0xfc, 0x1f, 0xfe, 0x3f, 0xfe, 0x3f,
   0x7f, 0x7f, 0x3f, 0x7e, 0x7f, 0x7f, 0xfe, 0x3f, 0xfe, 0x3f, 0xfc, 0x1f,
   0xfc, 0x1f, 0xf0, 0x07, 0xc0, 0x01};
    }
    diamond_green,fg green
    diamond_green {
#define diamond_green_width 15
#define diamond_green_height 15
static unsigned char diamond_green_bits[] = {
   0x80, 0x00, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, 0xf8, 0x0f, 0xfc, 0x1f,
   0xfe, 0x3f, 0xff, 0x7f, 0xfe, 0x3f, 0xfc, 0x1f, 0xf8, 0x0f, 0xf0, 0x07,
   0xe0, 0x03, 0xc0, 0x01, 0x80, 0x00};
    }
    diamond_red,fg red
    diamond_red {
#define diamond_red_width 15
#define diamond_red_height 15
static unsigned char diamond_red_bits[] = {
   0x80, 0x00, 0xc0, 0x01, 0xe0, 0x03, 0xf0, 0x07, 0xf8, 0x0f, 0xfc, 0x1f,
   0xfe, 0x3f, 0xff, 0x7f, 0xfe, 0x3f, 0xfc, 0x1f, 0xf8, 0x0f, 0xf0, 0x07,
   0xe0, 0x03, 0xc0, 0x01, 0x80, 0x00};
    }
    MOB,fg   red
    MOB {
#define MOB_width 15
#define MOB_height 15
static unsigned char MOB_bits[] = {
   0xff, 0x7f, 0xff, 0x7f, 0xfd, 0x7f, 0xf9, 0x7f, 0xf1, 0x7f, 0xe1, 0x7f,
   0xc1, 0x7f, 0x81, 0x7f, 0x01, 0x7f, 0x01, 0x7e, 0x01, 0x7c, 0x01, 0x78,
   0x01, 0x70, 0x01, 0x60, 0xff, 0x7f};
    }
    interr,fg  blue
    interr {
#define interr_width 15
#define interr_height 15
static unsigned char interr_bits[] = {
   0xe0, 0x03, 0xf0, 0x07, 0xf8, 0x0f, 0x7c, 0x1e, 0x3c, 0x3c, 0x3c, 0x3c,
   0x00, 0x3c, 0x00, 0x1e, 0x80, 0x0f, 0xc0, 0x03, 0xe0, 0x03, 0x00, 0x00,
   0xc0, 0x01, 0xe0, 0x03, 0xc0, 0x01};
    }
}

# general procs

proc InitSymbolImages {} {
    # initialize images for symbols and the frame image
    global SRCDIR SYMBOLS SYMBOLIMAGE FRAMEIMAGE DEFINEIMGS INTERNALIMG

    set f gif
    set fdims $INTERNALIMG(frame,dims)
    if { [catch {set FRAMEIMAGE [image create photo \
	    -file [file join $SRCDIR gmicons redframe${fdims}.$f]]}] } {
        set FRAMEIMAGE [image create bitmap -data $INTERNALIMG(frame) \
		              -foreground $INTERNALIMG(frame,fg)]
    }
    set sdims $INTERNALIMG(SYMBOL,dims)
    # assuming that $DEFINEIMGS contains both WP_dot and interr
    foreach sy $DEFINEIMGS {
	if { [catch {set im$sy [image create photo \
				    -file [file join $SRCDIR gmicons \
					       ${sy}${sdims}.$f]]}] } {
	    set im$sy [image create bitmap -data $INTERNALIMG($sy) \
			   -foreground $INTERNALIMG($sy,fg)]
	}
	set SYMBOLIMAGE($sy) [set im$sy]
    }
    set SYMBOLIMAGE(interr) $iminterr
    foreach sy $SYMBOLS {
	if { [lsearch -exact $DEFINEIMGS $sy] == -1 } {
	    if { [catch {set im [image create photo \
				     -file [file join $SRCDIR gmicons \
						${sy}${sdims}.$f]]}] } {
		set im $imWP_dot
	    }
	    set SYMBOLIMAGE($sy) $im
	}
    }
    return
}

proc InitBitmaps {} {
    # initialize bitmaps
    global SRCDIR BITMAP BITMAPS

    set dir [file join [pwd] $SRCDIR gmicons]
    foreach b $BITMAPS {
	if { [file readable [set f [file join $dir $b.bmp]]] } {
	    set BITMAP($b) @$f
	} else { set BITMAP($b) error }
    }
    return
}

proc FillSymbolsMenu {menu commd} {
    #  $menu is the parent menu to fill in
    #  $commd is the callback to associate to each selection
    #    whose arguments will be the symbol name and $menu (even on sub-menus)
    global SYMBOLSCATS SYMBOLSFOR SYMBOLIMAGE UNKNOWNSYMBOLS TXT MAXMENUITEMS

    set n 0 ; set m 0 ; set mw $menu
    foreach cat $SYMBOLSCATS {
	if { $n > $MAXMENUITEMS } {
	    $mw add cascade -label "$TXT(more) ..." -menu $mw.m$m
	    set mw $mw.m$m ; menu $mw -tearoff 0
	    set n 0 ; incr m
	}
	$mw add cascade -label $TXT(SYCAT$cat) -menu $mw.c$cat
	incr n
	set nc 0 ; set mc 0 ; set mwc $mw.c$cat
	menu $mwc -tearoff 0
	foreach it $SYMBOLSFOR($cat) {
	    if { $nc > $MAXMENUITEMS } {
		$mwc add cascade -label "$TXT(more) ..." -menu $mwc.m$mc
		set mwc $mwc.m$mc ; menu $mwc -tearoff 0
		set nc 0 ; incr mc
	    }
	    if { [lsearch -exact $UNKNOWNSYMBOLS $it] != -1 } {
		set t "~ $TXT(SY$it)"
	    } else { set t $TXT(SY$it) }
	    $mwc add command -image $SYMBOLIMAGE($it) -accelerator $t \
		    -command "$commd $it $menu"
	    incr nc
	}
    }
    return
}

proc BadSymbol {name} {
    # check if $name is a valid GPSMan symbol name
    global SYMBOLS

    return [expr [lsearch -exact $SYMBOLS $name] == -1]
}

proc BadDispOpt {name} {
    # check if $name is a valid GPSMan display option name
    global DISPOPTS

    return [expr [lsearch -exact $DISPOPTS $name] == -1]
}

proc NameForCodeOf {id code} {
    # get name for $code of $id
    #  $id in {SYMBOL DISPOPT}
    global DEFAULT$id UNKNOWN${id}S MESS

    if { [set ns [FindArrayIndices ${id}CODE $code -1]] == -1 } {
	GMMessage "$MESS(bad${id}code): $code"
	return [set DEFAULT$id]
    }
    foreach n $ns {
	if { [lsearch -exact [set UNKNOWN${id}S] $n] == -1 } {
	    return $n
	}
    }
    GMMessage "$MESS(bad${id}code): $code"
    return [set DEFAULT$id]
}


