#!/bin/sh
# -*-Mode: TCL;-*-

#--------------------------------------------------------------
#   BUILD.TK
#
#   A cheesy graphical front-end for building and installing REMIND.
#
#   This file is part of REMIND.
#   Copyright (C) 1992-2018 Dianne Skoll
#
#--------------------------------------------------------------

# the next line restarts using wish \
exec wish "$0" "$@"

#***********************************************************************
# %PROCEDURE: SetConfigDefaults
# %ARGUMENTS:
#  None
# %RETURNS:
#  Nothing
# %DESCRIPTION:
#  Sets up default values for various parameters.
#***********************************************************************
proc SetConfigDefaults {} {
    global Config
    set Config(LAT_DEG) 45
    set Config(LAT_MIN) 24
    set Config(LON_DEG) 75
    set Config(LON_MIN) 39
    set Config(LOCATION) "Ottawa"
    set Config(DEFAULT_PAGE) "Letter"
    set Config(DATESEP) "-"
    set Config(TIMESEP) ":"
    set Config(ISOLATIN1) 0
    set Config(IBMEXTENDED) 0
    set Config(ISOLATIN2) 0
    set Config(IBM852) 0
    set Config(NORTHERN_HEMISPHERE) 1
    set Config(WESTERN_HEMISPHERE) 1
    set Config(LANGUAGE) "English"
    set Config(INST_DIR) "/usr/local/bin"
    set Config(MAN_DIR) "/usr/local/man"
}

#***********************************************************************
# %PROCEDURE: Bail
# %ARGUMENTS:
#  msg -- a message
# %RETURNS:
#  Does not return
# %DESCRIPTION:
#  Pops up an error dialog; then calls exit.
#***********************************************************************
proc Bail { msg } {
    tk_dialog .err "Remind Configuration Error" $msg error 0 "Bummer"
    exit 1
}

#***********************************************************************
# %PROCEDURE: CheckSanity
# %ARGUMENTS:
#  None
# %RETURNS:
#  Nothing
# %DESCRIPTION:
#  Checks sanity of install dir -- checks for critical files,
#  warns user if something looks wrong.
#***********************************************************************
proc CheckSanity {} {
    if {![file executable ./configure]} {
	wm withdraw .
	Bail "I can't seem to execute the file ./configure -- make sure you have all required files and are running this from the top-level Remind directory"
    }
    if {![file readable ./src/custom.h.in]} {
	wm withdraw .
	Bail "I can't seem to find the file src/custom.h.in -- make sure you have all required files and are running this from the top-level Remind directory"
    }
}

#***********************************************************************
# %PROCEDURE: CreateMainDialog
# %ARGUMENTS:
#  None
# %RETURNS:
#  Nothing
# %DESCRIPTION:
#  Creates and displays the main configuration dialog
#***********************************************************************
proc CreateMainDialog {} {
    global Instdir Loc Options

    wm title . "Remind Configuration"
    wm iconname . "Remind Config"

    SetConfigFromRemind
    tabnotebook_create .tn

    set Instdir [tabnotebook_page .tn "Installation Directories"]
    CreateInstallDirDialog $Instdir

    set Loc [tabnotebook_page .tn "Location"]
    CreateLocationDialog $Loc

    set Options [tabnotebook_page .tn "Options"]
    CreateOptionsDialog $Options
    pack .tn -side top -expand 1 -fill both

    frame .buttons
    button .build -text "Build Remind" -command BuildRemind
    button .cancel -text "Cancel" -command exit

    pack .build .cancel -in .buttons -side left -expand 1 -fill both
    pack .buttons -side top -expand 0 -fill x
}

#***********************************************************************
# %PROCEDURE: CreateInstallDirDialog
# %ARGUMENTS:
#  w -- frame containing widgets
# %RETURNS:
#  Nothing
# %DESCRIPTION:
#  Creates the "installation directories" dialog.
#***********************************************************************
proc CreateInstallDirDialog { w } {
    global Config
    label $w.binlabel -text "Location for programs: "
    entry $w.bin -width 30
    $w.bin insert end $Config(INST_DIR)

    label $w.manlabel -text "Location for man pages: "
    entry $w.man -width 30
    $w.man insert end $Config(MAN_DIR)

    text $w.blurb -width 1 -height 5 -wrap word -relief flat -takefocus 0
    $w.blurb insert end "\n(Tabbed-notebook Tcl code taken from \"Effective Tcl/Tk Programming\" by Mark Harrison and Michael McLennan, Addison-Wesley Professional Computing Series.)"
    $w.blurb configure -state disabled
    # Disable all text-window behaviour
    bindtags $w.blurb {NoSuchTag}
    grid $w.binlabel -row 0 -column 0 -sticky e
    grid $w.bin -row 0 -column 1 -sticky nsew
    grid $w.manlabel -row 1 -column 0 -sticky e
    grid $w.man -row 1 -column 1 -sticky nsew
    grid $w.blurb - -sticky nsew
}

#***********************************************************************
# %PROCEDURE: CreateLocationDialog
# %ARGUMENTS:
#  w -- frame containing dialog
# %RETURNS:
#  Nothing
# %DESCRIPTION:
#  Creates the location dialog
#***********************************************************************
proc CreateLocationDialog { w } {
    global Config
    scale $w.latdeg -label "Latitude (degrees)" -orient horizontal \
	    -from 0 -to 89 -length 300 -variable Config(LAT_DEG)
    scale $w.latmin -label "Latitude (minutes)" -orient horizontal \
	    -from 0 -to 59 -length 300 -variable Config(LAT_MIN)
    scale $w.londeg -label "Longitude (degrees)" -orient horizontal \
	    -from 0 -to 179 -length 300 -variable Config(LON_DEG)
    scale $w.lonmin -label "Longtude (minutes)" -orient horizontal \
	    -from 0 -to 59 -length 300 -variable Config(LON_MIN)

    radiobutton $w.north -text "Northern Hemisphere" \
	    -variable Config(NORTHERN_HEMISPHERE) -value 1
    radiobutton $w.south -text "Southern Hemisphere" \
	    -variable Config(NORTHERN_HEMISPHERE) -value 0
    radiobutton $w.west -text "Western Hemisphere" \
	    -variable Config(WESTERN_HEMISPHERE) -value 1
    radiobutton $w.east -text "Eastern Hemisphere" \
	    -variable Config(WESTERN_HEMISPHERE) -value 0

    label $w.loclab -text "City or Town: "
    entry $w.location -width 20
    $w.location insert end $Config(LOCATION)
    grid $w.latdeg -
    grid $w.latmin -
    grid $w.londeg -
    grid $w.lonmin -

    grid $w.north $w.west
    grid $w.south $w.east
    grid $w.loclab -sticky e 
    grid $w.location -sticky nsew -row 6 -column 1
}

#***********************************************************************
# %PROCEDURE: CreateOptionsDialog
# %ARGUMENTS:
#  w -- frame containing dialog
# %RETURNS:
#  Nothing
# %DESCRIPTION:
#  Creates the options dialog
#***********************************************************************
proc CreateOptionsDialog { w } {
    global Config

    label $w.pagelabel -text "Default page size: "
    menubutton $w.page -text $Config(DEFAULT_PAGE) \
	    -indicatoron 1 -relief raised \
	    -menu $w.page.menu
    menu $w.page.menu -tearoff 0
    $w.page.menu add command -label "Letter" \
	    -command "$w.page configure -text Letter"
    $w.page.menu add command -label "A4" -command "$w.page configure -text A4"

    grid configure $w.pagelabel -row 0 -column 0 -sticky e
    grid configure $w.page -row 0 -column 1 -sticky nsew

    label $w.datelabel -text "Default date separator: "
    menubutton $w.date -text $Config(DATESEP) -indicatoron 1 -relief raised \
	    -menu $w.date.menu
    menu $w.date.menu -tearoff 0
    $w.date.menu add command -label "/" -command "$w.date configure -text /"
    $w.date.menu add command -label "-" -command "$w.date configure -text -"

    grid configure $w.datelabel -row 1 -column 0 -sticky e
    grid configure $w.date -row 1 -column 1 -sticky nsew

    label $w.timelabel -text "Default time separator: "
    menubutton $w.time -text $Config(TIMESEP) -indicatoron 1 -relief raised \
	    -menu $w.time.menu
    menu $w.time.menu -tearoff 0
    $w.time.menu add command -label ":" -command "$w.time configure -text :"
    $w.time.menu add command -label "." -command "$w.time configure -text ."

    grid configure $w.timelabel -row 2 -column 0 -sticky e
    grid configure $w.time -row 2 -column 1 -sticky nsew

    label $w.charlabel -text "Character set: "
    menubutton $w.char -text "ISO 8859-1" -indicatoron 1 -relief raised \
	    -menu $w.char.menu
    menu $w.char.menu -tearoff 0
    $w.char.menu add command -label "ISO 8859-1" -command "$w.char configure -text {ISO 8859-1}"
    $w.char.menu add command -label "ISO 8859-2" -command "$w.char configure -text {ISO 8859-2}"
    $w.char.menu add command -label "IBM Extended" -command "$w.char configure -text {IBM Extended}"
    $w.char.menu add command -label "IBM CPI-852" -command "$w.char configure -text {ISO 8859-2}"
    $w.char.menu add command -label "Plain ASCII" -command "$w.char configure -text {Plain ASCII}"

    grid configure $w.charlabel -row 3 -column 0 -sticky e
    grid configure $w.char -row 3 -column 1 -sticky nsew

    label $w.langlabel -text "Language: "
    menubutton $w.lang -text $Config(LANGUAGE) -indicatoron 1 -relief raised \
	    -menu $w.lang.menu
    menu $w.lang.menu -tearoff 0
    foreach lang {
	"Brazilian Portuguese"
	"Danish"
	"Dutch"
	"English"
	"Finnish"
	"French"
	"German"
	"Italian"
	"Norwegian"
	"Polish"
	"Romanian"
        "Spanish"
	"Icelandic"
    } {
	$w.lang.menu add command -label $lang -command [list $w.lang configure -text $lang]
    }

    grid configure $w.langlabel -row 4 -column 0 -sticky e
    grid configure $w.lang -row 4 -column 1 -sticky nsew

}

#***********************************************************************
# %PROCEDURE: BuildRemind
# %ARGUMENTS:
#  None
# %RETURNS:
#  Nothing
# %DESCRIPTION:
#  Builds Remind by:
#  -- creating custom.h from custom.h.in
#  -- running ./configure
#  -- running make
#***********************************************************************
proc BuildRemind {} {
    pack forget .tn
    pack forget .buttons
    wm title . "Remind Configuration Status"
    text .msgs -width 130 -height 35 -wrap char -yscrollcommand ".sb set"
    scrollbar .sb -orient vertical -command ".msgs yview"

    .msgs tag configure green -foreground #005500
    .msgs tag configure red -foreground #990000
    pack .msgs -side left -expand 1 -fill both
    pack .sb -side left -expand 0 -fill y

    update

    .msgs insert end "\n>>> Creating src/custom.h...\n\n" green
    CreateCustomH
    .msgs insert end ">>> Calling `./configure'...\n\n" green
    CallConfigure
    .msgs insert end ">>> Calling `make'...\n\n" green
    CallMake
    .msgs insert end "\n----------------------------------------------\n\n"
    .msgs insert end "Remind" red
    .msgs insert end " has been built.  To install it, type:\n\n"
    .msgs insert end "make install\n\n" green
    .msgs insert end "from the top-level "
    .msgs insert end "Remind" red
    .msgs insert end " directory.  (You may need to be root.)\n\n"
    .msgs insert end "After it's installed, create an empty file called:\n"
    .msgs insert end "       \$HOME/.reminders\n" green
    .msgs insert end "and type "
    .msgs insert end "tkremind" green
    .msgs insert end " for a nice easy introduction to "
    .msgs insert end "Remind.\n\n" red
    .msgs insert end "Press me to exit --> "
    button .msgs.ok -text "OK" -command "exit"
    .msgs window create end -window .msgs.ok
    .msgs see end
}

#***********************************************************************
# %PROCEDURE: RunCommand
# %ARGUMENTS:
#  cmd -- shell command to run
# %RETURNS:
#  Return code of command
# %DESCRIPTION:
#  Runs a command putting output into ".msgs"
#***********************************************************************
proc RunCommand { cmd } {
    global CmdDone

    set CmdDone 0

    .msgs insert end "$cmd\n" red

    set problem [catch {set CmdFile [open "|$cmd" "r"]} err]
    if {$problem} {
	Bail "Error running command `$cmd': $err"
    }

    fconfigure $CmdFile -blocking 0

    fileevent $CmdFile readable "CommandReadable $CmdFile"
    vwait CmdDone

    set problem [catch {close $CmdFile} err]
    if {$problem} {
	Bail "Error running command `$cmd': $err"
    }

}

#***********************************************************************
# %PROCEDURE: CommandReadable
# %ARGUMENTS:
#  f -- file to read from
# %RETURNS:
#  Nothing
# %DESCRIPTION:
#  Reads characters from command pipelin and appends them to .msg.
#***********************************************************************
proc CommandReadable { f } {
    global CmdDone
    set stuff [read $f]
    .msgs insert end $stuff
    .msgs see end
    if {[eof $f]} {
	set CmdDone 1
    }
}

#***********************************************************************
# %PROCEDURE: CallConfigure
# %ARGUMENTS:
#  None
# %RETURNS:
#  Nothing
# %DESCRIPTION:
#  Executes "./configure" with appropriate arguments
# %PRECONDITIONS:
#  Any preconditions
# %POSTCONDITIONS:
#  Any postconditions
# %SIDE EFFECTS:
#  Any side effects
#***********************************************************************
proc CallConfigure {} {
    global Instdir
    set bin [$Instdir.bin get]
    set man [$Instdir.man get]
    RunCommand "./configure --bindir=$bin --mandir=$man"
}

#***********************************************************************
# %PROCEDURE: CreateCustomH
# %ARGUMENTS:
#  None
# %RETURNS:
#  Nothing
# %DESCRIPTION:
#  Creates "src/custom.h" from "src/custom.h.in"
#***********************************************************************
proc CreateCustomH {} {
    global Loc Options Config
    set problem [catch {set in [open "src/custom.h.in" "r"]} err]
    if {$problem} {
	Bail "Can't read src/custom.h.in: $err"
    }
    set problem [catch {set out [open "src/custom.h" "w"]} err]
    if {$problem} {
	Bail "Can't write src/custom.h: $err"
    }

    # Retrieve values
    # The latitude/longitude ones are tied to the scales; we can't
    # modify them willy-nilly
    set LAT_DEG $Config(LAT_DEG)
    set LAT_MIN $Config(LAT_MIN)
    set LON_DEG $Config(LON_DEG)
    set LON_MIN $Config(LON_MIN)
    if {!$Config(NORTHERN_HEMISPHERE)} {
	set LAT_DEG "-$LAT_DEG"
	set LAT_MIN "-$LAT_MIN"
    }
    if {!$Config(WESTERN_HEMISPHERE)} {
	set LON_DEG "-$LON_DEG"
	set LON_MIN "-$LON_MIN"
    }
    set Config(LOCATION) [$Loc.location get]

    switch -- [$Options.page cget -text] {
	"A4" {
	    set Config(DEFAULT_PAGE) "{\"A4\", 595, 842}"
	}
	default {
	    set Config(DEFAULT_PAGE) "{\"Letter\", 612, 792}"
	}
    }
    set Config(DATESEP) [$Options.date cget -text]
    set Config(TIMESEP) [$Options.time cget -text]

    switch -- [$Options.char cget -text] {
	"ISO 8859-1" {
	    set Config(ISOLATIN1) 1
	}
	"ISO 8859-2" {
	    set Config(ISOLATIN2) 1
	}
	"IBM CPI-852" {
	    set Config(IBM852) 1
	}
	"IBM Extended" {
	    set Config(IBMEXTENDED) 1
	}
    }

    while {[gets $in line] != -1} {
	switch -glob -- $line {
	    "#define LAT_DEG *" {
		puts $out "#define LAT_DEG $LAT_DEG"
		.msgs insert end "#define LAT_DEG $LAT_DEG\n"
	    }
	    "#define LAT_MIN *" {
		puts $out "#define LAT_MIN $LAT_MIN"
		.msgs insert end "#define LAT_MIN $LAT_MIN\n"
	    }
	    "#define LON_DEG *" {
		puts $out "#define LON_DEG $LON_DEG"
		.msgs insert end "#define LON_DEG $LON_DEG\n"
	    }
	    "#define LON_MIN *" {
		puts $out "#define LON_MIN $LON_MIN"
		.msgs insert end "#define LON_MIN $LON_MIN\n"
	    }
	    "#define LOCATION *" {
		puts $out "#define LOCATION \"$Config(LOCATION)\""
		.msgs insert end "#define LOCATION \"$Config(LOCATION)\"\n"
	    }
	    "#define DEFAULT_PAGE *" {
		puts $out "#define DEFAULT_PAGE $Config(DEFAULT_PAGE)"
		.msgs insert end "#define DEFAULT_PAGE $Config(DEFAULT_PAGE)\n"
	    }
	    "#define DATESEP *" {
		puts $out "#define DATESEP '$Config(DATESEP)'"
		.msgs insert end "#define DATESEP '$Config(DATESEP)'\n"
	    }
	    "#define TIMESEP *" {
		puts $out "#define TIMESEP '$Config(TIMESEP)'"
		.msgs insert end "#define TIMESEP '$Config(TIMESEP)'\n"
	    }
	    "#define ISOLATIN1 *" {
		puts $out "#define ISOLATIN1 $Config(ISOLATIN1)"
		.msgs insert end "#define ISOLATIN1 $Config(ISOLATIN1)\n"
	    }
	    "#define ISOLATIN2 *" {
		puts $out "#define ISOLATIN2 $Config(ISOLATIN2)"
		.msgs insert end "#define ISOLATIN2 $Config(ISOLATIN2)\n"
	    }
	    "#define IBM852 *" {
		puts $out "#define IBM852 $Config(IBM852)"
		.msgs insert end "#define IBM852 $Config(IBM852)\n"
	    }
	    "#define IBMEXTENDED *" {
		puts $out "#define IBMEXTENDED $Config(IBMEXTENDED)"
		.msgs insert end "#define IBMEXTENDED $Config(IBMEXTENDED)\n"
	    }
	    default {
		puts $out $line
	    }
	}
    }
    close $in
    close $out
}

#***********************************************************************
# %PROCEDURE: CallMake
# %ARGUMENTS:
#  None
# %RETURNS:
#  Nothing
# %DESCRIPTION:
#  Runs "make" with appropriate language definitions
#***********************************************************************
proc CallMake {} {
    global Options
    set lang [$Options.lang cget -text]
    switch -- $lang {
	"German"               { set lang GERMAN }
	"Dutch"                { set lang DUTCH }
	"Finnish"              { set lang FINNISH }
	"French"               { set lang FRENCH }
	"Norwegian"            { set lang NORWEGIAN }
	"Danish"               { set lang DANISH }
	"Polish"               { set lang POLISH }
	"Brazilian Portuguese" { set lang BRAZPORT }
	"Italian"              { set lang ITALIAN }
	"Romanian"             { set lang ROMANIAN }
        "Spanish"              { set lang SPANISH }
	"Icelandic"            { set lang ICELANDIC }
	default                { set lang ENGLISH }
    }
    RunCommand "make \"LANGDEF=-DLANG=$lang\""
}


# Tabbed notebook code from "Effective Tcl/Tk Programming"
# ----------------------------------------------------------------------
#  EXAMPLE: tabnotebook that can dial up pages
# ----------------------------------------------------------------------
#  Effective Tcl/Tk Programming
#    Mark Harrison, DSC Communications Corp.
#    Michael McLennan, Bell Labs Innovations for Lucent Technologies
#    Addison-Wesley Professional Computing Series
# ======================================================================
#  Copyright (c) 1996-1997  Lucent Technologies Inc. and Mark Harrison
# ======================================================================

option add *Tabnotebook.tabs.background #666666 widgetDefault
option add *Tabnotebook.margin 6 widgetDefault
option add *Tabnotebook.tabColor #a6a6a6 widgetDefault
option add *Tabnotebook.activeTabColor #d9d9d9 widgetDefault
option add *Tabnotebook.tabFont \
    -*-helvetica-bold-r-normal--*-120-* widgetDefault

proc tabnotebook_create {win} {
    global tnInfo

    frame $win -class Tabnotebook
    canvas $win.tabs -highlightthickness 0
    pack $win.tabs -fill x

    notebook_create $win.notebook
    pack $win.notebook -expand yes -fill both

    set tnInfo($win-tabs) ""
    set tnInfo($win-current) ""
    set tnInfo($win-pending) ""
    return $win
}

proc tabnotebook_page {win name} {
    global tnInfo

    set page [notebook_page $win.notebook $name]
    lappend tnInfo($win-tabs) $name

    if {$tnInfo($win-pending) == ""} {
        set id [after idle [list tabnotebook_refresh $win]]
        set tnInfo($win-pending) $id
    }
    return $page
}

proc tabnotebook_refresh {win} {
    global tnInfo

    $win.tabs delete all

    set margin [option get $win margin Margin]
    set color [option get $win tabColor Color]
    set font [option get $win tabFont Font]
    set x 2
    set maxh 0

    foreach name $tnInfo($win-tabs) {
        set id [$win.tabs create text \
            [expr $x+$margin+2] [expr -0.5*$margin] \
            -anchor sw -text $name -font $font \
            -tags [list $name]]

        set bbox [$win.tabs bbox $id]
        set wd [expr [lindex $bbox 2]-[lindex $bbox 0]]
        set ht [expr [lindex $bbox 3]-[lindex $bbox 1]]
        if {$ht > $maxh} {
            set maxh $ht
        }

        $win.tabs create polygon 0 0  $x 0 \
            [expr $x+$margin] [expr -$ht-$margin] \
            [expr $x+$margin+$wd] [expr -$ht-$margin] \
            [expr $x+$wd+2*$margin] 0 \
            2000 0  2000 10  0 10 \
            -outline black -fill $color \
            -tags [list $name tab tab-$name]

        $win.tabs raise $id

        $win.tabs bind $name <ButtonPress-1> \
            [list tabnotebook_display $win $name]

        set x [expr $x+$wd+2*$margin]
    }
    set height [expr $maxh+2*$margin]
    $win.tabs move all 0 $height

    $win.tabs configure -width $x -height [expr $height+4]

    if {$tnInfo($win-current) != ""} {
        tabnotebook_display $win $tnInfo($win-current)
    } else {
        tabnotebook_display $win [lindex $tnInfo($win-tabs) 0]
    }
    set tnInfo($win-pending) ""
}

proc tabnotebook_display {win name} {
    global tnInfo

    notebook_display $win.notebook $name

    set normal [option get $win tabColor Color]
    $win.tabs itemconfigure tab -fill $normal

    set active [option get $win activeTabColor Color]
    $win.tabs itemconfigure tab-$name -fill $active
    $win.tabs raise $name

    set tnInfo($win-current) $name
}

# ----------------------------------------------------------------------
#  EXAMPLE: simple notebook that can dial up pages
# ----------------------------------------------------------------------
#  Effective Tcl/Tk Programming
#    Mark Harrison, DSC Communications Corp.
#    Michael McLennan, Bell Labs Innovations for Lucent Technologies
#    Addison-Wesley Professional Computing Series
# ======================================================================
#  Copyright (c) 1996-1997  Lucent Technologies Inc. and Mark Harrison
# ======================================================================

option add *Notebook.borderWidth 2 widgetDefault
option add *Notebook.relief sunken widgetDefault

proc notebook_create {win} {
    global nbInfo

    frame $win -class Notebook
    pack propagate $win 0

    set nbInfo($win-count) 0
    set nbInfo($win-pages) ""
    set nbInfo($win-current) ""
    return $win
}

proc notebook_page {win name} {
    global nbInfo

    set page "$win.page[incr nbInfo($win-count)]"
    lappend nbInfo($win-pages) $page
    set nbInfo($win-page-$name) $page

    frame $page

    if {$nbInfo($win-count) == 1} {
        after idle [list notebook_display $win $name]
    }
    return $page
}

proc notebook_display {win name} {
    global nbInfo

    set page ""
    if {[info exists nbInfo($win-page-$name)]} {
        set page $nbInfo($win-page-$name)
    } elseif {[winfo exists $win.page$name]} {
        set page $win.page$name
    }
    if {$page == ""} {
        error "bad notebook page \"$name\""
    }

    notebook_fix_size $win

    if {$nbInfo($win-current) != ""} {
        pack forget $nbInfo($win-current)
    }
    pack $page -expand yes -fill both
    set nbInfo($win-current) $page
}

proc notebook_fix_size {win} {
    global nbInfo

    update idletasks

    set maxw 0
    set maxh 0
    foreach page $nbInfo($win-pages) {
        set w [winfo reqwidth $page]
        if {$w > $maxw} {
            set maxw $w
        }
        set h [winfo reqheight $page]
        if {$h > $maxh} {
            set maxh $h
        }
    }
    set bd [$win cget -borderwidth]
    set maxw [expr $maxw+2*$bd]
    set maxh [expr $maxh+2*$bd]
    $win configure -width $maxw -height $maxh
}

#***********************************************************************
# %PROCEDURE: FindRemind
# %ARGUMENTS:
#  None
# %RETURNS:
#  Full path to an existing "remind" if one is found.  Otherwise,
#  empty string.
#***********************************************************************
proc FindRemind {} {
    global env
    set path [concat [split $env(PATH) ":"] "/bin" "/usr/bin" "/usr/local/bin"]
    foreach thing $path {
	if [file executable [file join $thing "remind"]] {
	    return [file join $thing "remind"]
	}
    }
    return {}
}

#***********************************************************************
# %PROCEDURE: SetConfigFromRemind
# %ARGUMENTS:
#  None
# %RETURNS:
#  Sets config settings based on existing remind (if one found) or else
#  sensible defaults.
#***********************************************************************
proc SetConfigFromRemind {} {
    global Config
    SetConfigDefaults
    set rem [FindRemind]
    if {"$rem" == ""} {
	return
    }
    set dir [file dirname $rem]
    set Config(INST_DIR) $dir
    if {"$dir" == "/usr/local/bin"} {
	set Config(MAN_DIR) "/usr/local/man"
    } elseif {$dir == "/usr/bin"} {
	set Config(MAN_DIR) "/usr/share/man"
    }

    # Check for existing man page
    if {[file readable "/usr/share/man/man1/remind.1"]} {
	set Config(MAN_DIR) "/usr/share/man"
    } elseif {[file readable "/usr/man/man1/remind.1"]} {
	set Config(MAN_DIR) "/usr/man"
    } elseif {[file readable "/usr/local/man/man1/remind.1"]} {
	set Config(MAN_DIR) "/usr/local/man"
    }

    # Query Remind for the rest
    QueryRemind $rem LAT_DEG {$LatDeg}
    QueryRemind $rem LAT_MIN {$LatMin}
    QueryRemind $rem LON_DEG {$LongDeg}
    QueryRemind $rem LON_MIN {$LongMin}
    QueryRemind $rem LOCATION {$Location}
    QueryRemind $rem DATESEP {$DateSep}
    QueryRemind $rem TIMESEP {$TimeSep}
    QueryRemind $rem LANGUAGE {language()}

    set $Config(LAT_MIN) [expr abs($Config(LAT_MIN))]
    if {$Config(LAT_DEG) >= 0} {
	set Config(NORTHERN_HEMISPHERE) 1
    } else {
	set Config(NORTHERN_HEMISPHERE) 0
	set Config(LAT_DEG) [expr abs($Config(LAT_DEG))]
    }

    set $Config(LON_MIN) [expr abs($Config(LON_MIN))]
    if {$Config(LON_DEG) >= 0} {
	set Config(WESTERN_HEMISPHERE) 1
    } else {
	set Config(WESTERN_HEMISPHERE) 0
	set Config(LON_DEG) [expr abs($Config(LON_DEG))]
    }

    # Get default page from rem2ps
    set rem2ps [file join $dir "rem2ps"]

    catch {
	exec $rem2ps -m help
    } err
    set errlist [split $err "\n"]
    set err [lindex $errlist end]
    if {[string match "Default media type is*" $err]} {
	set Config(DEFAULT_PAGE) [lindex $err end]
    }
}


proc QueryRemind { rem symbol rem_msg } {
    global Config
    catch {
	set fp [open "| $rem -" "r+"]
	puts $fp "banner %\nMSG \[$rem_msg\]%\nFLUSH\n"
	flush $fp
	gets $fp line
	catch { close $fp }
    }
    if {"$line" == ""} {
	return
    }
    set Config($symbol) $line
}

CheckSanity
CreateMainDialog
