;;; ---------------------------------------------------------
;;; OTalk-mode by Olaf Sylvester
;;;

(require 'hilit19)

(defvar otalk-mode-map ()
  "Keymap used in Select mode.")

(setq otalk-mode-map ())

(if otalk-mode-map
    ()
  (setq otalk-mode-map (make-sparse-keymap))
  (define-key otalk-mode-map "\t" 'otalk-indent-command)
  ;;(define-key otalk-mode-map [mouse-2] 'otalk-mouse)
  ;;(define-key otalk-mode-map [mouse-3] 'otalk-mouse-erase)
  )

(defvar otalk-mode-syntax-table nil
  "Syntax table in use in OTalk-mode buffers.")

(defvar otalk-indent-width 4 "")

(if otalk-mode-syntax-table
    ()
  (setq otalk-mode-syntax-table (make-syntax-table (standard-syntax-table)))
  (modify-syntax-entry ?_ "w" otalk-mode-syntax-table)
)

(defun otalk-indent-command ()
  (interactive)
  (let ((prev-line-indent (save-excursion (next-line -1) (current-indentation)))
	(prev-line-semicolon-p (save-excursion 
				 (next-line -1)
				 (beginning-of-line)
				 (looking-at ".*;\\s *$")))
	(start-line-p (save-excursion 
			(next-line -1)(beginning-of-line)
			(looking-at "^\\w")))
	(neg-line-keyword (save-excursion 
			    (beginning-of-line)
			    (looking-at "^\\s *\\(else\\|endif\\|end\\)")))
	(pos-line-keyword (save-excursion 
			    (next-line -1)
			    (beginning-of-line)
			    (looking-at "^\\s *\\(then\\|else\\|while\\)")))
	(same-line-keyword (save-excursion 
			    (beginning-of-line)
			    (looking-at "^\\s *\\(then\\|if\\)")))
	)
    ;;(y-or-n-p (format "%s" neg-line-keyword))
    (save-excursion
      (cond (start-line-p
	     (indent-line-to otalk-indent-width))
	    (same-line-keyword
	     (indent-line-to prev-line-indent))
	    (neg-line-keyword
	     (indent-line-to (- prev-line-indent otalk-indent-width)))
	    (pos-line-keyword
	     (indent-line-to (+ prev-line-indent otalk-indent-width)))
	    (prev-line-semicolon-p
	     (indent-line-to prev-line-indent))
	    (t nil)))
    (if (re-search-backward "^\\s *\\=" nil t)
	(back-to-indentation))))

(defun otalk-mode ()
  "Major mode for OTalk-Mode."
  (interactive)
  (kill-all-local-variables)
  (use-local-map otalk-mode-map)
  (setq major-mode 'otalk-mode)
  (setq mode-name "OTalk")
  (set-syntax-table otalk-mode-syntax-table)
  (run-hooks 'otalk-mode-hook))

(hilit-set-mode-patterns
 'otalk-mode
 '(;; comments
   ("#.*"     nil comment)
   ("^\\w.*"  nil defun)
   ("^\\w.*\\.\\(\\w+\\)"  1 default/grey80)
   ("\\<\\(self\\|super\\|if\\|else\\|endif\\|then\\|while\\|end\\)\\>"  1 keyword)
   ))

(setq auto-mode-alist (cons (cons "\\.ot$" 'otalk-mode)
			    auto-mode-alist))
;;;eof
