--[[
    Soundtrack addon for World of Warcraft

    Zone events functions.
    Functions that manage zone change events.
]]


Soundtrack.ZoneEvents = 
{
}

-- Finds the continent name, based on the zone name
local function FindContinentByZone(zoneName)
	if zoneName == nil then return nil end
	
	local inInstance, instanceType = IsInInstance();
	if inInstance then
		if instanceType == "arena" or instanceType == "pvp" then
			return SOUNDTRACK_PVP, nil;
		end
		if instanceType == "party" or instanceType == "raid" then
			return SOUNDTRACK_INSTANCES, nil;
		end
	end
	
	-- Find the current continent
	local areaid = GetCurrentMapAreaID()				-- Save map (in case it is open)
	SetMapToCurrentZone()
	local continentValue = GetCurrentMapContinent() * 2	-- Grab continent and zone, WoD Fix: "* 2"
	local zoneValue = GetCurrentMapAreaID()
	SetMapByID(areaid)									-- Set map back
	
	local continentNames = {GetMapContinents()}			-- Get continents
	local zoneNames = {GetMapZones(continentValue)}		-- Get zones
	
	local continent = continentNames[continentValue]
	local zone = nil
	for i=1, #zoneNames, 2 do
		if zoneNames[i] == zoneValue then
			zone = zoneNames[zoneValue]
		end
	end
	
	if continent == nil then 
		return SOUNDTRACK_UNKNOWN, zone
	end

	return continent, zone
   
	--return "Uncategorized";  -- Uncategorized stuff, usually is outside part of an instance
end

-- After migration, zone events have no priorities set. We only
-- discover them as we figure out which parent zones exist
local function AssignPriority(tableName, eventName, priority)
    local event = Soundtrack.GetEventByName(tableName, eventName)
    if event then
        event.priority = priority
    end

end


function Soundtrack_ZoneEvents_AddZones()	
	local zoneText = GetRealZoneText();
	if zoneText == nil then return end
	
    local continentText, zoneName = FindContinentByZone(zoneText); 
    local zoneSubText = GetSubZoneText();
    local minimapZoneText = GetMinimapZoneText();
	
	if zoneName ~= nil and zoneName ~= zoneText then
		if zoneSubText ~= nil and zoneSubText ~= "" then
			minimapZoneText = zoneSubText
		end
		if zoneText ~= nil and zoneText ~= "" then
			zoneSubText = zoneText
		end
		zoneText = zoneName
	end
	
    -- Construct full zone path
    
    local zoneText1, zoneText2, zoneText3, zoneText4;
    
    local zonePath;
        
    if not Soundtrack.IsNullOrEmpty(continentText) then
        zoneText1 = continentText;
		Soundtrack.TraceZones("AddZone Continent: " .. zoneText1);
        zonePath = continentText;
    end
        
    if not Soundtrack.IsNullOrEmpty(zoneText) then
        zoneText2 = continentText .. "/" .. zoneText;
		Soundtrack.TraceZones("AddZone ZoneText: " .. zoneText2);
        zonePath = zoneText2;
        Soundtrack.Events.RenameEvent(ST_ZONE, zoneText, zoneText2);
    end
    

    if zoneText ~= zoneSubText and not Soundtrack.IsNullOrEmpty(zoneSubText) then
        zoneText3 = zonePath .. "/" .. zoneSubText;
		Soundtrack.TraceZones("AddZone SubZoneText: " .. zoneText3);
        zonePath = zoneText3;
        Soundtrack.Events.RenameEvent(ST_ZONE, zoneSubText, zoneText3);
    end
    
    if zoneText ~= minimapZoneText and zoneSubText ~= minimapZoneText and not Soundtrack.IsNullOrEmpty(minimapZoneText) then
        zoneText4 = zonePath .. "/" .. minimapZoneText;
		Soundtrack.TraceZones("AddZone MinimapZoneText: " .. zoneText4);
        zonePath = zoneText4;
        Soundtrack.Events.RenameEvent(ST_ZONE, minimapZoneText, zoneText4);
    end
	
    
    Soundtrack.TraceZones("AddZone Zone: " .. zonePath);
	
    if zoneText4 then
		local eventTable = Soundtrack.Events.GetTable(ST_ZONE)
		if eventTable[zoneText4] == nil then
			Soundtrack.AddEvent(ST_ZONE, zoneText4, ST_MINIMAP_LVL, true)
        end
		AssignPriority(ST_ZONE, zoneText4, ST_MINIMAP_LVL)
    end
    
    if zoneText3 then
		local eventTable = Soundtrack.Events.GetTable(ST_ZONE)
		if eventTable[zoneText3] == nil then
			Soundtrack.AddEvent(ST_ZONE, zoneText3, ST_SUBZONE_LVL, true)
		end
		AssignPriority(ST_ZONE, zoneText3, ST_SUBZONE_LVL)
    end
    
    if zoneText2 then
		local eventTable = Soundtrack.Events.GetTable(ST_ZONE)
		if eventTable[zoneText2] == nil then
			Soundtrack.AddEvent(ST_ZONE, zoneText2, ST_ZONE_LVL, true)
        end
		AssignPriority(ST_ZONE, zoneText2, ST_ZONE_LVL)
    end
    
    if zoneText1 then
		local eventTable = Soundtrack.Events.GetTable(ST_ZONE)
		if eventTable[zoneText1] == nil then
			Soundtrack.AddEvent(ST_ZONE, zoneText1, ST_CONTINENT_LVL, true)
		end
		AssignPriority(ST_ZONE, zoneText1, ST_CONTINENT_LVL)
    end
   
end

local function OnZoneChanged()
    
    local zoneText = GetRealZoneText();
	if zoneText == nil then return end
	
    local continentText, zoneName = FindContinentByZone(zoneText); 
    local zoneSubText = GetSubZoneText();
    local minimapZoneText = GetMinimapZoneText();
	
	if zoneName ~= nil and zoneName ~= zoneText then
		if zoneSubText ~= nil and zoneSubText ~= "" then
			minimapZoneText = zoneSubText
		end
		if zoneText ~= nil and zoneText ~= "" then
			zoneSubText = zoneText
		end
		zoneText = zoneName
	end
    
	--[[
    Soundtrack.TraceZones("continentText: " .. continentText);
    Soundtrack.TraceZones("zoneText: " .. zoneText);
    Soundtrack.TraceZones("zoneSubText: " .. zoneSubText);
    Soundtrack.TraceZones("minimapZoneText:" .. minimapZoneText);
    --]]
	
    -- Construct full zone path
    
    local zoneText1, zoneText2, zoneText3, zoneText4;
    
    local zonePath;
        
    if not Soundtrack.IsNullOrEmpty(continentText) then
        zoneText1 = continentText;
		Soundtrack.TraceZones("OnZoneChanged Continent: " .. zoneText1);
        zonePath = continentText;
    end
        
    if not Soundtrack.IsNullOrEmpty(zoneText) then
        zoneText2 = continentText .. "/" .. zoneText;
		Soundtrack.TraceZones("OnZoneChanged ZoneText: " .. zoneText2);
        zonePath = zoneText2;
        Soundtrack.Events.RenameEvent(ST_ZONE, zoneText, zoneText2);
    end
    

    if zoneText ~= zoneSubText and not Soundtrack.IsNullOrEmpty(zoneSubText) then
        zoneText3 = zonePath .. "/" .. zoneSubText;
		Soundtrack.TraceZones("OnZoneChanged SubZoneText: " .. zoneText3);
        zonePath = zoneText3;
        Soundtrack.Events.RenameEvent(ST_ZONE, zoneSubText, zoneText3);
    end
    
    if zoneText ~= minimapZoneText and zoneSubText ~= minimapZoneText and not Soundtrack.IsNullOrEmpty(minimapZoneText) then
        zoneText4 = zonePath .. "/" .. minimapZoneText;
		Soundtrack.TraceZones("OnZoneChanged MinimapZoneText: " .. zoneText4);
        zonePath = zoneText4;
        Soundtrack.Events.RenameEvent(ST_ZONE, minimapZoneText, zoneText4);
    end
	
    
    Soundtrack.TraceZones("Zone: " .. zonePath);
	
    if zoneText4 then
        if Soundtrack.Settings.AutoAddZones then
			local eventTable = Soundtrack.Events.GetTable(ST_ZONE)
			if eventTable[zoneText4] == nil then
				Soundtrack.AddEvent(ST_ZONE, zoneText4, ST_MINIMAP_LVL, true)
			end
        end
		AssignPriority(ST_ZONE, zoneText4, ST_MINIMAP_LVL)
		Soundtrack.PlayEvent(ST_ZONE, zoneText4, false);
    else
        Soundtrack.StopEventAtLevel(ST_MINIMAP_LVL);
    end
    
    if zoneText3 then
        if Soundtrack.Settings.AutoAddZones then
			local eventTable = Soundtrack.Events.GetTable(ST_ZONE)
			if eventTable[zoneText3] == nil then
				Soundtrack.AddEvent(ST_ZONE, zoneText3, ST_SUBZONE_LVL, true)
			end
        end
		AssignPriority(ST_ZONE, zoneText3, ST_SUBZONE_LVL)
		Soundtrack.PlayEvent(ST_ZONE, zoneText3, false);
    else
        Soundtrack.StopEventAtLevel(ST_SUBZONE_LVL);
    end
    
    if zoneText2 then
        if Soundtrack.Settings.AutoAddZones then
			local eventTable = Soundtrack.Events.GetTable(ST_ZONE)
			if eventTable[zoneText2] == nil then
				Soundtrack.AddEvent(ST_ZONE, zoneText2, ST_ZONE_LVL, true)
			end
        end
		AssignPriority(ST_ZONE, zoneText2, ST_ZONE_LVL)
		Soundtrack.PlayEvent(ST_ZONE, zoneText2, false);
    else        
        Soundtrack.StopEventAtLevel(ST_ZONE_LVL);
    end
    
    if zoneText1 then
        if Soundtrack.Settings.AutoAddZones then
			local eventTable = Soundtrack.Events.GetTable(ST_ZONE)
			if eventTable[zoneText1] == nil then
				Soundtrack.AddEvent(ST_ZONE, zoneText1, ST_CONTINENT_LVL, true)
			end
        end
		AssignPriority(ST_ZONE, zoneText1, ST_CONTINENT_LVL)
		Soundtrack.PlayEvent(ST_ZONE, zoneText1, false);
    else        
        Soundtrack.StopEventAtLevel(ST_CONTINENT_LVL);
    end
   
end

function Soundtrack.ZoneEvents.OnLoad(self)
    self:RegisterEvent("ZONE_CHANGED_NEW_AREA")
    self:RegisterEvent("ZONE_CHANGED")
    self:RegisterEvent("ZONE_CHANGED_INDOORS")
    self:RegisterEvent("VARIABLES_LOADED")
end
    

local delayTime = 0
local updateTime = 1
local zoneType = nil
	
function Soundtrack.ZoneEvents.OnUpdate(self)
	
	local currentTime = GetTime()
	
	if currentTime >= delayTime then
		delayTime = currentTime + updateTime
		
		local inInstance, newZoneType = IsInInstance();
		if not newZoneType == zoneType then
			zoneType = newZoneType
			OnZoneChanged()
		end
    
	end
end	

function Soundtrack.ZoneEvents.OnEvent(self, event, ...)
    if not Soundtrack.Settings.EnableZoneMusic then
        return
    end
	
	if event == "VARIABLES_LOADED" then
		Soundtrack.ZoneEvents.Initialize()
    end
	
	Soundtrack.TraceZones(event);
	
    if event == "ZONE_CHANGED" or 
       event == "ZONE_CHANGED_INDOORS" or
	   event == "ZONE_CHANGED_NEW_AREA" or
       event == "VARIABLES_LOADED" then
		Soundtrack.TraceZones("Event: "..event);
        OnZoneChanged()
    end
end    

function Soundtrack.ZoneEvents.Initialize()
    -- Add default zones
	
	-- Add Instances and PVP 'continents'
    Soundtrack.AddEvent(ST_ZONE, SOUNDTRACK_INSTANCES, ST_CONTINENT_LVL, true);
	Soundtrack.AddEvent(ST_ZONE, SOUNDTRACK_PVP, ST_CONTINENT_LVL, true);
	
	-- Add continents and zones
	local continentNames = { GetMapContinents() }
	for i = 1, #continentNames, 2 do
		-- Add continent
		local cName = continentNames[i+1];
		Soundtrack.AddEvent(ST_ZONE, cName, ST_CONTINENT_LVL, true);
		-- Add zones in continent
		local continentNumber = (i+1)/2		-- WoD fix
		local zoneNames = { GetMapZones(continentNumber) };
		for j = 2, #zoneNames, 2 do
			local zName = cName .. "/" .. zoneNames[j];
			Soundtrack.AddEvent(ST_ZONE, zName, ST_ZONE_LVL, true);
		end
	end
end