#lang racket/base

; Yggdrasil room generator: maze
; Generate a maze, with possible loops

(require
  "cell.rkt"
  "../maze.rkt"
  "../../collection/2d-array.rkt")

(provide
  yggdrasil-maze-generate)

; Translate maze generated by the maze generator into a 2d-array of yggdrasil cells
; Each cell of the maze corresponds to a 2x2 yggdrasil cells, to be able to place walls.
; The top-left cell of the 2x2 area is always a path, the bottom-right always a wall.
; Because of this, the width and height should be odd (and not even), so that the last line and column is not a wall.
; Also, this generator places events at dead-ends. Those events will be transformed later into other kind of features.
(define (yggdrasil-maze-generate width height loop?)
  ; Output
  (define output (make-2d-array width height (yggdrasil-cell-undefined))) ; By default, undefined
  ; The maze to generate has width_maze = (width + 1) / 2, similar for height.
  (define maze-width (floor (/ (+ width 1) 2)))
  (define maze-height (floor (/ (+ height 1) 2)))
  (define maze (make-maze maze-width maze-height loop?))
  ; Render the maze
  (2d-array-for-each/indexes
    maze
    (lambda (cell i j)
      ; Top-left of 2x2: Path (or event if dead-end)
      (2d-array-set! output (* 2 i) (* 2 j)
        (if (maze-cell-dead-end? cell)
            (get-yggdrasil-cell 'event)
            (get-yggdrasil-cell 'path)))
      ; Bottom-right of 2x2: Wall (if inside)
      (when (2d-array-inside? output (+ 1 (* 2 i)) (+ 1 (* 2 j)))
        (2d-array-set! output (+ 1 (* 2 i)) (+ 1 (* 2 j))
          (get-yggdrasil-cell 'wall)))
      ; Top-right of 2x2: Path if connected to right, else wall
      (when (2d-array-inside? output (+ 1 (* 2 i)) (* 2 j))
        (2d-array-set! output (+ 1 (* 2 i)) (* 2 j)
          (if (maze-cell-linked-right? cell)
              (get-yggdrasil-cell 'path)
              (get-yggdrasil-cell 'wall))))
      ; Bottom-right of 2x2: Path if connected to bottom, else wall
      (when (2d-array-inside? output (* 2 i) (+ 1 (* 2 j)))
        (2d-array-set! output (* 2 i) (+ 1 (* 2 j))
          (if (maze-cell-linked-down? cell)
              (get-yggdrasil-cell 'path)
              (get-yggdrasil-cell 'wall))))
      ))
  ; Return
  output)
