;;; -*-Emacs-Lisp-*-

;; SKK-MK: installer for SKK.
;; Copyright (C) 1999 Mikio Nakajima <minakaji@osaka.email.ne.jp>

;; Author: Mikio Nakajima <minakaji@osaka.email.ne.jp>
;; Maintainer: Mikio Nakajima <minakaji@osaka.email.ne.jp>
;; Version: $Id: SKK-MK,v 1.43 2000/10/13 11:29:24 akiho Exp $
;; Last Modified: $Date: 2000/10/13 11:29:24 $

;; Commentary
;;
;; Those values of variables below are default configurations.
;; If you would like to change some of those, you should edit SKK-CFG.
;;
;;              DO NOT EDIT THIS FILE DIRECTLY!
;;
;; Please note that all variables specified in the command line
;; overwrite ones defined in SKK-MK and SKK-CFG.
;;
;; Variable sections are all three parts.  GENERIC VARIABLE section,
;; NON-PACKAGE INSTALL RELATED VARIABLE section, and PACKAGE INSTALL
;; RELATED VARIABLE section.
;;
;; You can confirm target directories without an actual installation
;; by M-x SKK-MK-what-where or M-x SKK-MK-what-where-package after
;; load this program.

;;; Code:
;; tinyinstall.el is independent of APEL.
(require 'tinyinstall (expand-file-name "./tinyinstall"))

;;;; User variables to control SKK-MK.
(defvar SKK-MK-debugging nil "*Non-nil means making verbose output.")

;;;; Load configuration file.
;; load user custom file if exists.
(load (expand-file-name "./SKK-CFG") t nil t)

;;;; load-path related.
;; `install-prefix' is defined in tinyinstall.el.
;; Maybe it is `/usr/local', if you use UNIX.
(defvar EMU_PREFIX
  (or (getenv "EMU_PREFIX")
      (if (or (featurep 'xemacs)
	      (and (fboundp 'set-buffer-multibyte)
		   (subrp (symbol-function 'set-buffer-multibyte))))
	  "emu"
	"")))
(defvar PREFIX (or (getenv "PREFIX") install-prefix))
(defvar LISPDIR
  (let ((dir (expand-file-name
	      (or (getenv "LISPDIR") (install-detect-elisp-directory PREFIX)))))
    (if (file-exists-p dir)
	(progn
	  ;; default-load-path takes effect for detecting directory.
	  (setq default-load-path (tinyinstall-add-load-path dir default-load-path))
	  dir))))
(defvar VERSION_SPECIFIC_LISPDIR
  (let ((dir (expand-file-name
	      (or (getenv "VERSION_SPECIFIC_LISPDIR")
		  (install-detect-elisp-directory PREFIX nil 'version-specific)))))
    (if (file-exists-p dir) dir)))
(defvar APEL_SPECIFIC_LISPDIR (let ((dir (getenv "APEL_SPECIFIC_LISPDIR")))
				(and dir (file-exists-p dir) (expand-file-name dir))))

;; in case of defining these variables in SKK-CFG.
(and APEL_SPECIFIC_LISPDIR
     (setq APEL_SPECIFIC_LISPDIR (expand-file-name APEL_SPECIFIC_LISPDIR)))
(and LISPDIR (setq LISPDIR (expand-file-name LISPDIR)))
(and VERSION_SPECIFIC_LISPDIR
     (setq VERSION_SPECIFIC_LISPDIR (expand-file-name VERSION_SPECIFIC_LISPDIR)))

;; searching APEL installed directory...
(if (and LISPDIR (file-exists-p LISPDIR))
    (setq load-path (tinyinstall-add-load-path LISPDIR load-path)))

(let* ((emutmp)
       (apeldir
	(cond ((and APEL_SPECIFIC_LISPDIR (file-exists-p APEL_SPECIFIC_LISPDIR)
		    APEL_SPECIFIC_LISPDIR))
	      ((file-exists-p (expand-file-name "apel" LISPDIR))
	       (expand-file-name "apel" LISPDIR))
	      ;; Unix
	      ((file-exists-p (expand-file-name "../../site-lisp/apel" data-directory))
	       (expand-file-name "../../site-lisp/apel" data-directory))
	      ;; Mule for Windows.
	      ((and
		;; Following two lines identifies Mule for Windows, but are there
		;; any other Emacsen that have the same directory structure?
		;;(featurep 'mule) (eq system-type 'windows-nt)
		;;(= emacs-major-version 19)
		(file-exists-p (expand-file-name "../site-lisp/apel" exec-directory)))
	       (expand-file-name "../site-lisp/apel" exec-directory))))
       (emudir
	(cond ((and
		VERSION_SPECIFIC_LISPDIR
		(setq emutmp (expand-file-name EMU_PREFIX VERSION_SPECIFIC_LISPDIR))
		(cond ((and (file-exists-p emutmp)
			    (not (string= emutmp VERSION_SPECIFIC_LISPDIR))
			    (file-exists-p (expand-file-name "emu.el" emutmp))))
		      ((and
			(string= EMU_PREFIX "")
			;; try again with not standard emu directory.
			(setq emutmp (expand-file-name "emu" VERSION_SPECIFIC_LISPDIR))
			(not (string= emutmp VERSION_SPECIFIC_LISPDIR))
			(file-exists-p emutmp)
			(file-exists-p (expand-file-name "emu.el" emutmp))))))
	       emutmp)
	      ((and
		apeldir
		(setq emutmp (expand-file-name (concat "../" EMU_PREFIX) apeldir))
		(cond ((and (file-exists-p emutmp)
			    (not (string= emutmp VERSION_SPECIFIC_LISPDIR))
			    (file-exists-p (expand-file-name "emu.el" emutmp))))
		      ((and
			(string= EMU_PREFIX "")
			;; try again with not standard emu directory.
			(setq emutmp (expand-file-name "../emu" apeldir))
			(not (string= emutmp VERSION_SPECIFIC_LISPDIR))
			(file-exists-p emutmp)
			(file-exists-p (expand-file-name "emu.el" emutmp))))))
	       emutmp))))
  (and emudir
       (setq load-path (tinyinstall-add-load-path emudir load-path)))
  (and apeldir
       (setq load-path (tinyinstall-add-load-path apeldir load-path))))

(setq load-path (cons (expand-file-name ".") load-path))

(and VERSION_SPECIFIC_LISPDIR
     (file-exists-p VERSION_SPECIFIC_LISPDIR)
     (setq load-path (tinyinstall-add-load-path
		      (expand-file-name VERSION_SPECIFIC_LISPDIR) load-path)))

(if SKK-MK-debugging
    (progn
      (princ (format "APEL_SPECIFIC_LISPDIR=%s\n" APEL_SPECIFIC_LISPDIR))
      (princ (format "load-path=%s\n" load-path))))

;; After seaching APEL installed dirctory, require full set install.el.
(require 'poe)
(require 'install)

;; constants.
(defconst SKK-MK-texinfo-coding-system
  (if (or (featurep 'xemacs)
	  (and (boundp 'mule-version)
	       (or (string< "4.0" mule-version) (string< "3.0" mule-version))))
      'junet
    *junet*))

;; GENERIC VARIABLE.
(defvar DOCDIR (or (getenv "DOCDIR") "./doc"))
(defvar ETCDIR (or (getenv "ETCDIR") "./etc"))
(defvar SKK_PREFIX (or (getenv "SKK_PREFIX") "skk"))
(defvar SKK_INFO (or (getenv "SKK_INFO") "skk.info"))
(defvar SKK_TEXIS (or (getenv "SKK_TEXIS") '("skk.texi")))
(defvar SKK_TUTORIALS (or (getenv "SKK_TUTORIALS") '("SKK.tut" "SKK.tut.E")))
(defvar SKK_MODULES
  ;; $B$3$s$J$b$s%3%^%s%I%i%$%s$G;XDj$9$k?M$$$J$$$h$M!)(B
  (or (getenv "SKK_MODULES")
      (let ((list '(queue-m skk-foreword
			    skk-gadget skk-isearch skk-auto skk-comp
			    skk-kakasi skk-kcode skk-leim skk-look
			    skk-num skk-obsolete skk-server skk-tut
			    skk skk-develop skk-cursor skk-autoloads
			    ;; EXPERIMENTAL
			    skk-rdbms skk-study skk-tutcode skk-tutcdef skk-dcomp
			    skk-abbrev skk-jisx0201 skk-hankaku-mode
			    ;; VIP 3.7
			    ;; vip
			    )))
	(and (featurep 'xemacs)
	     (member "skk-leim" preloaded-file-list)
	     (setq list (nconc list (list 'skk-vars))))
	(condition-case nil
	    ;; you might have to add lookup installed directory to `load-path'.
	    (and (let ((lookup-byte-compile t)) (require 'lookup))
                 (setq list (nconc list (list 'skk-lookup))))
	  (error))
	(condition-case nil
	    (and (require 'viper) (setq list (nconc list (list 'skk-viper))))
	  (error))
	(and (or (featurep 'gdbm) (featurep 'dbm) (featurep 'berkdb)
		 (featurep 'berkeley-db))
	     (setq list (nconc list (list 'skk-dbm))))
	list)))

;; NON-PACKAGE INSTALL RELATED VARIABLE.
(defvar SKK_DATADIR
  (or (getenv "SKK_DATADIR")
      (expand-file-name SKK_PREFIX (expand-file-name "share" PREFIX))))
(defvar SKK_INFODIR
  (or (getenv "SKK_INFODIR")(expand-file-name "info" PREFIX)))
(defvar SKK_LISPDIR
  (or (getenv "SKK_LISPDIR")
      (and LISPDIR (expand-file-name SKK_PREFIX LISPDIR))
      (and PREFIX 
           (expand-file-name SKK_PREFIX 
                             (install-detect-elisp-directory PREFIX)))))

;; PACKAGE INSTALL RELATED VARIABLE.
(defvar PACKAGEDIR
  (or (getenv "PACKAGEDIR")
      (if (boundp 'early-packages)
	  (let ((dirs
		 (append (if early-package-load-path early-packages)
			 (if late-package-load-path late-packages)
			 (if last-package-load-path last-packages)))
		dir)
	    (while (not (file-exists-p (setq dir (car dirs))))
	      (setq dirs (cdr dirs)))
	    dir))))
(defvar PACKAGE_INFODIR
  (or (getenv "PACKAGE_INFODIR") (expand-file-name "info" PACKAGEDIR)))
(defvar PACKAGE_DATADIR
  (or (getenv "PACKAGE_DATADIR")
      (expand-file-name SKK_PREFIX (expand-file-name "etc" PACKAGEDIR))))
(defvar PACKAGE_LISPDIR
  (or (getenv "PACKAGE_LISPDIR")
      (expand-file-name SKK_PREFIX (expand-file-name "lisp" PACKAGEDIR))))

(if SKK-MK-debugging (princ (format "SKK_MODULES=%s\n" SKK_MODULES)))

(defconst SKK_PACKAGE_NOT_USE '(skk-autoloads))
(defconst SKK_MAINTRUNK_NOT_USE '(skk-vip skk-macs skk-xm20_4 stack-m leim-list skk-setup))

;;; [FUNCTIONS]
(defun SKK-MK-compile ()
  (SKK-MK-generate-autoloads-el)
  (compile-elisp-modules SKK_MODULES "."))

(defun SKK-MK-compile-info ()
  (and SKK_INFO
       (if (or (not (file-exists-p (expand-file-name SKK_INFO DOCDIR)))
	       (file-newer-than-file-p (expand-file-name (car SKK_TEXIS) DOCDIR)
				       (expand-file-name SKK_INFO DOCDIR)))
	   (SKK-MK-texinfo-format SKK_TEXIS))))

(defun SKK-MK-install ()
  (SKK-MK-compile)
  (SKK-MK-compile-info)
  (setq DOCDIR (expand-file-name DOCDIR)
	ETCDIR (expand-file-name ETCDIR))
  (or (file-exists-p SKK_LISPDIR)
      (make-directory SKK_LISPDIR t))
  (or (file-exists-p SKK_DATADIR)
      (make-directory SKK_DATADIR t))
  (or (file-exists-p SKK_INFODIR)
      (make-directory SKK_INFODIR t))
  (let ((not-use SKK_MAINTRUNK_NOT_USE)
	file)
    (while not-use
      (setq SKK_MODULES (delq (car not-use) SKK_MODULES)
	    file (expand-file-name
		  (concat (prin1-to-string (car not-use)) ".el")
		  SKK_LISPDIR)
	    not-use (cdr not-use))
      (and (file-exists-p file) (delete-file file))
      (setq file (concat file "c"))
      (and (file-exists-p file) (delete-file file))))
  ;; install Emacs Lisp programs.
  (install-elisp-modules SKK_MODULES "." SKK_LISPDIR)
  ;; install infos.
  (when SKK_INFO
    (let ((files (list SKK_INFO))
	  (i 1) file)
      (while (file-exists-p
	      (expand-file-name (setq file (format "%s-%d" SKK_INFO i)) DOCDIR))
	(setq files (cons file files))
	(setq i (1+ i)))
      (install-files (nreverse files) DOCDIR SKK_INFODIR nil t nil)))
  ;; install tutorials.
  (install-files SKK_TUTORIALS ETCDIR SKK_DATADIR nil t nil))

(defun SKK-MK-install-package ()
  (or (featurep 'xemacs) (error "This directive is only for XEmacs."))
  (or (file-exists-p PACKAGE_LISPDIR)
      (make-directory PACKAGE_LISPDIR t))
  (or (file-exists-p PACKAGE_DATADIR)
      (make-directory PACKAGE_DATADIR t))
  (or (file-exists-p PACKAGE_INFODIR)
      (make-directory PACKAGE_INFODIR t))
  (let ((not-use (append SKK_PACKAGE_NOT_USE SKK_MAINTRUNK_NOT_USE))
	file)
    (while not-use
      (setq SKK_MODULES (delq (car not-use) SKK_MODULES)
	    file (expand-file-name
		  (concat (prin1-to-string (car not-use)) ".el")
		  PACKAGE_LISPDIR)
	    not-use (cdr not-use))
      (and (file-exists-p file) (delete-file file))
      (setq file (concat file "c"))
      (and (file-exists-p file) (delete-file file))))
  ;; install Emacs Lisp programs.
  (compile-elisp-modules SKK_MODULES ".")
  (install-elisp-modules SKK_MODULES "." PACKAGE_LISPDIR)
  (setq autoload-package-name "skk")
  (add-to-list 'command-line-args-left PACKAGE_LISPDIR)
  (batch-update-directory)
  (add-to-list 'command-line-args-left PACKAGE_LISPDIR)
  (Custom-make-dependencies)
  (byte-compile-file (expand-file-name "auto-autoloads.el" PACKAGE_LISPDIR))
  (byte-compile-file (expand-file-name "custom-load.el" PACKAGE_LISPDIR))
  ;; install infos.
  (SKK-MK-compile-info)
  (when SKK_INFO
    (let ((files (list SKK_INFO))
	  (i 1) file)
      (while (file-exists-p
	      (expand-file-name (setq file (format "%s-%d" SKK_INFO i)) DOCDIR))
	(setq files (cons file files))
	(setq i (1+ i)))
      (install-files (nreverse files) DOCDIR PACKAGE_INFODIR nil t nil)))
  ;; install tutorials.
  (install-files SKK_TUTORIALS ETCDIR PACKAGE_DATADIR nil t nil))

(defun SKK-MK-texinfo-format (targets)
  (let (
	;; Emacs20.2's default is 'raw-text-unix.
	(coding-system-for-write SKK-MK-texinfo-coding-system)
	x obuf beg standard-output)
    (require 'ptexinfmt (expand-file-name "ptexinfmt.el" default-directory))
    (while targets
      (setq x (expand-file-name (car targets) DOCDIR))
      (find-file x)
      (setq obuf (current-buffer))
      (texinfo-format-buffer)
      (save-buffer)
      (kill-buffer (current-buffer))	; info
      (kill-buffer obuf)		; texi
      (setq targets (cdr targets)))))

(defun SKK-MK-what-where ()
  (interactive)
  (let ((string
	 (format "
SKK modules:
  %s
  -> %s

SKK infos:
  %s
  -> %s

SKK tutorials:
  %s
  -> %s
"
		 (mapconcat 'symbol-name SKK_MODULES ", ")
		 SKK_LISPDIR
		 SKK_INFO
		 SKK_INFODIR
		 (mapconcat 'identity SKK_TUTORIALS ", ")
		 SKK_DATADIR)))
    (if (interactive-p)
	(progn (with-output-to-temp-buffer "*What where*" (princ string))
	       (message ""))
      (princ string))))

(defun SKK-MK-what-where-package ()
  (interactive)
  (or (featurep 'xemacs) (error "This directive is only for XEmacs."))
  (let ((string
	 (format "
SKK modules:
  %s
  -> %s

SKK infos:
  %s
  -> %s

SKK tutorials:
  %s
  -> %s
"
		 (mapconcat 'symbol-name SKK_MODULES ", ")
		 PACKAGE_LISPDIR
		 SKK_INFO
		 PACKAGE_INFODIR
		 (mapconcat 'identity SKK_TUTORIALS ", ")
		 PACKAGE_DATADIR)))
    (if (interactive-p)
	(progn (with-output-to-temp-buffer "*What where*" (princ string))
	       (message ""))
      (princ string))))

(defun SKK-MK-generate-autoloads-el ()
  "Generate skk-autoload.el."
  (let ((modules SKK_MODULES)
        (buf (get-buffer-create " *SKK-MK-generate-autoloads-el*"))
        (sort-min)
        (funcs)
	standard-output)
    (save-excursion
      (set-buffer buf)
      (erase-buffer)
      (insert "\
;;; skk-autoloads.el --- autoload settings for SKK.

;; This file was generated automatically by SKK-MK at "
              (current-time-string)
              ".

;; This file is part of Daredevil SKK.

;; Daredevil SKK is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either versions 2, or (at your option)
;; any later version.

;; Daredevil SKK is distributed in the hope that it will be useful
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
;; GNU General Public License for more details.

;; You should have received a copy of the GNU General Public License
;; along with Daredevil SKK, see the file COPYING.  If not, write to the Free
;; Software Foundation Inc., 59 Temple Place - Suite 330, Boston,
;; MA 02111-1307, USA.

;;; Code:\n\n")
      (setq sort-min (point))
      (while modules
        (setq funcs (SKK-MK-collect-autoload-functions (car modules)))
        (while funcs
          (insert "(autoload '" (caar funcs)
                  " \"" (symbol-name (car modules))
                  "\" nil "
                  (symbol-name (if (cdar funcs) t))
                  " nil)\n")
          (setq funcs (cdr funcs)))
        (setq modules (cdr modules)))
      (sort-lines nil sort-min (point-max))
      (goto-char (point-max))
      (insert "\n(provide 'skk-autoloads)\n;;; skk-autoloads.el ends here\n")
      (write-region (point-min) (point-max) "skk-autoloads.el" nil 'quiet)
      (kill-buffer buf))))

(defun SKK-MK-collect-autoload-functions (module)
  "Return a list of autoload functions defined in MODULE."
  (let ((el-file (concat (symbol-name module) ".el"))
        (funcs))
    (if (file-exists-p el-file)
        (progn
          (save-excursion
            (insert-file-contents el-file)
            (while (re-search-forward "^;;;###autoload" nil t)
              (beginning-of-line 2)
              (if (looking-at "(defun[ 	]+\\([^ 	(]+\\)")
                  (setq funcs
                        (cons (cons (match-string 1)
                                    (save-excursion
                                      (re-search-forward
                                       "^[ 	]*(interactive"
                                       (save-excursion
					 (re-search-forward "^(defun" nil t 2))
                                       t)))
                              funcs)))))
          (delete-region (point) (point-max))))
    funcs))

;;; SKK-MK ends here
