(in-package :gsharp-cursor)

(defmethod end-of-line ((cursor gsharp-cursor))
  (let* ((bar (bar cursor))
         (slice (slice cursor))
         (yp (gsharp-drawing::system-y-position bar)))
    (loop for number = (1+ (number bar)) then (1+ number)
          until (= number (nb-bars (slice cursor)))
          until (/= yp (gsharp-drawing::system-y-position (barno slice number)))
          do (forward-bar cursor)
          finally (loop until (end-of-bar-p cursor)
                        do (forward-element cursor)))))

(defmethod beginning-of-line ((cursor gsharp-cursor))
  (let* ((bar (bar cursor))
         (slice (slice cursor))
         (yp (gsharp-drawing::system-y-position bar)))
    (loop for number = (1- (number bar)) then (1- number)
          until (= number -1)
          until (/= yp (gsharp-drawing::system-y-position (barno slice number)))
          do (backward-bar cursor)
          finally (loop until (beginning-of-bar-p cursor)
                        do (backward-element cursor)))))

(defmethod forward-line ((cursor gsharp-cursor))
  (end-of-line cursor)
  (unless (last-bar-p cursor)
    (forward-element cursor)))

(export '(end-of-line beginning-of-line forward-line))

(in-package :gsharp)

(define-gsharp-command (com-end-of-line)
    ((count 'integer :prompt "Number of lines"))
  ;; FIXME: negative COUNT
  (loop repeat (1- count) do (forward-line (current-cursor)))
  (end-of-line (current-cursor)))

(define-gsharp-command (com-beginning-of-line)
    ((count 'integer :prompt "Number of lines"))
  ;; FIXME: negative COUNT
  (loop repeat (1- count) do (forward-line (current-cursor)))
  (beginning-of-line (current-cursor)))

(set-key `(com-end-of-line ,*numeric-argument-marker*) 'global-gsharp-table '((#\e :control)))
(set-key `(com-beginning-of-line ,*numeric-argument-marker*) 'global-gsharp-table '((#\a :control)))