;; th-tis820.mim -- Thai input method with TIS-820.2538 keyboard layout
;; Copyright (C) 2006, 2007
;;   National Institute of Advanced Industrial Science and Technology (AIST)
;;   Registration Number H15PRO112

;; This file is part of the m17n database; a sub-part of the m17n
;; library.

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

;; The m17n library 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
;; Lesser General Public License for more details.

;; You should have received a copy of the GNU Lesser General Public
;; License along with the m17n library; if not, write to the Free
;; Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
;; Boston, MA 02110-1301, USA.

(input-method th tis820)

(description "Thai input method simulating the TIS-820.2538 keyboard
with WTT 2.0 input sequence correction.
The correction algorithm follows the one shown in the following 
  <http://linux.thai.net/~thep/th-xim/>
")

(variable
 (level (_"Acceptance level
The level of character sequence acceptance defined in WTT 2.0.
0 accepts any key sequence.  2 accepts only orthographic ones.
1 is somewhere between.")
	1 0 1 2))

(title "ท")

(include (th kesmanee) macro)

(map
 (map
  ("!" "ๅ")
  ("\"" ".")
  ("#" "๒")
  ("$" "๓")
  ("%" "๔")
  ("&" "๎")
  ("'" "ง")
  ("(" "๖")
  (")" "๗")
  ("*" "๕")
  ("+" "๙")
  ("," "ม")
  ("-" "ข")
  ("." "ใ")
  ("/" "ฝ")
  ("0" "จ")
  ("1" "฿")
  ("2" "/")
  ("3" "-")
  ("4" "ภ")
  ("5" "ถ")
  ("6" "ุ")
  ("7" "ึ")
  ("8" "ค")
  ("9" "ต")
  (":" "ซ")
  (";" "ว")
  ("<" "ฒ")
  ("=" "ช")
  (">" "ฬ")
  ("?" "ฦ")
  ("@" "๑")
  ("A" "ฤ")
  ("B" "ฺ")
  ("C" "ฉ")
  ("D" "ฏ")
  ("E" "ฎ")
  ("F" "โ")
  ("G" "ฌ")
  ("H" "็")
  ("I" "ณ")
  ("J" "๋")
  ("K" "ษ")
  ("L" "ศ")
  ("M" "?")
  ("N" "์")
  ("O" "ฯ")
  ("P" "ญ")
  ("Q" "๐")
  ("R" "ฑ")
  ("S" "ฆ")
  ("T" "ธ")
  ("U" "๊")
  ("V" "ฮ")
  ("W" "\"")
  ("X" ")")
  ("Y" "ํ")
  ("Z" "(")
  ("[" "บ")
  ("\\" "ฅ")
  ("]" "ล")
  ("^" "ู")
  ("_" "๘")
  ("`" "๏")
  ("a" "ฟ")
  ("b" "ิ")
  ("c" "แ")
  ("d" "ก")
  ("e" "ำ")
  ("f" "ด")
  ("g" "เ")
  ("h" "้")
  ("i" "ร")
  ("j" "่")
  ("k" "า")
  ("l" "ส")
  ("m" "ท")
  ("n" "ื")
  ("o" "น")
  ("p" "ย")
  ("q" "ๆ")
  ("r" "พ")
  ("s" "ห")
  ("t" "ะ")
  ("u" "ี")
  ("v" "อ")
  ("w" "ไ")
  ("x" "ป")
  ("y" "ั")
  ("z" "ผ")
  ("{" "ฐ")
  ("|" "ฃ")
  ("}" ",")
  ("~" "๛")))

(state

 (init
  (map
   (delete @<)
   (pushback 1)
   (shift main)))
 
 (main
  (map
   (set x @-3)
   (set y @-2)
   (set z @-1)

   (set arg1 y)
   (set arg2 z)
   (cp)
   (cond
    ((= ret 1)) ;; CP(y,z) succeeded.
    (1
     (ac)
     (cond
      ((= ret 1)) ;; AC(y,z) succeeded.
      (1
       ;; WTT-based input sequence correction starts here.

       ;; begin
       ;; if CP(x,z) then
       (set arg1 x)
       (set arg2 z)
       (cp)
       (cond
	((= ret 1)

	 ;; if CP(z,y) then
	 (set arg1 z)
	 (set arg2 y)
	 (cp)
	 (cond
	  ((= ret 1)

	   ;; reorder(y -> zy)
	   (delete @-2)
	   (insert z)
	   (insert y))

	  ;; elif CP(x,y) then
	  (1
	   (set arg1 x)
	   (set arg2 y)
	   (cp)
	   (cond
	    ((= ret 1)

	     ;; replace(y -> z)
	     (delete @-2)
	     (insert z))

	    ;; elif y is FV1 and z is TONE then
	    ((& (| (= y 0x0E30) (= y 0x0E32) (= y 0x0E33))
		(>= z 0x0E48)
		(<= z 0x0E4B))

	     ;; reorder(y -> zy)
	     (delete @-2)
	     (insert z)
	     (insert y))

	    ;; else
	    ;; reject(z)
	    (1
	     (delete @-1))

	    ;;endif
	    ))))

	;; elif AC(x,z) then
	(1
	 (set arg1 x)
	 (set arg2 z)
	 (ac)
	 (cond
	  ((& (= ret 1)
	      ;; Only Thai characters should be replaced.
	      (& (>= y 0x0E01) (<= y 0x0E5B))
	      (& (>= z 0x0E01) (<= z 0x0E5B)))

	   ;; replace(y -> z)
	   (delete @-2)
	   (insert z))

	  ;; else
	  ;; reject(z)
	  (1
	   (delete @-1))

	  ;; endif
	  )))
       ;; end

       ))))

   ;; Now we commit the preedit chars that are fixed.
   (set w @-1)
   (cond
    ;; If surrounding text is supported, commit the only char in preedit.
    ((> @-0 -2)
     (commit))

    ;; If the last char is CTRL or NON, we can commit everything.
    ((| (& (>= w 0x0000) (<= w 0x0E00))
	(= w 0x0E2F)
	(= w 0x0E3F)
	(= w 0x0E46)
	(>= w 0x0E4F))
     (commit))

    ;; If the last char is CONS, we can commit everything but the last
    ;; unless the second last is FV3.
    ((| (& (>= w 0x0E01) (<= w 0x0E23))
	(= w 0x0E25)
	(& (>= w 0x0E27) (<= w 0x0E2E)))
     (cond
      ((| (= @-2 0x0E24) (= @-2 0x0E26))
       ; not commit yet
       )
      (1
       (delete @-1)
       (commit)
       (insert w))))

    ;; If the last char is LV, FV2 or FV3, we can commit
    ;; everything but the last.
    ((| (& (>= w 0x0E40) (<= w 0x0E45))
	(= w 0x0E24)
	(= w 0x0E26))
     (delete @-1)
     (commit)
     (insert w))

    ;; If the last char is FV1 (excluding AM) and ...
    ((| (= w 0x0E30) (= w 0x0E32))
     (delete @-1)
     (set v @-1)
     (cond

      ;; ... the before last is CONS, we can commit other than the
      ;; last two.
      ((| (& (>= v 0x0E01) (<= v 0x0E23))
	  (= v 0x0E25)
	  (& (>= v 0x0E27) (<= v 0x0E2E)))
       (delete @-1)
       (commit)
       (insert v)
       (insert w))

      ;; ... else if the before last is not CONS, we can commit
      ;; everything but the last.
      (1
       (commit)
       (insert w))))
    ))))

;; Local Variables:
;; coding: utf-8
;; mode: emacs-lisp
;; End:
