#
# This file is part of:
#
#  gpsman --- GPS Manager: a manager for GPS receiver data
#
# Copyright (c) 1998-2013 Miguel Filgueiras migfilg@t-online.de
#
#    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 3 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: setup.tcl
#  Last change:  6 October 2013
#
# Includes contributions by
#  - Brian Baulch (baulchb _AT_ onthenet.com.au) marked "BSB contribution"
#  - Matt Martin (matt.martin _AT_ ieee.org) marked "MGM contribution"
#  - Valere Robin (valere.robin _AT_ wanadoo.fr) marked "VR contribution"
#  - David Gardner (djgardner _AT_ users.sourceforge.net) marked
#    "DJG contribution"
#

# default set up code; may be overridden by a patch file

##### Img library

 # xbm gives black images
set ImgOutFormats {bmp gif jpeg png tiff xpm}

##### initialize interface

set NAMEWIDTH [expr $NAMELENGTH+2]
set COMMENTWIDTH [expr $COMMENTLENGTH+2]

set OBSWIDTH 40
set OBSHEIGHT 3

set DATEWIDTH $DATEW($DateFormat)

set DATUMWIDTH 32

set SUBDTUNIT $DLUNIT($DISTUNIT,subdist)

  # crosshair cursor centre in pixels from lower right corner
set CRHAIRx 5
set CRHAIRy 5

proc GlobalOptionsBindings {} {
    # change some of the default options and bindings of Tcl widgets
    global COLOUR

    option add *Frame.borderWidth 0
    option add *Frame.relief flat
    option add *Menubutton.relief raised
    option add *Menubutton.direction below
    option add *Menu.tearOff 0
    option add *Entry.exportSelection 1
    option add *Entry.disabledBackground $COLOUR(bg)
    option add *Checkbutton.selectColor $COLOUR(check)
    option add *Radiobutton.selectColor $COLOUR(check)
    option add *Text.wrap word
    option add *Text.exportSelection 1

    bind Listbox <B1-Leave> { break }
    bind Listbox <Button-2> { break }
    bind Listbox <B2-Motion> { break }
    return
}

proc GMInit {} {
    # set up main window(s)
    global MapHeight MapWidth LISTWIDTH LISTHEIGHT COLOUR MAPCOLOUR \
	VERSION SRCDIR LPOSX LPOSY MPOSX MPOSY RPOSX RPOSY MAPSCALE MAPDISTS \
	MAPDISTVALS MAPSCLENGTH MWINDOWSCONF TYPES RECTYPES MYGPS Temp1 List \
	ListInds EdWindow GPSLabel PositionFormat Datum GPSState Map \
	MapBounds TXT MESS DISTUNIT DTUNIT DSCALE SUBDTUNIT SUBDSCALE DLUNIT \
	MAPDISTUNITS MapScale MpW LsW RcW LsWTit MpWTit RcWTit WConf OVx OVy \
	XCoord YCoord MapZone MapProjTitle MapTransfTitle MapPFormat MapRange \
	MapWPMoving MapMakingRT MapLoading MapScInitVal MapImageItems \
	GetDispl MAPKNOWNPROJS RECPROTOCOLS SYMBOLIMAGE RcMenu GPSProtocol \
	GPSProtocolExt RealTimeLogAnim PVTState USvState \
	GSHPVersion NoImgLib ImgOutFormats SmallLogo UNIX GMEd FILEFORMAT \
	MapScaleButton MapPFDatum AutoNumRts SUPPORTLAPS FixedFont DATUMWIDTH \
	GPSProtocolButton RECINFO SERIALPORT RECBAUDS

    set MapBounds "0 0 $MapWidth $MapHeight"
    set MapRange(x) $MapWidth ; set MapRange(y) $MapHeight
    set MapRange(x0) 0 ; set MapRange(y0) 0
    set OVx 0 ; set OVy 0 ; set XCoord "" ; set YCoord "" ; set MapZone ""
    set MapWPMoving -1 ; set MapMakingRT 0 ; set MapLoading 0
    set MapImageItems ""

    option add *Foreground $COLOUR(fg)
    option add *Background $COLOUR(bg)

    wm protocol . WM_DELETE_WINDOW { QuitNow }
    wm title . "$TXT(GMtit) $VERSION"
    bind . <Control-c> QuitNow

    set mt [Measure "GPS Manager"]

    set WConf(datastate) ""

    switch $MWINDOWSCONF {
	lists {
	    set gtit .title
	    wm geometry . +$LPOSX+$LPOSY
	    set MpW .mpw.fr ; set LsW .lsw.frls ; set RcW .rcw.fr
	    frame .lsw
	    frame $LsW

	    foreach w ".mpw .rcw" t "MpW RcW" p "M R" z "nameMap GPSrec" {
		set ${t}Tit "GPS Manager"
		GMToplevel $w $z +[set ${p}POSX]+[set ${p}POSY] {} \
		    [list WM_DELETE_WINDOW "lower $w"] {}
		lower $w .
		frame [set $t] -borderwidth 10
	    }

	    button .rcw.tit -textvariable RcWTit -width $mt \
		    -command "Raise . ; .rcw.tit configure -state normal"
	    bind .rcw.tit <Enter> "set RcWTit {$TXT(mainwd)}"
	    bind .rcw.tit <Leave> "set RcWTit {GPS Manager}"

	    frame .mpw.top
	    frame .mpw.top.frNT
	    set ft .mpw.top.frNT
	    # to be filled in by proc ToTravel
	    frame .mpw.top.frT
	    set WConf(travel,fr) .mpw.top.frT
	    set WConf(travel,alt) $ft
	    button $ft.tit -textvariable MpWTit -width $mt \
		    -command "Raise . ; $ft.tit configure -state normal"
	    bind $ft.tit <Enter> "set MpWTit {$TXT(mainwd)}"
	    bind $ft.tit <Leave> "set MpWTit {GPS Manager}"

	    frame .lsw.frmb -borderwidth 2
	    menubutton .lsw.frmb.dtitle -text Datum -menu .lsw.frmb.dtitle.m
	    menu .lsw.frmb.dtitle.m \
		 -postcommand "FillDatumMenu .lsw.frmb.dtitle.m ChangeMapDatum"
	    label .lsw.frmb.datum -textvariable Datum \
		    -width $DATUMWIDTH

	    set t [Measure $TXT(GPSrec)]
	    frame .lsw.frmb.frb
	    frame .lsw.frmb.frb.sep -height 6 -bg $COLOUR(dialbg) -width $t
	    button .lsw.frmb.frb.load -text $TXT(load) \
		    -command { LoadFile Data ; \
		    .lsw.frmb.frb.load configure -state normal }
	    set m .lsw.frmb.frb.import.m
	    menubutton .lsw.frmb.frb.import -text $TXT(import) -menu $m
	    menu $m
	    foreach fmt $FILEFORMAT(_type,in,data) {
		$m add command -label $fmt -command "ImportFile Data $fmt"
	    }
	    button .lsw.frmb.frb.save -text $TXT(save) -state disabled \
		    -command { SaveFile all Data ; \
		    .lsw.frmb.frb.save configure -state normal }
	    # based on VR contribution
	    set m .lsw.frmb.frb.export.m
	    menubutton .lsw.frmb.frb.export -text $TXT(export) -menu $m \
		-state disabled
	    menu $m
	    foreach fmt $FILEFORMAT(_type,out,data) {
		$m add command -label $fmt -command "ExportFile all $fmt Data"
	    }
	    #--
	    button .lsw.frmb.frb.search -text $TXT(search) -state disabled \
		    -command { Search ; \
		    .lsw.frmb.frb.search configure -state normal }
	    frame .lsw.frmb.frb.sep2 -height 6 -bg $COLOUR(dialbg) -width $t
	    set WConf(datastate) [list [list \
		    button [list .lsw.frmb.frb.save .lsw.frmb.frb.export \
				.lsw.frmb.frb.search]]]
	    button .lsw.frmb.mpw -text $TXT(nameMap) -width $t \
		    -command "ToggleWindow .mpw $MPOSX $MPOSY ; \
		    .lsw.frmb.mpw configure -state normal"
	    set RcMenu .lsw.frmb.rcw.m
	    menubutton .lsw.frmb.rcw -text $TXT(GPSrec) -width $t -menu $RcMenu
	    frame .lsw.frmb.sep -height 6 -bg $COLOUR(dialbg) -width $t
	    button .lsw.frmb.opt -text $TXT(options) -width $t \
		    -command { SetOptions ; \
	                       .lsw.frmb.opt configure -state normal }
	}
	map {
	    wm geometry . +$MPOSX+$MPOSY
	    set MpW .fr ; set LsW .lsw.frbl.frls ; set RcW .rcw.fr
	    frame $MpW -borderwidth 5

	    foreach w ".lsw .rcw" t "LsW RcW" p "L R" z "nameLists GPSrec" {
		set ${t}Tit "GPS Manager"
		GMToplevel $w $z +[set ${p}POSX]+[set ${p}POSY] {} \
		    [list WM_DELETE_WINDOW "lower $w"] {}
		lower $w .
		button $w.tit -textvariable ${t}Tit -width $mt \
			-command "Raise . ; $w.tit configure -state normal"
		bind $w.tit <Enter> "set ${t}Tit {$TXT(mainwd)}"
		bind $w.tit <Leave> "set ${t}Tit {GPS Manager}"
	    }

	    frame .rcw.fr -borderwidth 10

	    frame .lsw.frbl
	    frame .lsw.frbl.frls -borderwidth 10
	    frame .lsw.frbl.frb
	    button .lsw.frbl.frb.load -text $TXT(load) \
		    -command { LoadFile Data ; \
		    .lsw.frbl.frb.load configure -state normal }
	    set m .lsw.frbl.frb.import.m
	    menubutton .lsw.frbl.frb.import -text $TXT(import) -menu $m
	    menu $m
	    foreach fmt $FILEFORMAT(_type,in,data) {
		$m add command -label $fmt -command "ImportFile Data $fmt"
	    }
	    button .lsw.frbl.frb.save -text $TXT(save) -state disabled \
		    -command { SaveFile all Data ; \
		    .lsw.frbl.frb.save configure -state normal }
	    # based on VR contribution
	    set m .lsw.frbl.frb.export.m
	    menubutton .lsw.frbl.frb.export -text $TXT(export) -menu $m \
		-state disabled
	    menu $m
	    foreach fmt $FILEFORMAT(_type,out,data) {
		$m add command -label $fmt -command "ExportFile all $fmt Data"
	    }
	    #--
	    button .lsw.frbl.frb.search -text $TXT(search) -state disabled \
		    -command { Search ; \
		    .lsw.frbl.frb.search configure -state normal }
	}
    }

    frame $MpW.frm
    frame $MpW.frm.frmap1
    set Map $MpW.frm.frmap1.map
    canvas $Map -borderwidth 5 -relief groove -confine true \
	    -scrollregion $MapBounds \
	    -width $MapWidth -height $MapHeight \
	    -xscrollincrement 1 -yscrollincrement 1 \
	    -xscrollcommand "$MpW.frm.frmap1.mhscr set" \
	    -yscrollcommand "$MpW.frm.frmap1.mvscr set"
    bind $Map <Configure> { MapResize }
    scrollbar $MpW.frm.frmap1.mvscr -command "ScrollMap y"
    scrollbar $MpW.frm.frmap1.mhscr -command "ScrollMap x" -orient horizontal

    frame $MpW.frm.frmap3
    # need another frame for the map-main-window layout
    frame $MpW.frm.frmap3.fr3
    set fr3 $MpW.frm.frmap3.fr3
    canvas $fr3.cv -width $MAPSCLENGTH -height 15 -relief flat
    label $fr3.cv.val -width 10 -font $FixedFont
    $fr3.cv create line 0 7.5 $MAPSCLENGTH 7.5 -arrow both \
	    -fill $MAPCOLOUR(mapsel)
    $fr3.cv create line 1 0 1 15 -fill $MAPCOLOUR(mapsel)
    set l [expr $MAPSCLENGTH-1]
    $fr3.cv create line $l 0 $l 15 -fill $MAPCOLOUR(mapsel)
    $fr3.cv create window [expr $MAPSCLENGTH/2] 7.5 \
	    -window $fr3.cv.val
    menubutton $fr3.mn -text $TXT(change) -menu $fr3.mn.m
    menu $fr3.mn.m
    set nf 1 ; set nmd "" ; set MAPDISTVALS ""
    set u $SUBDTUNIT ; set f $SUBDSCALE ; set ims [lindex $MAPSCALE 0]
    set imsu [lreplace $MAPSCALE 0 0]
    # map scale in meters/pixel
    if { $imsu == [lindex $MAPDISTUNITS($DISTUNIT) 0] } {
	set ds $DSCALE
    } else { set ds $SUBDSCALE }
    set MapScale [expr $ims*$ds*1000.0/$MAPSCLENGTH]
    foreach d $MAPDISTS {
	set v [lindex $d 0]
	if { $v == 1 } {
	    set u $DTUNIT ; set f 1
	}
	set ad [expr $v*$f] ; set t "$v $u"
	lappend nmd $t ; lappend MAPDISTVALS $ad
	$fr3.mn.m add radiobutton -label $t -value $t \
	    -variable MapScaleButton -selectcolor $COLOUR(check) \
	    -command "MapScaleSet $ad"
	if { $v == $ims } {
	    # cannot call MapScaleSet yet!
	    set nf 0 ; set MapScInitVal $ad
	    set MapScaleButton $t
	    $fr3.cv.val configure -text $t
	}
    }
    if { $nf } {
	if { $imsu != $DTUNIT && $imsu != $SUBDTUNIT && \
		[lsearch -exact $MAPDISTUNITS($DISTUNIT) $imsu] == -1 } {
	    GMMessage "$MESS(baddistunit): $imsu"
	} else {
	    GMMessage "$MESS(badscale): $MAPSCALE"
	}
	set MapScInitVal 1 ; set t "1 $DTUNIT"
	set MapScaleButton $t
	$fr3.cv.val configure -text "1 $DTUNIT"
    }
    # labels in map scale menu aligned with km values in $MAPDISTVALS    
    set MAPDISTS $nmd

    frame $fr3.sep -height 6 -bg $COLOUR(dialbg) -width 5
    set mb $fr3.sh
    menubutton $mb -text $TXT(items) -menu $mb.m
    menu $mb.m
    foreach op "loc disp clr" lb "locate displ clear" exc "GR _ GR" \
	    fp "SelectApplyMapped SelectApplyUnmapped SelectApplyMapped" \
	    cm "Locate PutMap UnMap" mode "single many many" {
	set mn $mb.m$op
	$mb.m add cascade -label $TXT($lb) -menu $mn -state disabled
	menu $mn
	foreach wh $TYPES {
	    if { $wh != $exc } {
		$mn add command -label $TXT(name$wh) \
			-command "$fp $wh $mode $cm"
	    }
	}
    }   
    $mb.mloc insert 0 command -label $TXT(prevctr) -command LocatePrevious
    # DJG contribution
    $mb.m add cascade -label "$TXT(mkgrp)..." -menu $mb.m.mkg
    menu $mb.m.mkg
    $mb.m.mkg add command -label $TXT(dispitems) -command "NewGroupFromMap 1" 
    $mb.m.mkg add command -label $TXT(hiditems) -command "NewGroupFromMap 0"
    #--
    set WConf(mapstate) [list [list menu [list [list $mb.m [list 0 2]]]]]
    lappend WConf(datastate) [list menu [list [list $mb.m 1]]]

    frame $MpW.frmi

    set ltypes $TYPES
    if { $SUPPORTLAPS } { lappend ltypes LAP }
    switch $MWINDOWSCONF {
	lists {
	    set WConf(mapdatum) "$MpW.frmi.frcoords.dtitle \
		    $MpW.frmi.frcoords.ptitle"
	    lappend WConf(mapstate) \
		[list button \
		     [list $MpW.frmi.frmbs.msave $MpW.frmi.frmbs.mprint \
			  $MpW.frmi.frmbs.mclear $MpW.frmi.frmbs.mft]]
	    set WConf(mapstateback) \
		[list [list menu [list \
				      [list $MpW.frmi.frmbs.mback.m \
					   [list 1 2 3 4]]]]]
	    set WConf(additemstate) ""

	    set bl [Measure $TXT(backgrnd)]
	    frame $MpW.frmi.frmbs -borderwidth 2
	    label $MpW.frmi.frmbs.mtitle -text $TXT(map)
	    menubutton $MpW.frmi.frmbs.grid -textvariable MapPFormat \
		    -width 8 -menu $MpW.frmi.frmbs.grid.m
	    menu $MpW.frmi.frmbs.grid.m -postcommand \
		"FillPFormtMenu $MpW.frmi.frmbs.grid.m ChangeMapPFormat"
	    set mb $MpW.frmi.frmbs.grdatum
	    menubutton $mb -textvariable MapPFDatum \
		    -width $DATUMWIDTH -menu $mb.m
	    menu $mb.m -postcommand "FillDatumMenu $mb.m ChangeMPFDatum"

	    label $MpW.frmi.frmbs.zone -textvariable MapZone -width 4 \
		    -relief sunken
	    label $MpW.frmi.frmbs.xcoord -textvariable XCoord -width 11 \
		    -relief sunken
	    label $MpW.frmi.frmbs.ycoord -textvariable YCoord -width 11 \
		    -relief sunken
	    if { $NoImgLib } {
		button $MpW.frmi.frmbs.msave -text "$TXT(saveto) PS" \
			-command "SaveMap PS ; \
		              $MpW.frmi.frmbs.msave configure -state normal" \
			-state disabled -width $bl
	    } else {
		set m $MpW.frmi.frmbs.msave.m
		menubutton $MpW.frmi.frmbs.msave -text "$TXT(saveto)..." \
			-menu $m -state disabled -width $bl
		menu $m
		$m add command -label PS -command { SaveMap PS }
		foreach f $ImgOutFormats {
		    $m add command -label $f -command "SaveMap $f"
		}
	    }
	    button $MpW.frmi.frmbs.mprint -text $TXT(print) \
		    -command "PrintMap ; \
		              $MpW.frmi.frmbs.mprint configure -state normal" \
		    -state disabled -width $bl
	    menubutton $MpW.frmi.frmbs.mback -text $TXT(backgrnd) -width $bl \
		    -menu $MpW.frmi.frmbs.mback.m
	    set mbmn $MpW.frmi.frmbs.mback.m
	    menu $mbmn
	    # order of entries used in file map.tcl
	    $mbmn add cascade -label $TXT(loadmback) -menu $mbmn.m
	    menu $mbmn.m
	    $mbmn.m add command -label $TXT(fromfile) -command LoadMapBack
	    menu $mbmn.m.defs \
		-postcommand [list FillDefsMenu backgrnd $mbmn.m.defs \
				  LoadMapBack]
	    $mbmn.m add cascade -label $TXT(fromdef) -menu $mbmn.m.defs
	    foreach f [list $TXT(savemback) $TXT(exportTFW) $TXT(chgmback) \
		            $TXT(clearmback)] \
		    c {SaveMapBack ExportMapTFW ChangeMapBack ClearMapBack} \
		    s {normal disabled disabled disabled disabled} {
		$mbmn add command -label $f -command $c -state $s
	    }
	    button $MpW.frmi.frmbs.mclear -text $TXT(clear) -state disabled \
		    -width $bl \
		    -command "ClearMap ; \
		    $MpW.frmi.frmbs.mclear configure -state normal"
	    button $MpW.frmi.frmbs.mft -text $TXT(optMAPFONT) \
		-state disabled -width $bl \
		-command "CanvasChangeFont $Map MapFont MapFont;
		    $MpW.frmi.frmbs.mft configure -state normal"

	    frame $MpW.frmi.frcoords -borderwidth 2
	    menubutton $MpW.frmi.frcoords.dtitle -text Datum \
		    -menu $MpW.frmi.frcoords.dtitle.m
	    set dm $MpW.frmi.frcoords.dtitle.m
	    menu $dm -postcommand "FillDatumMenu $dm ChangeMapDatum"
	    label $MpW.frmi.frcoords.datum -textvariable Datum \
		    -width $DATUMWIDTH
	    menubutton $MpW.frmi.frcoords.ptitle -text $TXT(projection) \
		    -menu $MpW.frmi.frcoords.ptitle.m
	    menu $MpW.frmi.frcoords.ptitle.m \
		    -postcommand "FillProjsMenu $MpW.frmi.frcoords.ptitle.m \
		                   MAPKNOWNPROJS MapProjectionIs"
	    label $MpW.frmi.frcoords.proj -textvariable MapProjTitle \
		    -width 20
	    label $MpW.frmi.frcoords.ttitle -relief raised -text $TXT(transf)
	    label $MpW.frmi.frcoords.transf -textvariable MapTransfTitle \
		     -width 20

	    set defsmnbt $MpW.frmi.frcoords.udefs
	}
	map {
	    frame $MpW.frm.top -borderwidth 2
	    frame $MpW.frm.top.frmap0
	    # to be filled in by proc ToTravel
	    frame $MpW.frm.top.frmapT
	    set WConf(travel,fr) $MpW.frm.top.frmapT
	    set WConf(travel,alt) [set fr0 $MpW.frm.top.frmap0]
	    set gtit $fr0.title

	    menubutton $fr0.db -text $TXT(nameData) -width $mt -menu $fr0.db.m
	    menu $fr0.db.m
	    $fr0.db.m add command -label "$TXT(load) ..." \
		    -command "LoadFile Data"
	    set m $fr0.db.m.import
	    menu $m
	    $fr0.db.m add cascade -label "$TXT(import) ..." -menu $m
	    foreach fmt $FILEFORMAT(_type,in,data) {
		$m add command -label $fmt -command "ImportFile Data $fmt"
	    }
	    $fr0.db.m add command -label "$TXT(save) ..." \
		    -command "SaveFile all Data" -state disabled
	    # VR contribution
	    set m $fr0.db.m.export
	    menu $m
	    $fr0.db.m add cascade -label "$TXT(export) ..." -menu $m \
		-state disabled
	    foreach fmt $FILEFORMAT(_type,out,data) {
		$m add command -label $fmt -command "ExportFile all $fmt Data"
	    }
	    #--
	    $fr0.db.m add command -label $TXT(nameLists) \
		    -command "ToggleWindow .lsw $LPOSX $LPOSY"
	    $fr0.db.m add command -label "$TXT(search) ..." -command Search \
		    -state disabled
	    foreach i $ltypes {
		set openits [format $TXT(openits) $i]
		set m $fr0.db.m.e$i
		$fr0.db.m add cascade -label $TXT(name$i) -menu $m
		menu $m
		if { $i == "GR" } {
		    set tits [list $TXT(newGR) $openits $TXT(clearall) \
			       "$TXT(loadgrels) ..." $TXT(count)]
		    set coms [list NewItem OpenSelItems ClearList \
				  LoadGREls Count]
		    set sts "normal disabled disabled disabled normal"
		    set im 4
		    set imp importgrels ; set impst disabled
		    set imppr ImportGREls
		    set acts "save saveels"
		    set prs "SaveFile SaveGREls"
		    set exp exportels ; set exppr ExportGREls
		} elseif { $i != "LAP" } {
		    set tits [list $TXT(new$i) $openits $TXT(clearall) \
				  $TXT(count)]
		    set coms [list NewItem OpenSelItems ClearList Count]
		    set sts "normal disabled disabled normal"
		    set im 3
		    set imp import ; set impst normal
		    set imppr ImportFile
		    set acts save ; set prs SaveFile
		    set exp export ; set exppr ExportFile
		} else {
		    # LAP
		    set tits [list $openits $TXT(clearall) $TXT(count)]
		    set coms "OpenSelItems ClearList Count"
		    set sts "disabled disabled normal"
		    set im 2
		    set imp "" ; set impst "" ; set imppr ""
		    set acts save ; set prs SaveFile
		    set exp "" ; set exppr ""
		}
		foreach l $tits c $coms s $sts {
		    $m add command -label $l -command "$c $i" -state $s
		}
		foreach ip $imp s $impst p $imppr {
		    $m insert $im cascade -label "$TXT($ip) ..." \
			    -menu $m.$ip -state $s
		    menu $m.$ip
		    foreach fmt $FILEFORMAT(_type,in,$i) {
			regsub -all { } $fmt {_} gfmt
			$m.$ip add command -label $fmt -command "$p $i $gfmt"
		    }
		    incr im
		}
		foreach a $acts p $prs {
		    $m insert $im cascade -label "$TXT($a) ..." \
			    -menu $m.$a -state disabled
		    menu $m.$a
		    $m.$a add command -label $TXT(all) -command "$p all $i"
		    $m.$a add command -label "$TXT(select) ..." \
			    -command "$p select $i"
		    incr im
		}
		foreach ep $exp p $exppr {
		    $m insert $im cascade -label "$TXT($ep) ..." \
			    -menu $m.$ep -state disabled
		    menu $m.$ep
		    foreach fmt $FILEFORMAT(_type,out,$i) {
			regsub -all { } $fmt {_} gfmt
			$m.$ep add cascade -label $fmt -menu $m.$ep.f$gfmt
			menu $m.$ep.f$gfmt
			$m.$ep.f$gfmt add command -label $TXT(all) \
				-command "$p all $gfmt $i"
			$m.$ep.f$gfmt add command -label "$TXT(select) ..." \
				-command "$p select $gfmt $i"
		    }
		    incr im
		}
		if { $i == "WP" } {
		    $m insert [expr [$m index end]-1] cascade \
			-label $TXT(chgname) -menu $m.ren -state disabled
		    menu $m.ren
		    menu $m.ren.m -postcommand \
			[list FillDefsMenu renamethod $m.ren.m WPChangeNames]
		    $m.ren add cascade -label $TXT(use) -menu $m.ren.m
		    $m.ren add command -label $TXT(define) \
			-command "WPChangeNames \[Define renamethod\]"
		}
	    }

	    set RcMenu $fr0.rcw.m
	    menubutton $fr0.rcw -text $TXT(GPSrec) -width $mt -menu $RcMenu
	    menubutton $fr0.map -text $TXT(nameMap) -width $mt -menu $fr0.map.m
	    menu $fr0.map.m
	    # order of entries used in file map.tcl (proc SetMapBounds)
	    if { $NoImgLib } {
		$fr0.map.m add command -label "$TXT(saveto) PS" \
			-command { SaveMap PS } -state disabled
	    } else {
		set m $fr0.map.mapsave
		$fr0.map.m add cascade -label "$TXT(saveto)..." -menu $m \
			 -state disabled
		menu $m
		$m add command -label PS -command { SaveMap PS }
		foreach f $ImgOutFormats {
		    $m add command -label $f -command "SaveMap $f"
		}
	    }
	    $fr0.map.m add command -label $TXT(print) -command PrintMap \
		    -state disabled
	    $fr0.map.m add cascade -label $TXT(backgrnd) -menu $fr0.map.mback
	    menu $fr0.map.mback
	    $fr0.map.mback add cascade -label $TXT(loadmback) \
		-menu $fr0.map.mback.m
	    menu $fr0.map.mback.m
	    $fr0.map.mback.m add command -label $TXT(fromfile) \
		-command LoadMapBack
	    menu $fr0.map.mback.m.defs \
		-postcommand [list FillDefsMenu backgrnd \
				  $fr0.map.mback.m.defs LoadMapBack]
	    $fr0.map.mback.m add cascade -label $TXT(fromdef) \
		-menu $fr0.map.mback.m.defs	    
	    foreach f [list $TXT(savemback) $TXT(exportTFW) $TXT(chgmback) \
		            $TXT(clearmback)] \
		    c {SaveMapBack ExportMapTFW ChangeMapBack ClearMapBack} \
		    s {disabled disabled disabled disabled} {
		$fr0.map.mback add command -label $f -command $c -state $s
	    }
	    $fr0.map.m add command -label $TXT(clear) -command ClearMap \
		    -state disabled
	    $fr0.map.m add command -label $TXT(optMAPFONT) \
		    -command "CanvasChangeFont $Map MapFont MapFont"

	    set defsmnbt $fr0.udefs

	    button $fr0.options -text $TXT(options) -width $mt \
		    -command "SetOptions ; \
		    $fr0.options configure -state normal"

	    frame $MpW.frm.frmap3.fr4 -borderwidth 1 -bg $COLOUR(messbg)
	    set fr4 $MpW.frm.frmap3.fr4

	    menubutton $fr4.datum -textvariable Datum -menu $fr4.datum.m \
		    -width $DATUMWIDTH
	    menu $fr4.datum.m \
		    -postcommand "FillDatumMenu $fr4.datum.m ChangeMapDatum"
	    menubutton $fr4.proj -textvariable MapProjTitle -width 20 \
		    -menu $fr4.proj.m
	    menu $fr4.proj.m \
		    -postcommand "FillProjsMenu $fr4.proj.m \
		                     MAPKNOWNPROJS MapProjectionIs"
	    label $fr4.transf -textvariable MapTransfTitle -relief raised \
		    -width 20

	    frame $MpW.frm.frmap3.fr5 -borderwidth 1 -bg $COLOUR(messbg)
	    set fr5 $MpW.frm.frmap3.fr5

	    menubutton $fr5.grid -textvariable MapPFormat -width 8 \
		    -menu $fr5.grid.m
	    menu $fr5.grid.m \
		    -postcommand "FillPFormtMenu $fr5.grid.m ChangeMapPFormat"
	    label $fr5.zone -textvariable MapZone -width 4 -relief sunken
	    label $fr5.xcoord -textvariable XCoord -width 11 -relief sunken
	    label $fr5.ycoord -textvariable YCoord -width 11 -relief sunken
	    menubutton $fr5.grdat -textvariable MapPFDatum \
		    -width $DATUMWIDTH -menu $fr5.grdat.m
	    menu $fr5.grdat.m \
		    -postcommand "FillDatumMenu $fr5.grdat.m ChangeMPFDatum"

	    set WConf(mapdatum) "$fr4.datum $fr4.proj"
	    lappend WConf(mapstate) \
		[list menu [list [list $fr0.map.m [list 0 1 3 4]]]]
	    set WConf(mapstateback) \
		[list [list menu [list \
				      [list $fr0.map.mback [list 1 2 3 4]]]]]
	    set WConf(additemstate) $fr0.db.m.e
	    lappend WConf(datastate) \
		    [list menu [list [list $fr0.db.m [list 2 3 5]]]] \
		    [list button [list .lsw.frbl.frb.save \
				      .lsw.frbl.frb.export \
				      .lsw.frbl.frb.search]]
	}
    }

    set mn $defsmnbt.mn
    menubutton $defsmnbt -text $TXT(defs) -menu $mn
    menu $mn
    $mn add cascade -label $TXT(projection) -menu $mn.proj
    menu $mn.proj
    $mn.proj add command -label $TXT(define) -command DefineProjection
    menu $mn.proj.mn \
	    -postcommand "FillProjsMenu $mn.proj.mn UProjs OpenUserProjection"
    $mn.proj add cascade -label "$TXT(open)..." -menu $mn.proj.mn
    foreach t {datum ellpsd backgrnd renamethod plugin} {
	$mn add separator
	$mn add cascade -label $TXT($t) -menu $mn.$t
	menu $mn.$t
	$mn.$t add command -label $TXT(define) -command "Define $t"
	menu $mn.$t.mn -postcommand [list FillDefsMenu $t $mn.$t.mn \
					 [list Inspect $t]]
	$mn.$t add cascade -label "$TXT(open)..." -menu $mn.$t.mn
    }
    # menu used for plug-ins (see array PLGSWelcomed, plugins.tcl)
    menu $mn.plugin.exec
    $mn.plugin add cascade -label "$TXT(use)..." -menu $mn.plugin.exec
    $mn add separator
    $mn add command -label $TXT(syusrmenu) -command SymbolCustomMenu

    if { $SmallLogo == "" } {
	menubutton $gtit -text "GPS Manager" -menu $gtit.m
    } else {
	menubutton $gtit -image $SmallLogo -menu $gtit.m
    }
    menu $gtit.m
    $gtit.m add command -label $TXT(about) -command About
    $gtit.m add command -label $TXT(exit) -command QuitNow

    set tw [Measure $TXT(nameWP)]
    set bw [Measure $TXT(clear)]
    foreach i $ltypes {
	set openits [format $TXT(openits) $i]	
	set EdWindow($i) .gm$i ; set ListInds($i) ""
	set GMEd($i,Show) 0

	set n $TXT(name$i)
	set List($i) $LsW.frl$i.frl.box
	frame $LsW.frl$i -borderwidth 2
	frame $LsW.frl$i.frb
	menubutton $LsW.frl$i.frb.file -text $n -width $tw \
		-menu $LsW.frl$i.frb.file.m
	menu $LsW.frl$i.frb.file.m
	frame $LsW.frl$i.frl
	listbox $LsW.frl$i.frl.box -height $LISTHEIGHT -width $LISTWIDTH \
 	    -yscrollcommand "$LsW.frl$i.frl.bscr set" \
 	    -selectmode single -exportselection 1
	# SH contribution: no such bindings in non-unix systems
	if { $UNIX } {
	    bind $LsW.frl$i.frl.box <Enter> { focus %W }
	    bind $LsW.frl$i.frl.box <Leave> "focus $LsW"
	}
	bind $LsW.frl$i.frl.box <Double-1> "OpenListItem $i"
	bind $LsW.frl$i.frl.box <Key> { ScrollListIndex %W %A }
	scrollbar $LsW.frl$i.frl.bscr -command "$LsW.frl$i.frl.box yview"
	# BSB contribution: wheelmouse scrolling
	Mscroll $LsW.frl$i.frl.box

	# order of menu entries is used elsewhere!
	if { $i == "GR" } {
	    set tits [list $TXT(newGR) $openits $TXT(clearall) \
			  "$TXT(load) ..." "$TXT(loadgrels) ..." $TXT(count)]
	    set coms "NewItem OpenSelItems ClearList LoadFile LoadGREls Count"
	    set sts "normal disabled disabled normal disabled normal"
	    set im 5
	    set imp importgrels ; set impst disabled
	    set imppr ImportGREls
	    set acts "save saveels"
	    set prs "SaveFile SaveGREls"
	    set exp exportels ; set exppr ExportGREls
	} elseif { $i != "LAP" } {
	    set tits [list $TXT(new$i) $openits $TXT(clearall) \
			  "$TXT(load) ..." $TXT(count)]
	    set coms "NewItem OpenSelItems ClearList LoadFile Count"
	    set sts "normal disabled disabled normal normal"
	    set im 4
	    set imp import ; set impst normal
	    set imppr ImportFile
	    set acts save ; set prs SaveFile
	    set exp export ; set exppr ExportFile
	} else {
	    # LAP
	    set tits [list $openits $TXT(clearall) "$TXT(load) ..." \
			  $TXT(count)]
	    set coms "OpenSelItems ClearList LoadFile Count"
	    set sts "disabled disabled normal normal"
	    set im 3
	    set imp "" ; set impst "" ; set imppr ""
	    set acts save ; set prs SaveFile
	    set exp "" ; set exppr ""
	}
	set m $LsW.frl$i.frb.file.m
	foreach l $tits c $coms s $sts {
	    $m add command -label $l -command "$c $i" -state $s
	}
	foreach ip $imp s $impst p $imppr {
	    $m insert $im cascade -label "$TXT($ip) ..." -menu $m.$ip -state $s
	    menu $m.$ip
	    foreach fmt $FILEFORMAT(_type,in,$i) {
		$m.$ip add command -label $fmt -command "$p $i $fmt"
	    }
	    incr im
	}
	foreach a $acts p $prs {
	    $m insert $im cascade -label "$TXT($a) ..." \
		    -menu $m.$a -state disabled
	    menu $m.$a
	    $m.$a add command -label $TXT(all) -command "$p all $i"
	    $m.$a add command -label "$TXT(select) ..." -command "$p select $i"
	    incr im
	}
	foreach ep $exp p $exppr {
	    $m insert $im cascade -label "$TXT($ep) ..." \
		    -menu $m.$ep -state disabled
	    menu $m.$ep
	    foreach fmt $FILEFORMAT(_type,out,$i) {
		$m.$ep add cascade -label $fmt -menu $m.$ep.f$fmt
		menu $m.$ep.f$fmt
		$m.$ep.f$fmt add command -label $TXT(all) \
			-command "$p all $fmt $i"
		$m.$ep.f$fmt add command -label "$TXT(select) ..." \
			-command "$p select $fmt $i"
	    }
	    incr im
	}
	if { $i == "WP" } {
	    $m insert [expr [$m index end]-1] cascade -label $TXT(chgname) \
		-menu $m.ren -state disabled
	    menu $m.ren
	    menu $m.ren.m -postcommand [list FillDefsMenu \
					 renamethod $m.ren.m WPChangeNames]
	    $m.ren add cascade -label $TXT(use) -menu $m.ren.m
	    $m.ren add command -label $TXT(define) \
		-command "WPChangeNames \[Define renamethod\]"
	}
    }
    foreach t $TYPES {
	bind $LsW.frl$t.frl.box <Button-3> \
	    "ToggleDisplayItem $t \[%W nearest %y\]"
    }

    frame $RcW.frgps -borderwidth 2
    if { $MYGPS == "Garmin" } {
	global MyProdDescr

	set MyProdDescr $TXT(GPSrec)
	label $RcW.frgps.title -width 40 -textvariable MyProdDescr
    } else {
	label $RcW.frgps.title -text $TXT(GPSrec)
    }

    # receiver window; create and fill also receiver menu
    # changes here should be reflected in procs DisableGPS and EnableGPs
    #  in file gpsinfo.tcl
    menu $RcMenu
    $RcMenu add command -label $TXT(recwindow) \
	    -command "ToggleWindow .rcw $RPOSX $RPOSY"
    $RcMenu add separator
    menu $RcMenu.dev
    menu $RcMenu.pm
    $RcMenu add cascade -label $TXT(optDEFSPORT) -menu $RcMenu.dev
    $RcMenu add cascade -label $TXT(protcl) -menu $RcMenu.pm

    frame $RcW.frgps.dev -borderwidth 2 -bg $COLOUR(messbg)
    set fdev $RcW.frgps.dev
    # changing device when not connected
    label $fdev.tdev -text $TXT(optDEFSPORT)
    entry $fdev.dev -width 14 -textvariable SERIALPORT
    $RcMenu.dev add command -label $TXT(chgdev) -command GPSChangeDevice
    # changing baud rate when connected
    if { $MYGPS == "Garmin" } {
	menubutton $fdev.baud -text $TXT(optSERIALBAUD) \
	    -menu $fdev.baud.mn -state disabled
	menu $fdev.baud.mn
	$RcMenu.dev add cascade -label $TXT(optSERIALBAUD) \
	    -menu $RcMenu.dev.baud -state disabled
	menu $RcMenu.dev.tbaud
	foreach b $RECBAUDS {
	    $fdev.baud.mn add command -label $b -command "GPSChangeBaud $b"
	    $RcMenu.dev.tbaud add command -label $b -command "GPSChangeBaud $b"
	}
    }

    frame $RcW.frgps.prt -borderwidth 2 -bg $COLOUR(messbg)
    set fprt $RcW.frgps.prt
    menubutton $fprt.title -text $TXT(protcl) -menu $fprt.title.m
    menu $fprt.title.m
    set GPSProtocolExt $TXT($GPSProtocol)
    foreach p $RECPROTOCOLS($MYGPS) {
	$fprt.title.m add command -label $TXT($p) \
		-command "GPSChangeProtocol $p"
	$RcMenu.pm add radiobutton -label $TXT($p) -value $p \
	    -variable GPSProtocolButton -selectcolor $COLOUR(check) \
	    -command "GPSChangeProtocol $p"
    }
    set GPSProtocolButton $GPSProtocol
    label $fprt.prot -textvariable GPSProtocolExt -width 16
    
    if { $MYGPS != "Magellan" } {
	frame $RcW.frgps.rlt -borderwidth 2 -bg $COLOUR(messbg)
	set frlt $RcW.frgps.rlt
	label $frlt.title -text $TXT(realtimelog)
	menu $RcMenu.rtm
	$RcMenu add cascade -label $TXT(realtimelog) -menu $RcMenu.rtm
	$RcMenu.rtm add command -label $TXT(getlog) \
		-command GPSRealTimeLogOnOff
	$RcMenu.rtm add command -label $TXT(dolog) -command { set PVTState on }
	$RcMenu.rtm add checkbutton -label $TXT(animation) \
	        -offvalue 0 -onvalue 1 -variable RealTimeLogAnim \
	        -selectcolor $COLOUR(check)
	# Travel entry added below if Garmin

	button $frlt.onoff -text $TXT(getlog) -width 10 \
		-command "GPSRealTimeLogOnOff ; \
		$frlt.onoff configure -state normal"
	button $frlt.show -text $TXT(dolog) \
		-command "set PVTState on ; $frlt.show configure -state normal"
	button $frlt.anim -text $TXT(animation) \
		-command "set RealTimeLogAnim 1 ; \
		$frlt.anim configure -state normal"
	set WConf(realtime) [list $frlt.onoff [list $RcMenu.rtm 0]]
	set WConf(realtimetype) "button menuentry"
	grid configure $frlt.title -row 0 -column 0 -columnspan 2 -sticky news
	grid configure $frlt.onoff -row 1 -column 0 -rowspan 2 -sticky ew
	grid configure $frlt.show -row 1 -column 1 -sticky news
	grid configure $frlt.anim -row 2 -column 1 -sticky news
	if { $MYGPS == "Garmin" } {
	    $RcMenu.rtm add separator
	    $RcMenu.rtm add command -label $TXT(travel) -command ToTravel
	    button $frlt.trv -text $TXT(travel) \
		    -command "$frlt.trv configure -state normal ; ToTravel"
	    grid configure $frlt.trv -row 3 -column 0 -columnspan 2
	}
    } else {
	set WConf(realtime) ""
	set WConf(realtimetype) ""
    }

    frame $RcW.frgps.bs -borderwidth 2
    set GPSState offline ; set GPSLabel $TXT(offline)
    set r [Measure "Turn Off"]
    button $RcW.frgps.bs.state -textvariable GPSLabel -fg $COLOUR(offline) \
	    -width $r \
	    -command { CheckGPS ; $RcW.frgps.bs.state configure -state normal }
    bind $RcW.frgps.bs.state <Enter> { set GPSLabel $TXT(check) }
    bind $RcW.frgps.bs.state <Leave> { set GPSLabel $TXT($GPSState) }
    $RcMenu add command -accelerator $TXT(check) \
	    -image $SYMBOLIMAGE(diamond_red) -command CheckGPS
    button $RcW.frgps.bs.off -text $TXT(turnoff) -state disabled -width $r \
	    -command TurnOff
    $RcMenu add command -label $TXT(turnoff) -state disabled \
	    -command TurnOff
    set r [Measure $TXT(nameLAP)]
    frame $RcW.frget -borderwidth 2
    frame $RcW.frget.frget1
    # the following frame only children are the buttons for types in $RECTYPES
    frame $RcW.frget.frget2
    label $RcW.frget.frget1.title -text $TXT(get)
    # the following menu only entries are for types in $RECTYPES
    menu $RcMenu.gm
    set gmlst ""
    $RcMenu add cascade -label $TXT(get) -state disabled -menu $RcMenu.gm
    checkbutton $RcW.frget.frget1.displ -text $TXT(mapitems) \
	    -variable GetDispl -onvalue 1 -offvalue 0 \
	    -selectcolor $COLOUR(check)

    # the following frame only children are the buttons for types in $RECTYPES
    frame $RcW.frput -borderwidth 2
    label $RcW.frput.title -text $TXT(put)
    # the following menu only entries are for types in $RECTYPES
    menu $RcMenu.ptm
    set ptmlst ""
    $RcMenu add cascade -label $TXT(put) -state disabled -menu $RcMenu.ptm
    set gmix 0 ; set ptmix 0
    foreach i $RECTYPES {
	set n $TXT(name$i)
	button $RcW.frget.frget2.get$i -text $n -width $r -state disabled \
	    -command "GetFromGPS $i ; \
	                 $RcW.frget.frget2.get$i configure -state normal"
	$RcMenu.gm add command -label $n -command "GetFromGPS $i" \
	    -state disabled
	lappend gmlst rec,getmn,$i $gmix
	incr gmix
	# BSB contribution: no IC put button
	if { $i != "IC" && $i != "LAP" } {
	    menubutton $RcW.frput.put$i -text $n -width $r -state disabled \
		    -menu $RcW.frput.put$i.m
	    menu $RcW.frput.put$i.m
	    $RcW.frput.put$i.m add command -label $TXT(all) \
		    -command "PutOnGPS all $i"
	    $RcW.frput.put$i.m add command -label "$TXT(select) ..." \
		    -command "PutOnGPS select $i"
	    menu $RcMenu.ptm.m$i
	    $RcMenu.ptm add cascade -label $n -menu $RcMenu.ptm.m$i \
		    -state disabled
	    lappend ptmlst rec,putmn,$i $ptmix
	    incr ptmix
	    $RcMenu.ptm.m$i add command -label $TXT(all) \
		    -command "PutOnGPS all $i"
	    $RcMenu.ptm.m$i add command -label "$TXT(select) ..." \
		    -command "PutOnGPS select $i"
	    if { $AutoNumRts && $i == "RT" } {
		$RcW.frput.put$i.m add command -label $TXT(numberfrom0) \
		    -command ResetAutoNumberRT
		$RcMenu.ptm.m$i add command -label $TXT(numberfrom0) \
		    -command ResetAutoNumberRT
	    }
	}
    }
    # other information types that can be got from the receiver
    foreach i $RECINFO {
	set n $TXT(name$i)
	button $RcW.frget.frget2.get$i -text $n -width $r -state disabled \
	    -command "GetFromGPS $i ; \
	                 $RcW.frget.frget2.get$i configure -state normal"
	$RcMenu.gm add command -label $n -command "GetFromGPS $i" \
	    -state disabled
	lappend gmlst rec,getmn,$i $gmix
	incr gmix
    }
    array set WConf $gmlst
    array set WConf $ptmlst
    set WConf(rec,getbs) [winfo children $RcW.frget.frget2]
    set WConf(rec,putbs) [Delete [winfo children $RcW.frput] $RcW.frput.title]
    # BSB contribution
    if { $MYGPS == "Lowrance" } {
	frame $RcW.frinfo -borderwidth 2
	frame $RcW.frinfo1 -borderwidth 2
	label $RcW.frinfo.tprod -relief raised -width 10 -text $TXT(prod)
	label $RcW.frinfo.prod -width 16 -textvariable Prod
	label $RcW.frinfo.twp -relief raised -width 19 -text $TXT(WPCapac)
	label $RcW.frinfo.wp -width 6 -textvariable MAX(WP)
	label $RcW.frinfo.trt -relief raised -width 16 -text $TXT(RTCapac)
	label $RcW.frinfo.rt -width 6 -textvariable MAX(RT)
	label $RcW.frinfo.tic -relief raised -width 16 -text $TXT(ICCapac)
	label $RcW.frinfo.ic -width 6 -textvariable MAX(IC)
	label $RcW.frinfo1.tprt -relief raised -width 10 -text $TXT(protcl)
	label $RcW.frinfo1.prt -width 16 -textvariable Protv
	label $RcW.frinfo1.ticg -relief raised -width 16 -text $TXT(ICGraph)
	label $RcW.frinfo1.icg -width 6 -textvariable MAXICG
	label $RcW.frinfo1.ttr -relief raised -width 16 -text $TXT(TRCapac)
	label $RcW.frinfo1.tr -width 6 -textvariable MAX(TR)
	label $RcW.frinfo1.twr -relief raised -width 19 -text $TXT(WPperRT)
	label $RcW.frinfo1.wr -width 6 -textvariable MAXWPINROUTE
    }
    # end of BSB contribution

    # packing
    if { $MWINDOWSCONF == "map" } {
	set c -1
	foreach b \
	    "$gtit $fr0.db $fr0.rcw $fr0.map $defsmnbt $fr0.options" {
	    grid $b -row 0 -column [incr c] -ipadx 3
	}
	grid $fr0
	pack $MpW.frm.top
    }
    grid $Map -row 0 -column 0 -sticky nesw
    grid $MpW.frm.frmap1.mvscr -row 0 -column 1 -sticky ns
    grid $MpW.frm.frmap1.mhscr -row 1 -column 0 -sticky ew
    grid rowconfigure $MpW.frm.frmap1 0 -weight 1
    grid columnconfigure $MpW.frm.frmap1 0 -weight 1

    grid $fr3.cv -row 0 -column 0 -sticky nesw
    grid $fr3.mn -row 0 -column 1 -sticky nesw -padx 2
    grid $fr3.sep -row 0 -column 2 -sticky nesw -padx 10
    grid $fr3.sh -row 0 -column 3 -sticky nesw -padx 5

    foreach i $ltypes {
	pack $LsW.frl$i.frl.box $LsW.frl$i.frl.bscr -side left \
		-fill y -expand 1
	pack $LsW.frl$i.frb.file -side top -pady 5
	pack $LsW.frl$i.frb $LsW.frl$i.frl -side top \
		-fill y -expand 1
	pack $LsW.frl$i -side left -fill y
    }

    switch $MWINDOWSCONF {
	lists {
	    grid $fr3
	    pack $MpW.frm.frmap3 -pady 2 -side bottom
	    # must be the last one to be packed under $MpW.frm
	    pack $MpW.frm.frmap1 -expand 1 -fill both

	    pack $defsmnbt $MpW.frmi.frcoords.transf \
		    $MpW.frmi.frcoords.ttitle $MpW.frmi.frcoords.proj \
		    $MpW.frmi.frcoords.ptitle $MpW.frmi.frcoords.datum \
		    $MpW.frmi.frcoords.dtitle -pady 2 -side bottom
	    pack $MpW.frmi.frmbs.mtitle $MpW.frmi.frmbs.grid \
		    $MpW.frmi.frmbs.grdatum \
		    $MpW.frmi.frmbs.zone $MpW.frmi.frmbs.xcoord \
		    $MpW.frmi.frmbs.ycoord $MpW.frmi.frmbs.msave \
		    $MpW.frmi.frmbs.mprint $MpW.frmi.frmbs.mback \
		    $MpW.frmi.frmbs.mclear $MpW.frmi.frmbs.mft -pady 5

	    pack $MpW.frmi.frcoords -side top
	    pack $MpW.frmi.frmbs -side bottom

	    pack $MpW.frm -side left -fill y -fill both -expand 1
	    pack $MpW.frmi -side left -fill y
	}
	map {
	    grid $fr4.datum -row 0 -column 0 -sticky nesw
	    grid $fr4.proj -row 0 -column 1 -sticky nesw -padx 3
	    grid $fr4.transf -row 0 -column 2 -sticky nesw -padx 3

	    grid $fr5.grid -row 0 -column 0 -sticky nesw
	    grid $fr5.zone -row 0 -column 1 -sticky nesw -padx 3
	    grid $fr5.xcoord -row 0 -column 2 -sticky nesw -padx 3
	    grid $fr5.ycoord -row 0 -column 3 -sticky nesw -padx 3
	    grid $fr5.grdat -row 1 -column 0 -columnspan 4 -sticky nesw

	    grid $fr3 -row 0 -column 0
	    grid $fr4 -row 1 -column 0
	    grid $fr5 -row 0 -column 1 -rowspan 2 -padx 10

	    pack $MpW.frm.frmap3 -pady 2 -side bottom
	    # must be the last one to be packed under $MpW.frm
	    pack $MpW.frm.frmap1 -expand 1 -fill both

	    pack $MpW.frm -expand 1 -fill both
	    pack $MpW -expand 1 -fill both

	    pack .lsw.frbl.frb.load .lsw.frbl.frb.import .lsw.frbl.frb.save \
		.lsw.frbl.frb.export .lsw.frbl.frb.search -side left -padx 3
	    pack .lsw.frbl.frb $LsW -side top -pady 3
	    pack .lsw.tit .lsw.frbl -side top -pady 5
	}
    }

    grid $RcW.frgps.dev.tdev $RcW.frgps.dev.dev
    if { $MYGPS == "Garmin" } {
	grid $RcW.frgps.dev.baud -columnspan 2
    }
    pack $RcW.frgps.prt.title $RcW.frgps.prt.prot -side left
    pack $RcW.frgps.bs.state $RcW.frgps.bs.off -side left -pady 2
    if { $MYGPS != "Magellan" } {
	pack $RcW.frgps.title $RcW.frgps.dev $RcW.frgps.prt $RcW.frgps.rlt \
	    $RcW.frgps.bs -side top -pady 5
    } else {
	pack $RcW.frgps.title $RcW.frgps.dev $RcW.frgps.prt $RcW.frgps.bs \
		-side top -pady 5
    }
    pack $RcW.frget.frget1.title $RcW.frget.frget1.displ -side left -padx 5
    foreach i [concat $RECTYPES $RECINFO] {
	pack $RcW.frget.frget2.get$i -side left -pady 2
    }
    pack $RcW.frget.frget1 $RcW.frget.frget2 -side top
    pack $RcW.frput.title -side top
    # BSB contribution: no IC put button
    foreach i $RECTYPES {
	if { $i != "IC" && $i != "LAP" } { 
	    pack $RcW.frput.put$i -side left -pady 2
	}
    }

    switch $MWINDOWSCONF {
	lists {
	    pack .lsw.frmb.dtitle .lsw.frmb.datum -pady 2 -side top
	    pack .lsw.frmb.frb.sep .lsw.frmb.frb.load .lsw.frmb.frb.import \
		.lsw.frmb.frb.save .lsw.frmb.frb.export .lsw.frmb.frb.search \
		.lsw.frmb.frb.sep2 -side top -pady 3 -fill x
	    pack .lsw.frmb.frb -pady 20 -side top
	    pack .lsw.frmb.opt -pady 5 -side bottom
	    pack .lsw.frmb.sep -pady 5 -side bottom -fill x
	    pack .lsw.frmb.rcw .lsw.frmb.mpw -pady 5 -side bottom
	    pack $LsW .lsw.frmb -side left -fill y
	    pack $gtit .lsw -side top -pady 3

	    grid .mpw.top.frNT.tit -row 0 -column 0
	    grid .mpw.top.frNT
	    pack .mpw.top $MpW -side top -pady 3
	}
	map {
	    pack $RcW.frgps $RcW.frget $RcW.frput -side top -pady 5
	    pack .rcw.tit $RcW -side top -pady 3

	    # BSB contribution
	    if { $MYGPS == "Lowrance" } {
		pack $RcW.frinfo1 -side bottom -pady 5
		pack $RcW.frinfo1.tprt $RcW.frinfo1.prt $RcW.frinfo1.twr \
			$RcW.frinfo1.wr $RcW.frinfo1.ticg $RcW.frinfo1.icg \
			$RcW.frinfo1.ttr $RcW.frinfo1.tr -side left -pady 2
		pack $RcW.frinfo -side bottom -pady 5
		pack $RcW.frinfo.tprod $RcW.frinfo.prod $RcW.frinfo.twp \
			$RcW.frinfo.wp $RcW.frinfo.trt $RcW.frinfo.rt \
			$RcW.frinfo.tic $RcW.frinfo.ic -side left -pady 2
	    }
	    # end of BSB contribution
	}
    }

    SetMapBindings

    AttachPlugIns .

    # saved state
    if { [file readable $USvState] } {
	RestoreState
    }
    return
}

proc About {} {
    # create modal dialog for displaying information about GPSMan
    #  single button: OK; binding: return
    global EPOSX EPOSY TXT

    set gs [grab current]
    GMToplevel .about message +$EPOSX+$EPOSY {} \
        [list WM_DELETE_WINDOW  [list DestroyRGrabs .about $gs]] \
        [list <Key-Return> [list DestroyRGrabs .about $gs]]

    AboutInfo .about

    frame .about.fr.bt
    button .about.fr.ok -text $TXT(ok) -command [list DestroyRGrabs .about $gs]
    pack .about.fr.ok
    pack .about.fr -side top -pady 5
    RaiseWindow .about
    update idletasks
    grab .about
    return
}

##### initializing variables and quitting

proc GMStart {} {
    # initialize (most) global variables
    global Index Number Storage File Proc FDDatum \
	TYPES PROCTYPES CursorsChanged MapWidth MapHeight MAPW2 MAPH2 \
	AzimuthDegrees MapEmpty DataDefault DataIndex PositionFormat \
	DEFAULTSYMBOL DEFAULTDISPOPT Datum EMPTYSTR Anim \
	BalloonX BalloonY USERDIR RealTimeLogOn \
	RealTimeLogAnim PVTState USvState USvData USvMap \
	BITMAPS SERIALPORT DEFSPORT tcl_platform DEFTRTWIDTH DEFTTRWIDTH \
	DEFTLNWIDTH GPSProtocol RECPROTOCOLS GetDispl UNIX MAPCOLOUR \
	MapFont MAPFONT Travelling Travel TRAVELFONT NAMEWIDTH \
	MapMeasure DEFMAPPROJ DEFMAPPFRMT ALTUNIT AltUnit GMEd PlotWNo \
	FILEFORMAT DEFTRECPROTOCOL MapPFDatum DEFMAPPFDATUM \
	RealTimeGettingFix MAPWIDTH MAPHEIGHT GFShowInfo FromTimeOffset \
	RecCanChgBaud PlotFont PLOTFONT ReplNames

    # BSB contribution: globals needed for Lowrance receivers
    global UnusedICInx UnusedWPInx MAX MYGPS

    GlobalOptionsBindings

    # I/O port
    if { $UNIX && $SERIALPORT == "" } {
	set SERIALPORT $DEFSPORT
    }

       # receiver supports changing baud rate when connected
    set RecCanChgBaud 0
    if { $MYGPS == "Garmin" } {
	set GPSProtocol $DEFTRECPROTOCOL
	if { [regsub {^usb=} $SERIALPORT "" p] } {
	    # I/O port given as command argument
	    set SERIALPORT $p
	    set GPSProtocol garmin_usb
	}
    } else { set GPSProtocol [lindex $RECPROTOCOLS($MYGPS) 0] }
    set GetDispl 0

    # data-base
    set Number(Data) 0
           # the first element in Storage(_) must be identifier storage
           #  and the last one the display state
           # WPNum needed only for Lowrance receivers
           # WPRoute is set separately because cannot be edited
           # WPAlt and TPalt are lists with altitude in metres,
           #  altitude in user unit and user unit (as $ALTUNIT);
           #  empty list stands for undefined, last 2 elements may
           #  be missing if user unit is metre
           # ??MBack is name of map background definition to load when item
           #  is displayed and the map is empty; empty string means undefined;
           #  not valid for GR and LAP
    set Storage(WP) {WPName WPNum WPCommt WPObs WPPFrmt WPPosn WPDatum
	             WPDate WPSymbol WPDispOpt WPAlt WPMBack WPHidden WPDispl}
    set DataDefault(WP) [list "" -1 "" "" $PositionFormat "" $Datum \
	    "" $DEFAULTSYMBOL $DEFAULTDISPOPT "" "" "" 0]
    set Storage(RT) {RTIdNumber RTCommt RTObs RTWPoints RTStages RTWidth
	             RTColour RTMBack RTDispl}
    set DataDefault(RT) [list "" "" "" "" "" $DEFTRTWIDTH $MAPCOLOUR(RT) "" 0]
    set stRS {RScommt RSlabel RShidden}
    set DataDefault(RS) [list "" "" ""]
    set Storage(TR) {TRName TRObs TRDatum TRTPoints TRSegStarts TRHidden
                     TRWidth TRColour TRMBack TRDispl}
    set DataDefault(TR) [list "" "" $Datum "" "" "" $DEFTTRWIDTH \
			     $MAPCOLOUR(TR) "" 0]
    set stTP {TPlatd TPlongd TPlatDMS TPlongDMS TPdate TPsecs TPalt TPdepth}
    set DataDefault(TP) [list "" "" "" "" "01-Jan-1988 00:00:00" 0 "" ""]
    set Storage(LN) {LNName LNObs LNDatum LNPFrmt LNLPoints LNSegStarts \
	             LNWidth LNColour LNMBack LNDispl}
    set DataDefault(LN) [list "" "" $Datum $PositionFormat "" "" $DEFTLNWIDTH \
 	                      $MAPCOLOUR(LN) "" 0]
    set stLP {LPposn LPalt}
    set DataDefault(LP) [list "" ""]
    set Storage(GR) {GRName GRObs GRConts GRDispl}
    set DataDefault(GR) [list "" "" "" 0]
    # LAPs should be considered here, just in case support for them is asked
    #  during the current session
    set types $TYPES ; set ptypes $PROCTYPES
    lappend types LAP ; lappend ptypes GMLap
    # LAPName is formatted date and is not to be edited
    # LAPStart is the time stamp (list with formatted date and secs)
    # LAPDispl is here only for uniformity; it should be always 0
    set Storage(LAP) {LAPName LAPObs LAPStart LAPDur LAPDist LAPBegPosn
	LAPEndPosn LAPCals LAPTRIx LAPPFrmt LAPDatum LAPDispl}
    set DataDefault(LAP) [list "" "" "" 0 0 "" "" 0 "" $PositionFormat \
			      $Datum 0]
    foreach wh $types proc $ptypes {
	set Index($wh) 0 ; set Number($wh) 0 ; set Proc($wh) $proc
	set k 0
	foreach da $Storage($wh) {
	    set DataIndex($da) $k ; incr k
	}
    }
    foreach d "RS TP LP" {
	set k 0
	foreach da [set st$d] {
	    set DataIndex($da) $k ; incr k
	}
    }
    set GMEd(TR,ptname) TP
    set GMEd(LN,ptname) LP

    # files
    set filetypes {WP RT TR LN LAP GR Data WPDistBear WPNearest RTComp TRComp
                   Map Plot MapBkInfo Image PVTData Info tfwfile}
    foreach t $filetypes { set File($t) "" }
    set FDDatum ""
    set USvState [file join $USERDIR sstate]
    set USvData [file join $USERDIR sdata]
    set USvMap [file join $USERDIR smap]
    set FromTimeOffset ""

    # foreign formats
    set FILEFORMAT(_type,in,data) [set FILEFORMAT(_type,out,data) ""]
    foreach t $TYPES {
	set FILEFORMAT(_type,in,$t) [set FILEFORMAT(_type,out,$t) ""]
    }	
    foreach fmt $FILEFORMAT(names) {
	if { $fmt == "GPSMan" || \
		 ( ! [catch {set dep $FILEFORMAT($fmt,depends)}] && \
		   ! [eval $dep] ) } {
	    continue
	}
	if { [catch {set ts $FILEFORMAT($fmt,types)}] } {
	    foreach "in_ts out_ts" $FILEFORMAT($fmt,io_types) { break }
	} { set in_ts [set out_ts $ts] }
	if { ! [catch {set FILEFORMAT($fmt,GREls)}] } {
	    lappend in_ts GR ; lappend out_ts GR
	}
	if { $FILEFORMAT($fmt,filetype) == "data" } {
	    foreach m $FILEFORMAT($fmt,mode) {
		lappend FILEFORMAT(_type,$m,data) $fmt
	    }
	}
	foreach m $FILEFORMAT($fmt,mode) {
	    foreach t [set ${m}_ts] {
		lappend FILEFORMAT(_type,$m,$t) $fmt
	    }
	}
    }
    foreach i [array names FILEFORMAT _type,*] {
	set FILEFORMAT($i) [lsort -dictionary $FILEFORMAT($i)]
    }

    # real-time and travel/navigation
    set RealTimeLogOn 0 ; set RealTimeLogAnim 0 ; set RealTimeGettingFix 0
    set PVTState abort
    set Travelling 0
    if { [set Travel(font) $TRAVELFONT] == "default" } {
	set Travel(font) $TkDefaultFont
    }
    array set Travel {
	tosave {conf,1 conf,2 travel,cdsp font warn warn,* mindist offroad
	    chggparam chggwparam chggix}
	conf,1  {lab+fix lab+speed c_trkcts c_trn c_vel_z lab+hour
	lab+alt lab+nxtWP lab+prvWP lab+dist lab+vmg lab+ete lab+eta
	lab+xtk lab+cts}
	conf,2  {lab+fix lab+speed c_trkcts lab+hour lab+pos lab+alt lab+trk
	         c_vel_z}
	travel,cdsp 1
	warn  1
	warn,prox 0
	warn,prox,wpn ""
	warn,prox,dst 1
	warn,prox,level medium
	warn,anchor 0
	warn,anchor,wpn ""
	warn,anchor,dst 1
	warn,anchor,level medium
	warn,speed 0
	warn,speed,max 50
	warn,speed,level high
	warn,vspeed 0
	warn,vspeed,min -6
	warn,vspeed,max 6
	warn,vspeed,level medium
	warn,trn 0
	warn,trn,max 60
	warn,trn,level low
	warn,xtk 0
	warn,xtk,max 5
	warn,xtk,level low
	mindist 0.1
	offroad 0
	chggparam 0.8
	chggwparam 0.9
	chggix 2
    }
    trace variable Travel(chggix) w TravelChgGParam
    set Travel(elsizes) "4 4 8 23 5 4 $NAMEWIDTH $NAMEWIDTH 9 9 4 4 4 4 4"
    array set Travel {
	els
	  {fix speed hour pos alt trk nxtWP prvWP ete eta vmg xtk cts trn dist}
	cvss {c_trkcts c_trn c_vel_z}
	trav,els {fix speed hour pos alt trk}
	trav,cvels {{c_vel_z vel_z}}
	displays {1 2}
	warnings {prox anchor speed trn vspeed xtk}
	nav 0
	nav,els {nxtWP prvWP ete eta vmg xtk cts trn dist}
	nav,cvels {{c_trkcts cts}}
	nav,over land
	nav,datum {WGS 84}
	nav,maxdtime 5
	posns {}
	prevtime -1
	prevposn {}
	warncancel {}
	nav,pmode 1
	nav,pnear 0
	nav,prvrs 0
	chggvals {0.95 0.9 0.8 0.7 0.6}
	chggwvals {0.98 0.95 0.9 0.8 0.7}
	chggmaxix 4
    }
    # conditions for issuing warnings and their contents
    #  variables assumed to be defined in the context of execution,
    #  apart from $TXT():
    #    $posn, $datum, $speed (user units), $vel_z (m/s), $trn (-180..180),
    #    $xtk (signed, user units)
    #  any of these, except $posn, $datum, may be "" for undefined
    array set Travel {
	warn:prox,cond {
	    [ComputeDist $posn $Travel(warn,prox,pos) $datum] < $Travel(warn,prox,dst)
	}
	warn:prox,cont {[format $TXT(trvwarrv) $Travel(warn,prox,wpn)]}
	warn:anchor,cond {
	    [ComputeDist $posn $Travel(warn,anchor,pos) $datum] > $Travel(warn,anchor,dst)
	}
	warn:anchor,cont {[format $TXT(trvwleave) $Travel(warn,anchor,wpn)]}
	warn:speed,cond { $speed != {} && $speed > $Travel(warn,speed,max) }
	warn:speed,cont {[format $TXT(trvwspeed) $Travel(warn,speed,max)]}
	warn:trn,cond { $trn != {} && abs($trn) > $Travel(warn,trn,max) }
	warn:trn,cont {[format $TXT(trvwtrn) $Travel(warn,trn,max)]}
	warn:vspeed,cond {
	    $vel_z != {} && ($vel_z < $Travel(warn,vspeed,min) || $vel_z > $Travel(warn,vspeed,max))
	}
	warn:vspeed,cont {[format $TXT(trvwvspeed) $Travel(warn,vspeed,min) $Travel(warn,vspeed,max)]}
	warn:xtk,cond { $xtk != {} && abs($xtk) > $Travel(warn,xtk,max) }
	warn:xtk,cont {[format $TXT(trvwxtk) $Travel(warn,xtk,max)]}
    }

    # map
    set MapEmpty 1 ; set MapMeasure ""
    set MapWidth $MAPWIDTH ; set MapHeight $MAPHEIGHT
    set MAPW2 [expr $MapWidth/2.0] ; set MAPH2 [expr $MapHeight/2.0]
    set Anim(number) 0
    foreach x "high medium low" y "important normal info" {
	set MAPCOLOUR(trvwrn$x) $MAPCOLOUR(trvwrn$y)
    }
    if { [set MapFont $MAPFONT] == "default" } {
	set MapFont $TkDefaultFont
    }
    MapProjectionIs $DEFMAPPROJ
    # order is important here
    set MapPFDatum $DEFMAPPFDATUM
    ChangeMapPFormat $DEFMAPPFRMT

    if { [set PlotFont $PLOTFONT] == "default" } {
	set PlotFont $TkDefaultFont
    }

    # varia
    set ReplNames(busy) 0
    set GFShowInfo 1
    set AltUnit $ALTUNIT
    set PlotWNo 0
    set CursorsChanged 0
    set BalloonX 0 ; set BalloonY 0
    set EMPTYSTR ""
    set a 0
    foreach b "N NE E SE S SW W NW" {
	set AzimuthDegrees($b) $a ; incr a 45
    }
    set BITMAPS {brokenline}
    InitBitmaps

    # initializations depending on receiver brand
    # BSB contribution
    if { $MYGPS != "Lowrance" } {
	StartGPS
    } else {
	set UnusedWPInx 0
	for {set i 1} {$i < $MAX(WP)} {incr i} {
	   lappend UnusedWPInx $i
	}
	set UnusedICInx 0
	for {set i 1} {$i < $MAX(WP)} {incr i} {
	   lappend UnusedICInx $i
	}
    }

    return
}

proc QuitNow {} {
    global MESS TXT SAVESTATE

    switch $SAVESTATE {
	never {
	    if { ! [GMConfirm $MESS(oktoexit)] } { return }
	}
	ask {
	    switch [GMSelect $MESS(savestate) \
		    [list $TXT(ok) $TXT(no) $TXT(cancel)] "ok no cancel"] {
		ok { SaveState }
		cancel { return }
	    }
	}
	always {
	    SaveState
	}
    }
    GPSBye
    exit 0
}

