--[[

Timer routines for flight timers.

Code inspired by Kwarz's flightpath.

]]

-- Function: Update
function EFM_Timer_EventFrame_OnUpdate()
	local ctime;
	EFM_Timer_CheckInFlightStatus();

	if (EFM_MyConf.Timer) then
		if (UnitOnTaxi("player")) then
			ctime = time();
			if(ctime ~= EFM_Timer_LastTime) then
				EFM_Timer_ShowInFlightTimer(ctime-EFM_Timer_LastTime);
				EFM_Timer_LastTime = ctime;
			end
		end
	else
		EFM_Timer_HideTimers();
	end
end

-- Function: Check the in flight status
function EFM_Timer_CheckInFlightStatus()

	-- Check the flight recording state.
	if ((EFM_Timer_Recording) and (UnitOnTaxi("player") == nil)) then
		-- End of the road, stop recording
		EFM_FN_AddFlightTime(EFM_TaxiOrigin, EFM_TaxiDestination, (time() - EFM_Timer_StartTime));
		EFM_Timer_Recording			= false;
		EFM_Timer_StartRecording		= false;

		-- Hide timers
		EFM_Timer_HideTimers();
	end

	if ((EFM_Timer_StartRecording) and (UnitOnTaxi("player"))) then
		EFM_Timer_StartRecording	= false;
		EFM_Timer_Recording		= true;
		EFM_Timer_OrigContinent	= GetCurrentMapContinent();
	end

end

-- Function: Determine remote location from taxi node
function EFM_Timer_TakeTaxiNode(nodeID)
	-- If displaying the remote flight display, end processing.
	if (TaxiMerchant:GetText() == EFM_MSG_REMOTENAME) then
		return;
	end

	-- Get the casting bar position before we do anything with it in the addon.
	EFM_Timer_GetCastingBarPosition();

	EFM_TaxiDestination		= TaxiNodeName(nodeID);
	EFM_Timer_TimeRemaining	= 0;
	EFM_Timer_StartTime		= time();
	EFM_Timer_LastTime		= EFM_Timer_StartTime;

	local flightTime			= EFM_FN_GetFlightDuration(EFM_TaxiOrigin, EFM_TaxiDestination);

	-- If there is a known flight time, calculate the duration estimate
	if (flightTime ~= nil) then
		EFM_Timer_TimeRemaining	= flightTime;
		EFM_Timer_FlightTime		= flightTime;
		EFM_Timer_TimeKnown		= true;
	else
		EFM_Timer_TimeKnown	= false;
		EFM_Timer_FlightTime	= 0;
	end

	EFM_Timer_StartRecording = true;

	Original_TakeTaxiNode(nodeID);
end

-- Function: In flight timer
function EFM_Timer_ShowInFlightTimer(secondsElapsed)

	if (EFM_TaxiDestination) then
		EFM_TimerFrame_Dest:SetText(EFM_FT_DESTINATION..EFM_TaxiDestination);
	else
		EFM_TimerFrame_Dest:SetText(EFM_FT_DESTINATION..UNKNOWN);
	end

	-- Position the destination line of the timer frame as per the configuration.
	EFM_TimerFrame_Dest:SetPoint("CENTER", UIParent, "CENTER", 0, EFM_MyConf.TimerPosition);
	
	EFM_Timer_HideTimers();
	EFM_TimerFrame_Dest:Show();

	if(EFM_Timer_TimeRemaining > 0) then
		EFM_Timer_TimeRemaining = EFM_Timer_TimeRemaining - secondsElapsed;  -- Decrease in flight time remaining
		local displayTime = EFM_SF_FormatTime(EFM_Timer_TimeRemaining);

		-- Display in flight time display thingy...
		if (not EFM_MyConf.ShowTimerBar) then
			-- Show text status
			EFM_TimerFrame_CountDown:SetText(EFM_FT_ARRIVAL_TIME..displayTime);
			EFM_TimerFrame_CountDown:Show();

			-- Hide and reset the Blizzard casting frame
			if ((EFM_CB.point ~= nil) and (CastingBarFrame:IsVisible() == 1))then
				EFM_Timer_ReturnCastingBar();
			end
		else
			EFM_CB.Shown = true;

			-- Disable the CastingBarFrame OnUpdate routine - hack for CT_Mod strangeness
			CastingBarFrame:SetScript("OnUpdate", nil);

			if (EFM_MyConf.ShowLargeBar) then
				CastingBarFrame:SetScale(1.5);
			else
				CastingBarFrame:SetScale(EFM_CB.DefaultScale);
			end

			-- Position the CastingBarFrame
			CastingBarFrame:SetAlpha(1.0);
			CastingBarFrame:ClearAllPoints();
			CastingBarFrame:SetPoint(EFM_CB.point, EFM_TimerFrame_Dest, "BOTTOM", 0, "-30");

			-- Display the time remaining text.
			CastingBarText:SetText(EFM_FT_ARRIVAL_TIME..displayTime);

			-- Handle the CastingBarFrameStatusBar
			CastingBarFrameStatusBar:SetStatusBarColor(0.0, 1.0, 0.0, 0.5);
			CastingBarFrameStatusBar:SetMinMaxValues(0, EFM_Timer_FlightTime);
			CastingBarFrameStatusBar:SetValue(EFM_Timer_FlightTime - EFM_Timer_TimeRemaining);

			-- Display the "spark" for the status bar
--			local sparkPosition = floor((EFM_Timer_TimeRemaining / EFM_Timer_FlightTime) * 195);
			local sparkPosition = floor(((EFM_Timer_FlightTime - EFM_Timer_TimeRemaining) / EFM_Timer_FlightTime) * 195);
			if ( sparkPosition < 0 ) then
				sparkPosition = 0;
			end
			CastingBarSpark:SetPoint("CENTER", CastingBarFrame, "LEFT", sparkPosition, 2);
			CastingBarSpark:SetAlpha(0.5);
			CastingBarSpark:Show();

			-- Hide the "flash" around the casting bar.
			CastingBarFlash:Hide();

			-- Show the casting bar.
			CastingBarFrame:Show();
		end
	else
		if (not EFM_Timer_TimeKnown) then
			-- Display the flight timer screen if the time to destination is unknown as that way people will see it is online.
			EFM_TimerFrame_CountDown:SetText(EFM_FT_ARRIVAL_TIME..UNKNOWN);
			EFM_TimerFrame_CountDown:Show();
		else
			-- Display the flight timer as incorrect
			EFM_TimerFrame_CountDown:SetText(EFM_FT_INCORRECT);
			EFM_TimerFrame_CountDown:Show();
		end
	end
end

-- /script CastingBarFrame:SetPoint(EFM_CB.point, UIParent, "BOTTOM", 0, 200);
-- Function: Hide the flight timer(s)
function EFM_Timer_HideTimers()
	-- Hide my timer references.
	EFM_TimerFrame_Dest:Hide();
	EFM_TimerFrame_CountDown:Hide();

	-- Hide and reset the Blizzard casting frame
	if ((EFM_CB.Shown) and (CastingBarFrame:IsVisible() == 1)) then
		EFM_Timer_ReturnCastingBar();
	end
end

-- Function: Hide CastingBarFrame so we don't need to use it.
function EFM_Timer_ReturnCastingBar()
	-- Reset the CastingBar Scale to the original scale, if needed
	if (EFM_MyConf.ShowLargeBar) then
		CastingBarFrame:SetScale(EFM_CB.DefaultScale);
	end

	-- Return the Casting Bar
	CastingBarSpark:SetAlpha(1.0);
	CastingBarFrame:SetPoint(EFM_CB.point, UIParent, EFM_CB.relativePoint, EFM_CB.xOfs, EFM_CB.yOfs);
	CastingBarFrame:Hide();

	-- Re-enable the OnUpdate function
	CastingBarFrame:SetScript("OnUpdate", EFM_CB.OnUpdateScript);

	-- Set the "has shown" variable to false.
	EFM_CB.Shown = false;
end

-- Function: Get current casting bar position
function EFM_Timer_GetCastingBarPosition()
	local CB_numPoints = CastingBarFrame:GetNumPoints();
	for pointIndex = 1, CB_numPoints do
		local point, relativeObject, relativePoint, xOfs, yOfs = CastingBarFrame:GetPoint(pointIndex);
--		DEFAULT_CHAT_FRAME:AddMessage("point: "..point);

		-- Clear reference points
		EFM_CB.point		= nil;
		EFM_CB.relativeObject	= nil;
		EFM_CB.relativePoint	= nil;
		EFM_CB.xOfs		= nil;
		EFM_CB.yOfs		= nil;

		-- Set new reference point
		EFM_CB.point		= point;
		EFM_CB.relativeObject	= relativeObject;
		EFM_CB.relativePoint	= relativePoint;
		EFM_CB.xOfs		= xOfs;
		EFM_CB.yOfs		= yOfs;
	end
	EFM_CB.OnUpdateScript	= CastingBarFrame:GetScript("OnUpdate")
	EFM_CB.DefaultScale		= CastingBarFrame:GetScale();
end
