;;; ProgArgs installation utility
;;; (c) Copyright 1994 Dianne Hackborn
;;;
;;; Many thanks to Mikael Berglund for finding the Installer
;;; "deferred assign" bug.
;;;
;;; Installer and Installer project icon
;;; (c) Copyright 1991-93 Commodore-Amiga, Inc.  All Rights Reserved.
;;; Reproduced and distributed under license from Commodore.
;;; 
;;; INSTALLER SOFTWARE IS PROVIDED "AS-IS" AND SUBJECT TO CHANGE;
;;; NO WARRANTIES ARE MADE.  ALL USE IS AT YOUR OWN RISK.  NO LIABILITY
;;; OR RESPONSIBILITY IS ASSUMED.    
;;;
;;; Requires the following tooltypes or command line options:
;;; APPNAME=ProgArgs

;**
;** Figure out version of library we are installing
;**

(set libvernum (getversion (cat "68000/" @app-name ".library")))
(set libver (/ libvernum 65536))
(set librev (- libvernum (* libver 65536) ) )
(set libverstr ("%ld.%ld" libver librev) )

;**
;** Figure out which CPU version to install
;**

(set cpu (database "cpu"))
(if (= (strlen cpu) 5)
    (   (set cpu (+ cpu))
        (if (>= cpu 68020) (set cpu "68020") (set cpu "68000")) )
    (set cpu "68000"))

;**
;** Defines
;**

; User level enum
(set
    USER_Novice  0
    USER_Average 1
    USER_Expert  2
)

; Installation set flags
(set
    INSTB_Main      0
    INSTB_SupLibs   1
    INSTB_Locale    2
    INSTB_Headers   3
    INSTB_Extras    4
    INSTB_Autodocs  5
    INSTB_Manuals   6
    
    INSTF_Main      (shiftleft 1 INSTB_Main)
    INSTF_SupLibs   (shiftleft 1 INSTB_SupLibs)
    INSTF_Locale    (shiftleft 1 INSTB_Locale)
    INSTF_Headers   (shiftleft 1 INSTB_Headers)
    INSTF_Extras    (shiftleft 1 INSTB_Extras)
    INSTF_Autodocs  (shiftleft 1 INSTB_Autodocs)
    INSTF_Manuals   (shiftleft 1 INSTB_Manuals)
)

;**
;** Define our global variables
;**

; Full name of application
(set app-name (cat @app-name " v" libverstr))

; Required OS version
(set need-version 37)

; Find name of support shared library
(foreach "Examples/Support" "#?.lib" (set @sup-lib @each-name))

; Place to put shared libraries
(if (= (run "assign LIBS0: exists" (safe)) 0)  ; Make sure not deferred so
    (run "filenote LIBS0:" (safe)) )           ; that Installer doesn't crash
(if (getassign "LIBS0")
    (set sharedlib-dir "LIBS0:")
    (set sharedlib-dir "LIBS:") )

; Place to put locale catalogs
(if (= (run "assign LOCALE: exists" (safe)) 0) ; Make sure not deferred so
    (run "filenote LOCALE:" (safe)) )          ; that Installer doesn't crash
(if (getassign "LOCALE")
    (set locale-dir "LOCALE:Catalogs")
    (set locale-dir "NIL:") )

; Place to put header files
(if (= (run "assign SC: exists" (safe)) 0)     ; Make sure not deferred so
    (run "filenote SC:" (safe)) )              ; that Installer doesn't crash
(if (getassign "SC")
    (set include-dir "SC:Include")
    (   (if (getassign "INCLUDE")
            (set include-dir "INCLUDE:")
            (set include-dir "NIL:")
        )))

; Place to put linked libraries
(if (= (run "assign SC: exists" (safe)) 0)     ; Make sure not deferred so
    (run "filenote SC:" (safe)) )              ; that Installer doesn't crash
(if (getassign "SC")
    (set linkedlib-dir "SC:Lib")
    (   (if (getassign "LIB")
            (set linkedlib-dir "LIB:")
            (set linkedlib-dir "NIL:")
        )))

; Place to put autodocs
(if (= (run "assign AUTODOCS: exists" (safe)) 0) ; Make sure not deferred so
    (run "filenote AUTODOCS:" (safe)) )          ; that Installer doesn't crash
(if (getassign "AUTODOCS")
    (set autodoc-dir "AUTODOCS:")
    (set autodoc-dir "NIL:") )

; Place to put manuals
(if (= (run "assign HELP: exists" (safe)) 0)   ; Make sure not deferred so
    (run "filenote HELP:" (safe)) )            ; that Installer doesn't crash
(if (getassign "HELP")
    (set manuals-dir "HELP:")
    (set manuals-dir "NIL:") )

; Which options to install
(set install-options %1111111111111111)
(if (= locale-dir "NIL:")
    (set install-options (bitand install-options (bitnot INSTF_Locale))) )
(if (= include-dir "NIL:")
    (set install-options (bitand install-options (bitnot INSTF_Headers))) )
(if (= linkedlib-dir "NIL:")
    (set install-options (bitand install-options (bitnot INSTF_Extras))) )
(if (= autodoc-dir "NIL:")
    (set install-options (bitand install-options (bitnot INSTF_Autodocs))) )
(if (= manuals-dir "NIL:")
    (set install-options (bitand install-options (bitnot INSTF_Manuals))) )

; Set up default destination
(set DefaultDest @default-dest) ; get current @default-dest
(set @default-dest "")          ; assign it to something harmless to avoid putting log file somewhere stupid

;**
;** Put up welcome message
;**

(welcome "    Welcome to the " app-name " installation utility.\n")

;**
;** Define basic functions
;**

(procedure conv-version
    (if (and (>= conv-version-num 33) (<= conv-version-num 40))
        (set conv-version-name (select (- conv-version-num 33)
                "1.2" "1.3" "1.3" "2.0" "2.04" "2.1" "3.0" "3.1") )
        (set conv-version-name (cat "v" conv-version-num))
    )
)

; Check if the system is at least our needed version
; Lifted from AmiTCP installation...
(procedure check-system-version
    (set conv-version-num need-version)
    (conv-version)
    (set need-version-name conv-version-name)
    
    (set exec-version (/ (getversion) 65536))
    (set conv-version-num exec-version)
    (conv-version)
    (set exec-version-name conv-version-name)
    
    (transcript "Running on exec version " exec-version " (" conv-version-name ").")
    (if (< exec-version need-version)   ; check operating system version
        (   (message
                    "    " app-name " needs at least Exec version " need-version-name
                    " to run.  You have only version " exec-version-name ".\n"
                    "You can proceed with the installation, but consider "
                    "installing " app-name " with the proper version of "
                    "the operating system."
                (help
                    "    " app-name " uses some system functions "
                    "that are not present or functional in earlier system "
                    "versions. Consider updating your system.\n"
                    "    If you have a later version of operating system "
                    "and are only now using older version: be sure to use "
                    "only release " need-version-name " or newer with " app-name ". "
                    "No damage happens if you run " app-name " with an "
                    "earlier operating system, however.  It just "
                    "refuses to run.\n") )
            (transcript
                "User decided to continue installation while running "
                "on operating system release earlier than " need-version-name".") )
    )
)

; Query for which archive modules to install
(procedure askinstall
    (if (= @user-level USER_Novice)
        (set install-options (bitand install-options 
                (bitnot (bitor INSTF_Headers INSTF_Extras INSTF_Autodocs INSTF_Manuals)))
        ))
    ; Check if there are support libraries.
    (set i 0)
    (foreach "68000" "#?.library" (set i (+ i 1)))
    (if (> i 1) (set has-support 1) (set has-support 0))
    (if (not has-support)
        (set install-options (bitand install-options (bitnot INSTF_SupLibs)))
    )
        ;(set install-options
        ;   (bitor  (bitand install-options %1)
        ;           (shiftright (bitand install-options %1111111111111100) 1))
        ;))
    (if has-support
        (transcript "There are other shared libraries to install.\n")
        (transcript "There aren't any other shared libraries to install.\n") )
    ; Ask for options.
    (set install-options (askoptions
        (prompt (cat
            "\nSelect which components of the " app-name " distribution to install:") )
        (help
            "Explanation of choices:\n\n"
            "    \"" @app-name " Main Library\" -- The main " @app-name " shared library.\n\n"
            (if has-support "    \"Support Libraries\" -- Misc. support libraries which are not required by the main library.\n\n")
            "    \"Locale Catalogs\" -- Library localization catalogs for OS 2.1 or greater.\n\n"
            "    \"Header Files\" -- Developer C header files.\n\n"
            "    \"Extras Linked Library\" -- Developer extras linked library.\n\n"
            "    \"Library Autodocs\" -- Developer function autodoc files.\n\n"
            "    \"Programmer Manuals\" -- Developer manuals on programming " app-name ".\n"
            "\n"
            @askoptions-help)
        (choices    (cat @app-name " Main Library")
                    (if has-support "Support Libraries" "(Not available)")
                    "Locale Catalogs"
                    "Header Files"
                    "Extras Linked Library"
                    "Library Autodocs"
                    "Programmer Manuals" )
        (default install-options) ) )
    (if (not has-support)
        (set install-options (bitand install-options (bitnot INSTF_SupLibs)))
    )
        ;(set install-options
        ;   (bitor  (bitand install-options %1)
        ;           (shiftleft (bitand install-options %1111111111111110) 1))
        ;))
)
    
; Query for CPU type of code to install
(procedure askcpu
    (set n 0)
    (while  (set thiscpu (select n "68000" "68020" ""))
            (   (if (= thiscpu cpu)
                    (set defcpu n))
                (set n (+ n 1))
            ))
    (set cpu (select (askchoice
        (prompt
            "\nSelect CPU version of programs to install:")
        (help
            "Explanation of choices:\n"
            "    \"68000\" -- Select this CPU for computers a 68000 or 68010 microprocessor.  If in doubt, this is the safe choice.\n"
            "    \"68020\" -- Select this CPU for computers a 68020 or better microprocessor.  This allows the library to take advantage of features available in better processors.\n"
            "\n"
            @askchoice-help)
        (choices "68000" "68020")
        (default defcpu)
    ) "68000" "68020"))
    (transcript "Installing for " cpu " CPU.")
)

; Install the main library
(procedure install-main
    (if (= sharedlib-dir "NIL:")
        (set sharedlib-dir ""))
    (set sharedlib-dir (askdir
        (prompt (cat
            "In which drawer should the main " app-name " library be placed?") )
        (help
            "    The " @app-name " library needs to reside in a place where "
            "applications may find it when they try to access the library.  "
            "Shared libraries such as " @app-name " should normally be "
            "installed in the standard \"LIBS:\" volume.\n"
            "\n"
            @askdir-help)
        (default sharedlib-dir) ))
    (transcript "Shared lib directory set to " sharedlib-dir)
    (copylib
        (source (tackon cpu (cat @app-name ".library")))
        (dest sharedlib-dir)
        (prompt (cat "\n\nInstalling \"" @app-name ".library\" to \""
                        sharedlib-dir "\""))
        (help
            "Description of library:\n"
            "    The main " app-name " shared library.  This library is required.\n"
            "\n"
            @copylib-help)
        (confirm) )
)   

; Install the support libraries
(procedure install-suplibs
    (if (= sharedlib-dir "NIL:")
        (set sharedlib-dir ""))
    (set sharedlib-dir (askdir
        (prompt (cat
            "In which drawer should the support " app-name " libraries be placed?") )
        (help
            "    " app-name " comes with some support libraries which "
            "may be used by applications and/or the example programs that "
            "are included in the distribution.  They are not, however, required "
            "by the main library.  These support libraries need to "
            "reside in a place where applications can find them; "
            "this should normally be \"LIBS:\", or the directory where the "
            "main library is installed.\n"
            "\n"
            @askdir-help)
        (default sharedlib-dir) ))
    (transcript "Shared lib directory set to " sharedlib-dir)
    (foreach "68000" (cat "(~(" @app-name ")).library")
        (   (set LibName @each-name)
            (if (>  (getversion (tackon cpu LibName))
                    (getversion (tackon sharedlib-dir LibName)) )
                (copylib
                    (source (tackon cpu LibName))
                    (dest sharedlib-dir)
                    (confirm)
                    (prompt (cat "\n\nInstalling \"" LibName "\" to \""
                                    sharedlib-dir "\""))
                    (help
                        "Description of library:\n"
                        (if (= LibName "progargs.library")
                            "    Routines for handling program CLI and Workbench arguments.\n")
                        (if (= LibName "gadoutline.library")
                            "    Routines for constructing graphical user interfaces.\n")
                        "\n"
                        @copylib-help
                ) )
                (transcript "Skipped " (tackon cpu Libname)
                    " because " (tackon sharedlib-dir LibName) " was newer.") )
        )
    )
)   

; Install the localization catalogs
(procedure install-locale
    (if (= locale-dir "NIL:")
        (set locale-dir ""))
    (set locale-dir (askdir
        (prompt (cat
            "In which drawer should the " app-name " locale catalogs be placed?") )
        (help
            "    " app-name " includes catalog files for localization to "
            "various languages.  Only the catalogs for the languages "
            "which you will be running the library in are required; "
            "if you will only be running it in English, no catalogs are needed.\n"
            "    These catalogs should normally be placed in \"LOCALE:Catalogs\".\n"
            "\n"
            @askdir-help)
        (default locale-dir) ) )
    (transcript "Locale directory set to " locale-dir)
;    (set locale-types %0111)
;   (set locale-types (askoptions
;       (prompt
;           "\nSelect the types of language files to install:")
;       (help
;           "    " app-name " can install various types of localization files:\n"
;           "    \"Catalogs\"   -- These are the standard catalog files needed "
;           "for localization.  They are required for the library to localize itself.\n"
;           "    \"Templates\"  -- These are the .ct files from which catcomp "
;           "constructs the catalog files.  They are useful if you will be "
;           "making your own catalog, but not needed for localization.\n"
;           "    \"Descriptor\" -- These is the .cd file which describes all "
;           "of the localization strings used by the library.  Also not needed "
;           "for localization.\n"
;           "    \"Examples\"   -- These are the various catalog files for the "
;           "example programs.  You should not normally install these, as the "
;           "programs can find their own files if they are started from where "
;           "they are located in the main " @app-name " distribution folder.\n"
;           "\n"
;           @askoptions-help)
;       (choices "Catalogs" "Templates" "Descriptor" "Examples")
;       (default locale-types) ) )
    (set locale-languages %1111111111111111)
    (set locale-languages (askoptions
        (prompt
            "\nSelect the languages to install:")
        (help
            "    " app-name " includes catalog files for localization to "
            "various languages.  Only the catalogs for the languages "
            "which you will be running the library in are required; "
            "if you will only be running it in English, no catalogs are needed.\n"
            "\n"
            @askoptions-help)
        (choices "English")
        (default locale-languages) ) )
    (if locale-languages
        (   (set i 0)
            (while (set locale-name (select i "english" ""))
                (if (in locale-languages i)
                    (   (copyfiles
                            (prompt (cat "Copying " locale-name " catalog to \""
                                         locale-dir "\""))
                            (source (cat "Catalogs/" locale-name "/" @app-name ".catalog"))
                            (dest (tackon locale-dir locale-name))
                            (help
                                "This is the catalog which contains "
                                locale-name " versions of the library's messages.\n"
                                "\n"
                                @copyfiles-help)
                            (confirm))
                        ) )
                (set i (+ i 1)) )
        ) )
)   

; Install the library header files
(procedure install-headers
    (if (= include-dir "NIL:")
        (set include-dir ""))
    (set include-dir (askdir
        (prompt (cat
            "In which drawer should the " app-name " compiler header files be placed?"))
        (help
            "    " app-name " includes standard OS-style header files for "
            "developing applications with the library.  These should be placed "
            "in a directory within your compiler's search path, such as "
            "\"SC:Include\" for SAS/C users.\n"
            "    Files will be copied into the \"clib\", \"fd\", \"proto\", "
            "\"pragmas\", and \"libraries\" sub-directories within this folder.\n"
            "\n"
            @askdir-help)
        (default include-dir) ))
    (transcript "Include directory set to " include-dir)
    (set header-files %1111111111111111)
    (set i 0)
    (while (set header-name (select i "clib" "fd" "proto" "pragmas" "libraries" ""))
        (if (in header-files i)
            (   (copyfiles
                    (prompt (cat "\n\nCopying \"" header-name
                                "\" directory to \""
                                (tackon include-dir header-name) "\""))
                    (source (tackon "Includes" header-name))
                    (dest (tackon include-dir header-name))
                    (help
                        "These are compiler header files needed to write "
                        "applications using " app-name ".\n"
                        "\n"
                        @copyfiles-help)
                    (confirm)
                    (all))
                ) )
        (set i (+ i 1))
    )
)

; Install the library extras linked lib
(procedure install-linklib
    (if (= linkedlib-dir "NIL:")
        (set linkedlib-dir ""))
    (set linkedlib-dir (askdir
        (prompt (cat
            "In which drawer should the " app-name " support shared library be placed?") )
        (help
            "    " app-name " includes a shared library which contains many "
            "extra functions that may be useful to a developer using the library.  "
            "The most important of these is a set of function built on top of "
            "the basic shared library, which provide a standard application "
            "framework for handling multiple windows, menus, program arguments, "
            "and standard program operations such as screen jumping, iconification, "
            "preferences, etc.  It also includes SAS/C autoinitialization modules "
            "for all of the libraries and stubs for the varargs functions in "
            "the library along with other miscellaneous things.\n"
            "\n"
            @askdir-help)
        (default linkedlib-dir) ))
    (transcript "Linked lib directory set to " linkedlib-dir)
    (copyfiles
        (prompt (cat "Copying \"Examples/Support/" @sup-lib "\" to \""
                        linkedlib-dir "\""))
        (source (cat "Examples/Support/" @sup-lib ))
        (dest linkedlib-dir)
        (help
            "This is a linked library of additional support routines.\n"
            "\n"
            @copyfiles-help)
        (confirm))
    (set OldLevel (user USER_Expert))
    (if (askbool
            (prompt (cat
                "NOTE:\n"
                "\n"
                "If you use any modules in the " app-name " support link libarary "
                "(which was installed as \"" (tackon linkedlib-dir @sup-lib) "\"), "
                "you will need to place the associated header files in a location "
                "where your programs can find them.\n"
                "\n"
                "Would you like these headers installed for you?"))
            (help (cat
                "The " app-name " support library "
                "includes many associated header files, located in "
                "the distribution's \"Examples/Support\" folder, which "
                "define the library's modules.  You will need to place these "
                "in a location where your compiler can "
                "find them, if you will be using any of the modules from the "
                "library which have header files.  The headers are not needed for "
                "the low-level support modules such as the auto-constructors "
                "and varargs entry stubs.  A good place for these files is in a "
                "\"support\" directory within "
                "the main compiler include directory.\n"
                "\n"
                @askbool-help))
            (default 1))
        (   (user OldLevel)
            (if (= include-dir "NIL:")
                (set include-dir ""))
            (set include-dir (askdir
                (prompt (cat
                    "In which drawer should the " app-name " support header files be placed?  "
                    "A sub-directory named \"support\" will be created in this directory."))
                (help (cat
                    "    " app-name " includes standard header files for the included "
                    "support link library.  These are required if you will be using any "
                    "of the modules contained in the library.  These headers should be placed "
                    "in a directory within your compiler's search path, such as "
                    "\"SC:Include\" for SAS/C users.\n"
                    "    Files will be copied into a \"support\" sub-directory, which "
                    "will be created in the include directory which you select.\n"
                    "\n"
                    @askdir-help))
                (default include-dir) ))
            (transcript "Include directory set to " include-dir)
            (set support-dir (tackon include-dir "support"))
            (foreach "Examples/Support" ("#?.h")
                (   (set HeaderName @each-name)
                    (if (>= (getversion (tackon "Examples/Support" HeaderName))
                            (getversion (tackon support-dir HeaderName)) )
                        (copyfiles
                            (source (tackon "Examples/Support" HeaderName))
                            (dest support-dir)
                            (prompt (cat "\n\nInstalling \"" HeaderName "\" to \""
                                            support-dir "\""))
                            (help
                                "This is a header file for the " app-name " support "
                                "library.\n"
                                "\n"
                                @copyfiles-help
                        ) )
                        (transcript "Skipped " (tackon "Examples/Support" HeaderName)
                            " because " (tackon support-dir HeaderName) " was newer.") )
                )
            )
        )
    )
    (user OldLevel)
)

; Install the library autodocs
(procedure install-autodocs
    (if (= autodoc-dir "NIL:")
        (set autodoc-dir ""))
    (set autodoc-dir (askdir
        (prompt (cat
            "In which drawer should the " app-name " autodocs be placed?") )
        (help
            "    " app-name " includes standard Amiga autodocs for all of its "
            "functions.  These should be installed with all of your other "
            "autodoc files, if you would like them.\n"
            "\n"
            @askdir-help)
        (default autodoc-dir) ))
    (transcript "Autodoc directory set to " autodoc-dir)
    (copyfiles
        (prompt (cat "Copying \"Includes/" @app-name ".doc\" to \""
                        autodoc-dir "\""))
        (source (cat "Includes/" @app-name ".doc"))
        (dest autodoc-dir)
        (help
            "This is a standard Autodocs-style file documenting the library functions.\n"
            "\n"
            @copyfiles-help)
        (confirm))
)

; Install the library manuals
(procedure install-manuals
    (if (= manuals-dir "NIL:")
        (set manuals-dir ""))
    (if (exists "Docs/Tutorial.ps") (set has-tutorial 1) (set has-tutorial 0))
    (set manuals-dir (askdir
        (prompt (cat
            "In which drawer should the " app-name " manuals be placed?") )
        (help
            "    " app-name " includes an AmigaGuide hypertext version of "
            "its autodocs as its primary manual"
            (if has-tutorial
                ", along with a Postscript file which introduces the basic library concepts.  These"
                ".  This")
            " should be installed where you keep your other programming documentation.\n"
            "\n"
            @askdir-help)
        (default manuals-dir) ))
    (transcript "Manuals directory set to " manuals-dir)
    (copyfiles
        (prompt (cat "Copying \"Includes/" @app-name ".guide\" to \""
                    manuals-dir "\""))
        (source (cat "Includes/" @app-name ".guide"))
        (dest manuals-dir)
        (help
            "This is the library autodoc in a hypertext form which can "
            "be read with AmigaGuide or MultiView.\n"
            "\n"
            @copyfiles-help)
        (confirm)
        (infos) )
    (if has-tutorial
        (copyfiles
            (prompt (cat "Copying \"Docs/Tutorial.doc\" to \""
                            (tackon manuals-dir (cat @app-name "-Tutorial.ps")) "\""))
            (source "Docs/Tutorial.ps")
            (dest manuals-dir)
            (newname (cat @app-name "-Tutorial.ps"))
            (help
                "This is a standard Postscript file which contains a basic "
                "tutorial on using " app-name ".\n"
                "\n"
                @copyfiles-help)
            (confirm)
            (infos))
    )
)

;**
;** Main installation code
;**

(transcript "Installing " app-name ".")
(transcript "Default shared library dir: " sharedlib-dir)
(transcript "Default locale dir: " locale-dir)
(transcript "Default includes dir: " include-dir)
(transcript "Default linked library dir: " linkedlib-dir)
(transcript "Default autodoc dir: " autodoc-dir)
(transcript "Default manuals dir: " manuals-dir)
(transcript "Support shared library: " @sup-lib)

(check-system-version)      ; Make sure OS is correct version
(askinstall)                ; Query user for which parts to install

(if (bitand install-options (bitor INSTF_Main INSTF_SupLibs))
    (askcpu)                ; Query user for cpu to install
)

(if (bitand install-options INSTF_Main)
    (install-main)          ; Install main library
)

(if (bitand install-options INSTF_SupLibs)
    (install-suplibs)       ; Install support libraries
)

(if (bitand install-options INSTF_Locale)
    (install-locale)        ; Install locale catalogs
)

(if (bitand install-options INSTF_Headers)
    (install-headers)       ; Install header files
)

(if (bitand install-options INSTF_Extras)
    (install-linklib)       ; Install extras linked library
)

(if (bitand install-options INSTF_Autodocs)
    (install-autodocs)      ; Install plain autodocs
)

(if (bitand install-options INSTF_Manuals)
    (install-manuals)       ; Install AmigaGuide, Postscript manuals
)

(run (cat "About" @app-name))
(exit app-name " has been successfully installed.")
