# -*- tcl -*-
# Main installation script for ActiveTcl
# NO Tk
#
# Copyright 2001, ActiveState Corp.
# All Rights Reserved.

# Arguments: 1 - Location of the distribution.
# Asks the user for the location to install to.

proc main {} {
    # Default install directory
    set ::INSTALL_DIR [default_installdir]
    # Default install error message
    set ::ERRMSG ""

    set state 1
    while {1} {
	switch -exact $state {
	    1 { incr state [intro] }
	    2 { incr state [license] }
	    3 { incr state ; # we have no check_previous_install step here }
	    4 { incr state [get_installdir] }
	    5 { incr state [overinstall] }
	    6 { incr state [get_demodir] }
	    7 { incr state [get_runtimedir] }
	    8 { incr state [plugin_setup] }
	    9 { incr state [install_ready] }
	    10 { exit 0 }
	    default {
		return -code error "Unknow run state \"$state\""
	    }
	}
    }
}

# ----------------------------------------------

proc intro {} {
    puts stdout $::WELCOME
    return [wait_next]
}

proc license {} {
    puts stdout [license_text]
    return [wait_nextc "Cancel         \[no\]  => \[RET]\nAccept License \[yes\] => 'A' >>"]
}

# ----------------------------------------------

proc get_installdir {} {
    if {[string length $::ERRMSG]} { puts stdout $::ERRMSG }
    puts stdout "Please specify the installation directory."

    wait_next "Path \[$::INSTALL_DIR\]: "
    if {[string length $::ANSWER]} {
	set ::INSTALL_DIR $::ANSWER
    }

    if {[string equal $::AT(MODE) lite]} {
	foreach {::INSTALL_DIR ::ERRMSG} [check_installdir_lite $::INSTALL_DIR] {break}
	if {[string length $::ERRMSG]} {
	    # Something wrong with dir, do this again
	    return 0
	} else {
	    # Skip the overinstall check and demo dir
	    return 3
	}
    } else {
	foreach {::INSTALL_DIR ::ERRMSG} [check_installdir $::INSTALL_DIR] {break}
	if {[string length $::ERRMSG]} {
	    # Something wrong with dir, do this again
	    return 0
	} elseif {[string length $::AT(InstVersion)]} {
	    # That we are here means that overinstallation was/is allowed.
	    # Moved to next step (overinstall check).

	    set ::DEMO_DIR [default_demodir $::INSTALL_DIR]
	    set ::RUNTIME_DIR $::INSTALL_DIR
	    return 1
	} else {
	    # Skip the overinstall check

	    set ::DEMO_DIR [default_demodir $::INSTALL_DIR]
	    set ::RUNTIME_DIR $::INSTALL_DIR
	    return 2
	}
    }
}

proc overinstall {} {
    puts stdout [overinstall_warning]
    return [wait_next_back]
}

# ----------------------------------------------

proc get_demodir {} {
    if {[string length $::ERRMSG]} { puts stdout $::ERRMSG }
    puts stdout "Please specify the directory for the demos."

    wait_next "Path \[$::DEMO_DIR\]: "
    if {[string length $::ANSWER]} {
	set ::DEMO_DIR $::ANSWER
    }
    foreach {::DEMO_DIR ::ERRMSG} [check_demodir $::DEMO_DIR] {break}
    if {[string length $::ERRMSG]} {
	# Something wrong with dir, do this again
	return 0
    } else {
	return 1
    }
}

# ----------------------------------------------

proc get_runtimedir {} {
    if {[string length $::ERRMSG]} { puts stdout $::ERRMSG }
    puts stdout "Please specify the runtime installation directory.\n
This is the directory the applications will see as their installation directory
when searching for packages and libraries, instead of the directory the files
were copied to. In most circumstances this is the same as the installation
directory chosen before."

    wait_next "Path \[$::RUNTIME_DIR\]: "
    if {[string length $::ANSWER]} {
	set ::RUNTIME_DIR $::ANSWER
    }
    foreach {::RUNTIME_DIR ::ERRMSG} [check_runtimedir $::RUNTIME_DIR] {break}
    if {[string length $::ERRMSG]} {
	# Something wrong with dir, do this again
	return 0
    } else {
	return 1
    }
}

# ----------------------------------------------

array set ::BROWSELABEL {
    netscape  Netscape
    mozilla   Mozilla
    iexplorer {Internet Explorer}
}

proc plugin_setup {} {
    global HAVE_TCLAPP BROWSE BROWSELABEL BROWSEDIR

    # Skip over plugin for distributions without it.
    if {!$HAVE_TCLAPP} {return 1}

    puts stdout "Installation of the tclplugin for Netscape and/or Mozilla.\n"

    foreach bcode {netscape mozilla} {
	set repeat 1
	set BROWSEDIR($bcode) [set plugdir [get_plugin_dir $bcode]]
	while {$repeat} {
	    if {![file exists $plugdir] || ![file isdirectory $plugdir]} {
		puts      "  $BROWSELABEL($bcode) not found."
		wait_next "  Do you wish to install the tcl plugin for $BROWSELABEL($bcode) ? \[y/N\] >>"
		if {$::ANSWER == {}} {set ::ANSWER n}
	    } else {
		wait_next "  Do you wish to install the tcl plugin for $BROWSELABEL($bcode) ? \[Y/n\] >>"
		if {$::ANSWER == {}} {set ::ANSWER y}
	    }

	    switch -exact -- $::ANSWER {
		N - n {
		    set ::BROWSE($bcode) 0
		    set repeat           0
		}
		Y - y {
		    set ::BROWSE($bcode) 1
		    wait_next "  Path to install the plugin into \[$plugdir\]: "
		    if {[string length $::ANSWER]} {
			set newplugdir $::ANSWER
			if {
			    ![file exists      $newplugdir] ||
			    ![file isdirectory $newplugdir] ||
			    ![file writable    $newplugdir]
			} {
			    puts "  The chosen path does not exist, is no directory, or not writable."
			    puts "  Please choose again."
			    continue
			}
			set BROWSEDIR($bcode) $newplugdir
		    }
		    set repeat 0
		}
	    }
	}
    }

    return 1
}

# ----------------------------------------------

proc install_ready {} {
    puts stdout "Press return to begin installation"
    puts stdout "     Installation Directory:  $::INSTALL_DIR"

    if {[string equal $::AT(MODE) lite]} {
	set ::DEMO_DIR {}
    } else {
	puts stdout "     Demos Directory:         $::DEMO_DIR"
    }
    if {[string equal $::INSTALL_DIR $::RUNTIME_DIR]} {
	puts stdout "     Runtime Directory:       See Installation Directory"
    } else {
	puts stdout "     Runtime Directory:       $::RUNTIME_DIR"
    }

    set res [wait_next]
    if {$res < 0} {
	# The exact target depends on lite.
	# lite/platform: No lite => Standard behaviour

	if {![string equal $::AT(MODE) lite]} {return $res}
	return -4 ; # We are state 8, target is 4 (get_installdir)
    }

    # Install all the files
    do_install_modules	$::SCRIPT_DIR $::INSTALL_DIR $::DEMO_DIR
    # Patch files
    do_finish		$::SCRIPT_DIR $::INSTALL_DIR $::RUNTIME_DIR

    puts [parting_message]

    wait_next "Finish >>"
    exit 0
}

# ----------------------------------------------
# WAIT ROUTINES
# ----------------------------------------------

proc wait_next_back {} {
    while {1} {
	puts -nonewline stdout "\nCancel => C\nNext   => N\nBack   => B : "
	flush stdout

	set answer [gets stdin]
	switch -exact -- [string index $answer 0] {
	    C - C {exit 0}
	    N - n {return  1}
	    B - b {return -1}
	}
    }
}

proc wait_next {{label {}}} {
    if {$label == ""} {
	set label "Cancel => C\nNext   => \[RET] >>"
    }

    puts -nonewline stdout "$label"
    flush stdout

    set res [gets stdin]
    if {
	$res != "" &&
	[regexp Cancel $label] &&
	[string match ${res}* "Cancel"]
    } {
	exit 0
    }
    puts stdout ""
    set ::ANSWER $res
    return 1
}

proc wait_nextc {{label {}}} {
    # Like wait_next, but cancel is default !!

    if {$label == ""} {
	set label "Cancel => \[RET]\nNext   => N >>"
    }

    puts -nonewline stdout "$label"
    flush stdout

    set res [gets stdin]
    if {
	$res == "" &&
	[regexp Cancel $label]
    } {
	exit 0
    }
    puts stdout ""
    set ::ANSWER $res
    return 1
}

# ----------------------------------------------
# LOGGING ROUTINE
# ----------------------------------------------

proc log {msg {type ok}} {
    puts stdout "-- $msg"
}

# ----------------------------------------------
# GO TO IT
# ----------------------------------------------

set ::SCRIPT_DIR [file dirname [info script]]
set here [pwd] ; cd $::SCRIPT_DIR ; set ::SCRIPT_DIR [pwd] ; cd $here
source [file join $SCRIPT_DIR install_lib.tcl]
main
