;; th-pattachote.mim -- Thai input method with Pattachote keyboard layout
;; Copyright (C) 2006, 2007, 2008, 2009
;;   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
;; 02110-1301, USA.

(input-method th pattachote)

(description "Thai input method simulating the Pattachote 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/>
")

(title "ท")

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

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