local S = minetest.get_translator("quikbild")

local storage = quikbild.storage



-- funcs defined

local update_leaderboard = function(arena) end
local clearinv = function(p_name) end
local send_lang_fs = function(p_name) end
local reset_arena_choose_artist = function(arena) end


arena_lib.on_load("quikbild", function(arena)

    --randomize math.random
    math.randomseed = os.time()
  	local f = quikbild.csv.open(minetest.get_modpath("quikbild")..arena.word_list_path)
  	if not f then
  		f = quikbild.csv.open(minetest.get_worldpath()..arena.word_list_path)
  	end

    if f then
        local word_list = {}

    	for fields in f:lines() do
        local translation_list = {}
    	  for i, v in ipairs(fields) do
          table.insert(translation_list,v)
        end
        table.insert(word_list,translation_list)
    	end
        arena.word_list = word_list
    end

    for pl_name,stats in pairs(arena.players) do
        -- recall the player's saved language or default to English
        local code = storage:get_string("lang_"..pl_name)
        code = tonumber(code) or 1
        arena.players[pl_name].lang = code
        -- set up the players' huds
        quikbild.create_hud(pl_name)
    end

    local poss = {}
    local ser_poss = storage:get_string("pos_"..arena.name)
    if ser_poss then
        poss = minetest.deserialize(ser_poss)
        if poss == nil then poss = {} end
    end
    for _,pos in ipairs(poss) do
        minetest.set_node(pos, {name="quikbild:climb"})
    end
    storage:set_string("pos_"..arena.name,minetest.serialize({}))

end)





arena_lib.on_time_tick('quikbild', function(arena)

    -- update hud leaderboard
    update_leaderboard(arena)

    if arena.state == 'choose_artist' then
        --choose the artist
        local artist_canidates = {}
        for pl_name,stats in pairs(arena.players) do
            if arena.has_built[pl_name] ~= true then
                table.insert(artist_canidates,pl_name)
            end
        end
        if #artist_canidates == 0 then --we have reached game's end
            arena.state = 'game_over'
            local winning_score = 0
            local winners = {}

            for pl_name,stats in pairs(arena.players) do
                if stats.score == winning_score then
                    table.insert(winners,pl_name)
                elseif stats.score > winning_score then
                    winning_score = stats.score
                    winners = {pl_name}
                end
            end

            if winning_score == 0 then --if no one got any points, then eliminate everyone
                local msg = S('No one got any points')..' :(   '..S('Try again!')
                arena_lib.HUD_send_msg_all("broadcast", arena, msg, 3 ,'sumo_lose',0xCFC6B8)
                arena_lib.send_message_in_arena(arena, "both", msg)
                minetest.after(4,function(arena)
                    arena_lib.force_arena_ending('quikbild', arena,'Game')
                end,arena)
            else

                local winner_string = ''
                local pts = 0
                for i,pl_name in pairs(winners) do
                    winner_string = winner_string..pl_name
                    if #winners ~= i then
                        winner_string = winner_string ..", "
                    else 
                        winner_sting = winner_string .. " "
                    end
                end
                local msg = winner_string..' '..S('won with')..' '..winning_score.. ' pts!'
                arena_lib.HUD_send_msg_all("broadcast", arena, msg, 3 ,'sumo_win',0xDFF6F5)
                arena_lib.send_message_in_arena(arena, "both", msg)
                minetest.after(4,function(arena) --cant use arena_lib.load celebration rn, doesnt recognize more than 1 winner
                    arena_lib.force_arena_ending('quikbild', arena,'Game')

                end,arena)
            end

            return
        end


        --game isn't over, so we choose the artist


        local rand_art_idx = math.random(1,#artist_canidates)
        arena.artist = artist_canidates[rand_art_idx]
        arena.has_built[arena.artist] = true --indicate that they were the artist
        arena.state = 'build_think' --change the arena state so we dont run this code again
        --send info messages
        arena_lib.HUD_send_msg("broadcast", arena.artist, S('You are the Artist. Build the word you see'), 4 ,nil,0xFF0000)
        for pl_name,stats in pairs(arena.players) do

            if pl_name ~= arena.artist then
                arena_lib.HUD_send_msg("broadcast", pl_name, arena.artist .. ' '..S('is the artist.'), 2 ,nil,0xFF0000)
                
                -- give everyone except the artist helpful tools
                local l_player = minetest.get_player_by_name(pl_name)
                l_player:hud_set_hotbar_itemcount(3)

                for idx ,itemname in pairs({
                    "",
                    "quikbild:lang",
                    "quikbild:help",
                    --"quikbild:kick"
                }) do
                    local item = ItemStack(itemname)
                    l_player:get_inventory():set_stack("main", idx, item)
                end

                minetest.after(2, function(arena,pl_name)
                    arena_lib.HUD_send_msg("hotbar", pl_name, S('Guess what they are building.'), 2 ,nil,0xFF0000)
                end,arena,pl_name)
            else
                -- set the artist's hotbar larger
                local player = minetest.get_player_by_name(pl_name)
                player:hud_set_hotbar_itemcount(#dye.dyes)
            end
        end


        --choose the word

        arena.word = arena.word_list[math.random(1,#arena.word_list)]

        -- clear the board of old building peices
        local poss = {}
        local ser_poss = storage:get_string("pos_"..arena.name)
        if ser_poss then
            poss = minetest.deserialize(ser_poss)
            if poss == nil then poss = {} end
        end
        for _,pos in ipairs(poss) do
            minetest.set_node(pos, {name="quikbild:climb"})
        end
        storage:set_string("pos_"..arena.name,minetest.serialize({}))

        -- teleport the artist in to the building area.
        local artist_pl = minetest.get_player_by_name(arena.artist)
        artist_pl:move_to(arena.artist_spawn_pos)
    end

    if arena.state == 'build_think' then
        if not(arena.players[arena.artist]) and arena.in_celebration  then 
            for pl_name,stats in pairs(arena.players) do
                local msg = S("Oops! The artist left the game.")
                arena_lib.HUD_send_msg("title", pl_name, msg, 3, 'sumo_elim',0xFFFFFF)
                minetest.chat_send_player(pl_name,minetest.colorize("#7D7071",">> "..msg))
            end
            reset_arena_choose_artist(arena)
            return
        end
        arena.state_time = arena.state_time + 1 --increase the timer counter
        if arena.state_time == 4 then
            --send the word to the artist
            arena_lib.HUD_send_msg("title", arena.artist, arena.word[arena.players[arena.artist].lang], 4 ,nil,0xFF0000)
            arena_lib.HUD_send_msg_all("broadcast", arena, S('Round begins in')..' 5', 1 ,nil,0xFF0000)
        end
        if arena.state_time == 5 then
            arena_lib.HUD_send_msg_all("broadcast", arena, S('Round begins in')..' 4', 1 ,nil,0xFF0000)
        end
        if arena.state_time == 6 then
            arena_lib.HUD_send_msg_all("broadcast", arena, S('Round begins in')..' 3', 1 ,nil,0xFF0000)
        end
        if arena.state_time == 7 then
            arena_lib.HUD_send_msg_all("broadcast", arena, S('Round begins in')..' 2', 1 ,nil,0xFF0000)
        end
        if arena.state_time == 8 then
            arena_lib.HUD_send_msg_all("broadcast", arena, S('Round begins in')..' 1', 1 ,nil,0xFF0000)
        end
        if arena.state_time == 9 then
            --give the artist his tools, send start to everyone, change state
            for pl_name, stats in pairs(arena.players) do
                if pl_name == arena.artist then
                    local player = minetest.get_player_by_name(pl_name)
                    for idx ,itemname in pairs(quikbild.items) do
                        local item = ItemStack(itemname)
                        player:get_inventory():set_stack("main", idx, item)
                    end
                    arena_lib.HUD_send_msg("title", pl_name, S('BUILD!'), 1 ,nil,0x00FF00)
                else
                    arena_lib.HUD_send_msg("title", pl_name, S('BEGIN GUESSING!'), 1 ,nil,0x00FF00)
                end
                arena.state = 'build'
                arena.state_time = 0
            end
        end
    end





    if arena.state == 'build' then
        if not arena.stall then
            local time_left = arena.build_time - arena.state_time


            local art_is_in_game = false
            for pl_name,stats in pairs(arena.players) do
                if pl_name == arena.artist then
                    art_is_in_game = true
                end
            end

            if not(art_is_in_game) then --if arena.artist is no longer in the game, then send message to players, and change game state to choose artist, and return
                for pl_name,stats in pairs(arena.players) do
                    local msg = S("Oops! The artist left the game. The word was").." "..arena.word[stats.lang]
                    arena_lib.HUD_send_msg("title", pl_name, msg, 3, 'sumo_elim',0xFFFFFF)
                    minetest.chat_send_player(pl_name,minetest.colorize("#7D7071",">> "..msg))
                end
                reset_arena_choose_artist(arena)
                return

            end


            if time_left == 0 then

                --change game state
                for pl_name,stats in pairs(arena.players) do
                    local msg = S("TIME's UP! The word was:").." "..arena.word[stats.lang]
                    arena_lib.HUD_send_msg("title", pl_name, msg, 3, 'sumo_lose',0xFFFFFF)
                    minetest.chat_send_player(pl_name,minetest.colorize("#7D7071",">> "..msg))
                end
                reset_arena_choose_artist(arena)
                return
            end

            for pl_name,stats in pairs(arena.players) do
                if pl_name == arena.artist then
                    arena_lib.HUD_send_msg("hotbar", pl_name, S("WORD")..": ".. arena.word[stats.lang] .." TIME: "..time_left, 1 ,nil,0xFFFFFF)
                else
                    arena_lib.HUD_send_msg("hotbar", pl_name, S("TIME LEFT IN ROUND")..": "..time_left, 1 ,nil,0xFFFFFF)
                end
            end

            arena.state_time = arena.state_time + 1

        end

    end
end)



table.insert(minetest.registered_on_chat_messages, 1, function(p_name, message)  --thanks rubenwardy, for giving this code snippet that works around Arena_libs's chat prevention!
    if message:sub(1, 1) == "/" then
        return false
    end

    if arena_lib.is_player_in_arena(p_name,'quikbild') then
        local arena = arena_lib.get_arena_by_player(p_name)
        if not(arena.in_queue) and not(arena.in_celebration) and not(arena.in_loading) then

            if arena.state == 'build' and arena.stall == false then

                if p_name == arena.artist then
                    return true -- prevent cheating!
                else

                    if string.find(message,arena.word[arena.players[p_name].lang]) then -- if the word was said...

                        for pl_name, stats in pairs(arena.players) do
                            if pl_name == p_name then
                                local list = {S('Correct!'), S('You got it!'),S('Way to go!'), S('Outstanding!'), S('Yay!')}
                                local msg = list[math.random(1,5)]..' +1 pt'
                                arena_lib.HUD_send_msg("title", pl_name, msg, 3 ,'sumo_win',0x00FF00)
                                minetest.chat_send_player(pl_name,minetest.colorize("#7D7071",">> "..msg.."  "..S("The word was:").." "..arena.word[stats.lang]))
                                arena.players[p_name].score = arena.players[p_name].score + 1
                            elseif pl_name == arena.artist then
                                local msg = S('Yay!').. ' '.. p_name ..' ' .. S('guessed your word.') ..' +1 pt'
                                arena_lib.HUD_send_msg("title", pl_name, msg, 3 ,'sumo_win',0x00FF00)
                                arena.players[pl_name].score = arena.players[pl_name].score + 1
                            else
                                local msg = p_name..' '..S('guessed the word. Round over!')
                                arena_lib.HUD_send_msg("title", pl_name, msg, 3 ,'sumo_elim',0x00FF00)
                                minetest.chat_send_player(pl_name,minetest.colorize("#7D7071",">> "..msg.."  "..S("The word was:").." "..arena.word[stats.lang]))
                            end
                        end

                        reset_arena_choose_artist(arena)
                    end
                end
            end
        end
    end

end)


arena_lib.on_join("quikbild", function(p_name, arena, as_spectator)
    if not(as_spectator) then
        quikbild.create_hud(p_name)
    end
end)

arena_lib.on_celebration('quikbild', function(arena, winner_name)
    for pl_name,stats in pairs(arena.players) do
        minetest.close_formspec(pl_name, "qb_lang")
    end
end)

arena_lib.on_end('quikbild', function(arena, players, winners, spectators, is_forced)
    for pl_name,stats in pairs(players) do
        quikbild.remove_hud(pl_name)
    end
end)

arena_lib.on_quit('quikbild', function(arena, p_name, is_forced)
    minetest.close_formspec(p_name, "qb_lang")
    quikbild.remove_hud(p_name)
end)


minetest.register_on_joinplayer(function(player)
    local name = player:get_player_name()
    clearinv(name)
end)



-- ##########################
-- Functions Defined
-- ##########################


update_leaderboard = function(arena)
    
    local ordered_players = {}
    for pl_name,stats in pairs(arena.players) do
        table.insert(ordered_players,{name=pl_name,score=stats.score})
    end
    table.sort(ordered_players,function(data1,data2) return data1.score > data2.score end)

    -- take the top 5 players, get the display strings
    local top_5 = {}
    for i = 1,5 do
        if ordered_players[i] then
            table.insert(top_5,ordered_players[i] )
            top_5[i].str = top_5[i].score .. "     ".. top_5[i].name
        end
    end

    for pl_name,stats in pairs(arena.players) do
        quikbild.update_hud(pl_name,top_5,stats.score)
    end
end

-- clears inventory of quikbild items
clearinv = function(p_name)
    local player = minetest.get_player_by_name(p_name)
    local inv = player:get_inventory()
    for idx ,itemname in pairs(quikbild.items) do
        local stack = ItemStack(itemname)
        local taken = inv:remove_item("main", stack)
    end
    local list = inv:get_list("main")
    for k, v in pairs(list) do
        if v:get_name() == "quikbild:lang" or v:get_name() == "quikbild:help" or v:get_name() == "quikbild:kick" then
            inv:remove_item("main", v)
        end
    end
end


send_lang_fs = function(p_name) 
    minetest.show_formspec(p_name, "qb_lang", "formspec_version[5]"..
    "size[16.6,3]"..
    "background9[0,0;0,0;quikbild_gui_bg.png;true;6,6]"..
    "style_type[image_button;textcolor=#302C2E;font=normal,bold]"..
    "image_button[0.6,0.6;2.6,1.8;english.png;english;EN;false;true]"..
    "image_button[3.8,0.6;2.6,1.8;italian.png;italian;IT;false;true]"..
    "image_button[7,0.6;2.6,1.8;spanish.png;spanish;ES;false;true]"..
    "image_button[10.2,0.6;2.6,1.8;french.png;french;FR;false;true]"..
    "image_button[13.4,0.6;2.6,1.8;german.png;german;DE;false;true]")
end

quikbild.send_lang_fs = send_lang_fs


reset_arena_choose_artist = function(arena)

    arena.stall = true --stop gameplay for 3 sec
    minetest.after(3,function(arena)
        if arena.in_game then
            arena.stall = false
            arena.state = 'choose_artist'
            arena.state_time = 0
            for pl_name,stats in pairs(arena.players) do
                local pos = arena_lib.get_random_spawner(arena)
                local pl_obj = minetest.get_player_by_name(pl_name)
                pl_obj:move_to(pos)
                clearinv(pl_name)
            end

        end

    end,arena)
end



minetest.register_on_player_receive_fields(function(player, formname, fields)
    if formname ~= "qb_lang" then return end
    local p_name = player:get_player_name()
    local arena = arena_lib.get_arena_by_player(p_name)
    local setting = 0
    if fields.english then
        setting = 1
        minetest.close_formspec(p_name, "qb_lang")
    end
    if fields.italian then
        setting = 2
        minetest.close_formspec(p_name, "qb_lang")
    end
    if fields.spanish then
        setting = 3
        minetest.close_formspec(p_name, "qb_lang")
    end
    if fields.french then
        setting = 4
        minetest.close_formspec(p_name, "qb_lang")
    end
    if fields.german then
        setting = 5
        minetest.close_formspec(p_name, "qb_lang")
    end
    if setting ~= 0 then

        local code = setting
        code = tostring(code)
        storage:set_string("lang_"..p_name,code)
        if arena then
            arena.players[p_name].lang = setting
        end
        minetest.chat_send_player(p_name,minetest.colorize("#7D7071",">> "..S("Language setting confirmed!")))
    end
end)

