;; This is the beginnings of a "Geometry-mode" for emacs...

;; The following functions are defined:
;;	adjust-geometry (dx dy)
;;	reflect-geometry (cx cy)
;;	extend-left (dx)
;;	extend-down (dy)
;;	extend-up (dy)

(defun adjust-geometry (dx dy)
  "Modify the geometry specification on this line, add fixed offsets."
  (interactive "*nHorizontal delta: \nnVertical delta: ")
  (beginning-of-line)
  (search-forward "+")
  (if (looking-at "[0-9]+")
      (let ((n (string-to-int (buffer-substring (match-beginning 0)
						(match-end 0)))))
	(delete-region (match-beginning 0) (match-end 0))
	(insert (int-to-string (+ n dx))))
    (error "Invalid geometry"))
  (search-forward "+")
  (if (looking-at "[0-9]+")
      (let ((n (string-to-int (buffer-substring (match-beginning 0)
						(match-end 0)))))
	(delete-region (match-beginning 0) (match-end 0))
	(insert (int-to-string (+ n dy))))
    (error "Invalid geometry"))
  (beginning-of-line 2)
  )

(defun reflect-geometry (cx cy)
  "Modify the geometry specification on this line, reflect about coords."
  (interactive "*nHorizontal center (0->no reflection): \nnVertical center (0->no reflection): ")
  (beginning-of-line)
  (search-forward "+")
  (if (not (= cx 0)) 
      (if (looking-at "[0-9]+")
	  (let ((n (string-to-int (buffer-substring (match-beginning 0)
						    (match-end 0)))))
	    (delete-region (match-beginning 0) (match-end 0))
	    (insert (int-to-string (+ cx (- cx n)))))
	(error "Invalid geometry")))
  (search-forward "+")
  (if (not (= cy 0))
      (if (looking-at "[0-9]+")
	  (let ((n (string-to-int (buffer-substring (match-beginning 0)
						    (match-end 0)))))
	    (delete-region (match-beginning 0) (match-end 0))
	    (insert (int-to-string (+ cy (- cy n)))))
	(error "Invalid geometry")))
  (beginning-of-line 2)
  )

(defun extend-left (dx)
  "Modify the geometry specification on this line, extend left edge."
  (interactive "*nHorizontal extension: ")
  (beginning-of-line)
  (search-forward "+")
  (forward-word -1)
  (if (not (looking-at "\\([0-9]+\\)x[0-9]*\\+\\([0-9]+\\)\\+[0-9]*"))
      (error "Invalid geometry"))
  (let ((w (string-to-int (buffer-substring (match-beginning 1)
					    (match-end 1))))
	(x (string-to-int (buffer-substring (match-beginning 2)
					    (match-end 2)))))
    ;; Rightmost first so values of match-... don't get wrong
    (goto-char (match-beginning 2))
    (delete-region (match-beginning 2) (match-end 2))
    (insert (int-to-string (- x (/ dx 2))))
    (goto-char (match-beginning 1))
    (delete-region (match-beginning 1) (match-end 1))
    (insert (int-to-string (+ w dx)))
    (beginning-of-line 2)
    ))

(defun extend-right (dx)
  "Modify the geometry specification on this line, extend right edge."
  (interactive "*nExtend right: ")
  (beginning-of-line)
  (search-forward "+")
  (forward-word -1)
  (if (not (looking-at "\\([0-9]+\\)x[0-9]*\\+\\([0-9]+\\)\\+[0-9]+"))
      (error "Invalid geometry"))
  (let ((w (string-to-int (buffer-substring (match-beginning 1)
					    (match-end 1))))
	(x (string-to-int (buffer-substring (match-beginning 2)
					    (match-end 2)))))
    ;; Rightmost first so values of match-... don't get wrong
    (goto-char (match-beginning 2))
    (delete-region (match-beginning 2) (match-end 2))
    (insert (int-to-string (+ x (/ dx 2))))
    (goto-char (match-beginning 1))
    (delete-region (match-beginning 1) (match-end 1))
    (insert (int-to-string (+ w dx)))
    (beginning-of-line 2)
    ))

(defun extend-down (dy)
  "Modify the geometry specification on this line, extend bottom edge."
  (interactive "*nextend down: ")
  (beginning-of-line)
  (search-forward "+")
  (forward-word -1)
  (if (not (looking-at "[0-9]*x\\([0-9]+\\)\\+[0-9]*\\+\\([0-9]+\\)"))
      (error "Invalid geometry"))
  (let ((h (string-to-int (buffer-substring (match-beginning 1)
					    (match-end 1))))
	(y (string-to-int (buffer-substring (match-beginning 2)
					    (match-end 2)))))
    ;; Rightmost first so values of match-... don't get wrong
    (goto-char (match-beginning 2))
    (delete-region (match-beginning 2) (match-end 2))
    (insert (int-to-string (+ y (/ dy 2))))
    (goto-char (match-beginning 1))
    (delete-region (match-beginning 1) (match-end 1))
    (insert (int-to-string (+ h dy)))
    (beginning-of-line 2)
    ))

(defun extend-up (dy)
  "Modify the geometry specification on this line, extend top edge."
  (interactive "*nextend up: ")
  (beginning-of-line)
  (search-forward "+")
  (forward-word -1)
  (if (not (looking-at "[0-9]*x\\([0-9]+\\)\\+[0-9]*\\+\\([0-9]+\\)"))
      (error "Invalid geometry"))
  (let ((h (string-to-int (buffer-substring (match-beginning 1)
					    (match-end 1))))
	(y (string-to-int (buffer-substring (match-beginning 2)
					    (match-end 2)))))
    ;; Rightmost first so values of match-... don't get wrong
    (goto-char (match-beginning 2))
    (delete-region (match-beginning 2) (match-end 2))
    (insert (int-to-string (- y (/ dy 2))))
    (goto-char (match-beginning 1))
    (delete-region (match-beginning 1) (match-end 1))
    (insert (int-to-string (+ h dy)))
    (beginning-of-line 2)
    ))
