--[[
	ChatTimeStamps

	Originally by sarf (Anders Kronquist)
	Recode by Alexander (Alexander Brazie)

	This mod allows time stamps to be prepended to chat. 
		
  ]]--
   
-- These variables are remebered across sessions even if Khaos is off
-- The idea is to be able to use them without Khaos in lightweight debugging environment
-- They can be set with macros such as /script ChatTimeStamps_Data.enabled = ture
-- or /script ChatTimeStamps_Data.format = "%X"
ChatTimeStamps_Data = {};
ChatTimeStamps_Data.enabled = true;
ChatTimeStamps_Data.separator = nil;
ChatTimeStamps_Data.localtime = true;
ChatTimeStamps_Data.silence = nil;
ChatTimeStamps_Data.delay = nil;

--[[
Format codes:
	%a Abbreviated weekday name 
	%A Full weekday name 
	%b Abbreviated month name 
	%B Full month name 
	%c Date and time representation appropriate for locale 
	%d Day of month as decimal number (01 – 31) 
	%H Hour in 24-hour format (00 – 23) 
	%I Hour in 12-hour format (01 – 12) 
	%j Day of year as decimal number (001 – 366) 
	%m Month as decimal number (01 – 12) 
	%M Minute as decimal number (00 – 59) 
	%p Current locale's A.M./P.M. indicator for 12-hour clock 
	%S Second as decimal number (00 – 59) 
	%U Week of year as decimal number, with Sunday as first day of week (00 – 53) 
	%w Weekday as decimal number (0 – 6; Sunday is 0) 
	%W Week of year as decimal number, with Monday as first day of week (00 – 53) 
	%x Date representation for current locale 
	%X Time representation for current locale 
	%y Year without century, as decimal number (00 – 99) 
	%Y Year with century, as decimal number 
	%% Percent sign 
	The # flag may prefix any formatting code. In that case, the meaning of the format code is changed as follows.
	%#a, %#A, %#b, %#B, %#p, %#X, %#% # flag is ignored. 
	%#c Long date and time representation, appropriate for current locale. For example: "Tuesday, March 14, 1995, 12:41:29". 
	%#x Long date representation, appropriate to current locale. For example: "Tuesday, March 14, 1995". 
	%#d, %#H, %#I, %#j, %#m, %#M, %#S, %#U, %#w, %#W, %#y, %#Y Remove leading zeros (if any). 
]]--
ChatTimeStamps_Data.format = "%c";

--------------[[ Khaos Configuration ]]----------------

function ChatTimeStamps_ChangeDelay(state)	
	if (state.checked) then 
		ChatTimeStamps_Data.delay = state.slider*60;
	else
		ChatTimeStamps_Data.delay = nil;
	end
end

function ChatTimeStamps_ChangeAffectedChatFrames(state)
	for i=1, NUM_CHAT_WINDOWS do 
		if ( Sea.list.isInList(state.value, i) ) then 
			Sea.util.hook("ChatFrame"..i..".AddMessage", ChatTimeStamps_NewAddMessage, "before");
		else
			Sea.util.unhook("ChatFrame"..i..".AddMessage", ChatTimeStamps_NewAddMessage, "before");
		end
	end
end

function ChatTimeStamps_ConfigureKhaos()
	Khaos.registerFolder(
		{
			id = "chat";
			text = CHAT_FOLDER_TITLE;
			helptext = CHAT_FOLDER_HELP;
			difficulty = 1;
		}
	);

	local CTTS_Feedback = function ( state )
		if ( ChatTimeStamps_Data.enabled ) then 
			return string.format(CHATTS_CONFIG_FEEDBACK_ENABLED,  ChatTimeStamps_TimeStamp(CHATTS_CONFIG_FEEDBACK_EXAMPLE) );
		else
			return string.format(CHATTS_CONFIG_FEEDBACK_DISABLED,  ChatTimeStamps_TimeStamp(CHATTS_CONFIG_FEEDBACK_EXAMPLE) );
		end
	end;

	local CTTS_Options = {
			{
				id="ChatTimeStampsHeader";
				text=CHATTS_CONFIG_HEADER;
				helptext=CHATTS_CONFIG_HEADER_INFO;
				difficulty=1;
				type=K_HEADER;
			},
			{
				id="ChatTimeStampsSeparator";
				text=CHATTS_CONFIG_SEPARATOR;
				helptext=CHATTS_CONFIG_SEPARATOR_INFO;
				difficulty=2;
				key="separator";
				check=true;
				type=K_TEXT;
				callback= function(state) ChatTimeStamps_Data.separator = state.checked; end;
				feedback=CTTS_Feedback;
				default = {
					checked = true;
				};
				disabled = {
					checked = false;
				};
			},
			{
				id="ChatTimeStampsDelay";
				text=CHATTS_CONFIG_PERIODICSTAMPS;
				helptext=CHATTS_CONFIG_PERIODICSTAMPS_INFO;
				difficulty=3;
				key="delay";
				check=true;
				type=K_SLIDER;
				callback=ChatTimeStamps_ChangeDelay;
				feedback=CTTS_Feedback;
				setup = {
					sliderMin = 1;
					sliderMax = 60;
					sliderStep = 1;
					sliderText = CHATTS_CONFIG_PERIODICSTAMPS_SLIDER_TEXT;
				};
				default = {
					checked = false;
					slider = 5;
				};
				disabled = {
					checked = false;
					slider = 1;
				};
			},
			{
				id="ChatTimeStampsSilence";
				text=CHATTS_CONFIG_SILENCE;
				helptext=CHATTS_CONFIG_SILENCE_INFO;
				difficulty=3;
				key="silence";
				check=true;
				type=K_TEXT;
				callback= function(state) ChatTimeStamps_Data.silence = state.checked; end;
				feedback=CTTS_Feedback;
				default = {
					checked = false;
				};
				disabled = {
					checked = false;
				};
				dependencies = {
					delay = {checked=true;match=true;};
				};
			},
			{
				id="ChatTimeStampsLocalTime";
				text=CHATTS_CONFIG_LOCALTIME;
				helptext=CHATTS_CONFIG_LOCALTIME_INFO;
				difficulty=2;
				key="localtime";
				check=true;
				type=K_TEXT;
				callback=ChatTimeStamps_ToggleLocalTime;
				callback= function(state) ChatTimeStamps_Data.localtime = state.checked; end;
				feedback=CTTS_Feedback;
				default = {
					checked = false;
				};
				disabled = {
					checked = false;
				};
			},		
			{
				id="ChatTimeStampsDateTimeFormat";
				text=CHATTS_CONFIG_TIMEFORMAT;
				helptext=CHATTS_CONFIG_TIMEFORMAT_INFO;
				difficulty=3;
				type=K_EDITBOX;
				key="ctsFormat";
				callback=function(state) ChatTimeStamps_Data.format = state.value; end;
				feedback=CTTS_Feedback;
				default = {
					value = "%c";
				};
				disabled = {
					value = "%c";
				};
				setup = {
					callOn = {"change"};
				};
				dependencies = {
					localtime = {checked=true;match=true;};
				};
			},
			{
				id="ChatTimeStampsAffectedFrames";
				text=CHATTS_CONFIG_CHOOSEFRAMES;
				helptext=CHATTS_CONFIG_CHOOSEFRAMES_INFO;
				difficulty=2;
				key="frames";
				type=K_PULLDOWN;
				callback=ChatTimeStamps_ChangeAffectedChatFrames;
				feedback=CTTS_Feedback;
				default = {
					value={1,2,3,4,5,6,7};
				};
				disabled = {
					value={};
				};
				setup = {
					options = ChatTimeStamps_GetFrameNames;
					multiSelect = true;
				};
			}
		};

	Khaos.registerOptionSet(
		"chat",
		{
			id = "ChatTimeStamps";
			text = CHATTS_CONFIG_HEADER;
			helptext = CHATTS_CONFIG_HEADER_INFO;
			options = CTTS_Options;
			difficulty = 1;
			callback=function(enabled)
				ChatTimeStamps_Data.enabled = enabled;
			end;
		}
	);

end

--------------[[ Main code ]]----------------

function ChatTimeStamps_OnLoad()
	if ( Khaos ) then 
		ChatTimeStamps_ConfigureKhaos();
	else
		ChatTimeStamps_LoadDefaults();
	end
end

function ChatTimeStamps_LoadDefaults()
	for i=1, NUM_CHAT_WINDOWS do
		Sea.util.hook("ChatFrame"..i..".AddMessage", ChatTimeStamps_NewAddMessage, "before");
	end
end

function ChatTimeStamps_TimeStamp(msg, hour, minute)
	if (ChatTimeStamps_Data.enabled) and ( msg ) and ( msg ~= "" ) and ( msg ~= " " ) then
		local separator = "";
		if ( ChatTimeStamps_Data.separator ) then
			separator = ">";	
		end
		if ( date and ChatTimeStamps_Data.localtime ) then 
			local status, dateString = pcall(date, ChatTimeStamps_Data.format);
			if not status then
				dateString = date();
			end
			return dateString..separator.." "..msg;
		end
		if (Clock_GetTimeText) then
			return Clock_GetTimeText()..separator.." "..msg;
		end

		if ( not hour or not minute ) then 
			hour, minute = GetGameTime();
		end
		
		if (hour < 10) then 
			hour = "0"..hour; 
		end
	
		if (minute < 10) then 
			minute = "0"..minute; 
		end
	
		local timestring = hour..":"..minute;
		local ts_body = timestring..separator.." "..msg;
	
		return ts_body;
	else
		return msg;
	end
end

ChatTimeStamps_LastStamp = {}; 
function ChatTimeStamps_NewAddMessage(self, msg, a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20)
	if ( not ChatTimeStamps_LastStamp[self:GetName()] ) then 
		ChatTimeStamps_LastStamp[self:GetName()] = 0;
	end
	if ( ChatTimeStamps_Data.silence and ChatTimeStamps_LastStamp[self:GetName()] + ChatTimeStamps_Data.delay < GetTime() ) then 
		ChatTimeStamps_LastStamp[self:GetName()] = GetTime();
	end
	if ( not ChatTimeStamps_Data.delay or ChatTimeStamps_LastStamp[self:GetName()] + ChatTimeStamps_Data.delay < GetTime() ) then 
		msg = ChatTimeStamps_TimeStamp(msg);
		ChatTimeStamps_LastStamp[self:GetName()] = GetTime();
	end

	return true, self, msg, a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20;
end

function ChatTimeStamps_GetFrameNames()
	local options = {};

	for i=1, NUM_CHAT_WINDOWS do 
		local name, fontSize, r, g, b, a, shown, locked, docked = GetChatWindowInfo(i);
		
		if ( name ~= "" ) then 
			options[name] = i;
		elseif ( i==1 ) then
			options[GENERAL] = i;
		elseif ( i==2 ) then
			options[COMBAT_LOG] = i;
		end
	end

	return options;
end
