;;;
;;; irchat-pj-coding-system.el
;;; last modify : Thu, 28 Oct 1999 00:04:46 +0900
;;;               by simm@irc.fan.gr.jp / irchat-PJ Project
;;; (date format modification by simm@irc.fan.gr.jp, Sun, 27 Jun 1999)
;;; see file irchat-copyright.el for change log and copyright info
;;;

(require 'irchat-pj-jisx0201)

;; load version-specific module

(or (and (featurep 'xemacs)
	 (require 'irchat-pj-specific-xmas))
    (and (featurep 'mule)
	 (boundp 'emacs-major-version)
	 (<= 20 emacs-major-version)
	 (require 'irchat-pj-specific-emacs20))
    (and (featurep 'mule)
	 (require 'irchat-pj-specific-mule2))
    (and (boundp 'NEMACS)
	 (require 'irchat-pj-specific-nemacs))
    (require 'irchat-pj-specific-other-emacsen))

;; parse and read
(defun irchat-pj-string-in-euc-jp (str)
  (let ((len (length str)) (ch 0) (ps 0) (pt 0) (msb nil) (slist nil))
    ;; Phase 1: split EUC code and others
    (while (< pt len)
      (setq ch (elt str pt))
      ;;(message "%d" ch)
      (cond ((and (eq nil msb) (>= ch 128))
             (setq slist (append slist (list (substring str ps pt))))
             (setq msb t
                   ps pt
                   pt (+ 2 pt)))
            ((and (eq t msb) (< ch 128))
             (setq slist (append slist (list (substring str ps pt))))
             (setq msb nil
                   ps pt
                   pt (1+ pt)))
            ((eq nil msb)
             (setq pt (1+ pt)))
            ((eq t msb)
             (setq pt (+ 2 pt)))))
    (setq slist (append slist (list (substring str ps len))))
    ;; Phase 2: convert string
    (setq str "")
    (while slist
      (setq str (concat str (if (< (elt (car slist) 0) 128)
                                (irchat-pj-string-in-iso-2022-7bit-ss2 (car slist))
                              (irchat-pj-string-in-euc-jp-internal (car slist))))
            slist (cdr slist)))
    str))

(defun irchat-pj-string-in-sjis (str)
  (let ((len (length str)) (ch 0) (ps 0) (pt 0) (msb nil) (slist nil))
    ;; Phase 1: split SJIS code and others
    (while (< pt len)
      (setq ch (elt str pt))
      (cond ((and (eq nil msb) (>= ch 128))
             (setq slist (append slist (list (substring str ps pt))))
             (setq msb t
                   ps pt
                   pt (1+ pt))
             (if (or (and (<= 128 ch) (<= ch 159)) (<= 224 ch)) ;; 2bytes
                 (setq pt (1+ pt))))
            ((and (eq t msb) (< ch 128))
             (setq slist (append slist (list (substring str ps pt))))
             (setq msb nil
                   ps pt
                   pt (1+ pt)))
            (t
             (setq pt (1+ pt))
             (if (or (and (<= 128 ch) (<= ch 159)) (<= 224 ch)) ;; 2bytes
                 (setq pt (1+ pt))))))
    (setq slist (append slist (list (substring str ps len))))
    ;; Phase 2: convert string
    (setq str "")
    (while slist
      (setq str (concat str (if (< (elt (car slist) 0) 128)
                                (irchat-pj-string-in-iso-2022-7bit-ss2 (car slist))
                              (irchat-pj-string-in-sjis-internal (car slist))))
            slist (cdr slist)))
    str))

;; begin: from irchat-pj-filter-convert-code in irchat-pj 2.4.23.19
(defun irchat-pj-string-in-auto-detect-primitive (str)
  (let ((len (length str))(pp 0)(ps 0)(pe 0)(fl 0)(code nil))
    ;; Phase 1: check MSB
    (while (and (< pp len) (eq nil code))
      (setq ps (elt str pp)
            pp (1+ pp))
      (if (<= 128 ps)
          (setq code t)))
    (if (eq nil code)
        'iso-2022-7bit-ss2
      (setq pp 0
            code nil)
      (while (null code)
        (setq ps (elt str pp)
              pp (1+ pp))
        (if (= pp len)
            (setq code 'unknown))
        (cond ((or (= 13 ps) (= 10 ps))      ;; CRLF
               (setq code 'unknown))
              ((and (<= 128 ps) (<= ps 159)) ;; 0x80 <= ch <= 0x9f
               (setq code 'sjis))
              ((and (= pe 1) (<= ps 127))    ;; second byte MSB = 0
               (setq code 'sjis))
              ((and (= 2 pe) (<= 161 ps) (<= ps 243)) ;; second byte of EUC kana
               (setq fl 2)
               (setq pe 0))
              ((and (= 0 pe) (= 164 ps))     ;; first byte of EUC kana
               (setq pe 2))
              ((<= 160 ps)                   ;; 0xa0 <= ch
               (if (null (= 2 fl ))
                   (setq fl 1))
               (if (= 2 pe)
                   (setq code 'sjis)
                 (setq pe (- 1 pe))))))
      (if (eq 'unknown code)
          (if (= 2 fl) 'euc-jp 'sjis)
        code))))

(defun irchat-pj-string-in-auto-detect (str)
  "Decide code of argument string."
  (let ((code (irchat-pj-string-in-auto-detect-primitive str)))
    (cond ((eq 'euc-jp code)
	   (if irchat-pj-code-verbose
	       (message "EUC-JP code detected."))
	   (irchat-pj-string-in-euc-jp str))
	  ((eq 'sjis code)
	   (if irchat-pj-code-verbose
	       (message "SJIS code detected."))
	   (irchat-pj-string-in-sjis str))
	  ((eq 'iso-2022-7bit-ss2 code)
	   (irchat-pj-string-in-iso-2022-7bit-ss2 str))
	  (t
	   str))))

(defun irchat-pj-string-in-non-euc (str)
  "Decide code of argument string."
  (let ((code (irchat-pj-string-in-auto-detect-primitive str)))
    (cond ((or (eq 'sjis code)(eq 'euc-jp code))
	   (if irchat-pj-code-verbose
	       (message "SJIS code detected."))
	   (irchat-pj-string-in-sjis str))
	  ((eq 'iso-2022-7bit-ss2 code)
	   (irchat-pj-string-in-iso-2022-7bit-ss2 str))
	  (t
	   str))))
;; end: from irchat-pj-filter-convert-code in irchat-pj 2.4.23.19

;; begin: modified by simm@irc.fan.gr.jp
(defun irchat-pj-string-in-convert (str)
  (cond ((eq irchat-pj-string-in-code 'noconv) str)
	((or (eq irchat-pj-string-in-code 'euc-jp)
	     (eq irchat-pj-string-in-code 'euc-japan))
	 (irchat-pj-string-in-euc-jp str))
	((or (eq irchat-pj-string-in-code 'sjis)
	     (eq irchat-pj-string-in-code 'shift-jis)
	     (eq irchat-pj-string-in-code 'ms-kanji))
	 (irchat-pj-string-in-sjis str))
	((or (eq irchat-pj-string-in-code 'iso-2022-7bit-ss2)
	     (eq irchat-pj-string-in-code 'jis))
	 (irchat-pj-string-in-iso-2022-7bit-ss2 str))
	((eq irchat-pj-string-in-code 'iso-2022-jp)
	 (irchat-pj-string-in-iso-2022-jp str))
	(t
	 (irchat-pj-string-in-auto-detect str))))

(defun irchat-pj-string-out-convert (str)
  (cond ((eq irchat-pj-string-out-code 'noconv) str)
	((or (eq irchat-pj-string-out-code 'euc-jp)
	     (eq irchat-pj-string-out-code 'euc-japan))
	 (irchat-pj-string-out-euc-jp str))
	((or (eq irchat-pj-string-out-code 'sjis)
	     (eq irchat-pj-string-out-code 'shift-jis)
	     (eq irchat-pj-string-out-code 'ms-kanji))
	 (irchat-pj-string-out-sjis str))
	((eq irchat-pj-string-out-code 'iso-2022-7bit-ss2)
	 (irchat-pj-string-out-iso-2022-7bit-ss2 str))
	((or (eq irchat-pj-string-out-code 'iso-2022-jp)
	     (eq irchat-pj-string-out-code 'jis))
	 (irchat-pj-string-out-iso-2022-jp str))
	(t
	 (irchat-pj-string-out-iso-2022-7bit-ss2 str))))

(defun irchat-string-in (str)
  (if str
      (or (irchat-pj-string-in-convert str) str) nil))

(defun irchat-string-out (str)
  (if str
      (or (irchat-pj-string-out-convert str) str) nil))

(provide 'irchat-pj-coding-system)

;; end: modified by simm@irc.fan.gr.jp
