
(progn
  (add-hook 'c-mode-common-hook   'd-cc--stuff)
  ;;(add-hook 'java-mode-hook       'd-cc--stuff)
  ;;(add-hook 'emacs-lisp-mode-hook 'd-cc--stuff)
  (add-hook 'c-mode-common-hook 'turn-on-font-lock)
  )

(remove-hook 'font-lock-mode-hook 'd-if-java)
(add-hook    'font-lock-mode-hook 'd-if-java)
(defun d-if-java ()
  (interactive)
  (if (eq major-mode 'java-mode)
;;      (d-foo)
      (d-cc--stuff)
    ))

(defun d-cc--stuff ()
  "My own C stuff.  Swaps RET and LFD (^J) and customizes
indentation style and dynamic abbrevs."
  (interactive)

  (progn
    ;;
    ;; NOTE: so that M-* \<foo\> doesn't touch hello_foo_hello
    ;;
    (modify-syntax-entry ?_ "w")
    )

  ;;(kill-local-variable 'c-basic-offset)
  (kill-local-variable 'comment-column)
  (if (eq major-mode 'java-mode)
      (progn
;;        (setq c-basic-offset 2)
        (setq d-display-toggle-value 6))
    (setq d-display-toggle-value 3)
    )
  (setq c-basic-offset 3)
  (setq c-electric-pound-behavior '(alignleft))
  (setq c-progress-interval 2);; or else I tend to think it crashed
  (setq c-macro-shrink-window-flag t)
  (setq c-macro-prompt-flag t)
  (c-set-offset 'substatement-open 0)
  (set (make-local-variable 'dabbrev-case-fold-search) nil)
  (set (make-local-variable 'dabbrev-case-replace) nil)
  ;;(d-foo)
  (setq case-fold-search nil)
  (local-set-key "\C-c %" 'match-paren)
  (local-set-key "\C-j" 'd-indent-new-comment-line)
  (local-set-key "\C-m" 'd-indent-new-comment-line)

  (local-set-key "\M-q" 'd-fill-paragraph)

  (local-set-key [kp-decimal] 'cfind-first-function)
  (local-set-key "\C-t" 'cfind-first-function)

  ;;(local-set-key "\C-n" 'cfind-next-function)
  (local-set-key "#" 'self-insert-command)

  (local-set-key [(shift prior)] 'backward-paragraph)
  (local-set-key [(shift next)]  'forward-paragraph)
  ;;(local-set-key [(control prior)] 'd-backward-c-defun)
  ;;(local-set-key [(control next)]  'd-forward-c-defun)
  (local-set-key "/" 'self-insert-command)
  (local-set-key ":" 'self-insert-command)

  (local-set-key [(control c) (control c)] 'd-cc--comment-region)

  (local-set-key [(meta up)]   'beginning-of-method)
  (local-set-key [(meta down)] 'end-of-method)
  ;;(local-set-key [(control up)]   'beginning-of-method)
  ;;(local-set-key [(control down)] 'end-of-method)
  (local-set-key [(control meta home)] 'beginning-of-defun)
  (local-set-key [(control meta end)]  'end-of-defun)

  (setq truncate-lines t)

  (if os-type--graphical-p
      (local-set-key "\C-d" 'd-find-file))

  (if emacs-dialect--xemacs-p
      (progn
        (local-set-key [delete] 'd-hungry-delete)
        ))
  )

(if emacs-dialect--xemacs-p
    (add-hook 'find-file-hook 'font-lock-fontify-buffer))

;; The following code fontifies the RTTI methods:
(add-hook 'font-lock-mode-hook 'd-cc--rtti)
(defun d-cc--rtti ()
  (if (eq major-mode 'c++-mode)
      (d-font-lock-add-end
       '(("\\<\\(instanceof_\\|castto_\\)\\(\\sw*\\)"
          (1 font-lock-keyword-face t)
          (2 font-lock-type-face t)))

         )))
;;(remove-hook 'font-lock-mode-hook 'd-cc--rtti)
;;(remove-hook 'font-lock-mode-hook 'd-cc--font-lock-mode-hook)

;; The following code fontifies the list iterator macros:
(add-hook 'font-lock-mode-hook 'd-cc--iterator)
(defun d-cc--iterator ()
  (if (eq major-mode 'c++-mode)
      (d-font-lock-add-end
       '(("\\<for_\\sw*\\>" . font-lock-keyword-face)
         ))))

;;(add-hook 'font-lock-mode-hook 'd-cc--debug)
(defun d-cc--debug ()
  (if (eq major-mode 'c++-mode)
      (progn
        ;;(d-foo)
        (d-font-lock-add-end
         '(("\\<debug_\\sw*\\>" . 'fg:lightgreen)
           ("\\<\\(debug\\)\\( <<.*\\);"
            (1 'fg:lightgreen t) (2 'fg:green t))
           ;;("FUCK" fg:green t)
           )))))

;; (remove-hook 'font-lock-mode-hook 'd-font-lock-mode-hook)

;;(add-hook 'text-mode-hook 'turn-on-font-lock)



;;(make-local-variable 'c++-font-lock-extra-types)

(defun d-fill-paragraph ()
  (interactive)

  (let ((was-here     (point-marker))
        (p-min-marker nil)
        (p-max-marker nil))

    (if (and (eq major-mode 'c++-mode)
             (save-excursion
               (beginning-of-line)
               (looking-at "^[ \t]*///")))
        (progn
          (setq p-min-marker (save-excursion
                               (while (save-excursion
                                        (beginning-of-line)
                                        (looking-at "^[ \t]*///"))
                                 (forward-line -1))
                               (forward-line)
                               (point-marker)))
          (setq p-max-marker (save-excursion
                               (while (save-excursion
                                        (beginning-of-line)
                                        (looking-at "^[ \t]*///"))
                                 (forward-line 1))
                               ;;(forward-line)
                               ;;(forward-line -1)
                               ;;(forward-char -1)
                               (point-marker)))
          ;;(delete-region p-min p-max)

          (goto-char (marker-position p-min-marker))
          (while (< (point) (marker-position p-max-marker))
            (delete-region (point-at-bol)
                           (save-excursion
                             (beginning-of-line)
                             (skip-chars-forward " \t")
                             (skip-chars-forward "/")
                             (skip-chars-forward " \t")
                             (point)))
            (beginning-of-line)
            (forward-line 1))

          (goto-char (marker-position p-min-marker))
          (while (< (point) (marker-position p-max-marker))
            (beginning-of-line)
            (insert "// ")
            (c-indent-command)
            (forward-line 1))

          (goto-char (marker-position was-here))
          (fill-paragraph nil)

          (goto-char (marker-position p-min-marker))
          (while (< (point) (marker-position p-max-marker))
            (beginning-of-line)
            (skip-chars-forward " \t")
            (skip-chars-forward "/")
            (insert "/")
            (forward-line 1))

          (set-marker p-min-marker nil)
          (set-marker p-max-marker nil)
          (goto-char (marker-position was-here))
          (set-marker was-here nil)
          )
      (fill-paragraph t))))




(defun d--is-inside-a-class ()
  (save-excursion
    (let ((p0 (point))
          (p1 (re-search-backward "^\\(\\(abstract\\|public\\|final\\)[ \t]+\\)*class" nil t)))
    (when p1
      (forward-line 1)
      (when (looking-at "^{")
        (forward-sexp 1)
        (when (< p0 (point))
          (cons p1 (point))))))))

(defun beginning-of-method ()
  (interactive)
  (if (setq p (d--is-inside-a-class))
      (progn
        (push-mark (point) 'no-msg)
        (when (re-search-backward (concat "^" (make-string c-basic-offset ? ) "{") (car p) t)
          (forward-line -1)
          (skip-chars-forward " \t")))
    (beginning-of-defun)))

(defun end-of-method ()
  (interactive)
  (if (setq p (d--is-inside-a-class))
      (progn
        (push-mark (point) 'no-msg)
        (re-search-forward (concat "^" (make-string c-basic-offset ? ) "}") (cdr p) t))
    (end-of-defun)))

(add-hook 'java-mode-hook 'd-java-hook)
(add-hook 'jde-mode-hook 'd-java-hook)
(defun d-java-hook ()
  (interactive)
  ;;(setq tab-width 2)
  (setq case-fold-search nil)
  (if (boundp 'java-mode-map)
      (progn
        (define-key java-mode-map [backspace] 'd-backspace-key)
        (define-key java-mode-map [delete]    'd-delete-key)
        (define-key java-mode-map [(tab)]     'indent-for-tab-command)
        ))
  ;;  (d-font-lock-add-end
  ;;   '(
  ;;     ("^\\(.*\\log.*\\)$"     . 'bg:yellow)
  ;;     )
  ;;   )
  )

(eval-after-load
 "jde"
 '(progn
   (define-key jde-mode-map [backspace] 'd-backspace-key)
   (define-key jde-mode-map [delete]    'd-delete-key)
   )
 )

;;
;; PATCH FOR BIZARRE ERROR!!!!! That caused c++-mode C-c C-c to become
;; undefined.
;;
;;(save-excursion
;;  (set-buffer (generate-new-buffer "foo.cc"))
;;  (c++-mode)
;;  (if (string-match "undefined" (describe-key-briefly "\C-c\C-c"))
;;      (local-set-key "\C-c\C-c" 'comment-region))
;;  (kill-buffer "foo.cc"))
;;
                                      ;; c defun navigation

(setq d-c-defun-regexp "^[ \t]*{[ \t]*$")
(setq d-c-not-defun-regexp
      "^[ \t]*\\(if\\|else\\|while\\|do\\|for\\|switch\\|try\\|catch\\)\\>")

(defun d-forward-c-defun ()
  (interactive)
  (d-deposit-mark-if-small-movement)
  (if (looking-at "^{")
      (forward-char 1))
  (re-search-forward "^{" nil 'NOERROR)
  (beginning-of-line)
  (recenter)

;;  (let ((p (point)))
;;    (while (and (/= (point) (point-max))
;;                (< (abs (count-lines p (point)))
;;                   (/ (window-height) 4)))
;;
;;      (if (looking-at d-c-defun-regexp)
;;          (forward-line))
;;      (let ((done nil))
;;        (while (not done)
;;          (if (re-search-forward d-c-defun-regexp nil t)
;;              (if (save-excursion
;;                    (forward-line -1)
;;                    (not (looking-at d-c-not-defun-regexp)))
;;                  (progn
;;                    (setq done t)
;;                    (beginning-of-line)))
;;            (progn
;;              (setq done t)
;;              (goto-char (point-max))))))
;;      (if (= (point) (point-max))
;;          (recenter (- (window-height) 4))
;;        (recenter (/ (window-height) 3)))
;;      ))
)

(defun d-backward-c-defun ()
  (interactive)
  (d-deposit-mark-if-small-movement)
  (re-search-backward "^{" nil 'NOERROR)
  (recenter)
  )
;;  (let ((p (point)))
;;    (while (and (/= (point) (point-min))
;;                (< (abs (count-lines p (point)))
;;                   (/ (window-height) 4)))
;;
;;      (let ((done nil))
;;        (while (not done)
;;          (if (re-search-backward d-c-defun-regexp nil t)
;;              (if (save-excursion
;;                    (forward-line -1)
;;                    (not (looking-at d-c-not-defun-regexp)))
;;                  (progn
;;                    (setq done t)
;;                    (beginning-of-line)))
;;            (progn
;;              (setq done t)
;;              (goto-char (point-min))))))
;;      (recenter (/ (window-height) 3))
;;      ))

(defun d-cc--comment-region (p-min p-max &optional arg)
  (interactive "r\nP")
  ;;(message "arg=%s" (if arg "yes" "no"))

  (let ((temp-min       (min p-min p-max))
        (temp-max       (max p-min p-max))
        (p-max-marker-1 nil)
        (p-max-marker-2 nil))

    (setq p-min temp-min)
    (setq p-max temp-max)

    (setq p-max-marker-1 (save-excursion
                           (goto-char p-max)
                           (beginning-of-line)
                           (forward-line -1)
                           (point-marker)))

    (setq p-max-marker-2 (save-excursion
                           (goto-char p-max)
                           (point-marker)))

    ;; UNCOMMENT!
    (when arg
      (goto-char p-min)
      (beginning-of-line)
      (when (looking-at "[ ]*//")
        (while (<= (point) (marker-position p-max-marker-1))
          (beginning-of-line)
          (when (looking-at "^[ \t]*//")
            (delete-region (point) (save-excursion
                                     (skip-syntax-forward " ")
                                     (forward-char 2)
                                     (if (looking-at " ")
                                         (forward-char 1))
                                     (point))))
          (forward-line 1)
          ;; END WHILE:
          )
        ;;(comment-region p-min p-max arg)
        ;;(d-foo)
        (execute-kbd-macro "\M-\C-\\")
        ;;(indent-region p-min (marker-position p-max-marker-2) 15)
        ;; END WHEN:
        )
      (goto-char (marker-position p-max-marker-2))
      ;; END WHEN:
      )

    ;; COMMENT OUT!
    (when (not arg)
      (goto-char p-min)
      (beginning-of-line)
      (setq space (- (save-excursion
                       (skip-syntax-forward " ")
                       (point)) (point)))
      (while (<= (point) (marker-position p-max-marker-1))
        (beginning-of-line)
        (if (looking-at (make-string space ? ))
            (delete-region (point) (save-excursion
                                     (goto-char (+ (point) space))
                                     ;;(skip-syntax-forward " ")
                                     (point))))
        (insert "// ")
        ;;(setq p-max (+ p-max 3))
        (forward-line 1)
        ;; END WHILE:
        )
      (goto-char (marker-position p-max-marker-2))
      (call-interactively 'indent-region)
      ;; END WHEN:
      )

    (set-marker p-max-marker-1 nil)
    (set-marker p-max-marker-2 nil)
    ))

(defun d-cc--reggie (a b)
  (interactive "r")
  (message "Region = (%d:%d)" a b))



;;(safe-require 'd-speedbar)

(defun d-comment-out-debug-print-statements (start end)
  (interactive "r")
  (save-excursion
    (goto-char start)
    (while (< (point) end)
      (beginning-of-line)
      (skip-syntax-forward "-")
      (if (looking-at "debug")
          (insert "//"))
      (beginning-of-line)
      (forward-line 1)))
  )
(defun d-uncomment-out-debug-print-statements (start end)
  (interactive "r")
  (save-excursion
    (goto-char start)
    (setq safety-step 0)
    (while (and (< safety-step 50000)
                (< (point) end))
      (incf safety-step)
      (beginning-of-line)
      (skip-syntax-forward "-")
      (if (looking-at "//debug")
          (delete-char 2))
      (beginning-of-line)
      (forward-line 1)))
  )
(setq toggle-debug-statements-flag t)
(defun toggle-debug-statements()
  (interactive)
  (save-excursion
    (beginning-of-defun)
    (if toggle-debug-statements-flag
        (d-comment-out-debug-print-statements (point) (progn
                                                         (forward-sexp 1)
                                                         (point)))
      (d-uncomment-out-debug-print-statements (point) (progn
                                                         (forward-sexp 1)
                                                         (point))))
    (setq toggle-debug-statements-flag (not toggle-debug-statements-flag))
    ))

(provide 'd-cc)
;;; d-cc.el ends here
