#
#  gpsman --- GPS Manager: a manager for GPS receiver data
#
# Copyright (c) 1998-2009 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:  16 March 2009
#

## GPSMan symbols and display options

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

# user defined symbols:
#  - shown as $DEFAULTSYMBOL or WP_dot
#  - represented as   user:REPR  where REPR is the brand-dependent
#   representation
#  - are not shown in symbol menus

# icons will have either 15x15 or 30x30 pixels depending on the user
#  option $ICONSIZE
#
# icon images are distributed as 15x15 pixels GIFs, 30x30 ones being
#  obtained by Tk image zooming
#
# a small number of icons is defined also as bitmaps below, in both
#  sizes, to avoid errors if the GIFs are missing

 # these values are used in forming the GIF files names and are then
 #  set depending on $ICONSIZE
set ICONWIDTH 15
set ICONHEIGHT 15

# GPSMan symbol names and their categories (not mutually exclusive)
#  user:REPR  is used for user-defined ones

set SYMBOLS {
    1st_aid
    MOB
    RV_park
    WP_buoy_white
    WP_dot
    airport
    amusement_park
    anchor
    anchor_prohib
    avn_danger
    avn_faf
    avn_lom
    avn_map
    avn_ndb
    avn_tacan
    avn_vor
    avn_vordme
    avn_vortac
    bait_tackle
    ball
    beach
    beacon
    bell
    biker
    boat
    boat_ramp
    border
    bot_cond
    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_blue
    circle_green
    circle_red
    circle_x
    civil
    cntct_afro
    cntct_alien
    cntct_ball_cap
    cntct_big_ears
    cntct_biker
    cntct_bug
    cntct_cat
    cntct_dog
    cntct_dreads
    cntct_female1
    cntct_female2
    cntct_female3
    cntct_goatee
    cntct_kung_fu
    cntct_pig
    cntct_pirate
    cntct_ranger
    cntct_smiley
    cntct_spike
    cntct_sumo
    coast_guard
    controlled
    cross
    cross_3p
    crossing
    dam
    danger
    deer
    diamond_blue
    diamond_green
    diamond_red
    diver_down_1
    diver_down_2
    dock
    dollar
    dot
    drinking_water
    dropoff
    duck
    elevation
    exit
    exit_no_serv
    factory
    fastfood
    fhs_facility
    fish
    fitness
    flag
    flag_pin_blue
    flag_pin_green
    flag_pin_red
    freeway
    fuel
    fuel_store
    geo_name_land
    geo_name_man
    geo_name_water
    geocache
    geocache_fnd
    glider
    golf
    heliport
    horn
    house
    house_2
    hydrant
    ice_skating
    info
    intersection
    is_highway
    knife_fork
    ladder
    landing
    large_city
    large_exit_ns
    large_ramp_int
    letter_a_blue
    letter_a_green
    letter_a_red
    letter_b_blue
    letter_b_green
    letter_b_red
    letter_c_blue
    letter_c_green
    letter_c_red
    letter_d_blue
    letter_d_green
    letter_d_red
    levee
    light
    lodging
    many_fish
    many_tracks
    marina
    mark_x
    medium_city
    mile_marker
    military
    mine
    monument
    mountains
    movie
    mug
    museum
    ntl_highway
    null
    null_2
    number_0_blue
    number_0_green
    number_0_red
    number_1_blue
    number_1_green
    number_1_red
    number_2_blue
    number_2_green
    number_2_red
    number_3_blue
    number_3_green
    number_3_red
    number_4_blue
    number_4_green
    number_4_red
    number_5_blue
    number_5_green
    number_5_red
    number_6_blue
    number_6_green
    number_6_red
    number_7_blue
    number_7_green
    number_7_red
    number_8_blue
    number_8_green
    number_8_red
    number_9_blue
    number_9_green
    number_9_red
    oil_field
    open_24hr
    oval_blue
    oval_green
    oval_red
    parachute
    park
    parking
    pharmacy
    phone
    picnic
    pin_blue
    pin_green
    pin_red
    pizza
    police
    post_office
    private
    radio_beacon
    ramp_int
    rect_blue
    rect_green
    rect_red
    reef
    restricted
    restrooms
    scenic
    school
    seaplane
    shopping_cart
    short_tower
    showers
    skiing
    skull
    small_city
    snow_skiing
    soft_field
    square_blue
    square_green
    square_red
    st_highway
    stadium
    store
    street_int
    stump
    summit
    swimming
    take_off
    tall_tower
    theater
    tide_pred_stn
    toll
    tow_truck
    traceback
    tracks
    trail_head
    tree
    triangle_blue
    triangle_green
    triangle_red
    truck_stop
    tunnel
    ultralight
    us_highway
    weedbed
    weight_station
    wreck
    zoo
}

set UNKNOWNSYMBOLS ""

    # high-level description of symbol menus: list of lists with symbol
    #  internal names or elements of the one of the forms ==TEXT or =INDEX,
    #  giving the title for a sub-menu (as literal text or index in TXT),
    #  followed by a sub-list describing the sub-menu

    # symbol default menu: assumed in proc SymbolCustomMenu to have a
    #  sub-menu for each category and nothing else at top-level and titles
    #  given by =INDEX
set SYDEFTMENU {=SYCATgeneral
    {WP_dot  danger skull  bell flag flag_pin_blue
        flag_pin_green  flag_pin_red traceback dollar
	null null_2 ball dot  cross cross_3p mark_x circle_x
	diamond_blue diamond_green diamond_red
	square_blue  square_green  square_red box_blue  box_green  box_red
	pin_blue  pin_green  pin_red
	circle_red circle_green circle_blue
	oval_red oval_green oval_blue
	rect_red rect_green rect_blue
	triangle_blue triangle_green triangle_red
	letter_a_red letter_b_red letter_c_red letter_d_red
	letter_a_green letter_c_green letter_b_green letter_d_green
	letter_a_blue  letter_b_blue   letter_c_blue   letter_d_blue
	number_0_red    number_1_red    number_2_red    number_3_red
	number_4_red    number_5_red    number_6_red    number_7_red
	number_8_red    number_9_red    number_0_green    number_1_green
	number_2_green    number_3_green    number_4_green    number_5_green
	number_6_green    number_7_green    number_8_green    number_9_green
	number_0_blue    number_1_blue    number_2_blue    number_3_blue
	number_4_blue    number_5_blue    number_6_blue    number_7_blue
	number_8_blue    number_9_blue
	cntct_smiley    cntct_ball_cap    cntct_big_ears    cntct_spike
	cntct_goatee    cntct_afro    cntct_dreads    cntct_female1
	cntct_female2    cntct_female3    cntct_ranger    cntct_kung_fu
	cntct_sumo    cntct_pirate    cntct_biker    cntct_alien
	cntct_bug    cntct_cat    cntct_dog    cntct_pig}
    =SYCATland
    {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   hydrant
	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}
    =SYCATwater
    {anchor  anchor_prohib   beacon   reef   stump weedbed  dropoff
	dock    marina  coast_guard  tide_pred_stn 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
	open_24hr  fhs_facility  bot_cond  bait_tackle}
    =SYCATaviation
    {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 definitions as 15x15 and 30x30 bitmaps
# there is a frame image as 17x17 and 34x34 bitmaps
# this must be changed if initial values of $ICONWIDTH or $ICONHEIGHT change

 # both WP_dot and interr are assumed to be in this list
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};
    }
    frame,2,dims  34x34
    frame,2 {
#define fr_width 34
#define fr_height 34
static unsigned char fr_bits[] = {
   0xff, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff,
   0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0x03, 0x0f, 0x00, 0x00, 0xc0,
   0x03, 0x0f, 0x00, 0x00, 0xc0, 0x03, 0x0f, 0x00, 0x00, 0xc0, 0x03, 0x0f,
   0x00, 0x00, 0xc0, 0x03, 0x0f, 0x00, 0x00, 0xc0, 0x03, 0x0f, 0x00, 0x00,
   0xc0, 0x03, 0x0f, 0x00, 0x00, 0xc0, 0x03, 0x0f, 0x00, 0x00, 0xc0, 0x03,
   0x0f, 0x00, 0x00, 0xc0, 0x03, 0x0f, 0x00, 0x00, 0xc0, 0x03, 0x0f, 0x00,
   0x00, 0xc0, 0x03, 0x0f, 0x00, 0x00, 0xc0, 0x03, 0x0f, 0x00, 0x00, 0xc0,
   0x03, 0x0f, 0x00, 0x00, 0xc0, 0x03, 0x0f, 0x00, 0x00, 0xc0, 0x03, 0x0f,
   0x00, 0x00, 0xc0, 0x03, 0x0f, 0x00, 0x00, 0xc0, 0x03, 0x0f, 0x00, 0x00,
   0xc0, 0x03, 0x0f, 0x00, 0x00, 0xc0, 0x03, 0x0f, 0x00, 0x00, 0xc0, 0x03,
   0x0f, 0x00, 0x00, 0xc0, 0x03, 0x0f, 0x00, 0x00, 0xc0, 0x03, 0x0f, 0x00,
   0x00, 0xc0, 0x03, 0x0f, 0x00, 0x00, 0xc0, 0x03, 0x0f, 0x00, 0x00, 0xc0,
   0x03, 0x0f, 0x00, 0x00, 0xc0, 0x03, 0xff, 0xff, 0xff, 0xff, 0x03, 0xff,
   0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff, 0xff, 0x03, 0xff, 0xff, 0xff,
   0xff, 0x03 };
    }
    SYMBOL,dims   15x15
    SYMBOL,2,dims 30x30
    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};
    }
    WP_dot,2 {
#define dot_width 30
#define dot_height 30
static unsigned char dot_bits[] = {
   0x00, 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xff, 0x3f, 0x00,
   0x00, 0xff, 0x3f, 0x00, 0xf0, 0xff, 0xff, 0x03, 0xf0, 0xff, 0xff, 0x03,
   0xf0, 0xff, 0xff, 0x03, 0xf0, 0xff, 0xff, 0x03, 0xfc, 0xff, 0xff, 0x0f,
   0xfc, 0xff, 0xff, 0x0f, 0xfc, 0xff, 0xff, 0x0f, 0xfc, 0xff, 0xff, 0x0f,
   0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x0f, 0xfc, 0x3f,
   0xff, 0x0f, 0xfc, 0x3f, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f, 0xff, 0x3f,
   0xfc, 0xff, 0xff, 0x0f, 0xfc, 0xff, 0xff, 0x0f, 0xfc, 0xff, 0xff, 0x0f,
   0xfc, 0xff, 0xff, 0x0f, 0xf0, 0xff, 0xff, 0x03, 0xf0, 0xff, 0xff, 0x03,
   0xf0, 0xff, 0xff, 0x03, 0xf0, 0xff, 0xff, 0x03, 0x00, 0xff, 0x3f, 0x00,
   0x00, 0xff, 0x3f, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x03, 0x00 };
    }
    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_green,2 {
#define diamond_green_width 30
#define diamond_green_height 30
static unsigned char diamond_green_bits[] = {
   0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00,
   0x00, 0xf0, 0x03, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0xfc, 0x0f, 0x00,
   0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, 0x3f, 0x00, 0xc0, 0xff, 0xff, 0x00,
   0xc0, 0xff, 0xff, 0x00, 0xf0, 0xff, 0xff, 0x03, 0xf0, 0xff, 0xff, 0x03,
   0xfc, 0xff, 0xff, 0x0f, 0xfc, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0x3f,
   0xff, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0x0f, 0xfc, 0xff, 0xff, 0x0f,
   0xf0, 0xff, 0xff, 0x03, 0xf0, 0xff, 0xff, 0x03, 0xc0, 0xff, 0xff, 0x00,
   0xc0, 0xff, 0xff, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, 0x3f, 0x00,
   0x00, 0xfc, 0x0f, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0xf0, 0x03, 0x00,
   0x00, 0xf0, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 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};
    }
   diamond_red,2 {
#define diamond_red_width 30
#define diamond_red_height 30
static unsigned char diamond_red_bits[] = {
   0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xf0, 0x03, 0x00,
   0x00, 0xf0, 0x03, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0xfc, 0x0f, 0x00,
   0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, 0x3f, 0x00, 0xc0, 0xff, 0xff, 0x00,
   0xc0, 0xff, 0xff, 0x00, 0xf0, 0xff, 0xff, 0x03, 0xf0, 0xff, 0xff, 0x03,
   0xfc, 0xff, 0xff, 0x0f, 0xfc, 0xff, 0xff, 0x0f, 0xff, 0xff, 0xff, 0x3f,
   0xff, 0xff, 0xff, 0x3f, 0xfc, 0xff, 0xff, 0x0f, 0xfc, 0xff, 0xff, 0x0f,
   0xf0, 0xff, 0xff, 0x03, 0xf0, 0xff, 0xff, 0x03, 0xc0, 0xff, 0xff, 0x00,
   0xc0, 0xff, 0xff, 0x00, 0x00, 0xff, 0x3f, 0x00, 0x00, 0xff, 0x3f, 0x00,
   0x00, 0xfc, 0x0f, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0xf0, 0x03, 0x00,
   0x00, 0xf0, 0x03, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0xc0, 0x00, 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};
    }
    MOB,2 {
#define MOB_width 30
#define MOB_height 30
static unsigned char MOB_bits[] = {
   0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0x3f,
   0xff, 0xff, 0xff, 0x3f, 0xf3, 0xff, 0xff, 0x3f, 0xf3, 0xff, 0xff, 0x3f,
   0xc3, 0xff, 0xff, 0x3f, 0xc3, 0xff, 0xff, 0x3f, 0x03, 0xff, 0xff, 0x3f,
   0x03, 0xff, 0xff, 0x3f, 0x03, 0xfc, 0xff, 0x3f, 0x03, 0xfc, 0xff, 0x3f,
   0x03, 0xf0, 0xff, 0x3f, 0x03, 0xf0, 0xff, 0x3f, 0x03, 0xc0, 0xff, 0x3f,
   0x03, 0xc0, 0xff, 0x3f, 0x03, 0x00, 0xff, 0x3f, 0x03, 0x00, 0xff, 0x3f,
   0x03, 0x00, 0xfc, 0x3f, 0x03, 0x00, 0xfc, 0x3f, 0x03, 0x00, 0xf0, 0x3f,
   0x03, 0x00, 0xf0, 0x3f, 0x03, 0x00, 0xc0, 0x3f, 0x03, 0x00, 0xc0, 0x3f,
   0x03, 0x00, 0x00, 0x3f, 0x03, 0x00, 0x00, 0x3f, 0x03, 0x00, 0x00, 0x3c,
   0x03, 0x00, 0x00, 0x3c, 0xff, 0xff, 0xff, 0x3f, 0xff, 0xff, 0xff, 0x3f };
    }
    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};
    }
    interr,2 {
#define interr_width 30
#define interr_height 30
static unsigned char interr_bits[] = {
   0x00, 0xfc, 0x0f, 0x00, 0x00, 0xfc, 0x0f, 0x00, 0x00, 0xff, 0x3f, 0x00,
   0x00, 0xff, 0x3f, 0x00, 0xc0, 0xff, 0xff, 0x00, 0xc0, 0xff, 0xff, 0x00,
   0xf0, 0x3f, 0xfc, 0x03, 0xf0, 0x3f, 0xfc, 0x03, 0xf0, 0x0f, 0xf0, 0x0f,
   0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f, 0xf0, 0x0f,
   0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xfc, 0x03,
   0x00, 0x00, 0xfc, 0x03, 0x00, 0xc0, 0xff, 0x00, 0x00, 0xc0, 0xff, 0x00,
   0x00, 0xf0, 0x0f, 0x00, 0x00, 0xf0, 0x0f, 0x00, 0x00, 0xfc, 0x0f, 0x00,
   0x00, 0xfc, 0x0f, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
   0x00, 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xfc, 0x0f, 0x00,
   0x00, 0xfc, 0x0f, 0x00, 0x00, 0xf0, 0x03, 0x00, 0x00, 0xf0, 0x03, 0x00 };
    }
}

# general procs

proc InitImages {} {
    # initialize images including those for logos, symbols and the frame
    #  image; set up symbol menus low-level description from high-level ones
    global SRCDIR SYMBOLS SYMBOLIMAGE FRAMEIMAGE DEFINEIMGS INTERNALIMG \
	ICONSIZE ICONWIDTH ICONHEIGHT Logo SmallLogo

    if { $ICONSIZE == "30x30" } {
	set ICONWIDTH [set ICONHEIGHT 30]
	set is ",2"
    } else { set is "" }
    # logos
    foreach v "Logo SmallLogo" f "gpsman-logo.gif gpsman-logo-small.gif" {
	if { [catch {set $v [image create photo \
				 -file [file join $SRCDIR gmicons $f]]}] } {
	    set $v ""
	} elseif { $is != "" } {
	    DoubleImageSize "\#0" $v
	}
    }
    # frame and symbols
    set f gif
    set fdims $INTERNALIMG(frame,dims)
    set udims $INTERNALIMG(frame$is,dims)
    if { [catch {set FRAMEIMAGE [image create photo \
	    -file [file join $SRCDIR gmicons redframe${fdims}.$f]]}] } {
        set FRAMEIMAGE [image create bitmap -data $INTERNALIMG(frame$is) \
		              -foreground $INTERNALIMG(frame,fg)]
    } elseif { $is != "" } {
	DoubleImageSize 1 FRAMEIMAGE
    }
    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$is) \
			   -foreground $INTERNALIMG($sy,fg)]
	} elseif { $is != "" } {
	    DoubleImageSize 1 im$sy
	}
	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
	    } elseif { $is != "" } {
		DoubleImageSize 1 im
	    }
	    set SYMBOLIMAGE($sy) $im
	}
    }
    InitSymbolMenuDescr
    return
}

proc DoubleImageSize {level iname} {
    # doubles the size of the photo image given in the variable $iname
    #  and destroys the original one
    upvar $level $iname img

    set new [image create photo -width 0 -height 0]
    $new copy $img -zoom 2
    image delete $img
    set img $new
    return
}

proc InitSymbolMenuDescr {} {
    # init low-level description of symbol menus from high-level ones
    #  which are list of lists with symbol internal names or elements
    #  of the one of the forms ==TEXT or =INDEX, giving the title for a
    #  sub-menu (as literal text or index in TXT), followed by a sub-list
    #  describing the sub-menu
    # the low-level description has a similar structure but each
    #  symbol internal name is followed by its text label and
    #  =INDEX elements are replaced by ==TEXT with TEXT the final
    #  text to be used as label; this description also reflects the
    #  partition of long menus according $MAXMENUITEMS
    global SYDEFTMENU SYUSRMENU SYMENU

    set high $SYDEFTMENU
    if { $SYUSRMENU != "" } {
	set high [linsert $high 0 =syusrmenu $SYUSRMENU]
    }
    set SYMENU [PartitionSymbolMenu $high]
    return
}

proc PartitionSymbolMenu {hdescr} {
    # create low-level description of symbol menus
    # this implements recursion on sub-menus
    global UNKNOWNSYMBOLS TXT MAXMENUITEMS

    set low "" ; set n 0 ; set sub 0
    foreach e $hdescr {
	if { $sub } {
	    lappend low [PartitionSymbolMenu $e]
	    set sub 0
	    continue
	}
	if { $n > $MAXMENUITEMS } {
	    # continue in a sub-menu
	    lappend low [list ==$TXT(more) ...] \
		[PartitionSymbolMenu [lreplace $hdescr 0 $n]]
	    break
	}
	if { [regexp {^=(.+)$} $e x ti] } {
	    set sub 1
	    if { ! [regexp {^=(.+)$} $ti x ti] } { set ti $TXT($ti) }
	    lappend low ==$ti
	} else {
	    set sub 0
	    if { [lsearch -exact $UNKNOWNSYMBOLS $e] != -1 } {
		set t "~ $TXT(SY$e)"
	    } else { set t $TXT(SY$e) }
	    lappend low $e $t
	}
	incr n
    }
    return $low
}

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} {
    # fill a symbols menu using the low-level description built by
    #  proc InitSymbolMenuDescr
    #  $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 SYMENU

    FillSymbolsMenuRec $SYMENU $menu $menu $commd
    return
}

proc FillSymbolsMenuRec {ldescr topmenu menu commd} {
    # recursively fill a symbols menu using the low-level description $ldescr
    global SYMBOLIMAGE

    set mc 0
    foreach "e ei" $ldescr {
	if { [regexp {^==(.+)$} $e x txt] } {
	    # sub-menu title
	    set submenu $menu.m$mc ; incr mc
	    $menu add cascade -label $txt -menu $submenu
	    menu $submenu
	    FillSymbolsMenuRec $ei $topmenu $submenu $commd
	} else {
	    $menu add command -image $SYMBOLIMAGE($e) -accelerator $ei \
		    -command "$commd $e $menu"
	}
    }
    return
}

## user-defined menu

proc SymbolCustomMenu {} {
    # dialog for allowing the definition of the user symbol menu
    global SYDEFTMENU SYUSRMENU TXT MESS DPOSX DPOSY COLOUR MAPFTSIZES \
	SyCMenu LISTHEIGHT SYMBOLIMAGE ICONSIZE

    # used explicitly elsewhere
    set w .syumenu
    if { [winfo exists $w] } { bell ; Raise $w ; return }

    array set SyCMenu {
	cat ""
	submenus 0
	mtit,0 ""
	mparent,0 ""
	tmenu ""
	cmenu ""
    }

    GMToplevel $w syusrmenu +$DPOSX+$DPOSY {} \
        [list WM_DELETE_WINDOW "destroy $w"] {}

    label $w.tit -text $TXT(syusrmenu)
    frame $w.fr -relief flat -borderwidth 5
    label $w.fr.tit -text $TXT(cfgsymenu)

    # categories and symbols
    # $SYDEFTMENU assumed to have a sub-menu for each category and nothing
    #  else, with each sub-menu title given by =INDEX
    set frcs $w.fr.frcs
    frame $frcs
    frame $frcs.frrbs
    frame $frcs.frbx
    set n 0
    if { $ICONSIZE == "15x15" } {
	set width 150 ; set height 21
    } else { set width 280 ; set height 35 }
    foreach "title subm" $SYDEFTMENU {
	regsub {^=} $title "" ti
	if { $n == 0 } { set cat $ti }
	set box $frcs.frbx.bx$ti
	ImageListbox create $box 10 $width $height extended $frcs.frbx.scr$ti
	scrollbar $frcs.frbx.scr$ti -command "$box yview"
	foreach e $subm {
	    if { [regexp {^=} $e] } {
		BUG sub-menu in SYDEFTMENU
	    } 
	    ImageListbox insert $box end $SYMBOLIMAGE($e) $TXT(SY$e) $e
	}
	radiobutton $frcs.frrbs.b$n -text $TXT($ti) -variable SyCMenu(cat) \
	    -value $ti -command "SyCMenuAct chgcat $ti" -anchor w
	grid $frcs.frrbs.b$n -sticky ew
	incr n
    }
    grid $frcs.frrbs -row 1 -column 0 -sticky ne
    grid $frcs.frbx -row 0 -column 0
    SyCMenuAct chgcat $cat

    # inserting
    frame $w.fr.fradd
    foreach b "ab aa" ti "insb insa" {
	button $w.fr.fradd.b$b -text "--$TXT($ti)-->" -command "SyCMenuAct $ti"
	grid $w.fr.fradd.b$b -sticky ew
    }

    # menu project
    frame $w.fr.frmn
    label $w.fr.frmn.cmenu -textvariable SyCMenu(tmenu) -width 15 \
	-relief sunken -justify left
    set frmbx $w.fr.frmn.frbx
    frame $frmbx
    SyCMenuFill $frmbx $SYUSRMENU

    # menu project buttons
    set frmop $w.fr.frmn.frmop
    frame $frmop
    foreach op "insmnb insmna opensbmn clssbmn del" {
	button $frmop.b$op -text $TXT($op) \
	    -command "SyCMenuAct $op ; $frmop.b$op configure -state normal"
	grid $frmop.b$op -sticky nesw
    }
    grid [BalloonButton $frmop.bhlp syhlpbx]

    grid $w.fr.frmn.cmenu -row 0 -column 0 -sticky w
    grid $frmbx -row 1 -column 0
    grid $frmop -row 1 -column 1
    SyCMenuAct chgmenu 0

    # ok, cancel buttons
    frame $w.fr.frbs
    button $w.fr.frbs.ok -text $TXT(ok) -command "SyCMenuAct ok"
    button $w.fr.frbs.cnc -text $TXT(cancel) -command "SyCMenuAct cancel"
    grid $w.fr.frbs.ok
    grid $w.fr.frbs.cnc -row 0 -column 1

    grid $w.fr.tit -row 0 -column 0 -columnspan 3
    grid $frcs -row 2 -column 0 -sticky n -pady 5
    grid $w.fr.fradd -row 2 -column 1 -sticky n -pady 5 -padx 3
    grid $w.fr.frmn -row 2 -column 2 -sticky n -pady 5 -padx 3
    grid $w.fr.frbs -row 3 -column 0 -columnspan 3 -pady 5
    grid $w.fr
    update idletasks
    return
}

proc SyCMenuFill {frm hdescr} {
    # create and fill image listboxes for symbol menu high-level description
    #  $frm will be taken as parent window of listboxes and scrollbars
    #     using a scheme similar of that used for displaying the
    #     available symbols
    # the following elements of global array SyCMenu are used/set:
    #      submenus  - counter of sub-menus, used in naming widgets
    #      mtit,$sm  - title (literal text) of sub-menu $sm
    #      mparent,$sm  - parent of sub-menu $sm
    # this is a recursive procedure
    global SyCMenu SYMBOLIMAGE TXT

    set n $SyCMenu(submenus) ; incr SyCMenu(submenus)
    set box $frm.bx$n
    ImageListbox create $box 10 150 21 extended $frm.scr$n
    set SyCMenu($box,move) ""
    foreach ev "<Button-3> <ButtonRelease-3>" p "start end" {
	bind $box $ev "SyCMenuMove $p $box %x %y"
    }
    bind $box <B3-Enter> "SyCMenuMove enter-down $box %X %Y; break"
    foreach ev "<B3-Motion> <Any-Enter> <B3-Leave>" p "go enter leave" {
	bind $box $ev "SyCMenuMove $p $box %X %Y"
    }
    scrollbar $frm.scr$n -command "$box yview"
    set sub 0
    foreach e $hdescr {
	if { $sub } {
	    SyCMenuFill $frm $e
	    set sub 0
	    continue
	}
	if { [regexp {^=(.+)$} $e x ti] } {
	    set sub 1
	    if { ! [regexp {^=(.+)$} $ti x ti] } { set ti $TXT($ti) }
	    ImageListbox insert $box end "" ">>> $ti" @@@=$SyCMenu(submenus)
	    set SyCMenu(mtit,$SyCMenu(submenus)) $ti
	    set SyCMenu(mparent,$SyCMenu(submenus)) $n
	} else {
	    set sub 0
	    ImageListbox insert $box end $SYMBOLIMAGE($e) $TXT(SY$e) $e
	}
    }
    return
}

proc SyCBuildDescr {tags} {
    # build high-level description of symbol menu from tags in image
    #  listboxes
    global SyCMenu

    set w .syumenu
    set frmbx $w.fr.frmn.frbx
    set hd ""
    foreach t $tags {
	if { [regsub {^@@@=} $t "" n] } {
	    # sub-menu
	    set ts [ImageListbox gettags $frmbx.bx$n 0 end]
	    lappend hd "==$SyCMenu(mtit,$n)" [SyCBuildDescr $ts]
	} else { lappend hd $t }	
    }
    return $hd
}

proc SyCMenuAct {act args} {
    # deal with user action when setting up user symbol menu
    #  $act in {chgcat, chgmenu, insa, insb, insmnb, insmna, opensbmn,
    #           clssbmn, del, ok, cancel}
    #    described in switch below
    #  $args depends on $act: void except for
    #    chgcat   text index for symbol category name
    #    chgmenu  number of sub-menu (0 is top menu)
    global SyCMenu SyCMenuAux SYUSRMENU SYMBOLIMAGE TXT MESS

    set w .syumenu
    set frbx $w.fr.frcs.frbx
    set sybox $frbx.bx$SyCMenu(cat)
    set frmbx $w.fr.frmn.frbx
    set mnbox $frmbx.bx$SyCMenu(cmenu)
    switch -glob $act {
	chgcat {
	    # change to listbox for symbol category $args
	    set SyCMenu(cat) $args
	    foreach s [grid slaves $frbx] { grid forget $s }
	    grid $frbx.bx$args -row 0 -column 0
	    grid $frbx.scr$args -row -0 -column 1 -sticky ns
	}
	chgmenu {
	    # display another sub-menu
	    set SyCMenu(cmenu) $args
	    set SyCMenu(tmenu) $SyCMenu(mtit,$args)
	    foreach s [grid slaves $frmbx] { grid forget $s }
	    grid $frmbx.bx$args -row 0 -column 0
	    grid $frmbx.scr$args -row -0 -column 1 -sticky ns
	}
	ins? {
	    # insert selected symbols before/after current selection
	    #  in menu listbox or if there is no selection at the
	    #  beggining/end; bell if there are no symbols selected
	    if { [set selsys [ImageListbox getseltags $sybox]] == "" } {
		bell ; return
	    }
	    set inspt [ImageListbox cursel $mnbox]
	    if { $act == "insa" } {
		if { $inspt == "" } {
		    set inspt end
		} else {
		    set inspt [lindex $inspt end]
		    incr inspt
		}
	    } elseif { $inspt == "" } {
		set inspt 0
	    } else { set inspt [lindex $inspt 0] }
	    foreach e $selsys {
		ImageListbox insert $mnbox $inspt $SYMBOLIMAGE($e) \
		    $TXT(SY$e) $e
		if { $inspt != "end" } { incr inspt }
	    }
	}
	insmn? {
	    # insert a sub-menu before/after current selection
	    #  in menu listbox or if there is no selection at the
	    #  beggining/end
	    if { ! [GMChooseParams $TXT(cfgsymenu) SyCMenuAux \
			[list "=$TXT(name)"]] } {
		return
	    }
	    set inspt [ImageListbox cursel $mnbox]
	    if { $act == "insa" } {
		if { $inspt == "" } {
		    set inspt end
		} else {
		    set inspt [lindex $inspt end]
		    incr inspt
		}
	    } elseif { $inspt == "" } {
		set inspt 0
	    } else { set inspt [lindex $inspt 0] }
	    set n $SyCMenu(submenus)
	    ImageListbox insert $mnbox $inspt "" ">>> $SyCMenuAux" @@@=$n
	    set SyCMenu(mtit,$n) $SyCMenuAux
	    set SyCMenu(mparent,$n) $SyCMenu(cmenu)
	    SyCMenuFill $frmbx ""
	    SyCMenuAct chgmenu $n
	}
	opensbmn {
	    # display sub-menu whose entry is the current single selection in
	    #  menu listbox
	    if { [set tag [ImageListbox getseltags $mnbox]] == "" || \
		     [lindex $tag 1] != "" || ! [regsub {^@@@=} $tag "" n] } {
		bell ; return
	    }
	    SyCMenuAct chgmenu $n
	}
	clssbmn {
	    # close sub-menu and go to parent sub-menu
	    if { [set p $SyCMenu(mparent,$SyCMenu(cmenu))] == "" } {
		bell ; return
	    }
	    SyCMenuAct chgmenu $p
	}
	del {
	    # delete selected entries
	    ImageListbox seldel $mnbox
	}
	ok -  cancel {
	    # exit
	    if { $act == "ok" } {
		if { [set tags [ImageListbox gettags $frmbx.bx0 0 end]] \
			 == "" } {
		    if { ! [GMConfirm $MESS(emptymenu)] } { return }
		    set SYUSRMENU ""
		} else { set SYUSRMENU [SyCBuildDescr $tags] }
		SaveSymbolCustomMenu
		InitSymbolMenuDescr
	    }
	    ImageListbox destroyall $w
	    destroy $w
	}
    }
    return
}

proc SyCMenuMove {how box x y} {
    # move element in image listbox $box when changing symbol custom menu
    #  $how in {start, go, end, enter-down, enter, leave}
    #  $x,$y are either the coordinates inside the listbox (for $how==start
    #   and $how==end) or the global coordinates
    global SyCMenu COLOUR SYMBOLIMAGE TXT

    set tb .sycmove$SyCMenu(cmenu)
    switch $how {
	start {
	    set ix [ImageListbox index $box $y]
	    set txt [lindex [ImageListbox get $box $ix] 0]
	    if { $SyCMenu($box,move) == "" } {
		set SyCMenu($box,move) in
	    }
	    NewBalloon $tb $txt \
	     +[expr $x+[winfo rootx $box]+9]+[expr $y+[winfo rooty $box]+9]
	    set SyCMenu($box,move,tag) [ImageListbox gettags $box $ix]
	    set SyCMenu($box,move,txt) $txt
	    set SyCMenu($box,move,ix) $ix
	}
	enter-down {
	    if { $SyCMenu($box,move) == "out" } {
		if { [winfo exists $tb] } {
		    set SyCMenu($box,move) in
		    wm geometry $tb +[expr $x+9]+[expr $y+9]
		} else {
		    set SyCMenu($box,move) ""
		}
	    }
	}
	enter {
	    if { $SyCMenu($box,move) != "" } {
		destroy $tb ; set SyCMenu($box,move) ""
	    }
	}
	go {
	    if { $SyCMenu($box,move) == "in" && [winfo exists $tb] } {
		wm geometry $tb +[expr $x+9]+[expr $y+9]
	    }
	}
	end {
	    if { $SyCMenu($box,move) == "in" && [winfo exists $tb] } {
		destroy $tb ; set SyCMenu($box,move) ""
		set fix [ImageListbox index $box $y]
		set ix $SyCMenu($box,move,ix)
		if { $fix != $ix } {
		    if { [regexp {^@@@=} \
			      [set tag $SyCMenu($box,move,tag)]] } {
			set img ""
		    } else { set img $SYMBOLIMAGE($tag) }
		    ImageListbox delete $box $ix
		    ImageListbox insert $box $fix $img \
			$SyCMenu($box,move,txt) $tag
		}
	    }
	}
	leave {
	    if { $SyCMenu($box,move) == "in" } {
		set SyCMenu($box,move) out
	    }
	}
    }
    return
}

proc SaveSymbolCustomMenu {} {
    # save user-defined symbol menu
    global UFile MESS SYUSRMENU

    if { [catch {set f [open $UFile(symenu) w]}] } {
	GMMessage $MESS(cantwrtsymenu)
	return
    }
    puts $f ""
    puts $f "# $MESS(written) GPSMan [NowTZ]"
    puts $f "# $MESS(editrisk)"
    puts $f ""
    puts $f "set SYUSRMENU \{$SYUSRMENU\}"
    puts $f ""
    close $f
    return
}

proc LoadSymbolCustomMenu {} {
    # load user-defined symbol menu
    global UFile SYUSRMENU

    # assumed to be in system encoding
    source $UFile(symenu)
    return
}

## utilities

proc SymbolImageName {symbol} {
    # returns list with image and external name of $symbol
    # needed when $symbol may be user-defined
    #  THIS PROC IS NOT BEING USED when symbols are assumed to be
    #  standard ones (e.g., in search.tcl)
    global SYMBOLIMAGE TXT

    if { [regexp {^user:} $symbol] } {
	set symbol WP_dot
	set t usrdef
    } else { set t SY$symbol }
    return [list $SYMBOLIMAGE($symbol) $TXT($t)]
}

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

    if { [regexp {^user:} $name] } { return 0 }
    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]
}


