(defun jtw2m4--inside-comment-or-string ()
  (let ((p (get-char-property (1- (point)) 'face)))
    (or (eq p 'font-lock-string-face)
        (eq p 'font-lock-comment-face)
        (eq p 'font-lock-doc-string-face)
        (eq p 'fg:lightmagenta))))

(defun jtw2m4--splat-re (old-text new-text)
  (save-match-data
    (save-excursion
      (goto-char (point-min))
      (while (re-search-forward old-text nil t)
        (if (not (jtw2m4--inside-comment-or-string))
            (replace-match new-text nil nil))))))

(defun jtw2m4--cap ()
  (interactive)
  ;;
  ;; NOTE: keywords
  ;;
  (jtw2m4--splat-re "\\<class\\>"             "CLASS")
  (jtw2m4--splat-re "\\<begin\\>"             "BEGIN")
  (jtw2m4--splat-re "\\<beginMainFunction\\>" "BEGINMAINFUNCTION")
  (jtw2m4--splat-re "\\<end\\>"               "END")
  (jtw2m4--splat-re "\\<endMainFunction\\>"   "ENDMAINFUNCTION")
  (jtw2m4--splat-re "\\<function\\>"          "FUNCTION")
  (jtw2m4--splat-re "\\<method\\>"            "METHOD")
  (jtw2m4--splat-re "\\<variable\\>"          "VARIABLE")
  (jtw2m4--splat-re "\\<classVariable\\>"     "CLASSVARIABLE")
  (jtw2m4--splat-re "\\<property\\>"          "PROPERTY")
  (jtw2m4--splat-re "\\<new\\>"               "NEW")
  (jtw2m4--splat-re "\\<true\\>"              "TRUE")
  (jtw2m4--splat-re "\\<false\\>"             "FALSE")
  (jtw2m4--splat-re "\\<null\\>"              "NULL")

  (jtw2m4--splat-re "\\<private\\>"           "PRIVATE")
  (jtw2m4--splat-re "\\<public\\>"            "POBLIC")
  (jtw2m4--splat-re "\\<protected\\>"         "PROTECTED")
  (jtw2m4--splat-re "\\<constructor\\>"       "CONSTRUCTOR")
  (jtw2m4--splat-re "\\<return\\>"            "RETURN")

  ;;
  ;; NOTE: types
  ;;
  (jtw2m4--splat-re "\\<boolean\\>"            "BOOLEAN")
  (jtw2m4--splat-re "\\<void\\>"               "VOID")
  (jtw2m4--splat-re "\\<char\\>"               "CHAR")
  (jtw2m4--splat-re "\\<float\\>"              "FLOAT")
  (jtw2m4--splat-re "\\<double\\>"             "DOUBLE")
  (jtw2m4--splat-re "\\<int\\>"                "INT")
  (jtw2m4--splat-re "\\<String\\>"             "STRING")
  (jtw2m4--splat-re "\\<System.out.println\\>" "SYSTEM_OUT_PRINTLN")
  (jtw2m4--splat-re "\\<System.out.print\\>"   "SYSTEM_OUT_PRINT")
  (jtw2m4--splat-re "\\<this\\>"               "THIS")
  )

(defun jtw2m4 ()
  (interactive)

  (c++-mode)
  (d-movement--unpad-buffer)


  (jtw2m4--func-names)
  (jtw2m4--method-names)

  (jtw2m4--cap)

  (jtw2m4--splat-re "\\<[A-Z]+[a-z][A-Za-z0-9_]*" "CLSS(\\&)")

  (jtw2m4--splat-re "\\<\\([A-Z]+[a-z][A-Za-z0-9_]*\\|BOOLEAN\\|CHAR\\|INT\\|FLOAT\\|DOUBLE\\|SHORT\\|LONG\\|STRING\\)\\([ \t]+\\)\\([a-z][A-Za-z0-9_]*\\)\\>" "CLSS(\\1)\\2VARI(\\3)")


  (jtw2m4--splat-re "\".*\"" "STRI(\\&)")

  (jtw2m4--splat-re "\\([ =(,]\\)\\([-+]?[0-9]+\\(\\.[0-9]+\\)?\\([eE][-+]?[0-9]+\\)?\\)" "\\1NUMB(\\2)")

  ;;(jtw2m4--splat-re "^CLASS \\([A-Z]+[a-z][A-Za-z0-9_]*\\)" "CLASS CLSS(\\1)")
  ;;(jtw2m4--splat-re "NEW \\([A-Z]+[a-z][A-Za-z0-9_]*\\)" "NEW CLSS(\\1)")

  (jtw2m4--splat-re "CLSS(BOOLEAN)" "BOOLEAN")
  (jtw2m4--splat-re "CLSS(CHAR)"    "CHAR")
  (jtw2m4--splat-re "CLSS(INT)"     "INT")
  (jtw2m4--splat-re "CLSS(FLOAT)"   "FLOAT")
  (jtw2m4--splat-re "CLSS(DOUBLE)"  "DOUBLE")
  (jtw2m4--splat-re "CLSS(STRING)"  "STRING")

  (progn
    (d-movement--unpad-buffer)
    (d-splat-re "//.*$" "COMM(\\&)"))


  (jtw2m4--splat-re "CLSS(Sir)" "Sir")
  (d-movement--pad-buffer)
  (html-mode)
 )

(defun jtw2m4--method-names ()
  (interactive)
  (goto-char (point-min))
  (while (re-search-forward "\\<method\\>" nil t)
    (when (not (jtw2m4--inside-comment-or-string))
      (skip-chars-forward " \t")
      (skip-chars-forward "A-Za-z0-9_")
      (skip-chars-forward " \t")
      (insert "FUNC(")
      (d-forward-sexp)
      (insert ")"))))

(defun jtw2m4--func-names ()
  (interactive)
  (goto-char (point-min))
  (while (re-search-forward "\\<function\\>" nil t)
    (when (not (jtw2m4--inside-comment-or-string))
      (skip-chars-forward " \t")
      (skip-chars-forward "A-Za-z0-9_")
      (skip-chars-forward " \t")
      (insert "FUNC(")
      (d-forward-sexp)
      (insert ")"))))
;;
;;
;; TODO: CLASSVARIABLE
;; TODO: PROPERTY
;; TODO: VARIABLE f
;; TODO: Fooo (NEW Foo|(Foo))
;; TODO: parameters

(provide 'jtw2m4)
;;; jtw2m4.el ends here
