;;;  -*- mode: LISP; Package: CL-USER; Syntax: COMMON-LISP;  Base: 10 -*-
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; 
;;; Author      : Mike Byrne & Dan Bothell
;;; Copyright   : (c)1997-2002 CMU/Rice U./Mike Byrne, All Rights Reserved
;;; Availability: public domain
;;; Address     : Rice University
;;;             : Psychology Department
;;;             : Houston,TX 77251-1892
;;;             : byrne@acm.org
;;; 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; 
;;; Filename    : * load-rpm.lisp
;;; Version     : 2.1b7
;;; 
;;; Description : File loader for ACT-R/PM system.
;;; 
;;; 99.12.21 Dan Bothell
;;;          : Made the loader ACL friendly - it now assumes that the 
;;;          :  files are located in the same dir as the load file
;;;	       : Added a feature check to quickdraw.
;;;          : The *file-list depends on which system is running (there should
;;;          :  probably be a neutral list also, but I didn't add it).
;;; 01.04.12 Dan Bothell
;;;          : Changed it to load the ACT-R 5.0 files.
;;;          : Rearranged the order slightly to put the
;;;          :   actr-interface after device-interface
;;;          :   so that process-display could be redefined.
;;;          : Added an ACL specific smart-load that checks 
;;;          :   for zero length fasl's to allow updates
;;;          :   for the Windows environment to work safely.
;;; 01.05.31 Dan Bothell
;;;             : Added a default *file-list definition and made the allegro 
;;;             : definition version specific (in an effort to make R/PM more general).
;;;             : Added a LispWorks smart-loader because it didn't like the
;;;             : pathname handling of the old one.
;;;             : Also removed act-sources from the lists because with 5.0 it's
;;;             : not an issue anymore. 
;;; 01.06.15 Dan
;;;             : Added a loader for clisp (man is it super fast
;;;             : it's an order of magnitude faster than MCL or ACL).
;;; 01.09.17 mdb
;;;             : Made some file changes for 2.1b1
;;;
;;; 02.01.15 Dan
;;;             : Changed the file lists to include the right UWI
;;;             : files, changed the allegro feature tests so that
;;;             : it works better for ACL versions other than 5.0.1,
;;;             : and added a warning (at the end) for ACL users that
;;;             : tells them not to use the Modern mode (case sensitive)
;;;             : version of ACL.
;;; 02.02.11 Dan
;;;             : added a new file "uniform-interface-exp.lisp" for the UWI experiment interface
;;;             : basically an "easier" interface to the UWI for use by tutorial models
;;;             : mostly just hiding of the need to keep a pointer to the window
;;;             : around to do things.
;;;
;;; 02.02.14 Dan
;;;             : Moved actr-interface after rpm-toplevel in the loading because
;;;             : I needed to redefine pm-run for ACT-R.
;;;
;;; 02.04.30 Dan
;;;             : Added the ALLEGRO-LITE tests back because there are
;;;             : people that have the trial version of 5.0.1 (even though it
;;;             : it expired long ago it still runs).
;;; 02.06.21 Dan [b7]
;;;             : Fixed the #+:mcl's so that openmcl will work and changed
;;;             : the ACL loaders to better form the pathname (it was leaving
;;;             : off the drive letter) - the merge-pathnames should probably
;;;             : be used for all of them, and it would simplify things, but
;;;             : I'm not going to do it right now.
;;; 02.06.30 Dan 
;;;             : Changed to reflect the updates to UWI/GUI interface.
;;;             : Simplified things so that there's only a new safe-load
;;;             : function when absolutely necessary.
;;;             : Changed the ACL-lite loader to be specific to :ALLEGRO-V5.0.1
;;;             : because the newer versions do have a compiler. 
;;;             : Removed (let ((*record-source-file* nil)) from around the
;;;             : load call.  Why was that there, it made things a pain when
;;;             : debugging?
;;;             : Added some comments and doc strings. 
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


#+(and :mcl (not :openmcl)) (require 'quickdraw)

;;; For non-MCL systems define the *.lisp-pathname* and *.fasl-pathname*
;;; variables appropriately.

(unless (boundp '*.lisp-pathname*)
  (defvar *.lisp-pathname* (make-pathname :type "lisp")))

(unless (boundp '*.fasl-pathname*)
  (defvar *.fasl-pathname* 
    #+:allegro (make-pathname :type "fasl")
    #+:clisp (make-pathname  :type "fas")
    #+(and :linux :cmu) (make-pathname :type "x86f")
    #+:lispworks (make-pathname :type "fsl")))


;;; Define the files to be loaded.

;;; start with a generic list

(defparameter *file-list '("actr5" "actr5-pm-compiler-fix"
                           "rpm-utils" "dmi" "rpm-parameters"
                           "master-process" "pm-module"
                           "vision-categorization" "vision-module" 
                           "motor-module" 
                           "speech-module"
                           "audio-module"
                           "device-interface" 
                           "cognition-module" "virtual-view" 
                           "UWI-virtual" 
                           "act-gui-interface"
                           "patch-support" "rpm-toplevel" 
                           "actr-interface"
                           "initialize-rpm"))


;;; then switch it to specifics where supported

#+(and :mcl (not :openmcl)) 
(defparameter *file-list '("actr5" "actr5-pm-compiler-fix"
                           "rpm-utils" "dmi" "rpm-parameters"
                           "master-process" "pm-module"
                           "vision-categorization" "vision-module" 
                           "motor-module" 
                           "speech-utils" "speech-module"
                           "audio-module"
                           "device-interface" 
                           "cognition-module" "virtual-view" 
                           "mcl-device"
                           "UWI-virtual" 
                           "UWI-mcl" 
                           "act-gui-interface"
                           
                           "patch-support" "rpm-toplevel" 
                           "actr-interface" "initialize-rpm"))

#+(and :ALLEGRO-IDE :allegro-version>= (version>= 5))

(defparameter *file-list '("actr5" "actr5-pm-compiler-fix"
                           "rpm-utils" "dmi" "rpm-parameters"
                           "master-process" "pm-module"
                           "vision-categorization" "vision-module" 
                           "motor-module" 
                           "speech-module"
                           "audio-module"
                           "device-interface" 
                           "cognition-module" "virtual-view" 
                           "acl-device"
                           
                           "UWI-virtual" 
                           "UWI-acl"
                           "act-gui-interface"
                           
                           
                           "patch-support" "rpm-toplevel" 
                           "actr-interface" "initialize-rpm"))


;;; SMART-LOAD      [Function]
;;; Date        : 99.12.21
;;; Description : Loads binary version of a specified file.  Of course, the 
;;;             : said binary version might not exist or be older than the 
;;;             : source version, in which case the source file is compiled 
;;;             : before loading.  

(defun smart-load (this-files-dir file)
  "Loads binary <file> in directory <this-files-dir> or compiles and loads 
   source version"
  (let* ((the-dir (directory-namestring this-files-dir)) 
         (srcpath (merge-pathnames  
                   (merge-pathnames file *.lisp-pathname*)
                   this-files-dir))
         (binpath (merge-pathnames  
                   (merge-pathnames file *.fasl-pathname*)
                   this-files-dir)))
    (unless (probe-file srcpath)
      (error "File ~S does not exist" srcpath))
    (when (or (not (probe-file binpath))
              (> (file-write-date srcpath) (file-write-date binpath)))
      (compile-file srcpath))
    (load binpath)))

#+:lispworks
(defun smart-load (this-files-dir file)
  "Loads binary <file> in directory <this-files-dir> or compiles and loads 
   source version"
  (let* ((srcpath (merge-pathnames  
                     (make-pathname :name file :type "lisp")
                     this-files-dir))
         (binpath (merge-pathnames 
                     (make-pathname :name file :type "fsl")
                     this-files-dir)))
    (unless (probe-file srcpath)
      (error "File ~S does not exist" srcpath))
    (when (or (not (probe-file binpath))
              (> (file-write-date srcpath) (file-write-date binpath)))
      (compile-file srcpath :output-file binpath))
    (load binpath)))

#+(and :ALLEGRO-IDE :ALLEGRO-V5.0.1 :ALLEGRO-CL-LITE)
(defun smart-load (this-files-dir file)
  "Loads <file> in directory <this-files-dir>"
  (let* ((the-dir (directory-namestring this-files-dir)) 
         (srcpath (merge-pathnames  
                   (merge-pathnames file *.lisp-pathname*)
                   this-files-dir)))
    (unless (probe-file srcpath)
      (error "File ~S does not exist" srcpath))
    (load srcpath)))


;;; LOAD-ACTRPM      [Function]
;;; Date        : 02.06.30
;;; Description : (smart)Loads all of the files specified in *file-list 
;;;             : from the directory in which this-file resides.

(defun load-actrpm (this-file)
  "smart-load all of the files in *file-list from the directory of <this-file>"
  (dolist (the-file *file-list)
    (smart-load this-file the-file)))


;;; If the user isn't using ACL then load things from the directory this file
;;; was loaded from.

#-:allegro
(load-actrpm *load-pathname*)

;;; Otherwise first check to see if they are in the 
;;; ACL Modern mode, and if so warn them that they
;;; should be using the ANSI version.

#+:allegro
(if (or (and (not (eq :case-sensitive-lower *current-case-mode*))
             (not (eq :case-sensitive-upper *current-case-mode*)))
        (yes-or-no-p "WARNING: you are using a case sensitive Lisp.  ACT-R ~
                      will not load and run correctly.  Continue anyway?"))
    (load-actrpm *load-pathname*)
  (format t "ACT-R 5 was NOT loaded."))
      