-----------------------------------
-- Starlight Celebration
-----------------------------------
xi = xi or {}
xi.events = xi.events or {}
xi.events.starlightCelebration = xi.events.starlightCelebration or {}
xi.events.starlightCelebration.data = xi.events.starlightCelebration.data or {}
xi.events.starlightCelebration.entities = xi.events.starlightCelebration.entities or {}

local event = SeasonalEvent:new('StarlightCelebration')

xi.events.starlightCelebration.enabledCheck = function()
    local month = JstMonth()
    return month == 12
end

event:setEnableCheck(xi.events.starlightCelebration.enabledCheck)

local musicZones =
{
    xi.zone.UPPER_JEUNO,
    xi.zone.LOWER_JEUNO,
    xi.zone.PORT_JEUNO,
}

local starlightCelebrationMusic = 239
local grandDuchyOfJeunoMusic    = 110

xi.events.starlightCelebration.setMusic = function(musicId)
    for _, zoneId in pairs(musicZones) do
        local zone = GetZone(zoneId)
        if zone then
            -- TODO: Save the original music into a table

            -- Set the music of the zone, so that players zoning in will
            -- be sent it immediately
            zone:setBackgroundMusicDay(musicId)
            zone:setBackgroundMusicNight(musicId)

            -- Set the music for players already in the zone (this is wiped when
            -- they zone out)
            for _, player in pairs(zone:getPlayers()) do
                player:changeMusic(0, musicId)
                player:changeMusic(1, musicId)
            end
        end
    end
end

local verticalOffset = 1.75

xi.events.starlightCelebration.data =
{
    [xi.zone.SOUTHERN_SAN_DORIA] =
    {
        {  0, -277.910, -3.500,  78.470, '0x0000DD0400000000000000000000000000000000', },
        {  0, -268.574, -3.600,  82.015, '0x0000DD0400000000000000000000000000000000', },
        { 33, -259.108, -3.595,  77.425, '0x0000DD0400000000000000000000000000000000', },
        { 23, -279.120, -3.500, 115.110, '0x0000DD0400000000000000000000000000000000', },
        {  0, -268.681, -3.600, 117.314, '0x0000DD0400000000000000000000000000000000', },
        { 99, -199.327, -1.002,  45.192, '0x0000DD0400000000000000000000000000000000', },
        {  0, -166.937, -2.000,  55.714, '0x0000DD0400000000000000000000000000000000', },
        {  0, -150.206, -2.000,  53.012, '0x0000DD0400000000000000000000000000000000', },
        { 64,  -98.100, -2.074,  29.115, '0x0000DD0400000000000000000000000000000000', },
        { 99, -103.950,  2.000, -12.820, '0x0000DD0400000000000000000000000000000000', },
        {  0,  -80.605,  1.994,   7.681, '0x0000DD0400000000000000000000000000000000', },
        { 97,  -73.995,  2.000, -54.240, '0x0000DD0400000000000000000000000000000000', },
        {  0,  -26.506,  2.069, -99.088, '0x0000DD0400000000000000000000000000000000', },
        { 29,   21.210,  2.215, -93.820, '0x0000DD0400000000000000000000000000000000', },
        {  0,  -33.286,  1.988, -30.758, '0x0000DD0400000000000000000000000000000000', },
        {  0,  -24.230,  2.090,  -4.039, '0x0000DD0400000000000000000000000000000000', },
        { 61,  -12.050,  2.090,  -0.419, '0x0000DD0400000000000000000000000000000000', },
        {  0,  -15.542,  2.090,  13.174, '0x0000DD0400000000000000000000000000000000', },
        { 30,   15.009,  2.090,  13.172, '0x0000DD0400000000000000000000000000000000', },
        {  3,   13.030,  2.090,  -1.089, '0x0000DD0400000000000000000000000000000000', },
        { 25,   24.820,  2.090,  -4.169, '0x0000DD0400000000000000000000000000000000', },
        { 42,   34.944,  2.069, -30.738, '0x0000DD0400000000000000000000000000000000', },
        {  0,   77.994,  1.878,   5.711, '0x0000DD0400000000000000000000000000000000', },
        { 64,  103.950,  2.000, -14.320, '0x0000DD0400000000000000000000000000000000', },
        {  0,  103.665,  3.895,  18.656, '0x0000DD0400000000000000000000000000000000', },
        { 29,   94.510,  4.035,  70.780, '0x0000DD0400000000000000000000000000000000', },
        { 29,  127.710,  0.000,  70.280, '0x0000DD0400000000000000000000000000000000', },
        { 40,  152.600, -1.991, 157.099, '0x0000DD0400000000000000000000000000000000', },
        {  0,  173.410, -2.272, 201.179, '0x0000DD0400000000000000000000000000000000', },
        { 29,  127.710,  0.000,  70.280, '0x0000DD0400000000000000000000000000000000', },
        { 40,  152.600, -1.991, 157.099, '0x0000DD0400000000000000000000000000000000', },
    },

    [xi.zone.NORTHERN_SAN_DORIA] =
    {
        { 64,    0.000, -2.500, 29.000, '0x0000DB0400000000000000000000000000000000', },
        { 64,    0.000, -2.500, 40.000, '0x0000DB0400000000000000000000000000000000', },
        { 64,    0.000, -2.500, 51.000, '0x0000DB0400000000000000000000000000000000', },
        {  0, -142.900, -0.199, 79.700, '0x0000DC0400000000000000000000000000000000', },
        {  0, -114.601, -0.199, 73.632, '0x0000DC0400000000000000000000000000000000', },
        {  0, -117.600, -0.199, 56.650, '0x0000DC0400000000000000000000000000000000', },
        {  0,  -86.200, -0.199, 54.200, '0x0000DC0400000000000000000000000000000000', },
        {  0,  -53.000, -0.199, 68.000, '0x0000DC0400000000000000000000000000000000', },
        {  0,  -37.000, -0.199, 53.000, '0x0000DC0400000000000000000000000000000000', },
        {  0,  -34.100, -0.199, 24.000, '0x0000DC0400000000000000000000000000000000', },
        {  0,  -11.800, -0.199,  8.000, '0x0000DC0400000000000000000000000000000000', },
        {  0,  -11.000, -0.199, -8.000, '0x0000DC0400000000000000000000000000000000', },
        {  0,   11.000, -0.199, -8.000, '0x0000DC0400000000000000000000000000000000', },
        {  0,   13.300, -0.199,  7.500, '0x0000DC0400000000000000000000000000000000', },
        {  0,  -20.000, -0.199, 84.000, '0x0000DC0400000000000000000000000000000000', },
        {  0,   15.507, -0.199, 80.767, '0x0000DC0400000000000000000000000000000000', },
        {  0,   37.141, -0.199, 60.419, '0x0000DC0400000000000000000000000000000000', },
        {  0,   44.300, -0.199, 24.100, '0x0000DC0400000000000000000000000000000000', },
        {  0,   59.000, -0.199, 71.000, '0x0000DC0400000000000000000000000000000000', },
        {  0,   73.911, -0.199, 45.529, '0x0000DC0400000000000000000000000000000000', },
        {  0,   80.811, -0.199, 28.629, '0x0000DC0400000000000000000000000000000000', },
    },

    -- Note: These are slighly elevated, so a small vertical offset has been added
    [xi.zone.BASTOK_MINES] =
    {
        { 0, -20.979, -3.000 + verticalOffset, -61.813, '0x0000DA0400000000000000000000000000000000', },
        { 0, -12.124, -3.000 + verticalOffset, -64.650, '0x0000DA0400000000000000000000000000000000', },
        { 0,  -4.769, -3.000 + verticalOffset, -65.301, '0x0000DA0400000000000000000000000000000000', },
        { 0,   4.749, -3.000 + verticalOffset, -65.382, '0x0000DA0400000000000000000000000000000000', },
        { 0,  12.071, -3.000 + verticalOffset, -64.690, '0x0000DA0400000000000000000000000000000000', },
        { 0,  20.946, -3.000 + verticalOffset, -61.886, '0x0000DA0400000000000000000000000000000000', },
    },

    -- Note: These are slighly elevated, so a small vertical offset has been added
    [xi.zone.BASTOK_MARKETS] =
    {
        { 0, -343.894, -10.004 + verticalOffset, -158.219, '0x0000DA0400000000000000000000000000000000', },
        { 0, -333.456, -10.004 + verticalOffset, -147.542, '0x0000DA0400000000000000000000000000000000', },
        { 0, -327.166, -10.004 + verticalOffset, -141.216, '0x0000DA0400000000000000000000000000000000', },
        { 0, -316.577, -10.004 + verticalOffset, -130.499, '0x0000DA0400000000000000000000000000000000', },
        { 0, -310.195, -10.004 + verticalOffset, -124.245, '0x0000DA0400000000000000000000000000000000', },
        { 0, -320.630, -15.001 + verticalOffset,  -89.007, '0x0000DA0400000000000000000000000000000000', },
        { 0, -317.792, -15.001 + verticalOffset,  -80.152, '0x0000DA0400000000000000000000000000000000', },
        { 0, -317.142, -15.001 + verticalOffset,  -72.797, '0x0000DA0400000000000000000000000000000000', },
        { 0, -317.060, -15.001 + verticalOffset,  -63.279, '0x0000DA0400000000000000000000000000000000', },
        { 0, -317.752, -15.001 + verticalOffset,  -55.957, '0x0000DA0400000000000000000000000000000000', },
        { 0, -320.556, -15.001 + verticalOffset,  -47.081, '0x0000DA0400000000000000000000000000000000', },
        { 0, -224.074,  -2.000 + verticalOffset,   60.103, '0x0000DA0400000000000000000000000000000000', },
        { 0, -210.960,  -2.000 + verticalOffset,   59.878, '0x0000DA0400000000000000000000000000000000', },
        { 0, -200.678,  -6.000 + verticalOffset,  -78.527, '0x0000DA0400000000000000000000000000000000', },
        { 0, -163.338,  -4.000 + verticalOffset,  -84.524, '0x0000DA0400000000000000000000000000000000', },
        { 0, -155.791,  -4.000 + verticalOffset,  -88.348, '0x0000DA0400000000000000000000000000000000', },
        { 0, -147.569,  -4.000 + verticalOffset, -103.741, '0x0000DA0400000000000000000000000000000000', },
        { 0, -140.203,  -4.000 + verticalOffset, -107.486, '0x0000DA0400000000000000000000000000000000', },
        { 0,  -98.607,  -4.000 + verticalOffset, -102.536, '0x0000DA0400000000000000000000000000000000', },
        { 0,  -93.292,  -4.000 + verticalOffset, -102.557, '0x0000DA0400000000000000000000000000000000', },
        { 0,  -58.862,  -6.000 + verticalOffset,  -78.927, '0x0000DA0400000000000000000000000000000000', },
        { 0,  -50.816,  -6.000 + verticalOffset,  -87.027, '0x0000DA0400000000000000000000000000000000', },
    },

    -- Note: These are slighly elevated, so a small vertical offset has been added
    [xi.zone.PORT_BASTOK] =
    {
        { 0,  116.000,  8.510 + verticalOffset, -40.000, '0x0000D90400000000000000000000000000000000', },
        { 0, -170.000, -6.000 + verticalOffset, -16.078, '0x0000D90400000000000000000000000000000000', },
        { 0, -182.255, -6.000 + verticalOffset, -12.077, '0x0000DA0400000000000000000000000000000000', },
        { 0, -178.841, -6.000 + verticalOffset,  -7.457, '0x0000DA0400000000000000000000000000000000', },
        { 0, -171.058, -6.000 + verticalOffset,  -0.132, '0x0000DA0400000000000000000000000000000000', },
        { 0, -166.878, -6.000 + verticalOffset,  -4.330, '0x0000DA0400000000000000000000000000000000', },
        { 0, -162.578, -6.000 + verticalOffset,  -8.301, '0x0000DA0400000000000000000000000000000000', },
        { 0, -151.440, -6.000 + verticalOffset,  -2.889, '0x0000DA0400000000000000000000000000000000', },
        { 0, -145.322, -6.000 + verticalOffset,   3.497, '0x0000DA0400000000000000000000000000000000', },
        { 0, -159.493, -6.000 + verticalOffset, -29.817, '0x0000DA0400000000000000000000000000000000', },
        { 0, -130.833, -0.999 + verticalOffset, -41.166, '0x0000DA0400000000000000000000000000000000', },
        { 0, -122.667, -0.999 + verticalOffset, -33.000, '0x0000DA0400000000000000000000000000000000', },
        { 0,  -97.815, -2.100 + verticalOffset, -13.741, '0x0000DA0400000000000000000000000000000000', },
        { 0,  -97.815, -2.100 + verticalOffset,  -2.145, '0x0000DA0400000000000000000000000000000000', },
        { 0,  -84.600, -2.100 + verticalOffset,   6.669, '0x0000DA0400000000000000000000000000000000', },
        { 0,  -75.297, -2.100 + verticalOffset,   6.891, '0x0000DA0400000000000000000000000000000000', },
        { 0,  -57.900, -2.100 + verticalOffset,   8.916, '0x0000DA0400000000000000000000000000000000', },
        { 0,  -50.563, -2.100 + verticalOffset,   8.916, '0x0000DA0400000000000000000000000000000000', },
        { 0,  -27.870, -3.300 + verticalOffset,   3.520, '0x0000DA0400000000000000000000000000000000', },
        { 0,  -32.975, -3.300 + verticalOffset,  28.154, '0x0000DA0400000000000000000000000000000000', },
        { 0,  -22.845, -3.300 + verticalOffset,  27.941, '0x0000DA0400000000000000000000000000000000', },
        { 0,    1.973, -2.100 + verticalOffset,   9.159, '0x0000DA0400000000000000000000000000000000', },
        { 0,   17.973, -2.100 + verticalOffset,   9.159, '0x0000DA0400000000000000000000000000000000', },
        { 0,   40.550, -4.100 + verticalOffset,  25.986, '0x0000DA0400000000000000000000000000000000', },
        { 0,   41.467, -4.100 + verticalOffset,  29.382, '0x0000DA0400000000000000000000000000000000', },
        { 0,   43.265, -4.100 + verticalOffset,  32.067, '0x0000DA0400000000000000000000000000000000', },
        { 0,   39.040, -6.100 + verticalOffset,  54.006, '0x0000DA0400000000000000000000000000000000', },
    },

    [xi.zone.WINDURST_WATERS] =
    {
        { 255, -125.921, -1.194, -163.106, '0x0000E00400000000000000000000000000000000', },
        {   0,  -84.583, -1.178, -169.583, '0x0000E00400000000000000000000000000000000', },
        {   0,  -46.075, -1.000, -166.281, '0x0000E00400000000000000000000000000000000', },
        {  57,   -8.966, -4.000, -158.335, '0x0000E00400000000000000000000000000000000', },
        {   0,    4.539, -1.000,   37.044, '0x0000E00400000000000000000000000000000000', },
        { 188,  -35.741, -3.500,   58.036, '0x0000E00400000000000000000000000000000000', },
        { 176,  -43.700, -3.500,   57.953, '0x0000E00400000000000000000000000000000000', },
        { 243,  -61.945, -3.500,   74.746, '0x0000E00400000000000000000000000000000000', },
        {   0,  -85.583, -5.000,   89.591, '0x0000E00400000000000000000000000000000000', },
        { 111,  -18.078, -3.500,   74.383, '0x0000E00400000000000000000000000000000000', },
        {   0,    1.244, -5.000,   92.761, '0x0000E00400000000000000000000000000000000', },
        { 246,  -50.166, -5.000,  132.575, '0x0000E00400000000000000000000000000000000', },
        {  99,  -29.833, -5.000,  132.575, '0x0000E00400000000000000000000000000000000', },
        { 255,  116.985, -2.187,   62.020, '0x0000E00400000000000000000000000000000000', },
        {   8,  142.000,  0.000,  150.000, '0x0000E00400000000000000000000000000000000', },
        { 120,  154.000,  0.000,  150.000, '0x0000E00400000000000000000000000000000000', },
        {  50,  157.750, -2.500,  202.000, '0x0000E00400000000000000000000000000000000', },
        {  87,  134.000, -2.500,  222.000, '0x0000E00400000000000000000000000000000000', },
        { 199,  116.929, -2.500,  202.000, '0x0000E00400000000000000000000000000000000', },
        {   0,   98.761, -2.500,  205.072, '0x0000E00400000000000000000000000000000000', },
    },

    [xi.zone.PORT_WINDURST] =
    {
        {   0, -185.773, -4.000,  93.305, '0x0000E00400000000000000000000000000000000', },
        { 135, -130.000, -4.000, 134.000, '0x0000E00400000000000000000000000000000000', },
        {   0, -139.260, -5.500, 162.123, '0x0000E00400000000000000000000000000000000', },
        {  48, -129.664, -5.500, 173.436, '0x0000E00400000000000000000000000000000000', },
        {   0, -105.875, -5.125, 174.000, '0x0000E00400000000000000000000000000000000', },
        {  36,  -94.000, -4.000, 134.000, '0x0000E00400000000000000000000000000000000', },
        {  97,  -78.000, -5.000, 146.000, '0x0000E00400000000000000000000000000000000', },
        {   0,  -14.971, -4.000, 109.261, '0x0000E00400000000000000000000000000000000', },
        {   0,   11.126, -4.000, 106.207, '0x0000E00400000000000000000000000000000000', },
        {  88,   33.238, -5.000, 137.268, '0x0000E00400000000000000000000000000000000', },
        {   0,  147.005, -3.728, 130.679, '0x0000E00400000000000000000000000000000000', },
        {  28,  165.585, -5.000, 155.864, '0x0000E00400000000000000000000000000000000', },
        {  26,  177.722, -5.000, 159.157, '0x0000E00400000000000000000000000000000000', },
        {  77,  188.611, -4.784, 127.276, '0x0000E00400000000000000000000000000000000', },
        {   0,  201.785, -4.427, 140.265, '0x0000E00400000000000000000000000000000000', },
    },

    [xi.zone.WINDURST_WOODS] =
    {
        {  14, -16.000, -1.300,  -64.000, '0x0000DF0400000000000000000000000000000000', },
        {   0,   0.937, -3.883, -164.015, '0x0000E00400000000000000000000000000000000', },
        {   0, -58.062, -1.000, -110.219, '0x0000E00400000000000000000000000000000000', },
        {   0, -59.408,  1.000,  -55.905, '0x0000E00400000000000000000000000000000000', },
        {  45, -30.250,  1.098,  -38.000, '0x0000E00400000000000000000000000000000000', },
        {   0, -46.368,  0.531,  -20.585, '0x0000E00400000000000000000000000000000000', },
        {   0,  14.125, -2.500,    5.968, '0x0000E00400000000000000000000000000000000', },
        {  67,  27.170,  2.000,  -33.669, '0x0000E00400000000000000000000000000000000', },
        { 162,  26.674,  1.834,  -45.900, '0x0000E00400000000000000000000000000000000', },
        {   0,  53.110, -2.049, -102.427, '0x0000E00400000000000000000000000000000000', },
        { 177,  98.243, -5.000,  -60.322, '0x0000E00400000000000000000000000000000000', },
        {  44, 117.251, -5.000,  -99.301, '0x0000E00400000000000000000000000000000000', },
        {   0, 107.025, -5.000, -125.327, '0x0000E00400000000000000000000000000000000', },
    },
}

xi.events.starlightCelebration.generateEntities = function()
    for zoneId, data in pairs(xi.events.starlightCelebration.data) do
        local zone = GetZone(zoneId)
        if zone then
            for _, entry in pairs(data) do
                local rot  = entry[1]
                local x    = entry[2]
                local y    = entry[3]
                local z    = entry[4]
                local look = entry[5]

                local npc = zone:insertDynamicEntity({
                    objtype = xi.objType.NPC,
                    name = '     ',
                    look = look,
                    x = x,
                    y = y,
                    z = z,
                    rotation = rot,
                    widescan = 0,
                    entityFlags = 2075,
                    namevis = 64,
                    releaseIdOnDisappear = true,
                })

                if npc then
                    table.insert(xi.events.starlightCelebration.entities, npc:getID())
                end
            end
        end
    end
end

xi.events.starlightCelebration.showEntities = function(enabled)
    if enabled and #xi.events.starlightCelebration.entities == 0 then
        xi.events.starlightCelebration.generateEntities()
    end

    for _, entityID in pairs(xi.events.starlightCelebration.entities) do
        local entity = GetNPCByID(entityID)
        if entity then
            if enabled then
                entity:setStatus(xi.status.NORMAL)
            else
                -- TODO: Why doesn't DISAPPEAR work here?
                -- entity:setStatus(xi.status.DISAPPEAR)

                entity:setStatus(xi.status.INVISIBLE)
            end
        end
    end

    if not enabled then
        xi.events.starlightCelebration.entities = {}
    end
end

event:setStartFunction(function()
    xi.events.starlightCelebration.setMusic(starlightCelebrationMusic)
    xi.events.starlightCelebration.showEntities(true)
end)

event:setEndFunction(function()
    xi.events.starlightCelebration.setMusic(grandDuchyOfJeunoMusic)
    xi.events.starlightCelebration.showEntities(false)
end)

return event
