;;;
;;;  cmail-resource.el
;;;

;; メッセージを追加するには:
;; 
;; (message "foobar") のように直接書いてはいけません。
;; まず、cmail-res.el に
;;     (cmail-resource-alist内でuniqueなシンボル . "英語のメッセージ")
;; を加えます。cmail-res-Japanese.el に
;;     (先程と同じシンボル . "日本語のメッセージ")
;; を加えます。
;;
;; (cmail-get-resource 'シンボル) でその文字列を取得するのが基本ですが、
;;   cmail-message-resource
;;   cmail-message-resource1
;;   cmail-error-resource
;;   cmail-error-resource1
;;   cmail-format-resource1
;; などの関数が用意してあります。
;;
;; format 関数でのパラメータの順番が言語によって異なる場合、
;; cmail-format-resource を用います。format 関数の制御文字列の
;; % の書式を拡張して、「何番目のパラメータか」を書けるように
;; してあります。
;;   '%' 番号 ';' タイプ(sとかdとか)
;;   例: %1;s
;; 番号は0から始まります。
;;   例:
;;       (cmail-format-resource 'foo-1 (cmail-get-resource 'foo-2) 11)
;;     で、foo-1 が "%0;s %1;d mails."、foo-2 が "Moved" の場合、結果は
;;       "Moved 11 mails."
;;     foo-1 が "%1;d通の手紙を%0;sしました."、foo-2 が "移動" の場合、結果は
;;       "11通の手紙を移動しました。"
;;     となります。

(provide 'cmail-resource)

(defconst cmail-resource-basename "cmail-res")
(or (and cmail-i18n-message
	 (boundp 'current-language-environment)
	 (or (featurep 'xemacs)
	     (and (boundp 'emacs-major-version)
		  (boundp 'emacs-minor-version)
		  (or (>= emacs-major-version 21)
		      (and (eq emacs-major-version 20) (>= emacs-minor-version 3)))))
	 (load (concat cmail-resource-basename "-" current-language-environment) t))
    (load cmail-resource-basename))

(defun cmail-get-resource (key)
  "シンボル kEY に関連付けられたオブジェクトを返します。"
  (cdr (assoc key cmail-resource-alist)))

(defun cmail-message-resource (key)
  "シンボル kEY に関連付けられたオブジェクトをパラメータにして (message) を呼びます。"
  (message (cdr (assoc key cmail-resource-alist))))

(defun cmail-message-resource1 (key p1)
  "シンボル kEY に関連付けられたオブジェクトをパラメータにして (message) を呼びます。"
  (message (cdr (assoc key cmail-resource-alist)) p1))

(defun cmail-error-resource (key)
  "シンボル kEY に関連付けられたオブジェクトをパラメータにして (error) を呼びます。"
  (error (cdr (assoc key cmail-resource-alist))))

(defun cmail-error-resource1 (key p1)
  "シンボル kEY に関連付けられたオブジェクトをパラメータにして (error) を呼びます。"
  (error (cdr (assoc key cmail-resource-alist)) p1))

(defun cmail-format-resource1 (key p1)
  "シンボル kEY に関連付けられたオブジェクトをパラメータにして (message) を呼びます。"
  (format (cdr (assoc key cmail-resource-alist)) p1))

(defun cmail-format-resource (key &rest args)
  (let ((form "")			;formatに渡すformat文字列
	fargs				;formatに渡すパラメータ
	(start 0)			;検索開始ポイント
	mstart				;マッチ位置
	(templ (cdr (assoc key cmail-resource-alist))))
    (while (setq mstart (string-match "%" templ start))
					;% の次の文字が % か?
      (setq mstart (1+ mstart))
      (cond ((string= "%" (substring templ mstart (1+ mstart)))
	     (setq form (concat form (substring templ start (1+ mstart)))
		   start (1+ mstart)))
					;% の次が "数値;" か?
	    ((eq mstart (string-match "\\([0-9]+\\);" templ mstart))
	     (setq form (concat form (substring templ start mstart))
		   start (match-end 0)
		   fargs (append fargs
				 (list (nth (string-to-int (match-string 1 templ))
					    args)))))
	    (t
	     (setq form (concat form (substring templ start mstart))
		   start mstart))))
    (setq form (concat form (substring templ start)))
    (eval (cons 'format (cons form fargs)))))

(require 'alist)
(defun cmail-add-resource (resource-alist)
  "`current-language-environment' に従って対応する言語のメッセージを追加
します。追加するメッセージは (識別子 (\"言語\" . \"メッセージ\") () ... )
のリストで指定します。言語が t がデフォルトのメッセージとなります。"
  (let ((lang (or (and cmail-i18n-message
		       (boundp 'current-language-environment)
		       (or (featurep 'xemacs)
			   (and (boundp 'emacs-major-version)
				(boundp 'emacs-minor-version)
				(or (>= emacs-major-version 21)
				    (and (eq emacs-major-version 20)
					 (>= emacs-minor-version 3)))))
		       (car (assoc current-language-environment
				   (cdr resource-alist))))
		  t)))
    (set-alist 'cmail-resource-alist
	       (car resource-alist)
	       (cdr (assoc lang (cdr resource-alist))))))
