proc setupGUI {} {
    global status env
    set status ""

    wm title . "Reaction Explorer Database"
    wm geometry . +4+25

    label .status -textvariable status -width 30
    pack .status -side bottom -expand yes -fill x

    catch {
	package require Utility
	set path [Environment res]
	set logoFile [Environment findFile $path REX/images/logo.gif]
    } result
    if {$logoFile != ""} {
	set logo [image create photo -file $logoFile -format gif]
	label .logo -image $logo
	pack .logo -side left
    }

    frame .total
    frame .current
    pack .total .current -expand yes -fill x
    label .total.v -textvariable counter(totalConnections) -width 5
    label .current.v -textvariable counter(currentConnections) -width 5
    pack .total.v .current.v -side right
    label .total.l   -text "Total clients:"
    label .current.l -text "Current clients:"
    pack .total.l .current.l -side right

    button .exit -command shutdown -text Exit
    pack .exit 

}

proc saveAll {} {
    global status Database

    set status "saving databases..."

    foreach db [array names Database] {
	saveDB $db
    }

    set status "saved [array names Database] at [clock format [clock seconds] -format %T]"
}

proc savePeriodically {{time 10}} {

    # note: time is in MINUTES, not seconds or milliseconds

    saveAll

    if {[Environment db_save_interval] != ""} {
        set time [Environment db_save_interval]
    }
    after [expr $time*60*1000] savePeriodically $time
}

proc shutdown {} {
    global Database counter

    saveAll

    if {$counter(currentConnections) != 0} {
	#
	# Do we really want to quit?
	#
	if {![winfo exists .md]} {
	    messagedialog .md -title "Stop RexDB server" \
		    -text "There are clients using the database. Really quit?" \
		    -bitmap questhead -modality application

	    .md hide Help
	    .md buttonconfigure OK -text Yes 
	    .md buttonconfigure Cancel -text No
	}
        .md center

	if {![.md activate]} {
	    return
	}
	destroy .md	
    }
    exit
}

proc createDB {name {filename ""}} {
    global Database

    if {[info exists Database($name)]} {
	error "Database $name is already open"
    }

    #
    # Create a new database
    #

    package require DemoDB
    DemoDB $name


    if {$filename == ""} {
	set Database($name) Databases/$name/DB
    } else {
	set Database($name) $filename
    }
}

proc openDB {name {filename ""}} {

    global Database

    #
    # Open an existing database
    #

    if {[info exists Database($name)]} {
	return
    }

    if {$filename == ""} {
	set filename Databases/$name/DB
    }

    package require Archive
    new FileArchive ar $filename read
    DemoDB $name

    $name deserialize $ar
    unset ar

    set Database($name) $filename
}

proc exists {name {filename ""}} {

    global Database

    #
    # Open an existing database
    #

    if {[info exists Database($name)]} {
	return 1
    }

    if {$filename == ""} {
	set filename Databases/$name.db
    }

    if {[glob -nocomplain $filename] == ""} {
	return 0
    }
    return 1
}

proc saveDB {name} {
    
    global status
    set status "saving $name"
    # 
    # Save the database to its file
    #

    global Database

    if {![info exists Database($name)]} {
	error "Database $name is not open"
    }

    set filename $Database($name)

    catch {file copy -force $filename ${filename}-}
    package require Archive
    new FileArchive ar $filename write
    $name serialize $ar
    unset ar

    set status "saved $name at [clock format [clock seconds] -format %T]"
}

proc closeDB {name} {
    # 
    # Close the database
    #

    global Database

    if {![info exists Database($name)]} {
	error "Database $name is not open"
    }

    delete object $name
    unset Database($name)
}

set v [package require ClientHandler]
set v [package require DemoDB]
set v [package require Request_Manager]

new ClientHandler dbServer $port counter

setupGUI

savePeriodically
