local Height = 0
local Width = 0

local myMath = require("modules.math")
local myTypes = require("modules.types")
local conductor = require("modules.conductor")
local json = require("modules.json")
local files = require("modules.files")
local logger = require("modules.logging")
local socket = require("socket")
local logging= require("modules.logging")

local newVector2 = myTypes.Vector2(10, 10)

local startTime = 0

local songName = "stress"
local songDifficulty = "hard"

local chartString = files.read_file(string.format("charts/%s/%s-%s.json", songName, songName, songDifficulty))

if not chartString then
    error("Chart couldn't be loaded!")
end
local chart = json.parse(chartString).song

local inst = love.audio.newSource(string.format("songs/%s/Inst.ogg", chart.song), "stream")
local voices = love.audio.newSource(string.format("songs/%s/Voices.ogg", chart.song), "stream")
local miss = love.audio.newSource("sounds/missnote1.ogg", "static")

conductor:setBpm(chart.bpm)
conductor:mapBpmChanges(chart)

local step = 0
local beat = 0

local graphics = {
}

function loadGraphic(graphic)
    if graphic.graphics == love.graphics.newImage then
        graphic.loaded = love.graphics.newImage(graphic.path)
    end

    if graphic.children then
        for index, graphicChild in next, graphic.children do
            loadGraphic(graphicChild)
        end
    end
 end

local playing = false

local characters = {}
local stage = json.parse(files.read_file("stages/stage.json"))
local unspawnedNotes = {}
local notes = {}

local directions = {
    "LEFT",
    "DOWN",
    "UP",
    "RIGHT"
}

local pressed = {
    false,
    false,
    false,
    false
}
local holded = {
    false,
    false,
    false,
    false
}

function love.load()

    characters.bf = myTypes.character("bf")
    characters.bf.stagePosition = myTypes.Vector2(stage.boyfriend[1], stage.boyfriend[2])

    for index, section in next, chart.notes do
        for index, note in next, section.sectionNotes do
            local newNote = myTypes.note(note, section.mustHitSection)
            table.insert(unspawnedNotes, newNote)
        end
    end

    for i = 0, 3 do
        local receptor = myTypes.Rect("sprites/NOTE_assets.png", "sprites/NOTE_assets.json")
        receptor:Frame("arrow"..directions[i+1], 0)

        receptor.position = myTypes.Vector2(100 + (65 * i), 0)
    end

    inst:play()
    voices:play()

    startTime = socket.gettime()

    playing = true
end

local function checkNote(dir)
    if pressed[dir] or holded[dir] then
        pressed[dir] = false
        holded[dir] = true
        return -- You dont check if you are already holding and not just pressing
    end
    pressed[dir] = true
    for index, note in next, notes do
        if note.position - conductor.songPosition < 200 then
            if note.mustPress and not note.pressed and note.direction == dir then
                characters.bf:PlayAnimation("sing"..directions[note.direction])
                note.pressed = true
                table.remove(notes, index)
                note:destroy()
            end
        end
    end
end

function love.update(dt)
    if not playing then return end

    local currentTime = socket.gettime()

    local elapsed = math.floor((currentTime - startTime) * 1000)

    conductor.songPosition = elapsed

    local oldStep = step
    local oldBeat = beat

    step = conductor:getStepRounded(elapsed)
    beat = conductor:getBeatRounded(elapsed)

    if beat ~= oldBeat then
        if beat % 2 == 0 then
            -- gf:PlayAnimation("BF NOTE LEFT", 30, false)
            for name, character in next, characters do
                if not character.singing then
                    character:PlayAnimation("idle")
                end
            end
        end
    end

    myTypes.updateSprites(dt)

    if love.keyboard.isDown("a") then
        checkNote(1)
    else
        holded[1] = false
        pressed[1] = false
    end
    if love.keyboard.isDown("s") then
        checkNote(2)
    else
        holded[2] = false
        pressed[2] = false
    end
    if love.keyboard.isDown("up") then
        checkNote(3)
    else
        holded[3] = false
        pressed[3] = false
    end
    if love.keyboard.isDown("right") then
        checkNote(4)
    else
        holded[4] = false
        pressed[4] = false
    end

    for index, note in next, notes do
        if note.position - conductor.songPosition < 0 then
            if note.mustPress then
                miss:stop()
                miss:play()
                characters.bf:PlayAnimation("sing"..directions[note.direction].."miss")
                table.remove(notes, index)
            end
        end
    end

    for name, character in next, characters do
        if character.sprite.animation ~= "idle" and character.sprite.ended then
            character:PlayAnimation("idle")
        end
    end

    for index, note in next, unspawnedNotes do
        if note.position - elapsed < 600 and note.mustPress then
            note:spawn()
            table.remove(unspawnedNotes, index)
            table.insert(notes, note)
        end
    end

    for index, note in next, notes do
        note.sprite.position = myTypes.Vector2(100 + 65 * (note.direction - 1), note.position - elapsed - 100)
        if note.position - elapsed < -150 then
            note:destroy()
            table.remove(notes, index)
        end
    end

    if not inst:isPlaying() then
        love.event.quit()
    end
end

local mainCanvas = love.graphics.newCanvas(1920, 1080)

function love.draw()

    love.graphics.setCanvas(mainCanvas)

    love.graphics.clear()

    love.graphics.circle("fill", 960, 59, 50000)

    myTypes.drawSprites()

    love.graphics.setCanvas()

    love.graphics.draw(mainCanvas, 0, 0, 0, (love.graphics:getHeight() / 1080) * (4/3), love.graphics:getHeight() / 1080)

end

love.window.setMode(1280, 720, { fullscreen = false , resizable = true})