------------------------------------------------
--                  CT_Core                   --
--                                            --
-- Core addon for doing basic and popular     --
-- things in an intuitive way.                --
-- Please do not modify or otherwise          --
-- redistribute this without the consent of   --
-- the CTMod Team. Thank you.                 --
------------------------------------------------

local _G = getfenv(0);
local module = _G.CT_Core;
local NUM_CHAT_WINDOWS = NUM_CHAT_WINDOWS;

--------------------------------------------
-- Chat Arrows

local hide = true;
local menuButton = _G.ChatFrameMenuButton;

-- Generic function to toggle a given ChatFrame's buttons
local function toggleButtons(self, hide)
	local name = self:GetName();
	if ( hide ) then
		_G[name.."BottomButton"]:Hide();
		_G[name.."UpButton"]:Hide();
		_G[name.."DownButton"]:Hide();
	else
		_G[name.."BottomButton"]:Show();
		_G[name.."UpButton"]:Show();
		_G[name.."DownButton"]:Show();
	end
end

-- Hide/Show all ChatFrames' buttons
local function toggleChatFrameButtons(hide)
	for i = 1, NUM_CHAT_WINDOWS, 1 do
		toggleButtons(_G["ChatFrame"..i], hide);
	end
	if ( hide ) then
		menuButton:Hide();
	else
		menuButton:Show();
	end
end

--------------------------------------------
-- Chat Scrolling

local shift, control = IsShiftKeyDown, IsControlKeyDown;

-- Function to scroll the ChatFrame according to the defined mode
local function onChatScroll(self, direction)
	if ( tonumber(direction) > 0 ) then
		if ( shift() ) then
			self:ScrollToTop();
		elseif ( control() ) then
			self:PageUp();
		else
			self:ScrollUp();
		end
	else
		if ( shift() ) then
			self:ScrollToBottom();
		elseif ( control() ) then
			self:PageDown();
		else
			self:ScrollDown();
		end
	end
end

-- Toggles Chat Scrolling on a given ChatFrame
local function toggleScrolling(self, enable)
	if ( enable ) then
		self:EnableMouseWheel(true);
		self:SetScript("OnMouseWheel", onChatScroll);
	else
		self:EnableMouseWheel(false);
		self:SetScript("OnMouseWheel", nil);
	end
end

-- Enable/Disable scrolling on all ChatFrames
local function toggleChatFrameScrolling(enable)
	for i = 1, NUM_CHAT_WINDOWS, 1 do
		toggleScrolling(_G["ChatFrame"..i], enable);
	end
end

--------------------------------------------
-- Chat Edit Move

local function toggleChatEditMove(move, initial)
	if ( move ) then
		local editBox = _G.ChatFrameEditBox;
		editBox:ClearAllPoints();
		editBox:SetPoint("BOTTOMLEFT", "ChatFrame1", "TOPLEFT", -5, 2);
		editBox:SetPoint("BOTTOMRIGHT", "ChatFrame1", "TOPRIGHT", 5, 2);
	elseif ( not initial ) then
		local editBox = _G.ChatFrameEditBox;
		editBox:ClearAllPoints();
		editBox:SetPoint("TOPLEFT", "ChatFrame1", "BOTTOMLEFT", -5, -2);
		editBox:SetPoint("TOPRIGHT", "ChatFrame1", "BOTTOMRIGHT", 5, -2);
	end
end

--------------------------------------------
-- Chat Timestamps

local stamp, defaultMessageFunction = 4;
local date, tonumber = date, tonumber;

-- Displays a message with a timestamp in various formats
local function displayChatTimestamp_12h(self, msg, ...)
	defaultMessageFunction(self, "["..tonumber(date("%I"))..date(":%M] ") .. msg, ...);
end
local function displayChatTimestamp_24h(self, msg, ...)
	defaultMessageFunction(self, date("[%H:%M] ") .. msg, ...);
end
local function displayChatTimestamp_12hs(self, msg, ...)
	defaultMessageFunction(self, "["..tonumber(date("%I"))..date(":%M:%S] ") .. msg, ...);
end
local function displayChatTimestamp_24hs(self, msg, ...)
	defaultMessageFunction(self, date("[%H:%M:%S] ") .. msg, ...);
end

-- Toggle chat timestamps for a given ChatFrame
local function toggleTimestamps(self, mode)
	if ( mode > 0 ) then
		if ( not defaultMessageFunction ) then
			-- Cache our default message
			defaultMessageFunction = self.AddMessage;
		end
		if ( mode == 1 ) then
			self.AddMessage = displayChatTimestamp_12h;
		elseif ( mode == 2 ) then
			self.AddMessage = displayChatTimestamp_12hs;
		elseif ( mode == 3 ) then
			self.AddMessage = displayChatTimestamp_24h;
		elseif ( mode == 4 ) then
			self.AddMessage = displayChatTimestamp_24hs;
		end
	elseif ( defaultMessageFunction ) then
		self.AddMessage = defaultMessageFunction;
	end
end

-- Toggle chat timestamps for all ChatFrames
local function toggleChatFrameTimestamps(mode)
	for i = 1, NUM_CHAT_WINDOWS, 1 do
		toggleTimestamps(_G["ChatFrame"..i], mode);
	end
end

-- /pri
module:setSlashCmd(function(msg) RunScript("ChatFrame1:AddMessage("..msg..", 1, 1, 0);"); end, "/pri");

--------------------------------------------
-- General Initializer

module.chatupdate = function(self, type, value)
	if ( type == "init" ) then
		local frame, onHide;
		
		local chatScrolling, chatTimestamp, chatTimestampFormat = self:getOption("chatScrolling"), 
			self:getOption("chatTimestamp"), self:getOption("chatTimestampFormat");
		for i = 1, NUM_CHAT_WINDOWS, 1 do
			frame = _G["ChatFrame"..i];
			if ( frame ) then
				onShow = frame:GetScript("OnShow");
				frame:SetScript("OnShow", function(self)
					if ( onShow ) then
						onShow(self);
					end
					local chatArrows = module:getOption("chatArrows");
					if ( chatArrows ) then
						toggleButtons(self, chatArrows );
					end
				end);
				toggleScrolling(frame, chatScrolling);
				toggleTimestamps(frame, ( chatTimestamp and chatTimestampFormat ) or 0);
			end
		end
		toggleChatFrameButtons(self:getOption("chatArrows"));
		toggleChatEditMove(self:getOption("chatEditMove"), true);
	else
		if ( type == "chatArrows" ) then
			toggleChatFrameButtons(value);
		elseif ( type == "chatScrolling" ) then
			toggleChatFrameScrolling(value);
		elseif ( type == "chatTimestamp" ) then
			toggleChatFrameTimestamps(( value and self:getOption("chatTimestampFormat") ) or 0);
		elseif ( type == "chatTimestampFormat" ) then
			toggleChatFrameTimestamps(( self:getOption("chatTimestamp") and value ) or 0);
		elseif ( type == "chatEditMove" ) then
			toggleChatEditMove(value);
		end
	end
end