# common.tcl --
#
#	Plugin main and remoted common parts (setup), which are not browser
#       specific either
#
# CONTACT:      sunscript-plugin@sunscript.sun.com
#
# AUTHORS:      Jacob Levy              Laurent Demailly
#               jyl@eng.sun.com         demailly@eng.sun.com
#               jyl@tcl-tk.com          dl@mail.org
#
# Please contact us directly for questions, comments and enhancements.
#
# Copyright (c) 1997 Sun Microsystems, Inc.
#
# See the file "license.terms" for information on usage and redistribution
# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
#
# SCCS: @(#) common.tcl 1.10 97/12/04 14:18:30

# we provide browser functionalities:

package provide setup 1.0

# We require logging (we will initialize it from here):

package require log 1.1

# Setup the lazyTkInit :

# Our caller should be run on in a tcl shell which has Tk available
# for loading through the "package require Tk" command but in which
# Tk is not loaded by default (loading of Tk is delayed until the
# need arises).
#
# To ensure that Tk will be properly loaded when it is needed, the rest of
# the code relies on the existance of a "tkLazyInit" procedure. This loads
# and initializes Tk only if that was not already done (ie. lazily and only
# once).
#
# We define "tkLazyInit" below. We detect whether Tk has been already
# initialized for this executable (if we are running inside a wish for
# instance) and in that case we implement an empty "tkLazyInit" proc.
#
# Nb: "package require Tk" would do almost everything right by itself
# but it insists on creating '.' which we may not need in all cases.
# Then, when we don't need to display anything and don't need '.', we 
# we need to remember to withdraw it etc. All of this is taken care of
# in the definition of tkLazyInit.

if {"[info command "wm"]" == "wm"} {
    # Tk is already there, so define an empty lazy init procedure.

    proc tkLazyInit {} {}

    # If no widget have been created, we withdraw the unneeded .

    if {"[winfo children .]" == ""} {
	wm withdraw .
    }

    # Set our nice name (to be seen by other apps (inspect, tkcon,...))

    tk appname $::Name

} else {
    # No Tk, let's define a tkLazyInit *if* one is not defined already:

    if {"[info proc tkLazyInit]" == ""} {
	set ::TkInitialized 0;

	proc tkLazyInit {} {
	    if {$::TkInitialized} {
		# already done, nothing to do
		return
	    }
	    log {} "Actually loading Tk ([info level -1])"
	    # This actually loads / initialize Tk
	    package require Tk 8.0
	    # Withdraw the "." untill someone actually need it
	    wm withdraw .
	    # Set our nice name (to be seen by other apps like inspect, tkcon)
	    tk appname $::Name
	    set ::TkInitialized 1
	}
    }
}


# Setup and eventually start logging facility:

proc SetupLogging {} {
    global env

    # bring logging to the global namespace (expected by the other folks)
    uplevel #0 {namespace import ::log::log ::log::truncateStr}

    if {[info exists env(TCL_PLUGIN_TS)]} {
	proc ::log::TS {} $env(TCL_PLUGIN_TS)
    }
    
    lappend ::log::attributes SLAVE {-background green -foreground black}

    # Start logging depending on environment vars.
    if {[info exists env(TCL_PLUGIN_LOGFILE)] 
        && ($env(TCL_PLUGIN_LOGFILE) != 0) } {
	::log::setup $env(TCL_PLUGIN_LOGFILE)
    } elseif {([info exists env(TCL_PLUGIN_LOGWINDOW)]) 
	&& ($env(TCL_PLUGIN_LOGWINDOW) != 0)} {
	# We need Tk for logging to a window :

	tkLazyInit

	::log::setup window "Log: $::Name"
    }
}	

# (Eventually) Set up a console if the user wants one:

proc SetupConsole {} {
    global env plugin

    # Create a console if the user asks for it:

    log {} "Console setup"
    if {[info exists env(TCL_PLUGIN_CONSOLE)] 
         && ($env(TCL_PLUGIN_CONSOLE) != 0)} {
	if {($env(TCL_PLUGIN_CONSOLE) == 1) || \
		($env(TCL_PLUGIN_CONSOLE) == "")} {
	    set consoleFile [file join $plugin(library) console.tcl]
	} else {
	    set consoleFile $env(TCL_PLUGIN_CONSOLE)
	}
	# Load Tk if not done already:

	tkLazyInit

	if {[catch {uplevel #0 [list source $consoleFile]} msg]} {
	    NotifyError Console\
		    "loading \"$consoleFile\": $msg\n$::errorInfo"
	    return
	}
	log {} "Console file \"$consoleFile\" sourced ok"
    } else {
	log {} "No console created"
    }
}


# Notify user of a critical error:

proc NotifyError {name msg} {

    log $name $msg ERROR
 
    # Load tk if not done already:

    tkLazyInit

    # If the main window . is iconified, our message box would not show up
    # (more like a tk bug to have application grab and iconfied dialog)
    # Also sometimes, the window is iconified but wm state returns withdraw!
    # even with an update inserted.... so we explictly check for ".c"...

    if {[wm state .]=="iconic" || [winfo exists .c]} {
	wm deiconify .
    }

    tk_messageBox -icon error -title "Error: $::Name"\
	    -message "$name: $msg" -type ok

}


# Check the release date

proc CheckAge {} {
    global plugin
    scan $plugin(release) %4d%2d%2d year month day
    set releaseSec [clock scan $month/$day/$year]
    set diff [expr {int(([clock scan seconds]-$releaseSec)/86400)}]
    if {$diff>182} {
	NotifyError Warning "Your copy of the plugin $plugin(patchLevel)\
		is outdated (~[format %.1f [expr {$diff/30.4}]] months\
		old)!\nYou should get a new copy\n(see About Plugins...)"
    }
}

# Configuration setup

proc SetupConfig {} {

    global plugin

    # Initialiaze the configuration (install time / raw parameters):

    package require cfg 1.0

    # one thing the installed.cfg is supposed to do is
    # to set a value for plugin(executable). initialize here it just in case.

    set plugin(executable) {}

    # We will register in the "plugin" slot but we use the semi generated
    # installed.cfg file which will point to the customizable userConfig
    # file (which is supposed to be "plugin" too but in the config/ dir)
    set configFile [file join $plugin(library) installed.cfg]
    if {[catch {::cfg::init "plugin" $configFile} msg]} {
	NotifyError Init "$msg: probable plugin install problem ($configFile)"
    }
    # Now re-init the config with the userConfig
    if {[catch {::cfg::init $::cfg::userConfig} msg]} {
	log {} "$msg: probable plugin configuration problem" ERROR
    }

    CheckAge

}
