
gen = { }
math.randomseed(os.time())


function gen:init( )
    
    self._genTable = { }
    self._wall = 0
    self._floor = 1

    self._mapWidth = 30
    self._mapHeight = 30
    self._map = {}
    self._collisionMap = {}

    for x = 1, self._mapWidth do
        self._map[x] = { }
        self._collisionMap[x] = {}
        for y = 1, self._mapHeight do
            self._map[x][y] = "#"
            self._collisionMap[x][y] = self._wall
        end
    end

    self._roomTypes = {}
    self._roomTypes[1] = "vault"
    self._roomTypes[2] = "library"
    self._roomTypes[3] = "shop"
    self._roomTypes[4] = "portal"


    self._roomSymbol = { }
    self._roomSymbol["vault"] = "."
    self._roomSymbol["library"] = "b"
    self._roomSymbol["shop"] = "s"
    self._roomSymbol["portal"] = "@"
    

    self._roomTable = { }
    self:dungeon( )
    self:output( )
end

function gen:newRoom(_x, _y, _width, _height)
    if _x ~= nil and _y ~= nil then
        local id = #self._roomTable + 1
        local rw = _width
        local rh = _height
        local posX = _x
        local posY = _y

        local temp = { 
            rId = #self._roomTable+1,
            width = _width,
            height = _height,
            x = _x,
            y = _y,
            centerX = math.floor( (_x + _width)/2 ),
            centerY = math.floor( (_y + _height)/2 ),
            id = 1,
        }
        temp._type = self._roomTypes[math.random(1, #self._roomTypes)]

        table.insert(self._roomTable, temp)
        return id
    end
end

function gen:getRandomStartPosition( )
    local startX = math.random(2, self._mapWidth-math.floor(self._mapWidth/4))
    local startY = math.random(2, self._mapHeight-math.floor(self._mapHeight/4))
    local width = math.random(2, 5)
    local height = math.random(2, 5)

    if self:doesRoomExistAt(startX, startY) == true then
        self:getRandomStartPosition( )
    else
        return startX, startY, width, height
    end
end

function gen:doesRoomExistAt(_x, _y)
    local bool = false
    for i,v in ipairs(self._roomTable) do
        if v.x ~= nil and v.y ~= nil then
            for y = v.x-1, v.x+v.width do
                for x = v.y-1, v.y+v.height do
                    if x == _x and y == _y then 
                        bool = true
                    end
                end
            end     
        end  
    end

    return bool
end

function gen:dungeon( )
    for i = 1, 28 do -- 7 rooms test
        self:newRoom(self:getRandomStartPosition( ))
    end

    for i, v in ipairs(self._roomTable) do
        if v.x ~= nil and v.y ~= nil then
            for _y = v.x, v.x+v.width-1 do
                for _x = v.y, v.y+v.height-1 do
                    self._map[_x][_y] =  self._roomSymbol[v._type]
                end
            end
        end
    end

    -- Library setup
    -- Calls the grid class
    local Grid = require ("jumper.grid")
    -- Calls the pathfinder class
    local Pathfinder = require ("jumper.pathfinder")
    
    grid = Grid(self._collisionMap)
    walkable = self._wall
    local myFinder = Pathfinder(grid, 'ASTAR', walkable)
    myFinder:setMode('ORTHOGONAL')
    -- connect all the foorms
    --local path = astar.path ( graph [ 2 ], graph [ 3 ], graph, true, valid_node_func )
    for i = 1, #self._roomTable do
        if i > 1 then 
            local start = {
                x = self._roomTable[i-1].x,
                y = self._roomTable[i-1].y    
            }

            local goal = {
                x = self._roomTable[i].x,
                y = self._roomTable[i].y    
            }
            local path = myFinder:getPath(start.x, start.y, goal.x, goal.y)
            --if path ~= nil then
            for node, count in path:nodes() do
                self._map[node:getX()][node:getY()] = "."
            end
        end
    end
end

function gen:_returnGeneratedMap( )
    return self._map
end

function gen:output( )
    local lineString = ""
    local newLineCounter = 0
    for x = 1, self._mapWidth do
        for y = 1, self._mapHeight do
            lineString = lineString..""..self._map[x][y]..""
            if y == self._mapHeight then
                print(""..lineString.."")
                lineString = ""
            end
        end
    end
end


gen:init( )
