#
# This file is part of:
#
#  gpsman --- GPS Manager: a manager for GPS receiver data
#
# Copyright (c) 1998-2011 Miguel Filgueiras migf@portugalmail.pt
#
#    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: gpsinfo.tcl
#  Last change:  19 July 2011
#
# Includes contributions by Brian Baulch (baulchb_AT_onthenet.com.au)
#  marked "BSB contribution"


proc DisableGPS {} {
    # change interface appearance when detecting that the receiver went offline
    global RcW RcMenu GPSState GPSLabel COLOUR TXT SYMBOLIMAGE WConf

    # state
    set GPSState offline ; set GPSLabel $TXT(offline)
    $RcW.frgps.bs.state configure -fg $COLOUR(offline)
    $RcMenu entryconfigure 5 -image $SYMBOLIMAGE(diamond_red)
    # device name can be changed
    $RcMenu.dev entryconfigure 0 -state normal
    $RcW.frgps.dev.dev configure -state normal
    # baud rate cannot be changed
    if { [winfo exists $RcW.frgps.dev.baud] } {
	$RcMenu.dev entryconfigure 1 -state disabled
	$RcW.frgps.dev.baud configure -state disabled
    }
    # cannot turn off or get/put items
    foreach ix "6 7 8" {
	$RcMenu entryconfigure $ix -state disabled
    }
    $RcW.frgps.bs.off configure -state disabled
    foreach m "getbs putbs" {
	foreach b $WConf(rec,$m) { $b configure -state disabled	}
    }
    return
}

proc EnableGPS {} {
    # change interface appearance when detecting that the receiver went on-line
    global RcW RcMenu GPSState GPSLabel COLOUR ListInds TXT RECTYPES RECINFO \
	MYGPS SYMBOLIMAGE WConf RecCanChgBaud

    # state
    set GPSState online ; set GPSLabel $TXT(online)
    $RcW.frgps.bs.state configure -fg $COLOUR(online)
    $RcMenu entryconfigure 5 -image $SYMBOLIMAGE(diamond_green)
    # cannot change device name when in use
    $RcMenu.dev entryconfigure 0 -state disabled
    $RcW.frgps.dev.dev configure -state disabled
    # baud rate can be changed if receiver supports that
    if { [winfo exists $RcW.frgps.dev.baud] && $RecCanChgBaud } {
	$RcMenu.dev entryconfigure 1 -state normal
	$RcW.frgps.dev.baud configure -state normal
    }
    # can turn off and see get/put submenus
    foreach ix "6 7 8" {
	$RcMenu entryconfigure $ix -state normal
    }
    # disable all get/put buttons and submenu entries, then enable valid ones
    foreach m "$RcMenu.gm $RcMenu.ptm" {
	set l [$m index last]
	for { set i 0 } { $i <= $l } { incr i } {
	    $m entryconfigure $i -state disabled
	}
    }
    $RcW.frgps.bs.off configure -state normal
    foreach m "getbs putbs" {
	foreach b $WConf(rec,$m) { $b configure -state disabled }
    }
    # enable valid entries in those menus and the corresponding buttons
    foreach i $RECTYPES {
	if { $i != "GR" || $ListInds(GR) != "" } {
	    $RcW.frget.frget2.get$i configure -state normal
	    $RcMenu.gm entryconfigure $WConf(rec,getmn,$i) -state normal
	}
	# based on BSB contribution: no IC put button
	if { $i != "IC" && $i != "LAP" && $ListInds($i) != "" } {
	    $RcW.frput.put$i configure -state normal
	    $RcMenu.ptm entryconfigure $WConf(rec,putmn,$i) -state normal
	}
    }
    foreach i $RECINFO {
	$RcW.frget.frget2.get$i configure -state normal
	$RcMenu.gm entryconfigure $WConf(rec,getmn,$i) -state normal
    }
    InitGPS
    return
}

proc CheckGPS {} {
    # check connectivity to receiver
    global GPSState GPSLabel COLOUR MESS TXT

    SetCursor . watch
    if { $GPSState == "offline" } {
	GPSConnection EnableGPS
    } else {
	GPSConnection [list GMMessage $MESS(GPSok)] DisableGPS
    }
    set GPSLabel $TXT($GPSState)
    ResetCursor .
    return
}

proc TurnOff {} {
    global GPSState COLOUR

    GPSOff
    DisableGPS
    return
}

proc PutOnGPS {how wh} {
    # put data into receiver
    #  $how in {all, select}, $wh in $RECTYPES
    global ListInds RECTYPES MESS TXT

    if { $wh == "LAP" } { return }
    switch $how {
	all {
	    set ixs $ListInds($wh)
	}
	select {
	    if { [set ixs [ChooseItems $wh]] == "" } {
		return
	    }
	}
    }
    switch $wh {
	GR {
	    set gtypes [Delete $RECTYPES LAP]
	    set ts ""
	    foreach k $gtypes { lappend ts $TXT(name$k) }
	    while 1 {
		set whs [GMChooseFrom many $MESS(putwhat) 6 $ts $gtypes]
		if { [set i [lsearch -exact $whs GR]] != -1 } {
		    set whs [lreplace $whs $i $i]
		    set r 1
		} else { set r 0 }
		if { [llength $whs] > 1 } {
		    GMMessage $MESS(exportonly1)
		} else { break }
	    }
	    # this only works for a single type
	    if { [set l [GRsElements $ixs $r $whs]] != "" } {
		PutItemsOnGPS $whs $l
	    }
	}
	default {
	    PutItemsOnGPS $wh $ixs
	}
    }
    return
}

proc PutItemsOnGPS {wh ixs} {
    # put items of kind $wh (in $RECTYPES except GR and LAP) on receiver
    #  $ixs is list of indices
    global MAX MESS TXT

    if { [llength $ixs] > $MAX($wh) } {
	GMMessage [format $MESS(toomany) $TXT(name$wh) $MAX($wh)]
	return
    }
    PutGPS $wh $ixs
    return
}

proc GetFromGPS {wh} {
    # get data from receiver
    #  $wh in $RECTYPES
    # if $wh==GR, select a single item type (in $RECTYPES except TR) to get
    global RECTYPES
    # BSB contribution
    global MYGPS

    if { $wh == "GR" } {
	# based on BSB contribution: do not get ICs
	if { $MYGPS != "Lowrance" } {
	    set not "TR"
	} else { set not "IC TR" }
	InputToGR $RECTYPES $not Ignore GetGPSIn Ignore receiver
    } else {
	GetGPS $wh
    }
    return
}

proc GPSChangeDevice {} {
    # get device name from user and set global SERIALPORT
    global SERIALPORT TXT

    set old $SERIALPORT
    if { [GMChooseParams $TXT(chgdev) SERIALPORT [list =$TXT(optDEFSPORT)]] \
	     == 0 } {
	set SERIALPORT $old
    }
    return
}


    
