--[[
  Copyright Tom Lukeywood 2018
    This file is part of Forest2D

    Forest2D is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    Forest2D is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with Forest2D.  If not, see <http://www.gnu.org/licenses/>.
]]--

EventHandler = {}   --I have only added the events I am currently using for now

EVENT_UPKEY_PRESSED = 1
EVENT_DOWNKEY_PRESSED = 2
EVENT_LEFTKEY_PRESSED = 3
EVENT_RIGHTKEY_PRESSED = 4

EVENT_AKEY_PRESSED = 5
EVENT_BKEY_PRESSED = 6
EVENT_CKEY_PRESSED = 7
EVENT_DKEY_PRESSED = 8
EVENT_EKEY_PRESSED = 9
EVENT_FKEY_PRESSED = 10
EVENT_GKEY_PRESSED = 11
EVENT_HKEY_PRESSED = 12
EVENT_IKEY_PRESSED = 13
EVENT_JKEY_PRESSED = 14
EVENT_KKEY_PRESSED = 15
EVENT_LKEY_PRESSED = 16
EVENT_MKEY_PRESSED = 17
EVENT_NKEY_PRESSED = 18
EVENT_OKEY_PRESSED = 19
EVENT_PKEY_PRESSED = 20
EVENT_QKEY_PRESSED = 21
EVENT_RKEY_PRESSED = 22
EVENT_SKEY_PRESSED = 23
EVENT_TKEY_PRESSED = 24
EVENT_UKEY_PRESSED = 25
EVENT_VKEY_PRESSED = 26
EVENT_WKEY_PRESSED = 27
EVENT_XKEY_PRESSED = 28
EVENT_YKEY_PRESSED = 29
EVENT_ZKEY_PRESSED = 30

EVENT_1KEY_PRESSED = 31
EVENT_2KEY_PRESSED = 32
EVENT_3KEY_PRESSED = 33
EVENT_4KEY_PRESSED = 34
EVENT_5KEY_PRESSED = 35
EVENT_6KEY_PRESSED = 36
EVENT_7KEY_PRESSED = 37
EVENT_8KEY_PRESSED = 38
EVENT_9KEY_PRESSED = 39

EVENT_MOUSEBUTTON_LEFT_CLICKED = 40
EVENT_MOUSEBUTTON_MIDDLE_CLICKED = 41
EVENT_MOUSEBUTTON_RIGHT_CLICKED = 42
EVENT_MOUSEBUTTON_LEFT_PRESSED = 43
EVENT_MOUSEBUTTON_MIDDLE_PRESSED = 44
EVENT_MOUSEBUTTON_RIGHT_PRESSED = 45
EVENT_MOUSEWHEEL_UP = 46
EVENT_MOUSEWHEEL_DOWN = 47
EVENT_MOUSEMOTION = 48

EVENT_F1KEY_PRESSED = 49

EVENT_LSHIFTKEY_PRESSED = 50

EVENT_ESCKEY_PRESSED = 51
EVENT_SDLQUIT = 52

NUMBER_OF_EVENTS = 53

function EventHandler.New(Delay)
    local self = {}

    self.EventStatus = {}

    for I = 1, NUMBER_OF_EVENTS do
        self.EventStatus[I] = {}
        self.EventStatus[I].Active = false
        self.EventStatus[I].Disabled = false
    end

    self.MouseX, self.MouseY = 0,0

    self.OldTicks = 0
    self.Delay = Delay

    self.DisableTimer = {} for I = 1, NUMBER_OF_EVENTS do self.DisableTimer[I] = {} self.DisableTimer[I].OldTicks = SDL.getTicks() self.DisableTimer[I].Time = 0 end

    local Keys = SDL.getKeyboardState()

    function self.GetActiveEvents()

            self.Reset()
            if SDL.getTicks() <= (self.OldTicks + self.Delay) then for I = 1, #self.EventStatus do self.EventStatus[I].Active = false end return self end-- Delay the time between registered events

            for I = 1, NUMBER_OF_EVENTS do -- Delay events if needed

                if SDL.getTicks() <= (self.DisableTimer[I].OldTicks + self.DisableTimer[I].Time) then
                    self.EventStatus[I].Disabled = true
                else
                    self.EventStatus[I].Disabled = false
                    self.DisableTimer[I].Time = 0
                    self.DisableTimer[I].OldTicks = SDL.getTicks()
                end

            end

            self.OldTicks = SDL.getTicks()

            SDL.pumpEvents()

            if Keys[SDL.scancode.Up] and not self.EventStatus[EVENT_UPKEY_PRESSED].Disabled then self.EventStatus[EVENT_UPKEY_PRESSED].Active = true end
            if Keys[SDL.scancode.Down] and not self.EventStatus[EVENT_DOWNKEY_PRESSED].Disabled then self.EventStatus[EVENT_DOWNKEY_PRESSED].Active = true end
            if Keys[SDL.scancode.Left] and not self.EventStatus[EVENT_LEFTKEY_PRESSED].Disabled then self.EventStatus[EVENT_LEFTKEY_PRESSED].Active = true end
            if Keys[SDL.scancode.Right] and not self.EventStatus[EVENT_RIGHTKEY_PRESSED].Disabled then self.EventStatus[EVENT_RIGHTKEY_PRESSED].Active = true end

            if Keys[SDL.scancode.F] and not self.EventStatus[EVENT_FKEY_PRESSED].Disabled then self.EventStatus[EVENT_FKEY_PRESSED].Active = true end
            if Keys[SDL.scancode.E] and not self.EventStatus[EVENT_EKEY_PRESSED].Disabled then self.EventStatus[EVENT_EKEY_PRESSED].Active = true end
            if Keys[SDL.scancode.S] and not self.EventStatus[EVENT_SKEY_PRESSED].Disabled then self.EventStatus[EVENT_SKEY_PRESSED].Active = true end
            if Keys[SDL.scancode.L] and not self.EventStatus[EVENT_LKEY_PRESSED].Disabled then self.EventStatus[EVENT_LKEY_PRESSED].Active = true end
            if Keys[SDL.scancode.R] and not self.EventStatus[EVENT_RKEY_PRESSED].Disabled then self.EventStatus[EVENT_RKEY_PRESSED].Active = true end
            if Keys[SDL.scancode.T] and not self.EventStatus[EVENT_TKEY_PRESSED].Disabled then self.EventStatus[EVENT_TKEY_PRESSED].Active = true end
            if Keys[SDL.scancode.V] and not self.EventStatus[EVENT_VKEY_PRESSED].Disabled then self.EventStatus[EVENT_VKEY_PRESSED].Active = true end

            if Keys[SDL.scancode.LeftShift] and not self.EventStatus[EVENT_LSHIFTKEY_PRESSED].Disabled then self.EventStatus[EVENT_LSHIFTKEY_PRESSED].Active = true end --indev

            -- Keys 1-9
            if Keys[30] and not self.EventStatus[EVENT_1KEY_PRESSED].Disabled then self.EventStatus[EVENT_1KEY_PRESSED].Active = true end
            if Keys[31] and not self.EventStatus[EVENT_2KEY_PRESSED].Disabled then self.EventStatus[EVENT_2KEY_PRESSED].Active = true end
            if Keys[32] and not self.EventStatus[EVENT_3KEY_PRESSED].Disabled then self.EventStatus[EVENT_3KEY_PRESSED].Active = true end
            if Keys[33] and not self.EventStatus[EVENT_4KEY_PRESSED].Disabled then self.EventStatus[EVENT_4KEY_PRESSED].Active = true end
            if Keys[34] and not self.EventStatus[EVENT_5KEY_PRESSED].Disabled then self.EventStatus[EVENT_5KEY_PRESSED].Active = true end
            if Keys[35] and not self.EventStatus[EVENT_6KEY_PRESSED].Disabled then self.EventStatus[EVENT_6KEY_PRESSED].Active = true end
            if Keys[36] and not self.EventStatus[EVENT_7KEY_PRESSED].Disabled then self.EventStatus[EVENT_7KEY_PRESSED].Active = true end
            if Keys[37] and not self.EventStatus[EVENT_8KEY_PRESSED].Disabled then self.EventStatus[EVENT_8KEY_PRESSED].Active = true end
            if Keys[38] and not self.EventStatus[EVENT_9KEY_PRESSED].Disabled then self.EventStatus[EVENT_9KEY_PRESSED].Active = true end

            if Keys[SDL.scancode.F1] and not self.EventStatus[EVENT_F1KEY_PRESSED].Disabled then self.EventStatus[EVENT_F1KEY_PRESSED].Active = true end

            if Keys[SDL.scancode.Escape] and not self.EventStatus[EVENT_ESCKEY_PRESSED].Disabled then self.EventStatus[EVENT_ESCKEY_PRESSED].Active = true end

            --Some events do not have SDL scancodes so SDL.pollEvent is used here
            for event in SDL.pollEvent() do

            if event.type == SDL.event.Quit and not self.EventStatus[EVENT_SDLQUIT].Disabled then
                self.EventStatus[EVENT_SDLQUIT].Active = true break end

            --These events do not update untill the mouse click has been released (hence they are distinguished from the "PRESSED" mousebutton events)
            if event.type == SDL.event.MouseButtonDown then
                if event.button == SDL.mouseButton.Left and not self.EventStatus[EVENT_MOUSEBUTTON_LEFT_CLICKED].Disabled then
                    self.EventStatus[EVENT_MOUSEBUTTON_LEFT_CLICKED].Active = true break end
                if event.button == SDL.mouseButton.Middle and not self.EventStatus[EVENT_MOUSEBUTTON_MIDDLE_CLICKED].Disabled then
                    self.EventStatus[EVENT_MOUSEBUTTON_MIDDLE_CLICKED].Active = true break end
                if event.button == SDL.mouseButton.Right and not self.EventStatus[EVENT_MOUSEBUTTON_RIGHT_CLICKED].Disabled then
                    self.EventStatus[EVENT_MOUSEBUTTON_RIGHT_CLICKED].Active = true break end
            end
            ----

            --These events update even if the mouse press has not been released
            if SDL.getMouseState()[SDL.mouseMask.Left] and not self.EventStatus[EVENT_MOUSEBUTTON_LEFT_PRESSED].Disabled then
                self.EventStatus[EVENT_MOUSEBUTTON_LEFT_PRESSED].Active = true
            end
            if SDL.getMouseState()[SDL.mouseMask.Right] and not self.EventStatus[EVENT_MOUSEBUTTON_RIGHT_PRESSED].Disabled then
                self.EventStatus[EVENT_MOUSEBUTTON_RIGHT_PRESSED].Active = true
            end
            if SDL.getMouseState()[SDL.mouseMask.Middle] and not self.EventStatus[EVENT_MOUSEBUTTON_MIDDLE_PRESSED].Disabled then
                self.EventStatus[EVENT_MOUSEBUTTON_MIDDLE_PRESSED].Active = true
            end
            ----

            if event.type == SDL.event.MouseWheel then
                if event.y == 1 and not self.EventStatus[EVENT_MOUSEWHEEL_UP].Disabled then
                    self.EventStatus[EVENT_MOUSEWHEEL_UP].Active = true end
                if event.y == -1 and not self.EventStatus[EVENT_MOUSEWHEEL_DOWN].Disabled then
                    self.EventStatus[EVENT_MOUSEWHEEL_DOWN].Active = true end
            end

            if event.type == SDL.event.MouseMotion and not self.EventStatus[EVENT_MOUSEMOTION].Disabled then
                self.EventStatus[EVENT_MOUSEMOTION].Active = true
                self.MouseX = event.x
                self.MouseY = event.y
            break end
            end
    end

    function self.DisableEvent(EventID, Time)
        self.EventStatus[EventID].Disabled = true
        self.DisableTimer[EventID].Time = Time
    end

    function self.Reset()
        for I = 1, #self.EventStatus do self.EventStatus[I].Active = false end
    end

    return self
end

function GetCurrentMouseTile(Ycord, Xcord, CameraY, CameraX) -- Work in progress need to update coordinates relative to camera

    if not Xcord or not Ycord or not CameraY or not CameraX then
        print("Warning: GetCurrentMouseTile: One or more arguments given are nil")
        return nil
    end

    i = 1
    j = Xcord

    while true do
      if j <= Forest2D.World.SizeOfTile then break end
        j = j - Forest2D.World.SizeOfTile
        i = i + 1
    end
    XMouseTile = i
    i = 1; j = Ycord

    while true do
      if j <= Forest2D.World.SizeOfTile then break end
        j = j - Forest2D.World.SizeOfTile
        i = i + 1
    end

    YMouseTile = i

    return YMouseTile, XMouseTile
end

return EventHandler
