
DynamicWeather = {};
DynamicWeather.fully_loaded = false;
DynamicWeather.default_options = {

	-- main frame position
	frameRef = "CENTER",
	frameX = 0,
	frameY = 0,
	hide = true,

	-- sizing
	frameW = 200,
	frameH = 200,
};


if(DynamicWeather_States == nil) then
	DynamicWeather_States = {}
end

if(DynamicWeather_WeatherStates == nil) then
	DynamicWeather_WeatherStates = {}
end

if(DynamicWeather_Stages == nil) then
	DynamicWeather_Stages = {}
	DynamicWeather_Forecasts = {}
end
DynamicWeather_ZoneBiomes = {}

RPWrandom_generator = RPWrandom.new()

--Eastern Kingoms
DynamicWeather_ZoneBiomes["Tiragarde Sound"] = {20.0, "heavy"};
DynamicWeather_ZoneBiomes["Ghostlands"] = {20.0, "heavy"};
DynamicWeather_ZoneBiomes["Hillsbrad Foothills"] = {15.0, "temperate"};
DynamicWeather_ZoneBiomes["Azuremyst Isle"] = {15.0, "temperate"};
DynamicWeather_ZoneBiomes["Bloodmyst Isle"] = {15.0, "temperate"};
--DynamicWeather_ZoneBiomes["Arathi Highlands"] = {30.0, "heavy"};
DynamicWeather_ZoneBiomes["Tol Barad"] = {30.0, "heavy"};
DynamicWeather_ZoneBiomes["Townlong Steppes"] = {30.0, "heavy"};
DynamicWeather_ZoneBiomes["Silverpine Forest"] = {10.0, "heavy"};
DynamicWeather_ZoneBiomes["Tirisfal Glades"] = {30.0, "heavy"};
DynamicWeather_ZoneBiomes["Ashran"] = {25.0, "temperate"};
DynamicWeather_ZoneBiomes["Dalaran"] = {25.0, "temperate"};
DynamicWeather_ZoneBiomes["Teldrassil"] = {15.0, "temperate"};
DynamicWeather_ZoneBiomes["Eversong Woods"] = {5.0, "temperate"};
DynamicWeather_ZoneBiomes["Silvermoon City"] = {5.0, "temperate"};
DynamicWeather_ZoneBiomes["Dread Wastes"] = {15.0, "temperate"};
DynamicWeather_ZoneBiomes["Emerald Dreamway"] = {15.0, "tropical"};
DynamicWeather_ZoneBiomes["The Dreamgrove"] = {15.0, "tropical"};
DynamicWeather_ZoneBiomes["The Jade Forest"] = {15.0, "tropical"};
DynamicWeather_ZoneBiomes["The Wandering Isle"] = {15.0, "tropical"};
DynamicWeather_ZoneBiomes["Gilneas"] = {65.0, "heavy"};
DynamicWeather_ZoneBiomes["Gorgrond"] = {35.0, "tropical"};
DynamicWeather_ZoneBiomes["Tanaan Jungle"] = {55.0, "tropical"};
DynamicWeather_ZoneBiomes["Isle of Giants"] = {35.0, "tropical"};
DynamicWeather_ZoneBiomes["Nagrand"] = {18.0, "savannah"};
DynamicWeather_ZoneBiomes["Nagrand (Outland)"] = {12.0, "savannah"};
DynamicWeather_ZoneBiomes["Redridge Mountains"] = {25.0, "temperate"};
DynamicWeather_ZoneBiomes["Elwynn Forest"] = {25.0, "temperate"};
DynamicWeather_ZoneBiomes["Terokkar Forest"] = {40.0, "temperate"};
DynamicWeather_ZoneBiomes["Talador"] = {30.0, "temperate"};
DynamicWeather_ZoneBiomes["Suramar"] = {15.0, "temperate"};
DynamicWeather_ZoneBiomes["Shadowmoon Valley"] = {35.0, "temperate"};
DynamicWeather_ZoneBiomes["Broken Shore"] = {35.0, "heavy"};
DynamicWeather_ZoneBiomes["Aszuna"] = {15.0, "temperate"};
DynamicWeather_ZoneBiomes["Val'sharah"] = {35.0, "heavy"};
DynamicWeather_ZoneBiomes["Duskwood"] = {35.0, "heavy"};
DynamicWeather_ZoneBiomes["Drustvar"] = {35.0, "heavy"};
DynamicWeather_ZoneBiomes["Stormheim"] = {45.0, "tropical"};
DynamicWeather_ZoneBiomes["Krarasang Wilds"] = {15.0, "tropical"};
DynamicWeather_ZoneBiomes["Mount Hyjal"] = {15.0, "temperate"};
DynamicWeather_ZoneBiomes["Darkshore"] = {25.0, "temperate"};
DynamicWeather_ZoneBiomes["Feralas"] = {12.0, "temperate"};
DynamicWeather_ZoneBiomes["Krokuun"] = {30.0, "legionworld"};
DynamicWeather_ZoneBiomes["Antoran Wastes"] = {50.0, "legionworld"};
DynamicWeather_ZoneBiomes["Mac'aree"] = {10.0, "mildlegionworld"};
DynamicWeather_ZoneBiomes["Shadowmoon Valley (Outland)"] = {18.0, "legionworld"};
DynamicWeather_ZoneBiomes["Spires of Arak"] = {17.0, "temperate"};
DynamicWeather_ZoneBiomes["Mulgore"] = {12.0, "temperate"};
DynamicWeather_ZoneBiomes["Thunder Bluff"] = {13.0, "temperate"};
DynamicWeather_ZoneBiomes["Frostfire Ridge"] = {30.0, "frigid"};
DynamicWeather_ZoneBiomes["Frostwall"] = {25.0, "cold"};
DynamicWeather_ZoneBiomes["Winterspring"] = {18.0, "frigid"};
DynamicWeather_ZoneBiomes["Dun Morogh"] = {18.0, "cold"};
DynamicWeather_ZoneBiomes["Coldridge Valley"] = {18.0, "cold"};
DynamicWeather_ZoneBiomes["Borean Tundra"] = {25.0, "frigid"};
DynamicWeather_ZoneBiomes["Dragonblight"] = {45.0, "frigid"};
DynamicWeather_ZoneBiomes["Icecrown"] = {37.0, "frigid"};
DynamicWeather_ZoneBiomes["Hrothgar's Landing"] = {18.0, "frigid"};
DynamicWeather_ZoneBiomes["Storm Peaks"] = {22.0, "frigid"};
DynamicWeather_ZoneBiomes["Wintergrasp"] = {22.0, "frigid"};
DynamicWeather_ZoneBiomes["Invasion Point: Val"] = {100.0, "frigid"};
DynamicWeather_ZoneBiomes["Durotar"] = {39.0, "desert"};
DynamicWeather_ZoneBiomes["Vol'dun"] = {44.0, "hotdesert"};
DynamicWeather_ZoneBiomes["Uldum"] = {28.0, "hotdesert"};
DynamicWeather_ZoneBiomes["Northern Barrens"] = {25.0, "savannah"};
DynamicWeather_ZoneBiomes["Southern Barrens"] = {25.0, "savannah"};
DynamicWeather_ZoneBiomes["Stranglethorn Vale"] = {28.0, "tropical"};
DynamicWeather_ZoneBiomes["Northern Stranglethorn"] = {28.0, "tropical"};
DynamicWeather_ZoneBiomes["The Cape of Stranglethorn"] = {28.0, "tropical"};
DynamicWeather_ZoneBiomes["Azshara"] = {18.0, "temperate"};
DynamicWeather_ZoneBiomes["Felwood"] = {18.0, "heavy"};
DynamicWeather_ZoneBiomes["Stonetalon Mountains"] = {18.0, "savannah"};
DynamicWeather_ZoneBiomes["Desolace"] = {15.0, "desert"};
DynamicWeather_ZoneBiomes["Un'goro Crater"] = {47.0, "tropical"};
DynamicWeather_ZoneBiomes["Sholazar Basin"] = {25.0, "tropical"};
DynamicWeather_ZoneBiomes["Tanaris"] = {40.0, "hotdesert"};
DynamicWeather_ZoneBiomes["Dustwallow Marsh"] = {20.0, "heavy"};
DynamicWeather_ZoneBiomes["Grizzly Hills"] = {15.0, "temperate"};
DynamicWeather_ZoneBiomes["Howling Fjord"] = {15.0, "temperate"};
DynamicWeather_ZoneBiomes["Nazmir"] = {30.0, "tropical"};
DynamicWeather_ZoneBiomes["Wetlands"] = {50.0, "heavy"};
DynamicWeather_ZoneBiomes["Tiragarde Sound"] = {20.0, "heavy"};
--DynamicWeather_ZoneBiomes["Stormsong Valley"] = {50.0, "heavy"};

DynamicWeather_Parents = {}
DynamicWeather_Parents["Thunder Bluff"] = "Mulgore"
DynamicWeather_Parents["Stormwind City"] = "Elwynn Forest"
DynamicWeather_Parents["Silvermoon City"] = "Eversong Woods"
DynamicWeather_Parents["Boralus"] = "Tiragarde Sound"
DynamicWeather_Parents["Tradewinds Market"] = "Tiragarde Sound"
DynamicWeather_Parents["Warspear"] = "Ashran"
DynamicWeather_Parents["Stormshield"] = "Ashran"
DynamicWeather_Parents["Darnassus"] = "Teldrassil"
DynamicWeather_Parents["Ruins of Gilneas"] = "Gilneas"
DynamicWeather_Parents["Lunarfall"] = "Shadowmoon Valley"
DynamicWeather_Parents["Frostwall"] = "Frostfire Ridge"
DynamicWeather_Parents["Tol Barad Peninsula"] = "Tol Barad"
DynamicWeather_Parents["Orgrimmar"] = "Durotar"
DynamicWeather_Parents["Booty Bay"] = "The Cape of Stranglethorn"
DynamicWeather_Parents["Shattrath City"] = "Terokkar Forest"
DynamicWeather_Parents["Theramore"] = "Dustwallow Marsh"

DynamicWeather_BiomeTypes = {["temperate"]={[1]="overcast", [2]="lightrain", [3]="heavyrain", [4]="thunderstorm", [5]="highwind"}, ["heavy"]={[1]="lightrain", [2]="heavyrain", [3]="thunderstorm", [4]="tropicalstorm", [5]="highwind"}, ["tropical"]={[1]="lightrain", [2]="heavyrain", [3]="thunderstorm", [4]="tropicalstorm", [5]="monsoon"}, ["legionworld"]={[1]="lightfelstorm", [2]="moderatefelstorm", [3]="chaoticfelstorm", [4]="apocalypticfelstorm"}, ["mildlegionworld"]={[1]="lightfelstorm", [2]="moderatefelstorm"}, ["frigid"]={[1]="highwind", [2]="snowstorm"}, ["cold"]={[1]="highwind"}, ["hotdesert"]={[1]="heatwave", [2]="sandstorm"}, ["desert"]={[1]="heatwave", [2]="overcast"}, ["savannah"]={[1]="heatwave", [2]="lightrain"}}

DynamicWeather_StateMessages = {["overcast"]="Dark clouds roll in and the sky grows overcast.", ["lightrain"]="It begins to rain lightly.", ["heavyrain"]="It begins to pour heavily, and you are quickly soaked.", ["thunderstorm"]="The sky rumbles with thunder.", ["tropicalstorm"]="The wind howls and nearly knocks you over, thunder begins to boom every few seconds, and the heavy rain pelts you like falling rocks.  A tropical storm has arrived.", ["monsoon"]="A horrible monsoon ravages the region, and you can barely remain standing.  The skies boom with thunder and the rain is nearly falling horizontally in the wind.", ["lightfelstorm"]="The strong smell of sulphur fills the air.  A felstorm has come.", ["moderatefelstorm"]="The air is filled with an energy you can feel as your hair stands on end and the smell of raw sulphur fills your nostrils.", ["chaoticfelstorm"]="You hear a loud rumbling as the ground quakes far in the distance, and bolts of fel lightning arc through the sky.  The wind picks up and swirls violently, and you feel as if you are being tossed in circles by it.", ["apocalypticfelstorm"]="The ground shakes violently, and you are sent stumbling for a moment.  The wind is making it nearly impossible to stand.  The ground underneath your feet begins to angle slightly with a loud rumbling as the landmass sinks slightly in its place before settling.", ["highwind"]="The bitter wind picks up rapidly, chilling your entire body.", ["snowstorm"]="The wind picks up, and with it comes an unceasing torrent of snow and ice.  A blizzard has arrived.", ["heatwave"]="The air is thick with the brutal heat of the sun.  A heat wave is here.", ["sandstorm"]="Dark clouds boom in the distance.  In mere minutes they swallow you, as a horrific sandstorm ravages the region."}
DynamicWeather_StateNames = {["clear"]="Average",["overcast"]="Overcast", ["lightrain"]="Light Rain", ["heavyrain"]="Heavy Rain", ["thunderstorm"]="Thundering", ["tropicalstorm"]="Tropical Storm", ["monsoon"]="Hurricane", ["lightfelstorm"]="Mild Felstorm", ["moderatefelstorm"]="Felstorm", ["chaoticfelstorm"]="Chaotic Felstorm", ["apocalypticfelstorm"]="Apocalyptic Felstorm", ["highwind"]="Strong Winds", ["snowstorm"]="Blizzard", ["heatwave"]="Heat Wave", ["sandstorm"]="Sandstorm"}

DynamicWeather_Soundkits = {["overcast"]=18414, ["lightrain"]=111995, ["heavyrain"]=112759, ["thunderstorm"]=112000, ["tropicalstorm"]=53302, ["monsoon"]=107435, ["lightfelstorm"]=112000, ["moderatefelstorm"]=53682, ["chaoticfelstorm"]=56602, ["apocalypticfelstorm"]=56602, ["highwind"]=39821, ["snowstorm"]=39789, ["heatwave"]=40351, ["sandstorm"]=24416}
DynamicWeather_Soundkits_Extra = {["thunderstorm"]=111998, ["tropicalstorm"]=111998, ["monsoon"]=111998, ["chaoticfelstorm"]=112000, ["apocalypticfelstorm"]=9984, ["snowstorm"]=39822}
DynamicWeather_IsRainingTriggers = {["lightrain"]=0.1, ["heavyrain"]=0.145, ["thunderstorm"]=0.18, ["tropicalstorm"]=0.28, ["monsoon"]=0.35}
DynamicWeather_IsSnowingTriggers = {["highwind"]=0.145, ["snowstorm"]=0.255, ["sandstorm"]=0.05}




DynamicWeather_Raindroplets = {}

-- Globals Section
--DynamicWeather_UpdateInterval = 108000.0; -- How often the OnUpdate code will run (in seconds)
DynamicWeather_UpdateInterval = 60.0; -- How often the OnUpdate code will run (in seconds)
--DynamicWeather_UpdateInterval = 10.0; -- How often the OnUpdate code will run (in seconds)
DynamicWeather_DuskHour = 19
DynamicWeather_NightfallHour = 21
DynamicWeather_DawnHour = 7
DynamicWeather_DayHour = 9
DynamicWeather_IsNight = false;

weatherSound, weatherSoundHandle = nil
weatherSound2, weatherSoundHandle2 = nil


-- based on http://www.ethernut.de/api/gmtime_8c_source.html

local floor=math.floor

local DSEC=24*60*60 -- secs in a day
local YSEC=365*DSEC -- secs in a year
local LSEC=YSEC+DSEC    -- secs in a leap year
local FSEC=4*YSEC+DSEC  -- secs in a 4-year interval
local BASE_DOW=4    -- 1970-01-01 was a Thursday
local BASE_YEAR=1970    -- 1970 is the base year

local _days={
    -1, 30, 58, 89, 119, 150, 180, 211, 242, 272, 303, 333, 364
}
local _lpdays={}
for i=1,2  do _lpdays[i]=_days[i]   end
for i=3,13 do _lpdays[i]=_days[i]+1 end

function CalculateForecast(t)
    local y,j,m,d,w,h,n,s
    local mdays=_days
    s=t
    -- First calculate the number of four-year-interval, so calculation
    -- of leap year will be simple. Btw, because 2000 IS a leap year and
    -- 2100 is out of range, this formula is so simple.
    y=floor(s/FSEC)
    s=s-y*FSEC
    y=y*4+BASE_YEAR         -- 1970, 1974, 1978, ...
    if s>=YSEC then
        y=y+1           -- 1971, 1975, 1979,...
        s=s-YSEC
        if s>=YSEC then
            y=y+1       -- 1972, 1976, 1980,... (leap years!)
            s=s-YSEC
            if s>=LSEC then
                y=y+1   -- 1971, 1975, 1979,...
                s=s-LSEC
            else        -- leap year
                mdays=_lpdays
            end
        end
    end
    j=floor(s/DSEC)
    s=s-j*DSEC
    local m=1
    while mdays[m]<j do m=m+1 end
    m=m-1
    local d=j-mdays[m]
    -- Calculate day of week. Sunday is 0
    w=(floor(t/DSEC)+BASE_DOW)%7
    -- Calculate the time of day from the remaining seconds
    h=floor(s/3600)
    s=s-h*3600
    n=floor(s/60)
    s=s-n*60
    --print("y","j","m","d","w","h","n","s")
    --local seed = ((m * 12) + (d * 30) + y + (h * 24))
	local seed = ((m * 12) + (d * 30) + y + (((h + 1) * 24)))
	
	--print(tostring(seed))
	return seed
end

function CalculateServerTimeSeed(t)
    local y,j,m,d,w,h,n,s
    local mdays=_days
    s=t
    -- First calculate the number of four-year-interval, so calculation
    -- of leap year will be simple. Btw, because 2000 IS a leap year and
    -- 2100 is out of range, this formula is so simple.
    y=floor(s/FSEC)
    s=s-y*FSEC
    y=y*4+BASE_YEAR         -- 1970, 1974, 1978, ...
    if s>=YSEC then
        y=y+1           -- 1971, 1975, 1979,...
        s=s-YSEC
        if s>=YSEC then
            y=y+1       -- 1972, 1976, 1980,... (leap years!)
            s=s-YSEC
            if s>=LSEC then
                y=y+1   -- 1971, 1975, 1979,...
                s=s-LSEC
            else        -- leap year
                mdays=_lpdays
            end
        end
    end
    j=floor(s/DSEC)
    s=s-j*DSEC
    local m=1
    while mdays[m]<j do m=m+1 end
    m=m-1
    local d=j-mdays[m]
    -- Calculate day of week. Sunday is 0
    w=(floor(t/DSEC)+BASE_DOW)%7
    -- Calculate the time of day from the remaining seconds
    h=floor(s/3600)
    s=s-h*3600
    n=floor(s/60)
    s=s-n*60
    --print("y","j","m","d","w","h","n","s")
    --local seed = ((m * 12) + (d * 30) + y + (h * 24))
    local seed = ((m * 12) + (d * 30) + y + (h * 24))
	--print(tostring(seed))
	return seed
end




function DynamicWeather.GetWeatherString(weatherState)
	return DynamicWeather_StateMessages[weatherState]
end


function DynamicWeather.PostProcessing()
	zoneIndex = tostring(GetRealZoneText())
	if(DynamicWeather_WeatherStates[zoneIndex] ~= nil) then
		weatherState = DynamicWeather_WeatherStates[zoneIndex]
	else
		
		weatherState = "clear"
		
	end
	
	
	if(DynamicWeather_Soundkits[weatherState] ~= nil) then
		if(weatherState ~= oldWeatherState) then
			if(weatherSoundHandle ~= nil) then
				StopSound(weatherSoundHandle, 2000.0)
			end
			weatherSound = nil
			weatherSoundHandle = nil
			
		end
		if(weatherSoundHandle == nil and IsIndoors() ~= true) then
			
			weatherSound, weatherSoundHandle = PlaySound(DynamicWeather_Soundkits[weatherState], "Ambience")
			isWeatherPlaying = true	
		elseif(weatherSoundHandle ~= nil) then
			--StopSound(weatherSoundHandle, 2000.0)
			--C_Timer.After(5500.0, function() weatherSoundHandle = nil end)
			--isWeatherPlaying = false
		end
	elseif(DynamicWeather_WeatherStates[zoneIndex] == nil) then
		if(weatherSoundHandle ~= nil) then
			StopSound(weatherSoundHandle, 2000.0)
		end
		isWeatherPlaying = false	
	end
	if(DynamicWeather_Soundkits_Extra[weatherState] ~= nil) then
		if(weatherState ~= oldWeatherState) then
			if(weatherSoundHandle2 ~= nil) then
				StopSound(weatherSoundHandle2, 2000.0)
			end
			weatherSoundHandle2 = nil
			
		end
		if(weatherSoundHandle2 == nil and IsIndoors() ~= true) then
			
			weatherSound2, weatherSoundHandle2 = PlaySound(DynamicWeather_Soundkits_Extra[weatherState], "Ambience")
			isWeather2Playing = true
		elseif(weatherSoundHandle2 ~= nil) then
			--StopSound(weatherSoundHandle2, 2000.0)
			--C_Timer.After(5500.0, function() weatherSoundHandle2 = nil end)
		end
	elseif(DynamicWeather_WeatherStates[zoneIndex] == nil) then
		if(weatherSoundHandle2 ~= nil) then
			StopSound(weatherSoundHandle2, 2000.0)
		end
		isWeather2Playing = false
	end
	
		
	

		
	if(weatherState == "clear" or IsIndoors() == true) then
		if(weatherSoundHandle ~= nil) then
			StopSound(weatherSoundHandle, 2000.0)
			isWeatherPlaying = false;
			weatherSoundHandle = nil;
		end
		if(weatherSoundHandle2 ~= nil) then
			StopSound(weatherSoundHandle2, 2000.0)
			isWeather2Playing = false;
			weatherSoundHandle2 = nil;
		end
	end
	--print(weatherState)
	oldWeatherState = weatherState;
	oldWeatherHandle = weatherSoundHandle;
	oldWeatherHandle2 = weatherSoundHandle2;
	if(IsIndoors() == true) then
		if(DynamicWeatherRainFrame:IsShown()) then
			DynamicWeatherRainFrame:Hide()
		else
			DynamicWeatherRainFrame:Hide()
		end
	elseif(DynamicWeather_IsRainingTriggers[weatherState] ~= nil) then
		DynamicWeather.ConvertToRainFrame()
		DynamicWeatherRainFrame:SetAlpha(DynamicWeather_IsRainingTriggers[weatherState])
		
		DynamicWeatherRainFrame:Show()
		
		
	elseif(DynamicWeather_IsSnowingTriggers[weatherState] ~= nil) then
		DynamicWeather.ConvertToIceFrame()
		DynamicWeatherRainFrame:SetAlpha(DynamicWeather_IsSnowingTriggers[weatherState])
		DynamicWeatherRainFrame:Show()
	else
		DynamicWeatherRainFrame:Hide()
	end
	
end


function DynamicWeather.ConvertToIceFrame()
	DynamicWeatherRainFrame.body:SetTexture("Interface\\Addons\\DynamicWeather\\Ice.tga")
	DynamicWeatherRainFrame.body:Show()
	--DynamicWeatherRainFrame.body2:SetTexture("Interface\\Addons\\DynamicWeather\\Ice.tga")
end

function DynamicWeather.ConvertToRainFrame()
	DynamicWeatherRainFrame.body:SetTexture("Interface\\Addons\\DynamicWeather\\RainOverlay2.tga")
	DynamicWeatherRainFrame.body:Show()
	--DynamicWeatherRainFrame.body2:SetTexture("Interface\\Addons\\DynamicWeather\\RainOverlay2.tga")
end

function DynamicWeather.CreateOldRainFrame()
	DynamicWeatherRainFrame = CreateFrame("Frame","DynamicWeatherRainFrame", EventFrame) --frameType, frameName, frameParent 
	
	DynamicWeatherRainFrame:SetSize(2048, 2048)
	DynamicWeatherRainFrame:SetPoint("TOPLEFT",0,0)
	
	DynamicWeatherRainFrame.body = DynamicWeatherRainFrame:CreateTexture("DynamicWeatherRainFrameBackdrop", "BACKGROUND")
	DynamicWeatherRainFrame.body:SetPoint("TOPLEFT",0,0)
	DynamicWeatherRainFrame.body:SetTexture("Interface\\Addons\\DynamicWeather\\RainOverlay2.tga")
	DynamicWeatherRainFrame.body:SetSize(2048, 2048)
	DynamicWeatherRainFrame.body:SetHorizTile(false)
	DynamicWeatherRainFrame.body:SetVertTile(false)
	--DynamicWeatherRainFrame.body:SetAllPoints(DynamicWeatherRainFrame)
	DynamicWeatherRainFrame.body:SetAlpha(1.0)
	--DynamicWeatherRainFrame.body2 = DynamicWeatherRainFrame:CreateTexture("DynamicWeatherRainFrameBackdrop2", "BACKGROUND")
	--DynamicWeatherRainFrame.body2:SetPoint("TOP",1024,0)
	--DynamicWeatherRainFrame.body2:SetTexture("Interface\\Addons\\DynamicWeather\\RainOverlay2.tga")
	--DynamicWeatherRainFrame.body2:SetHorizTile(false)
	--DynamicWeatherRainFrame.body2:SetVertTile(false)
	--DynamicWeatherRainFrame.body2:SetAllPoints(DNStatusWindow)
	--DynamicWeatherRainFrame.body2:SetAlpha(1.0)
end
function DynamicWeather.CreateRainFrame()
	
	DynamicWeather_Raindroplets = {[1] = DynamicWeather.CreateRainDroplet(1, 0), [2] = DynamicWeather.CreateRainDroplet(2, 0), [3] = DynamicWeather.CreateRainDroplet(3, 0), [4] = DynamicWeather.CreateRainDroplet(4, 0), [5] = DynamicWeather.CreateRainDroplet(5, 0), [6] = DynamicWeather.CreateRainDroplet(6, 0), [7] = DynamicWeather.CreateRainDroplet(7, 0), [8] = DynamicWeather.CreateRainDroplet(8, 0), [9] = DynamicWeather.CreateRainDroplet(9, 0), [10] = DynamicWeather.CreateRainDroplet(10, 0), [11] = DynamicWeather.CreateRainDroplet(11, 0), [12] = DynamicWeather.CreateRainDroplet(12, 0), [13] = DynamicWeather.CreateRainDroplet(13, 0), [14] = DynamicWeather.CreateRainDroplet(14, 0)} 
end

function DynamicWeather.DoRaindrops(numRaindrops)
	for i=1,numRaindrops do
		DynamicWeather_Raindroplets[i]:SetAlpha(0)
		DynamicWeather_Raindroplets[i]:Show()
		DynamicWeather_Raindroplets[i]:ClearAllPoints()
		DynamicWeather_Raindroplets[i]:SetPoint("CENTER",math.random(-1024, 1024), math.random(-512, 512))
		DynamicWeather_Raindroplets[i]:SetWidth(10)
		DynamicWeather_Raindroplets[i]:SetHeight(10)
		DynamicWeather_Raindroplets[i]:SetAllPoints()
		
		
		--RPWRaindropFadeOut(DynamicWeather_Raindroplets[i], 0.5)
		
	end
end

function RPWRaindropFadeIn(frame, fadeInTime)
	-- Fade in the shine and then fade it out with the ComboPointShineFadeOut function
	local fadeInfo = {};
	fadeInfo.mode = "IN";
	fadeInfo.timeToFade = fadeInTime;
	fadeInfo.finishedFunc = RPWRaindropFadeOut(frame, 0.6);
	--frame:Show()
	UIFrameFade(frame, fadeInfo);
end
function RPWRaindropFadeOut(frame, fadeOutTime)
	-- Fade in the shine and then fade it out with the ComboPointShineFadeOut function
	local fadeInfo = {};
	fadeInfo.mode = "OUT";
	fadeInfo.timeToFade = fadeOutTime;
	fadeInfo.finishedFunc = frame:Hide();
	UIFrameFade(frame, fadeInfo);
end


function DynamicWeather.CreateRainDroplet(index, alpha)
	local DynamicWeatherRainFrameDroplet = CreateFrame("Frame","DynamicWeatherRainFrameDroplet" .. tostring(index)) --frameType,		frameName, frameParent 
	
	
	DynamicWeatherRainFrameDroplet:SetPoint("CENTER",math.random(-1024, 1024), math.random(-512, 512))
	DynamicWeatherRainFrameDroplet:SetSize(10, 10)
	DynamicWeatherRainFrameDroplet:SetAllPoints()
	DynamicWeatherRainFrameDroplet.body = DynamicWeatherRainFrameDroplet:CreateTexture("DynamicWeatherRainFrameDropletBackdrop" .. tostring(index), "BACKGROUND")
	DynamicWeatherRainFrameDroplet.body:SetAlpha(0)
	DynamicWeatherRainFrameDroplet.body:SetPoint("CENTER",math.random(-1024, 1024), math.random(-512, 512))
	DynamicWeatherRainFrameDroplet.body:SetWidth(10)
	DynamicWeatherRainFrameDroplet.body:SetHeight(10)
	DynamicWeatherRainFrameDroplet.body:SetTexture("Interface\\Addons\\DynamicWeather\\Raindrop.tga")
	DynamicWeatherRainFrameDroplet.body:SetAllPoints()
	--DynamicWeatherRainFrameDroplet.body:Hide()
	DynamicWeatherRainFrameDroplet:Hide()
	return DynamicWeatherRainFrameDroplet
end

function DynamicWeather.CreateBar(name, value, previous)
	statusBar = CreateFrame("StatusBar", name .. "1", WorldMapFrame.BorderFrame) --frameType, frameName, frameParent  
	statusBar:SetSize(150,50)
	backgroundCol = {0,0,0}
	--statusBar background
	statusBar.bg = statusBar:CreateTexture(nil,"BACKGROUND",nil,-8)
	statusBar.bg:SetAllPoints(statusBar)
	statusBar.bg:SetTexture(unpack({0,0,0}))
	statusBar.bg:SetAlpha(0.35)
	--statusBar texture
	local tex = statusBar:CreateTexture(nil,"BACKGROUND",nil,-6)
	tex:SetTexture(unpack({1.0, 1.0, 1.0}))
	statusBar:SetStatusBarTexture("Interface\\TargetingFrame\\UI-StatusBar")
	statusBar:SetStatusBarColor(unpack({1.0, 1.0, 1.0, 0.5}))
	--values
	--statusBar:SetBackdrop({bgFile = "Interface/Tooltips/UI-Tooltip-Background", 
	--	edgeFile = "Interface/Tooltips/UI-Tooltip-Border", 
	--	tile = true, tileSize = 32, edgeSize = 8, 
	--	insets = { left = 2, right = 2, top = 4, bottom = 4 }
	--	})
	
	statusBar.border = CreateFrame("Frame", nil, statusBar)
	statusBar.border:SetPoint("TOPLEFT", statusBar, "TOPLEFT", -2, 2)
	statusBar.border:SetPoint("BOTTOMRIGHT", statusBar, "BOTTOMRIGHT", 2, -2)
	statusBar.border:SetBackdrop({
	edgeFile = "Interface/Tooltips/UI-Tooltip-Border", 
	tile = false, tileSize = 0, edgeSize = 12, 
	insets = { left = -1, right = -1, top = -1, bottom = -1}
	})
	statusBar.border:SetFrameLevel(statusBar:GetFrameLevel())
	statusBar:SetMinMaxValues(1, 100)
	statusBar.minValue, statusBar.maxValue = statusBar:GetMinMaxValues()
	statusBar:SetValue(100)
	statusBar.Text = statusBar:CreateFontString()
	statusBar.Text:SetFontObject(GameFontNormal)
	statusBar.Text:SetPoint("CENTER")
	statusBar.Text:SetJustifyH("CENTER")
	statusBar.Text:SetJustifyV("CENTER")
	statusBar:SetParent(WorldMapFrame.BorderFrame);
	statusBar:ClearAllPoints();

	local xPadding = 10;
	local yPadding = 10;

	if position == "TOPRIGHT" then
		xPadding = -10;
		yPadding = -45;
	elseif position == "TOPLEFT" then
		yPadding = -30;
	elseif position == "BOTTOMRIGHT" then
		xPadding = -10;
		yPadding = 40;
	end

	statusBar:SetPoint("BOTTOMLEFT", 40, 150, WorldMapFrame.ScrollContainer);
	return statusBar
end

function DynamicWeather.CreateForecast(zoneIndex)
	
	
	local xPadding = 10;
	local yPadding = 10;

	
	
	local uiMapID = WorldMapFrame:GetMapID();
	local mapID = C_Map.GetMapInfo(uiMapID)
	local name = mapID.name
	--print(name)
	if(DynamicWeather_WeatherStates[name] ~= nil) then
		forecast.Text:SetText(DynamicWeather_StateNames[DynamicWeather_WeatherStates[name]])		--forecast.Text:SetText(DynamicWeather_StateNames[DynamicWeather_WeatherStates[name]] .. "\nNext: " .. DynamicWeather_StateNames[DynamicWeather_Forecasts[name]])
	else
		forecast.Text:SetText("Average")
	end
	
end
function DynamicWeather.CalculateGlobalWeather()
	RPWrandom_generator:init_genrand(CalculateServerTimeSeed(GetServerTime()))
	for index, value in pairs(DynamicWeather_ZoneBiomes) do
		
		DynamicWeather.CalculateWeather(index)
		for index, value in pairs(DynamicWeather_Parents) do
			DynamicWeather_States[index] = DynamicWeather_States[value]
			DynamicWeather_Stages[index] = DynamicWeather_Stages[value]
			DynamicWeather_WeatherStates[index] = DynamicWeather_WeatherStates[value]
		end
		
	end
end

function DynamicWeather.PrintCurrentWeatherMsg(zoneIndex)
	if(DynamicWeather_WeatherStates[zoneIndex] ~= nil) then
		local weatherState = DynamicWeather_WeatherStates[zoneIndex]
		local weatherMsg = DynamicWeather_StateMessages[weatherState]
		print(weatherMsg)
	end
end

function DynamicWeather.CalculateWeatherWithSeed(zoneIndex, seed)
	--local zoneIndex = tostring(GetRealZoneText());
	local weatherUpdate = ""
	local forecast = "clear"
	RPWrandom_generator:init_genrand(seed)
	if(DynamicWeather_ZoneBiomes[zoneIndex] ~= nil) then
		local rainChance = RPWrandom_generator:random(55)
		
		--print(zoneIndex .. tostring(rainChance))
		if(rainChance <= DynamicWeather_ZoneBiomes[zoneIndex][1]) then
			DynamicWeather_Stages[zoneIndex] = {}
			local rainStateLength = 1
			local biomeType = DynamicWeather_ZoneBiomes[zoneIndex][2]
			for i = 1, rainStateLength do
				forecast = DynamicWeather_BiomeTypes[biomeType][RPWrandom_generator:random(#DynamicWeather_BiomeTypes[biomeType])]
			end
			--print(zoneIndex .. " Forecast")
			--for index, data in ipairs(DynamicWeather_Stages[zoneIndex]) do
			--	print(data)
			--end
		end
		
	end
	return forecast
	
end

function DynamicWeather.CalculateWeather(zoneIndex)
	--local zoneIndex = tostring(GetRealZoneText());
	local weatherUpdate = ""
	--DynamicWeather_Forecasts[zoneIndex] = DynamicWeather.CalculateWeatherWithSeed(zoneIndex, CalculateForecast(GetServerTime()))
	if(DynamicWeather_ZoneBiomes[zoneIndex] ~= nil) then
		local rainChance = RPWrandom_generator:random(55)
		--print(zoneIndex .. tostring(rainChance))
		if(rainChance <= DynamicWeather_ZoneBiomes[zoneIndex][1]) then
			DynamicWeather_Stages[zoneIndex] = {}
			local rainStateLength = 1
			local biomeType = DynamicWeather_ZoneBiomes[zoneIndex][2]
			for i = 1, rainStateLength do
				DynamicWeather_Stages[zoneIndex][i] = DynamicWeather_BiomeTypes[biomeType][RPWrandom_generator:random(#DynamicWeather_BiomeTypes[biomeType])]
			end
			--print(zoneIndex .. " Forecast")
			--for index, data in ipairs(DynamicWeather_Stages[zoneIndex]) do
			--	print(data)
			--end
			DynamicWeather_States[zoneIndex] = 0
			DynamicWeather_WeatherStates[zoneIndex] = DynamicWeather_Stages[zoneIndex][1]
		end
	if(DynamicWeather_States[zoneIndex] ~= nil) then
		local zoneState = DynamicWeather_States[zoneIndex]
		local zoneStateMax = DynamicWeather_Stages[zoneIndex]
		--print(zoneState)
		if(zoneState < #DynamicWeather_Stages[zoneIndex]) then
			zoneState = zoneState + 1
			DynamicWeather_States[zoneIndex] = zoneState
			weatherUpdate = DynamicWeather.GetWeatherString(DynamicWeather_Stages[zoneIndex][zoneState])
			DynamicWeather_WeatherStates[zoneIndex] = DynamicWeather_Stages[zoneIndex][zoneState]
		else
			DynamicWeather_States[zoneIndex] = nil;
			DynamicWeather_Stages[zoneIndex] = nil;
			DynamicWeather_WeatherStates[zoneIndex] = nil;
			
			weatherUpdate = "The skies begin to clear."
		end
	
	end
	end
	
	
	if(tostring(GetRealZoneText()) == zoneIndex and weatherUpdate ~= "") then
		print(weatherUpdate)
	end
end


local function isDivisible(x, y)
	if(x % y == 0) then
		return true
	else
		return false
	end
end

function DynamicWeather_GenerateSeed()
	local seed = CalculateServerTimeSeed(GetServerTime())
	--print("Setting random seed to..." .. tostring(seed))
	RPWrandom_generator:init_genrand(seed)
	return seed
end

-- Functions Section
function DynamicWeather.OnUpdate(self, elapsed)
	if (not DynamicWeather.fully_loaded) then
		return;
	end
  
  self.TimeSinceLastPostProcessingUpdate = self.TimeSinceLastPostProcessingUpdate + elapsed; 	
  --self.TimeSinceLastSeedUpdate = self.TimeSinceLastSeedUpdate + elapsed; 	
  --self.TimeSinceLastPostProcessingEffect = self.TimeSinceLastPostProcessingEffect + elapsed; 	
  self.TimeSinceLastUpdate = self.TimeSinceLastUpdate + elapsed; 	
  self.TimeSinceLastTempUpdate = self.TimeSinceLastTempUpdate + elapsed; 	

  
  
 
  
  if (self.TimeSinceLastUpdate > DynamicWeather_UpdateInterval) then
    
	local hours, minutes = GetGameTime()
	local seed = DynamicWeather_GenerateSeed()
	
	if(isDivisible(minutes, 30) or minutes == 0) then
		
		DynamicWeather.CalculateGlobalWeather()
		DynamicWeather.PostProcessing(tostring(GetRealZoneText()))
		DynamicWeather.PrintCurrentWeatherMsg(tostring(GetRealZoneText()))
		--print("Doing weather tick!")
	end
    --DynamicWeather.PostProcessing(tostring(GetRealZoneText()))
	self.TimeSinceLastUpdate = 0;
  end 
  
  if(self.TimeSinceLastPostProcessingUpdate > 2.0) then
	
	DynamicWeather.PostProcessing(tostring(GetRealZoneText()))
	
	self.TimeSinceLastPostProcessingUpdate = 0.0
  end
  --if(self.TimeSinceLastPostProcessingEffect > 1.3) then
	--if(DynamicWeather_IsRainingTriggers[weatherState] ~=nil) then
		--DynamicWeather.DoRaindrops(DynamicWeather_IsRainingTriggers[weatherState])
	--else
		--DynamicWeatherRainFrame:Hide()
	--end
	--self.TimeSinceLastPostProcessingEffect = 0.0
  --end
  DynamicWeather.CreateForecast(tostring(GetRealZoneText()))

end


local function round(x)
	rounded = x + 0.5 - (x + 0.5) % 1
	return rounded
end

function DynamicWeather.OnEvent(frame, event, ...)

	if (event == 'ADDON_LOADED') then
		frame.TimeSinceLastPostProcessingUpdate = 0.0;
		frame.TimeSinceLastUpdate = 0.0;
		frame.TimeSinceLastTempUpdate = 0.0;
		frame.TimeSinceLastPostProcessingEffect = 0.0;
		frame.TimeSinceLastSeedUpdate = 0.0
		
		
	end
	
	if (event == 'PLAYER_LOGIN') then
		
		--if(DynamicWeather_Stages[tostring(GetRealZoneText())] == nil) then
			--DynamicWeather.CalculateGlobalWeather()
		--end
		local hours, minutes = GetGameTime()
		local seed = DynamicWeather_GenerateSeed()
		DynamicWeather.CalculateGlobalWeather()
		DynamicWeather.fully_loaded = true;
		isWeatherPlaying = false;
		isWeather2Playing = false;
		--PrintStatus()
		DynamicWeather_LastLoginHour = GetGameTime()
		return;
	end
	if (event == 'ZONE_CHANGED') then
		
		
		zoneIndex = tostring(GetRealZoneText());
		--DynamicWeather.PrintCurrentWeatherMsg(tostring(GetRealZoneText()))
		
		DynamicWeather.PostProcessing(tostring(GetRealZoneText()))
		
		
		return;
	end
	if (event == 'PLAYER_ENTERING_WORLD') then
		if(DynamicWeatherRainFrame == nil) then
			DynamicWeather.CreateOldRainFrame()
		else
			DynamicWeatherRainFrame:Hide()
		end
		
		if(weatherSoundHandle ~= nil) then
			StopSound(weatherSoundHandle, 2000.0)
			weatherSoundHandle = nil;
			isWeatherPlaying = false;
		end
		if(weatherSoundHandle2 ~= nil) then
			StopSound(weatherSoundHandle2, 2000.0)
			weatherSoundHandle2 = nil;
			isWeather2Playing = false;
		end
		local seed = DynamicWeather_GenerateSeed()
		if(forecast == nil) then
			forecast = DynamicWeather.CreateBar("DynamicWeatherForecastBar", 100, nil)
		end
		DynamicWeather.PostProcessing(tostring(GetRealZoneText()))
		DynamicWeather.PrintCurrentWeatherMsg(tostring(GetRealZoneText()))
		return;
	end
	

	 
end

local function showColorPicker(r,g,b,a,callback)
  ColorPickerFrame:SetColorRGB(r,g,b)
  ColorPickerFrame.hasOpacity, ColorPickerFrame.opacity = (a ~= nil), a
  ColorPickerFrame.previousValues = {r,g,b,a}
  ColorPickerFrame.func, ColorPickerFrame.opacityFunc, ColorPickerFrame.cancelFunc = callback, callback, callback
  ColorPickerFrame:Hide() -- Need to run the OnShow handler.
  ColorPickerFrame:Show()
end
 
 
 
function DynamicWeather.CreateOptions()

	 DynamicWeather.panel = CreateFrame( "Frame", "DynamicWeatherPanel", UIParent );
	 -- Register in the Interface Addon Options GUI
	 -- Set the name for the Category for the Options Panel
	 DynamicWeather.panel.name = "DynamicWeather";
	 -- Add the panel to the Interface Options
	 InterfaceOptions_AddCategory(DynamicWeather.panel);
	 
	 -- Make a child panel
	 DynamicWeather.childpanel = CreateFrame( "Frame", "DynamicWeatherChild", DynamicWeather.panel);
	 DynamicWeather.childpanel.name = "Settings";
	 -- Specify childness of this panel (this puts it under the little red [+], instead of giving it a normal AddOn category)
	 DynamicWeather.childpanel.parent = DynamicWeather.panel.name;
	 DynamicWeather.childpanel:Hide();
	 InterfaceOptions_AddCategory(DynamicWeather.childpanel);
	 
end

function DynamicWeather.PrintForecast()
	for index, value in pairs(DynamicWeather_ZoneBiomes) do
		if(DynamicWeather_WeatherStates[index] ~= nil) then
			print(index .. ": " .. DynamicWeather_StateNames[DynamicWeather_WeatherStates[index]])
		--	print(index .. ": " .. DynamicWeather_StateNames[DynamicWeather_WeatherStates[index]] .. " | Next: " .. DynamicWeather_StateNames[DynamicWeather_Forecasts[index]])
		--elseif(DynamicWeather_Forecasts[index] ~= nil and DynamicWeather_Forecasts[index] ~= "clear") then
		--	print(index .. ": Clear | Next: " .. DynamicWeather_StateNames[DynamicWeather_Forecasts[index]])
		end
	end
end

DynamicWeatherChatHandler = C_ChatInfo.RegisterAddonMessagePrefix("VYDynamicWeather")
 
 
SLASH_RPW_CYCLE1 = "/dwcycle";
SLASH_RPW_FORECAST1 = "/dwforecast";
SlashCmdList["RPW_CYCLE"] = DynamicWeather.CalculateGlobalWeather
SlashCmdList["RPW_FORECAST"] = DynamicWeather.PrintForecast
DynamicWeather.EventFrame = CreateFrame("Frame");
DynamicWeather.EventFrame:SetScript("OnEvent", DynamicWeather.OnEvent);
DynamicWeather.EventFrame:SetScript("OnUpdate", DynamicWeather.OnUpdate);
DynamicWeather.EventFrame:RegisterEvent("ADDON_LOADED");
DynamicWeather.EventFrame:RegisterEvent("PLAYER_LOGIN");
DynamicWeather.EventFrame:RegisterEvent("PLAYER_LOGOUT"); -- Fired when about to log out
DynamicWeather.EventFrame:RegisterEvent("ZONE_CHANGED"); -- Fired when about to log out
DynamicWeather.EventFrame:RegisterEvent("PLAYER_ENTERING_WORLD"); -- Fired when about to log out
