;;; SKK-MK --- installer for SKK  -*-emacs-lisp-*-

;; Copyright (C) 1999, 2000 NAKAJIMA Mikio <minakaji@osaka.email.ne.jp>
;; Copyright (C) 2003, 2004 SKK Development Team <skk@ring.gr.jp>

;; Author: NAKAJIMA Mikio <minakaji@osaka.email.ne.jp>
;; Maintainer: SKK Development Team <skk@ring.gr.jp>
;; Version: $Id: SKK-MK,v 1.137 2006/01/10 15:32:06 skk-cvs Exp $
;; Last Modified: $Date: 2006/01/10 15:32:06 $

;;; 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"))

(when (string-lessp emacs-version "19")
  (error "%s" "\
Emacs 18 or older is not supported by this version of SKK.
Try ddskk-e18 branch"))

(when (string-lessp emacs-version "20.3")
  (error "%s" "\
Emacs 20.2 or older is not supported by this version of SKK.
Please install Daredevil SKK 11.6.0"))

(unless (featurep 'mule)
  (error "%s" "\
This version of SKK requires MULE features"))

(set-language-environment "Japanese")

;;;; 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 nil)

;;;; 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)
	      (fboundp 'normal-top-level-add-subdirs-to-load-path))
	  "emu"
	"")))

(defvar PREFIX (or (getenv "PREFIX")
		   install-prefix))

(defvar LISPDIR
  (let ((dir (expand-file-name
	      (or (getenv "LISPDIR")
		  (cond ((eq system-type 'windows-nt)
			 (expand-file-name "site-lisp" PREFIX))
			((eq system-type 'ms-dos)
			 (expand-file-name "site-lis" PREFIX))
			(t
			 (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)
      nil)))

(defvar VERSION_SPECIFIC_LISPDIR
  (let ((dir
	 (expand-file-name
	  (or (getenv "VERSION_SPECIFIC_LISPDIR")
	      (cond ((eq system-type 'windows-nt)
		     (expand-file-name "site-lisp" PREFIX))
		    (t
		     (install-detect-elisp-directory
		      PREFIX nil 'version-specific)))))))
    (if (file-exists-p dir)
	dir
      nil)))

(defvar APEL_SPECIFIC_LISPDIR
  (let ((dir (getenv "APEL_SPECIFIC_LISPDIR")))
    (if (and dir
	     (file-exists-p dir))
	(expand-file-name dir)
      nil)))

(defvar ADDITIONAL_LISPDIR nil)

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

(when LISPDIR
  (setq LISPDIR (expand-file-name LISPDIR)))

(when VERSION_SPECIFIC_LISPDIR
  (setq VERSION_SPECIFIC_LISPDIR
	(expand-file-name VERSION_SPECIFIC_LISPDIR)))

;; searching APEL installed directory...
(when (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 and NTEmacs.
	   (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))
	   (or
	    (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))
	   (or
	    (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))))

  (when emudir
    (setq load-path (tinyinstall-add-load-path emudir load-path)))
  (when apeldir
    (setq load-path (tinyinstall-add-load-path apeldir load-path))))

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

(when (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)))

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

(when SKK-MK-debugging
  (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 'poem)
(require 'install)

(condition-case nil
    (require 'product)
  (error
   (error "%s"
	  "This version of Daredevil SKK requires APEL/10.6 or later")))

(unless (product-version>= 'apel-ver
			   '(10 6))
 (error "%s"
	"This version of Daredevil SKK requires APEL/10.6 or later"))

;; constants.
(defconst SKK-MK-texinfo-coding-system 'iso-2022-jp)

;; GENERIC VARIABLE.
(defvar DOCDIR (or (getenv "DOCDIR")
		   "./doc"))
(defvar ETCDIR (or (getenv "ETCDIR")
		   "./etc"))
(defvar DICDIR (or (getenv "DICDIR")
		   "./dic"))
(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"
			    "NICOLA-SKK.tut"
			    "skk.xpm")))
(defvar SKK_DICTIONARIES
  (or (getenv "SKK_DICTIONARIES")
      '("SKK-JISYO.L" "SKK-JISYO.ML" "SKK-JISYO.M" "SKK-JISYO.S"
	"SKK-JISYO.JIS2" "SKK-JISYO.JIS3_4"
	"SKK-JISYO.pubdic+" "SKK-JISYO.edict"
	"SKK-JISYO.office.zipcode" "SKK-JISYO.zipcode")))

(defvar SKK_DEFAULT_JISYO
  (or (getenv "SKK_DEFAULT_JISYO")
      nil))

(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 '(context-skk
		    queue-m
		    skk-abbrev
		    skk-act
		    skk-annotation
		    skk-auto
		    skk-autoloads
		    skk-azik
		    skk-comp
;		    skk-cursor
		    skk-cus
		    skk-dcomp
		    skk-develop
		    skk-dic
		    skk-gadget
		    skk-isearch
		    skk-jisx0201
;                   skk-jisx0213
		    skk-jisyo-edit-mode
		    skk-kakasi
		    skk-kcode
		    skk-leim
		    skk-look
;                   skk-lookup
		    skk-macs
		    skk-num
		    skk-obsolete
		    skk-server-completion
		    skk-server
		    skk-tankan
		    skk-tut
		    skk-vars
		    skk-version
		    skk

		    ;; EXPERIMENTAL
		    skk-bayesian
		    skk-correct
		    skk-exsearch
		    skk-exserv
		    skk-hint
		    skk-rdbms
		    skk-study
		    skk-tutcdef
		    skk-tutcode
		    skk-w3m
		    skk-azik
		    ;; VIP 3.7
		    ;; vip
		    )))
	;; $B%P%$%H%3%s%Q%$%k;~$K(B X window $B$,(B initialize $B$5$l$F$$$J$$$H$$$&%(%i!<(B
	;; $B$K$J$k(B (;_;)$B!#(B
	;; yatex $B$_$?$$$K(B Window $B$r3+$$$F%P%$%H%3%s%Q%$%k$9$k$h$&$K$b(B
	;; $B$G$-$k$1$I!"(Bno-window $B$N(B make $B%3%^%s%I$rJL$K:n$i$J$-$c$J$i(B
	;; $B$J$$$7!"LLE]$@$J(B...$B!#(B
	;;(if (if (featurep 'xemacs)
	;;        (eq (device-class (selected-device)) 'color)
	;;      (x-display-color-p))
	;;    (setq list (nconc list (list 'skk-cursor))))
	(cond
	 ((featurep 'xemacs)
	  ;; XEmacs
	  (when	(or (featurep 'gdbm)
		    (featurep 'dbm)
		    (featurep 'berkdb)
		    (featurep 'berkeley-db))
	    (add-to-list 'list 'skk-dbm))
	  (add-to-list 'list 'skk-xemacs))
	 (t
	  ;; FSFmacs
	  (unless (fboundp 'define-minor-mode)
	    (setq list (delq 'context-skk list)))
	  (when (featurep 'faces)
	    (add-to-list 'list 'ccc))
	  (when (string< "5.0" mule-version)
	    (add-to-list 'list 'skk-e21))))
	;; skk-jisx0213.el
	(when (or (find-coding-system 'euc-jisx0213)
		  (condition-case nil
		      (and (require 'jisx0213)
			   (require 'un-define))
		    (error)))
	  (add-to-list 'list 'skk-jisx0213))
	;; skk-lookup.el
	(when (condition-case nil
		  ;; you might have to add lookup installed directory
		  ;; to `load-path'.
		  (let ((lookup-byte-compile t))
		    (require 'lookup))
		(error))
	  (add-to-list 'list 'skk-lookup))
	;; skk-w3m.el
	;;(when (condition-case nil
	;;          (require 'w3m-search)
	;;        (error))
	;;  (add-to-list 'list 'skk-w3m))
	;; skk-viper.el
	(when (condition-case nil
		  (require 'viper)
		(error))
	  (add-to-list 'list 'skk-viper))
	;; skk-cursor.el
	(when (or (featurep 'xemacs)
		  (featurep 'faces))
	  (add-to-list 'list 'skk-cursor))
	;;
	list)))

;; $B>C$5$J$/$H$b%$%s%9%H!<%k>e$OLdBj$,$J$$$,!"(Bwhat-where $B%$%s%9%H!<%k$5$l$J$$(B
;; $B%W%m%0%i%`$,I=<($5$l$k$N$rKI$0$?$a!"%H%C%W%G%#%l%/%H%j$K$J$$%W%m%0%i%`$O(B
;; $B>C$7$F$*$/!#(B
(let ((modules SKK_MODULES))
  (while modules
    (unless (or
	     ;; skk-autoloads.el $B$O<+F0@8@.$5$l$k$N$G$^$@B8:_$7$J$$!#(B
	     (memq (car modules) '(skk-autoloads skk-dic))
	     (file-exists-p (concat (symbol-name (car modules))
				    ".el")))
      (setq SKK_MODULES (delq (car modules) SKK_MODULES)))
    (setq modules (cdr modules))))

;; 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")
      ;;
      (cond
       ((file-directory-p
	 (expand-file-name "info" (expand-file-name "share" PREFIX)))
	(expand-file-name "info" (expand-file-name "share" PREFIX)))
       ;;
       ((file-directory-p (expand-file-name "info" PREFIX))
	(expand-file-name "info" PREFIX))
       (t
	(let ((list Info-default-directory-list)
	      dir)
	  (while (and (not dir)
		      list)
	    (when (file-directory-p (car list))
	      (setq dir (car list)))
	    (setq list (cdr list)))
	  dir)))
      ;;
      (expand-file-name "info" PREFIX)))

(defvar SKK_LISPDIR
  (or (getenv "SKK_LISPDIR")
      (cond
       (VERSION_SPECIFIC_LISPDIR
	(expand-file-name SKK_PREFIX VERSION_SPECIFIC_LISPDIR))
       (PREFIX
	(expand-file-name SKK_PREFIX
			  (install-detect-elisp-directory
			   PREFIX)))
       (t
	nil))))

;; 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)
	nil)))

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

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

(defconst SKK_DAREDEVIL_NOT_USE '(skk-vip
				  skk-foreword
				  stack-m
				  skk-cursor2
				  skk-cursor3))

;; This code is for skk-jisx0201.el.
(when (fboundp 'make-translation-table) ;; FSF Emacs 20.3 or later
  (setq standard-translation-table-for-decode
	(make-translation-table nil)))

;;; [FUNCTIONS]
(defun SKK-MK-make-setup-file (spec)
  ;; SPEC $B$O8rBe%j%9%H!#(B
  (with-temp-buffer
    (save-excursion
      (insert-file-contents "skk-setup.el.in")
      (goto-char (point-min))
      (when (looking-at ";;; -\\*- emacs-lisp -\\*-")
	(delete-region (point)
		       (progn
			 (forward-line 1)
			 (point))))
      (when (search-forward
	     ";;; skk-setup.el --- Initial setup for SKK")
	(forward-line 1)
	(insert
	 ";; This file was generated automatically by SKK-MK at "
	 (current-time-string)
	 "\n"))
      (while spec
	(goto-char (point-min))
	(while (re-search-forward
		(concat "^;;[^@]+\\(" (car spec) "\\)")
		nil t nil)
	  (delete-region (match-beginning 1)
			 (match-end 1))
	  (insert (nth 1 spec))
	  (beginning-of-line)
	  (while (looking-at ";")
	    (delete-char 1)))
	(setq spec (nthcdr 2 spec)))
      (write-region (point-min) (point-max) "skk-setup.el"))))

(defun SKK-MK-server-installed-p ()
  (if (and (not (featurep 'xemacs))
	   (eq system-type 'gnu/linux)
	   (string-lessp emacs-version "22"))
      ;; Do not call `open-network-stream' for Emacs 21.4 or earlier,
      ;; under GNU/Linux, due to a serious problem where Emacs with a
      ;; new shell process causes SIGPOLL in batch mode.  To return
      ;; `nil' here is just a workaround, without really checking the
      ;; server state.
      nil
    ;; Check whether we can talk to the server.
    (require 'skk-server (expand-file-name "skk-server.el"))
    (let ((skk-server-inhibit-startup-server t))
      (condition-case nil
	  (prog1
	      (skk-server-live-p (skk-open-server))
	    (skk-disconnect-server))
	(error)))))

(defvar SKK_SET_JISYO
  (let* ((set_jisyo (or (getenv "set_jisyo")
			(getenv "SET_JISYO")))
	 (flag
	  (cond ((not (stringp set_jisyo))
		 'fuzzy)
		((member (downcase set_jisyo)
			 '("yes" "1" "t" "y"))
		 t)
		((member (downcase set_jisyo)
			 '("no" "0" "-1" "nil" "n"))
		 nil)
		(t
		 'fuzzy))))
    ;;
    (if (eq flag 'fuzzy)
	(not (SKK-MK-server-installed-p))
      flag)))

(defun SKK-MK-compile ()
  (let (enable-local-eval)
    (SKK-MK-skk-dic)
    (SKK-MK-generate-autoloads-el)
    (load (expand-file-name "skk-autoloads.el"))
    (require 'skk (expand-file-name "skk.el"))
    (compile-elisp-modules SKK_MODULES
			   (expand-file-name "."))))

(defun SKK-MK-compile-info ()
  (when (and SKK_INFO
	     (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-compile-package ()
  (SKK-MK-skk-dic)
  (SKK-MK-generate-autoloads-el-package)
  (setq features (delq 'skk-autoloads features))
  (require 'skk-autoloads (expand-file-name "auto-autoloads.el"))
  (require 'skk (expand-file-name "skk.el"))
  (autoload 'custom-add-loads "cus-load")
  (compile-elisp-modules
   SKK_MODULES
   (expand-file-name ".")))

(defun SKK-MK-install ()
  (SKK-MK-install-elc)
  (SKK-MK-install-info))

(defun SKK-MK-install-elc ()
  (let ((dics SKK_DICTIONARIES)
	;;standard-output
	delete-target exists spec)
    ;; make target directories.
    (setq DOCDIR (expand-file-name DOCDIR)
	  ETCDIR (expand-file-name ETCDIR)
	  DICDIR (expand-file-name DICDIR))
    (unless (file-exists-p SKK_LISPDIR)
      (make-directory SKK_LISPDIR t))
    (unless (file-exists-p SKK_DATADIR)
      (make-directory SKK_DATADIR t))
    ;; delete already installed unnecessary files.
    (while SKK_DAREDEVIL_NOT_USE
      (setq SKK_MODULES (delq (car SKK_DAREDEVIL_NOT_USE)
			      SKK_MODULES)
	    delete-target (expand-file-name
			   (concat (prin1-to-string
				    (car SKK_DAREDEVIL_NOT_USE))
				   ".el")
			   SKK_LISPDIR)
	    SKK_DAREDEVIL_NOT_USE (cdr SKK_DAREDEVIL_NOT_USE))
      (when (file-exists-p delete-target)
	(delete-file delete-target))
      (setq delete-target (concat delete-target "c"))
      (when (file-exists-p delete-target)
	(delete-file delete-target)))
    ;; install Emacs Lisp programs.
    (SKK-MK-compile)
    (install-elisp-modules SKK_MODULES "." SKK_LISPDIR)
    (delete-file "./skk-autoloads.el")
    ;; make skk-setup.el.
    (while dics
      (when (file-exists-p (expand-file-name (car dics) DICDIR))
	(setq exists (cons (car dics) exists)))
      (setq dics (cdr dics)))
    (setq SKK_DICTIONARIES exists)
    ;; move existing largest dictionay to car of `SKK_DICTIONARIES'.
    (when (member "SKK-JISYO.M" SKK_DICTIONARIES)
      (setq SKK_DICTIONARIES
	    (cons "SKK-JISYO.M"
		  (delete "SKK-JISYO.M"
			  SKK_DICTIONARIES))))
    (when (member "SKK-JISYO.ML" SKK_DICTIONARIES)
      (setq SKK_DICTIONARIES
	    (cons "SKK-JISYO.ML"
		  (delete "SKK-JISYO.ML"
			  SKK_DICTIONARIES))))
    (when (member "SKK-JISYO.L" SKK_DICTIONARIES)
      (setq SKK_DICTIONARIES
	    (cons "SKK-JISYO.L"
		  (delete "SKK-JISYO.L"
			  SKK_DICTIONARIES))))
    (when SKK_TUTORIALS
      (setq spec (append
		  spec
		  (list "@TUT@"
			(expand-file-name
			 (car SKK_TUTORIALS) SKK_DATADIR)))))
    (cond
     (SKK_DICTIONARIES
      (setq spec
	    (append spec
		    (list "@AUXDIC@"
			  (expand-file-name
			   (car SKK_DICTIONARIES) SKK_DATADIR))))
      (when SKK_SET_JISYO
	(setq spec
	      (append spec
		      (list
		       "@DIC@"
		       (expand-file-name
			(car SKK_DICTIONARIES) SKK_DATADIR))))))
     (t
      ;; when dictionaries do not exist in ./dic subdirectory, check
      ;; already installed dictionary and detect largest one to setup
      ;; skk-setup.el.in.
      (setq dics '("SKK-JISYO.L"
		   "SKK-JISYO.ML"
		   "SKK-JISYO.M"
		   "SKK-JISYO.S"))
      (while (and dics
		  (not (file-exists-p (expand-file-name
				       (car dics)
				   SKK_DATADIR))))
	(setq dics (cdr dics)))
      (when dics
	(setq spec
	      (append spec
		      (list "@AUXDIC@"
			    (expand-file-name
			     (car dics)
			     SKK_DATADIR))))
	(when SKK_SET_JISYO
	  (setq spec
		(append spec
			(list "@DIC@"
			      (expand-file-name
			       (car dics)
			       SKK_DATADIR))))))))
    (if (not spec)
	;; merely copy without setup dictionary information.
	(copy-file "skk-setup.el.in"
		   "skk-setup.el"
		   'ok-if-already-exists)
      (SKK-MK-make-setup-file spec))
    (when SKK_DICTIONARIES
      ;; install dictionaries if the files exist in ./dic directory.
      (install-files SKK_DICTIONARIES
		     DICDIR
		     SKK_DATADIR
		     nil t nil))
    (when (and (fboundp 'register-input-method)
	       (not (featurep 'xemacs)))
      (copy-file "./leim-list.el.in"
		 "./leim-list.el"
		 'overwrite)
      (install-elisp-modules (list 'leim-list)
			     "."
			     SKK_LISPDIR)
      (delete-file "./leim-list.el"))
    ;; install skk-setup.el
    (install-elisp-modules (list 'skk-setup) "." SKK_LISPDIR)
    ;; install tutorials.
    (install-files SKK_TUTORIALS ETCDIR SKK_DATADIR nil t nil)
    (SKK-MK-detect-shadow-directory)))

(defun SKK-MK-detect-shadow-directory ()
  (condition-case nil
      (progn
	(require 'shadow)
	(save-match-data
	  (let ((list (find-emacs-lisp-shadows load-path))
		shadowed)
	    (while list
	      (if (and (string-match "skk-autoloads"
				     (car list))
		       (setq list (cdr list))
		       (string-match "skk-autoloads"
				     (car list)))
		  (setq shadowed
			(substring
			 (file-name-directory (car list))
			 0 -1)
			list nil))
	      (setq list (cdr list)))
	    (when shadowed
	      (princ (format "\
** WARNING ** %s is shadowed.  You might want to remove it
"
			     shadowed))))))
    (error)))

(defun SKK-MK-install-info ()
  (when SKK_INFO
    (unless (file-exists-p SKK_INFODIR)
      (make-directory SKK_INFODIR t))
    (SKK-MK-compile-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))
    (require 'install-info
	     (expand-file-name "install-info.el"))
    (let ((info-file (expand-file-name
		      SKK_INFO
		      SKK_INFODIR))
	  (dir-file
	   (cond
	    ((file-exists-p (expand-file-name
			     "dir" SKK_INFODIR))
	     (expand-file-name "dir" SKK_INFODIR))
	    ((file-exists-p (expand-file-name
			     "dir.info" SKK_INFODIR))
	     (expand-file-name "dir.info" SKK_INFODIR))
	    (t
	     (expand-file-name "dir" SKK_INFODIR)))))
      (when (file-readable-p dir-file)
	(install-info info-file
		      dir-file nil nil 'delete))
      (install-info info-file
		    dir-file nil nil nil))))

(defun SKK-MK-install-package ()
  (unless (featurep 'xemacs)
    (error "%s"
	   "This directcive is only for XEmacs."))
  (let ((dics SKK_DICTIONARIES)
	delete-target exist spec)
    ;; make target directories.
    (unless (file-exists-p PACKAGE_LISPDIR)
      (make-directory PACKAGE_LISPDIR t))
    (unless (file-exists-p PACKAGE_DATADIR)
      (make-directory PACKAGE_DATADIR t))
    (unless (file-exists-p PACKAGE_INFODIR)
      (make-directory PACKAGE_INFODIR t))
    ;; delete already installed unnecessary files.
    (setq SKK_MODULES (delq 'skk-autoloads
			    (append
			     SKK_MODULES
			     '(auto-autoloads custom-load))))
    (while SKK_DAREDEVIL_NOT_USE
      (setq SKK_MODULES (delq
			 (car SKK_DAREDEVIL_NOT_USE)
			 SKK_MODULES)
	    delete-target (expand-file-name
			   (concat
			    (prin1-to-string
			     (car SKK_DAREDEVIL_NOT_USE))
			    ".el")
			   PACKAGE_LISPDIR)
	    SKK_DAREDEVIL_NOT_USE (cdr SKK_DAREDEVIL_NOT_USE))
      (when (file-exists-p delete-target)
	(delete-file delete-target))
      (setq delete-target (concat delete-target "c"))
      (when (file-exists-p delete-target)
	(delete-file delete-target)))
    ;; install Emacs Lisp programs.
    (SKK-MK-compile-package)
    (install-elisp-modules SKK_MODULES "." PACKAGE_LISPDIR)
    (delete-file "./auto-autoloads.el")
    (delete-file "./custom-load.el")
    ;; make skk-setup.el.
    (when SKK_TUTORIALS
      (setq spec (list
		  "@TUT@"
		  (expand-file-name
		   (car SKK_TUTORIALS)
		   PACKAGE_DATADIR))))
    (while dics
      (when (file-exists-p (expand-file-name
			    (car dics)
			    DICDIR))
	(setq exist (cons (car dics) exist)))
      (setq dics (cdr dics)))
    (setq SKK_DICTIONARIES exist)
    ;; move existing largest dictionay to car of `SKK_DICTIONARIES'.
    (when (member "SKK-JISYO.M" SKK_DICTIONARIES)
      (setq SKK_DICTIONARIES
	    (cons "SKK-JISYO.M" (delete "SKK-JISYO.M"
					SKK_DICTIONARIES))))
    (when (member "SKK-JISYO.ML" SKK_DICTIONARIES)
      (setq SKK_DICTIONARIES
	    (cons "SKK-JISYO.ML"
		  (delete "SKK-JISYO.ML"
			  SKK_DICTIONARIES))))
    (when (member "SKK-JISYO.L" SKK_DICTIONARIES)
      (setq SKK_DICTIONARIES
	    (cons "SKK-JISYO.L" (delete "SKK-JISYO.L"
					SKK_DICTIONARIES))))
    (cond
     (SKK_DICTIONARIES
      (setq spec
	    (append spec
		    (list "@AUXDIC@"
			  (expand-file-name
			   (car SKK_DICTIONARIES)
			   PACKAGE_DATADIR))))
      (when SKK_SET_JISYO
	(setq spec
	      (append spec
		      (list "@DIC@"
			    (expand-file-name
			     (car SKK_DICTIONARIES)
			     PACKAGE_DATADIR)))))
      ;; install dictionaries if the files exist in ./dic directory.
      (install-files SKK_DICTIONARIES
		     DICDIR
		     PACKAGE_DATADIR nil t nil))
     (t
      ;; when dictionaries do not exist in ./dic subdirectory, check
      ;; already installed dictionary and detect largest one to setup
      ;; skk-setup.el.in.
      (setq dics '("SKK-JISYO.L"
		   "SKK-JISYO.ML"
		   "SKK-JISYO.M"
		   "SKK-JISYO.S"))
      (while (and dics
		  (not (or (file-exists-p (expand-file-name
					   (car dics) PACKAGE_DATADIR))
			   (file-exists-p (expand-file-name
					   (car dics) SKK_DATADIR)))))
	(setq dics (cdr dics)))
      (when dics
	(let ((dic
	       (if (file-exists-p (expand-file-name
				   (car dics) PACKAGE_DATADIR))
		   (expand-file-name (car dics) PACKAGE_DATADIR)
		 (expand-file-name (car dics) SKK_DATADIR))))
	  (setq spec (nconc spec (list "@AUXDIC@" dic)))
	  (when SKK_SET_JISYO
	    (setq spec (nconc spec (list "@DIC@" dic))))))))
    (if (not spec)
	;; merely copy without setup dictionary information.
	(copy-file "skk-setup.el.in"
		   "skk-setup.el"
		   'ok-if-already-exists)
      (SKK-MK-make-setup-file spec))
    ;; install skk-setup.el
    (install-elisp-modules (list 'skk-setup) "." 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)
    (SKK-MK-detect-shadow-directory)))

(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"))
    (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)
  (unless (featurep 'xemacs)
    (error "%s" "This directive is only for XEmacs."))
  (let ((string
	 (format "
SKK modules:
  %s
  -> %s

SKK infos:
  %s
  -> %s

SKK tutorials:
  %s
  -> %s
"
		 (mapconcat 'symbol-name
			    (delq 'skk-autoloads 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 version 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")
      (require 'autoload)
      (require 'poem)
      (while modules
	(let ((file (expand-file-name
		     (format "%s.el" (car modules)))))
	  (when (file-exists-p file)
	    (generate-file-autoloads file)))
	(setq modules (cdr modules)))
      (goto-char (point-max))
      (insert "(provide 'skk-autoloads)
;;; skk-autoloads.el ends here
")
      (write-region-as-coding-system
       'iso-2022-jp
       (point-min) (point-max)
       "skk-autoloads.el" nil 'quiet)
      (kill-buffer buf))))

(defun SKK-MK-generate-autoloads-el-package ()
  "Generate auto-autoload.el."
  (let ((modules SKK_MODULES))
    (require 'poem)
    (with-temp-buffer
      (dolist (module modules)
	(let ((file (expand-file-name
		     (format "%s.el" module))))
	  (when (file-exists-p file)
	    (generate-file-autoloads file))))
      (let ((generated-autoload-file
	     (expand-file-name "auto-autoloads.el")))
	(setq buffer-file-name generated-autoload-file)
	(fixup-autoload-buffer "skk-autoloads")
	(goto-char (point-max))
	(unless (bolp)
	  (insert "\n"))
	(write-region-as-coding-system 'iso-2022-jp
				       (point-min)
				       (point-max)
				       generated-autoload-file)))
    (add-to-list 'command-line-args-left ".")
    (Custom-make-dependencies)))

(defun SKK-MK-skk-dic ()
  (require 'poem)
  (let* ((buf (get-buffer-create " *SKK-JISYO.S*"))
	 (jisyo0 (and SKK_DEFAULT_JISYO
		      (expand-file-name SKK_DEFAULT_JISYO)))
	 (jisyo1 (and SKK_DEFAULT_JISYO
		      (expand-file-name SKK_DEFAULT_JISYO "dic")))
	 (jisyo2 (and SKK_DEFAULT_JISYO
		      (expand-file-name "SKK-JISYO.S" "dic")))
	 (jisyo3 (and
		  (expand-file-name "SKK-JISYO.S" "../dic")))
	 (jisyo (cond
		 ((not SKK_DEFAULT_JISYO)
		  nil)
		 ((and (file-readable-p jisyo0)
		       (not (file-directory-p jisyo0)))
		  jisyo0)
		 ((and (file-readable-p jisyo1)
		       (not (file-directory-p jisyo1)))
		  jisyo1)
		 ((and (file-readable-p jisyo2)
		       (not (file-directory-p jisyo2)))
		  jisyo2)
		 ((and (file-readable-p jisyo3)
		       (not (file-directory-p jisyo3)))
		  jisyo3)))
	 (skk-dic (expand-file-name "skk-dic.el")))
    (cond
     ((not jisyo)
      (copy-file "skk-dic.el.in" "skk-dic.el" t t))
     ((and (file-exists-p skk-dic)
	   (file-newer-than-file-p
	    skk-dic
	    (expand-file-name "skk-dic.el.in")))
      (princ (format "%s is up-to-date
"
		     skk-dic))
      nil)
     (t
      (princ (format "Processing %s...
"
		     jisyo))
      (with-current-buffer buf
	(erase-buffer)
	(insert-file-contents-as-coding-system 'euc-jp jisyo)
	(goto-char (point-min))
	(while (not (looking-at "^;; okuri-ari entries\\.$"))
	  (next-line 1))
	(delete-region (point-min) (point))
	(goto-char (point-min))
	(while (search-forward "\\" nil t)
	  (replace-match "\\\\\\\\"))
	(goto-char (point-min))
	(while (search-forward "\"" nil t)
	  (replace-match "\\\\\"")))
      (with-temp-buffer
	(erase-buffer)
	(insert-file-contents-as-coding-system
	 'iso-2022-jp
	 (expand-file-name "skk-dic.el.in"))
	(goto-char (point-min))
	(while (not (looking-at "^\")$"))
	  (next-line 1))
	(insert-buffer buf)
	(write-region-as-coding-system
	 'iso-2022-jp
	 (point-min) (point-max)
	 (expand-file-name "skk-dic.el")))))))

;;; SKK-MK ends here
