#!/bin/sh
# This is a Tcl/Tk script to be interpreted by tclsh  \
exec tclsh "$0" "$@"


############################################################################
#                                                                          #
#   dos2gpsman ---  Convert BGA Turnpoints gpsman "WayPoint" format        #
#                                                                          #
#   BGA Turnpoints are available at                                        #
#      http://www.spsys.demon.co.uk/turningpoints.htm                      #
#   The DOS format file is required by this program                        #
#                                                                          #
#   usage: dos2gpsman [-p feature] [-f findability] [-a air_activity] \    #
#              [-i in_file] [-o out_file] [-h] [--help]                    #
#                                                                          #
#   With no arguments, converts all records from stdin to stdout           #
#                                                                          #
#   Version 0.1                                                            #
#                                                                          #
#   Bugs:                                                                  #
#        * "Air activity" is best specified by any single or double        #
#          character, e.g. "x" or "xx", rather than the "#" or "##".       #
#          This avoids the need to escape "#" from the shell.              #
#                                                                          #
#        * There is no way to _exclude_ points by a criterion              #
#                                                                          #
#        * Some information in the original file is discarded              #
#                                                                          #
#        * This code will probably fail if the file format changes         #
#          e.g. if extra information is added to the TurnPoint file        #
#                                                                          #
#   Copyright (c) Paul Scorer, Leeds Metropolitan University               #
#    p.scorer@leedsmet.ac.uk                                               #
#                                                                          #
#   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.                                               #
#                                                                          #
############################################################################

global fullname trigraph bganum findability exactpoint\
	description distance direction feature\
	OSMap Easting_Northing Lat_Long altitude \
	degLat minLat NS degLong minLong decLong EW

################
#  Read one complete waypoint record
################
proc getRecord {f} {
	global fullname trigraph bganum findability exactpoint\
		description distance direction feature\
		OSMap Easting_Northing Lat_Long altitude\
		degLat minLat NS degLong minLong decLong EW

	if {[gets $f fullname] > 0 && \
	[gets $f trigraph] > 0 && \
	[gets $f bganum] > 0 && \
	[gets $f findability] > 0 && \
	[gets $f exactpoint] > 0 && \
	[gets $f description] > 0 && \
	[gets $f distance] > 0 && \
	[gets $f direction] > 0 && \
	[gets $f feature] > 0 && \
	[gets $f OSMap] > 0 && \
	[gets $f Easting_Northing] > 0 && \
	[gets $f Lat_Long] > 0 && \
	[gets $f altitude] > 0 && \
	[gets $f trigraph1] > 0 && \
	[gets $f junk] == 0} {
	# Blank line - Record Separator
		# Simple consistency check:
		# Trigraph at last line should match that at second line
		if {[string equal $trigraph $trigraph1] } {
			scan  $Lat_Long "%d%lf%s%d%d.%d%s" \
				degLat minLat NS degLong minLong decLong EW
			return 1;
		} else {
			puts stderr "Format Error";
			return 0;
		}
	} else {
		return 0
	}
}

##################
#  Check if current record is associated
#  with "feature" specified on command line
#################
proc checkPlace {} {
	global placeList feature 
	foreach place $placeList {
		if { [string equal -nocase $feature $place] } {
			return 1
		}
	}
	return 0
}

################
# Check if "findability" (A B C D or G)
# matches that given on command line
################
proc checkFind {} {
	global findList findability
	foreach category $findList {
		if { [string equal -nocase -length 1 $category $findability] } {
			return 1
		}
	}
	return 0
}

################
#  Check if category of "Air Activity"
#  matches that given on command line
################
proc checkActivity {} {
	global activityList findability
	foreach category $activityList {
		set len [string length $category]
		incr len 
		if { [string length $findability ] == $len } {
			return 1
		}
	}
	return 0
}


#################
#  Set some initial values
#################
set fi stdin
# May be modified by "-i <in-file>"

set fo stdout
# May be modified by "-o <out-file>"

set usage "
usage: dos2gpsman \[-p feature\] \[-f findability\] \[-a air_activity\] \
\[-i in_file\] \[-o out_file\] \n\
\tfindability == \[A B C D G\]\n\
\tair_activity == \[x xx\] (any character)\n\
\tArguments may be repeated (e.g. to seach for more than one place)\n\
\tSee http://www.spsys.demon.co.uk/turningpoints.htm for the meaning of these terms\n
"

################
#  Process args
################

foreach {option arg} $argv {
	# Need help?
	if {       [string equal -nocase -length 6 "--help" $option]} {
		puts stderr $usage
		exit 
	} elseif { [string equal -nocase -length 2 "-h" $option]} {
		puts stderr $usage
		exit 

	# Select points associated with "Feature" (aka "Place")
	} elseif { [string equal -nocase -length 2 "-p" $option]} {
		lappend placeList $arg

	# Select points with "Findability" A B C D or G
	} elseif { [string equal -nocase -length 2 "-f" $option]} {
		if { [lsearch -exact "A B C D G a b c d g" $arg] > 0 } {
			lappend findList $arg
		} else {
			puts stderr $usage
			exit
		}

	# Air Activity
	} elseif { [string equal -nocase -length 2 "-a" $option]} {
		if { [string length $arg] < 3 } {
			lappend activityList $arg
		} else { 
			puts stderr $usage
			exit
		}

	# Change i/p file
	} elseif { [string equal -nocase -length 2 "-i" $option]} {
		set fi [open $arg r]

	# Change o/p file
	} elseif { [string equal -nocase -length 2 "-o" $option]} {
		set fo [open $arg w]
	} else {
		puts stderr $usage
		exit 
	}
}

###############
#  Generate time stamp
#  Not used, but useful to give date of conversion
###############
set timestring [clock format [clock seconds] -format "%d-%b-%Y %H%M"]

set doneHdr 0;	# Flag to ensure header o/p once only

# Process each record
while { [getRecord $fi ] } {

	# Matches "Findability"?
	if { [info exists findList]  } {
		if { [checkFind] == 0} {
			continue
		}
	}
	
	# Matches "Feature"?
	if { [info exists placeList] } {
		if { [checkPlace] == 0} {
			continue
		}
	}
	
	# Matches "Air Activity"?
	if { [info exists activityList] } {
		if { [checkActivity] == 0} {
			continue
		}
	}
	
	# Do the Header if needed
	if {$doneHdr == 0} {
		puts $fo "!Format: DMM 0 WGS 84\n!Creation: no\n"
		set doneHdr 1;
	}

	# Output the record (with altitude in metres)
	puts $fo [format  "!W:\n%s\t%s\t%s%d %.3f\t%s%d %d.%d\talt=%.0f" \
			$trigraph \
			$timestring \
			$NS $degLat $minLat \
			$EW $degLong $minLong $decLong \
			[expr { $altitude * 12 * 25.4 / 1000 }]];
	puts $fo "!NB:"
	puts $fo $fullname
	puts $fo $exactpoint
	puts $fo $description
	puts $fo $feature
	puts $fo $findability
	puts $fo ""
}

if {$doneHdr == 0} {
	puts stderr "No matching waypoints found!\n"
}

