;;; -*- Mode: Lisp; Package: DESIGN; Syntax: Ansi-common-lisp -*-

(defun set-tiles-visible-from-center (to-region from-region
				      &optional (tile-size *default-tile-size*))
  (let ((grid (find-or-make-grid-for-region to-region tile-size)))
    (unless (find-center-viewpoint-data grid from-region)
	(save-center-viewpoint-data grid from-region)
	;; check each tile to see if its midpoint is visible from the viewpoint; visible = line
	;; between viewpoint and midpoint does not cross an opaque edge
	(check-visibility2 grid (find-or-make-center-viewpoint from-region))
	grid)))

(defmethod find-center-viewpoint-data ((grid grid) from-region)
  (with-slots (viewpoint-data) grid
    (let ((data (find (list from-region 'center) viewpoint-data :test #'equal)))
      (when data (second data)))))

(defun make-center-viewpoint (region)
  (multiple-value-bind (x y)
      (physical-center region)
    (let ((viewpoint (make-viewpoint x y nil nil region)))
      (add-property-value region 'viewpoint-data (list 'center viewpoint))
      viewpoint)))

(defun find-or-make-center-viewpoint (region)
  (or (find-center-viewpoint region)
      (make-center-viewpoint region)))

(defun find-center-viewpoint (region)
  (let ((data (find 'center (viewpoint-data-for-region region) :key #'car :test #'equal)))
    (when data (second data))))

(defmethod save-center-viewpoint-data ((grid grid) from-region)
  (with-slots (viewpoint-data) grid
    (push (list from-region 'center) viewpoint-data)))


(defmethod draw-center-viewpoint ((from-region territory) stream)
    (draw-self (find-center-viewpoint from-region) stream))


(defmethod draw-tiles-visible-from-center ((to-region territory) from-region stream
			       &optional (tile-size *default-tile-size*))
  (when (grid-for-region to-region tile-size)
    (dolist (tile (tiles-visible-from-center to-region from-region tile-size))
      (draw-self (tile-midpoint tile) stream))))

(defmethod tiles-visible-from-center ((to-region territory) (from-region territory)
			  &optional (tile-size *default-tile-size*))
  (let ((vis-tiles nil)
	(viewpoint (find-center-viewpoint from-region)))
    (loop-with-tiles (grid-for-region to-region tile-size)
      (when (visible-from-p tile viewpoint)
	(push tile vis-tiles)))
    vis-tiles))
