;;; -*-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.32 1999/11/10 12:09:03 minakaji Exp $
;; Last Modified: $Date: 1999/11/10 12:09:03 $

;; 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-cleanup-trouble-makers nil
  "*Non-nil means clean up already installed SKK package configration files.
If symbol `backup' makes backup files named `xxxx.BAK'.

Deleted files are `auto-autoloads.el', `custom-load.el', `skk-autoloads.el',
`skk-vars.el' which exist in `lisp/skk' under `package-locations', or
if `package-locations' does not exist `load-path' of which directories name
end with `skk'." )

(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 'install)

;; constants.
(defconst SKK-MK-running-xemacs (string-match "XEmacs" emacs-version))

(defconst SKK-MK-texinfo-coding-system
  (if (or SKK-MK-running-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_INFOS
  (or (getenv "SKK_INFOS")
      '("skk.info" "skk.info-1" "skk.info-2" "skk.info-3" "skk.info-4") ))
(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 stack-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 SKK-MK-running-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 (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 )))
(defvar SKK_PREFIX (or (getenv "SKK_PREFIX") "skk"))
(defvar SKK_TEXIS (or (getenv "SKK_TEXIS") '("skk.texi")))
(defvar SKK_TUTORIALS (or (getenv "SKK_TUTORIALS") '("SKK.tut" "SKK.tut.E")))

;; 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") (expand-file-name SKK_PREFIX LISPDIR)) )

;; 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 SKK_PACKAGE_DATADIR
  (or (getenv "SKK_PACKAGE_DATADIR")
      (expand-file-name SKK_PREFIX (expand-file-name "etc" PACKAGEDIR)) ))

(defvar SKK_PACKAGE_LISPDIR
  (or (getenv "SKK_PACKAGE_LISPDIR")
      (expand-file-name SKK_PREFIX (expand-file-name "lisp" PACKAGEDIR)) ))

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

(defun SKK-MK-compile ()
  (compile-elisp-modules SKK_MODULES ".") )

(defun SKK-MK-install ()
  (SKK-MK-compile)
  (if (and SKK-MK-running-xemacs SKK-MK-cleanup-trouble-makers)
      (SKK-MK-cleanup-trouble-makers
       (eq SKK-MK-cleanup-trouble-makers 'backup) ))
  (setq DOCDIR (expand-file-name DOCDIR)
	ETCDIR (expand-file-name ETCDIR) )
  ;; install Emacs Lisp programs.
  (install-elisp-modules SKK_MODULES "." SKK_LISPDIR)
  ;; install infos.
  (if (or (not (file-exists-p (expand-file-name (car SKK_INFOS) DOCDIR)))
	  (file-newer-than-file-p (expand-file-name (car SKK_TEXIS) DOCDIR)
				  (expand-file-name (car SKK_INFOS) DOCDIR) ))
      (SKK-MK-texinfo-format SKK_TEXIS) )
  (install-files SKK_INFOS 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."))
  (if SKK-MK-cleanup-trouble-makers
      (SKK-MK-cleanup-trouble-makers
       (eq SKK-MK-cleanup-trouble-makers 'backup) ))
  (or (file-exists-p SKK_PACKAGE_LISPDIR)
      (make-directory SKK_PACKAGE_LISPDIR t) )
  (or (file-exists-p SKK_PACKAGE_DATADIR)
      (make-directory SKK_PACKAGE_DATADIR t) )
  (or (file-exists-p PACKAGE_INFODIR)
      (make-directory PACKAGE_INFODIR t) )
  ;; install Emacs Lisp programs.
  (compile-elisp-modules SKK_MODULES ".")
  (install-elisp-modules SKK_MODULES "." SKK_PACKAGE_LISPDIR)
  (setq autoload-package-name "skk")
  (add-to-list 'command-line-args-left SKK_PACKAGE_LISPDIR)
  (batch-update-directory)
  (add-to-list 'command-line-args-left SKK_PACKAGE_LISPDIR)
  (Custom-make-dependencies)
  (byte-compile-file (expand-file-name "auto-autoloads.el" SKK_PACKAGE_LISPDIR))
  (byte-compile-file (expand-file-name "custom-load.el" SKK_PACKAGE_LISPDIR))
  ;; install infos.
  (if (or (not (file-exists-p (expand-file-name (car SKK_INFOS) DOCDIR)))
	  (file-newer-than-file-p (expand-file-name (car SKK_TEXIS) DOCDIR)
				  (expand-file-name (car SKK_INFOS) DOCDIR) ))
      (SKK-MK-texinfo-format SKK_TEXIS) )
  (install-files SKK_INFOS DOCDIR PACKAGE_INFODIR nil t nil)
  ;; install tutorials.
  (install-files SKK_TUTORIALS ETCDIR SKK_PACKAGE_DATADIR nil t nil) )

(defun SKK-MK-cleanup-trouble-makers (&optional backup)
  (let ((dirs
	 (if (boundp 'package-locations)
	     (let ((l
		    (mapcar
		     (function (lambda (d) (expand-file-name "lisp/skk" (car d))))
		     package-locations )))
	       (if early-package-load-path
		   (nconc
		    l 
		    (mapcar
		     (function (lambda (d) (expand-file-name "lisp/skk" d)))
		     early-packages )))
	       (if late-package-load-path
		   (nconc
		    l
		    (mapcar
		     (function (lambda (d) (expand-file-name "lisp/skk" d)))
		     late-packages )))
	       (if last-package-load-path
		   (nconc
		    l
		    (mapcar
		     (function (lambda (d) (expand-file-name "lisp/skk" d)))
		     last-packages )))
	       l )
	   (delq nil
		 (mapcar
		  (function (lambda (d) (if (string-match "skk/*$" d) d)))
		  load-path ))))
	(files '("auto-autoloads.el" "custom-load.el" "skk-autoloads.el"
		 ;; obsolete.
		 "skk-vars.el" ))
	(index0 0) (index1 0) (counter 0) dir file )
    (message "Cleanup trouble makers...")
   (while (setq dir (nth index0 dirs))
     (setq index1 0)
      (while (setq file (nth index1 files))
	(setq file (expand-file-name file dir))
	(condition-case nil
	    (progn
	      (if (file-exists-p file)
		  (progn
		    (if backup
			;; XXX not for ms-dos...
			(copy-file file (concat file ".BAK") t t) )
		    (delete-file file)
		    (setq counter (1+ counter)) ))
	      (if (file-exists-p (concat file "c"))
		  (progn
		    (if backup
			;; XXX not for ms-dos...
			(copy-file (concat file "c") (concat file ".BAK") t t) )
		    (delete-file (concat file "c"))
		    (setq counter (1+ counter)) )))
	  (error) )
	(setq index1 (1+ index1)) )
      (setq index0 (1+ index0)) )
    (message "Cleanup trouble makers...%s files done" counter) ))

(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 )
    (while targets
      (setq x (expand-file-name (car targets) DOCDIR))
      (find-file x)
      (setq obuf (current-buffer))
      (condition-case nil
	  (texinfo-format-buffer)
	(error				; one more try with no @direntry
	 ;;(kill-buffer (current-buffer))
	 (set-buffer obuf)
	 (goto-char (point-min))
	 (message "Format failed. Trying no @direntry")
	 (let (buffer-read-only)
	   (when (re-search-forward "@direntry" nil t)
	     (setq beg (match-beginning 0))
	     (when (re-search-forward "@end direntry" nil t)
	       (delete-region beg (match-end 0)) )))
	 (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
		 (mapconcat 'identity SKK_INFOS ", ")
		 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 ", ")
		 SKK_PACKAGE_LISPDIR
		 (mapconcat 'identity SKK_INFOS ", ")
		 PACKAGE_INFODIR
		 (mapconcat 'identity SKK_TUTORIALS ", ")
		 SKK_PACKAGE_DATADIR )))
    (if (interactive-p)
	(progn (with-output-to-temp-buffer "*What where*" (princ string))
	       (message "") )
      (princ string) )))

;;; SKK-MK ends here
