-- CHAT PROTOTYPE STUFF
 SELECTED_DOCK_FRAME = nil;
 DOCKED_CHAT_FRAMES = {};
 DOCK_COPY = {};
 
 MOVING_CHATFRAME = nil;
 
 CHAT_TAB_SHOW_DELAY = 0.2;
 CHAT_TAB_HIDE_DELAY = 1;
 CHAT_FRAME_FADE_TIME = 0.15;
 CHAT_FRAME_FADE_OUT_TIME = 2.0;
 CHAT_FRAME_BUTTON_FRAME_MIN_ALPHA = 0.2;
 
 CHAT_FRAME_TAB_SELECTED_MOUSEOVER_ALPHA = 1.0;
 CHAT_FRAME_TAB_SELECTED_NOMOUSE_ALPHA = 0.4;
 CHAT_FRAME_TAB_ALERTING_MOUSEOVER_ALPHA = 1.0;
 CHAT_FRAME_TAB_ALERTING_NOMOUSE_ALPHA = 1.0;
 CHAT_FRAME_TAB_NORMAL_MOUSEOVER_ALPHA = 0.6;
 CHAT_FRAME_TAB_NORMAL_NOMOUSE_ALPHA = 0.2;
 
 DEFAULT_CHATFRAME_ALPHA = 0.25;
 DEFAULT_CHATFRAME_COLOR = {r = 0, g = 0, b = 0};
 
 CHAT_FRAME_NORMAL_MIN_HEIGHT = 120;
 CHAT_FRAME_BIGGER_MIN_HEIGHT = 147;
 CHAT_FRAME_MIN_WIDTH = 296;
 
 CURRENT_CHAT_FRAME_ID = nil;
 
 CHAT_FRAME_TEXTURES = {
 	"Background",
 	"TopLeftTexture",
 	"BottomLeftTexture",
 	"TopRightTexture",
 	"BottomRightTexture",
 	"LeftTexture",
 	"RightTexture",
 	"BottomTexture",
 	"TopTexture",
 	--"ResizeButton",
 	
 	"ButtonFrameBackground",
 	"ButtonFrameTopLeftTexture",
 	"ButtonFrameBottomLeftTexture",
 	"ButtonFrameTopRightTexture",
 	"ButtonFrameBottomRightTexture",
 	"ButtonFrameLeftTexture",
 	"ButtonFrameRightTexture",
 	"ButtonFrameBottomTexture",
 	"ButtonFrameTopTexture",
 }
 
 CHAT_FRAMES = {};
 
 function FloatingChatFrame_OnLoad(self)
 	--IMPORTANT NOTE: This function isn't run by ChatFrame1.
 	tinsert(CHAT_FRAMES, self:GetName());
 	
 	FCF_SetTabPosition(self, 0);
 	FloatingChatFrame_Update(self:GetID());
 	
 	FCFTab_UpdateColors(_G[self:GetName().."Tab"], true);
 	self:SetClampRectInsets(-35, 35, 26, -50);
 	
 	local chatTab = _G[self:GetName().."Tab"];
 	chatTab.mouseOverAlpha = CHAT_FRAME_TAB_SELECTED_MOUSEOVER_ALPHA;
 	chatTab.noMouseAlpha = CHAT_FRAME_TAB_SELECTED_NOMOUSE_ALPHA;
 
 	FRAMELOCK_STATES.PETBATTLEOPENING[self:GetName()] = "hidden";
 	FRAMELOCK_STATES.PETBATTLEOPENING[chatTab:GetName()] = "hidden";
 	UpdateFrameLock(self);
 	UpdateFrameLock(chatTab);
 end
 
 function FloatingChatFrame_OnEvent(self, event, ...)
 	if ( (event == "UPDATE_CHAT_WINDOWS") or (event == "UPDATE_FLOATING_CHAT_WINDOWS") ) then
 		FloatingChatFrame_Update(self:GetID(), 1);
 		self.isInitialized = 1;
 	elseif ( event == "UPDATE_CHAT_COLOR" ) then
 		local chatType, r, g, b = ...;
 		if ( self.isTemporary and self.chatType == chatType ) then
 			local tab = _G[self:GetName().."Tab"];
 			tab.selectedColorTable.r, tab.selectedColorTable.g, tab.selectedColorTable.b = r, g, b;
 			FCFTab_UpdateColors(tab, not self.isDocked or self == FCFDock_GetSelectedWindow(GENERAL_CHAT_DOCK));
 		end
 	end
 end
 
 function FloatingChatFrame_OnMouseScroll(self, delta)
 	if ( delta > 0 ) then
 		self:ScrollUp();
 	else
 		self:ScrollDown();
 	end
 end
 
 function FCF_GetChatWindowInfo(id)
 	if ( id > NUM_CHAT_WINDOWS ) then
 		local frame = _G["ChatFrame"..id];
 		local tab = _G["ChatFrame"..id.."Tab"];
 		local background = _G["ChatFrame"..id.."Background"];
 		
 		if ( frame and tab and background ) then
 			local r, g, b, a = background:GetVertexColor();
 			
 			return tab:GetText(), select(2, frame:GetFont()), r, g, b, a, frame:IsShown(), frame.isLocked, frame.isDocked, frame.isUninteractable;
 			--This is a temporary chat window. Pass this to whatever handles those options.
 		end
 	else
 		return GetChatWindowInfo(id);
 	end
 end
 
 function FCF_CopyChatSettings(copyTo, copyFrom)
 	local name, fontSize, r, g, b, a, shown, locked, docked, uninteractable = FCF_GetChatWindowInfo(copyFrom:GetID());
-	FCF_SetWindowColor(copyTo, r, g, b, 1);
-	FCF_SetWindowAlpha(copyTo, a, 1);
+	
+	FCF_SetWindowColor(copyTo, r, g, b, true);
+	FCF_SetWindowAlpha(copyTo, a, true);
 	--If we're copying to a docked window, we don't want to copy locked.
 	if ( not copyTo.isDocked ) then
 		FCF_SetLocked(copyTo, locked);
 	end
 	FCF_SetUninteractable(copyTo, uninteractable);
 	FCF_SetChatWindowFontSize(nil, copyTo, fontSize);
 end
 
 function FloatingChatFrame_Update(id, onUpdateEvent)
 	local chatFrame = _G["ChatFrame"..id];
 	local chatTab = _G["ChatFrame"..id.."Tab"];
 	
 	local name, fontSize, r, g, b, a, shown, locked, docked, uninteractable = FCF_GetChatWindowInfo(id);
-	
 	-- Set Tab Name
-	FCF_SetWindowName(chatFrame, name, 1)
+	FCF_SetWindowName(chatFrame, name, true)
 
 	if ( onUpdateEvent ) then
 		-- Set Frame Color and Alpha
-		FCF_SetWindowColor(chatFrame, r, g, b, 1);
-		FCF_SetWindowAlpha(chatFrame, a, 1);
+		FCF_SetWindowColor(chatFrame, r, g, b, true);
+		FCF_SetWindowAlpha(chatFrame, a, true);
 		FCF_SetLocked(chatFrame, locked);
 		FCF_SetUninteractable(chatFrame, uninteractable);
 	end
 
 	if ( shown ) then
 		if ( not chatFrame.minimized ) then
 			chatFrame:Show();
 		end
 		FCF_SetTabPosition(chatFrame, 0);
 	else
 		if ( not chatFrame.isDocked ) then
 			chatFrame:Hide();
 			chatTab:Hide();
 		end
 	end
 	
 	if ( docked ) then
 		FCF_DockFrame(chatFrame, docked, (id == 1));
 	else
 		if ( shown ) then
 			FCF_UnDockFrame(chatFrame);
 			if ( not chatFrame.minimized ) then
 				chatTab:Show();
 			end
 		elseif ( not chatFrame.isTemporary ) then
 			FCF_Close(chatFrame);
 		end
 	end
 	
 	if ( not chatFrame.isTemporary and (chatFrame == DEFAULT_CHAT_FRAME or not chatFrame.isDocked)) then
 		FCF_RestorePositionAndDimensions(chatFrame);
 	end
 
 	FCF_UpdateButtonSide(chatFrame);
 end
 
 -- Channel Dropdown
 function FCFOptionsDropDown_OnLoad(self)
 	CURRENT_CHAT_FRAME_ID = self:GetParent():GetID();
 	UIDropDownMenu_Initialize(self, FCFOptionsDropDown_Initialize, "MENU");
 	UIDropDownMenu_SetButtonWidth(self, 50);
 	UIDropDownMenu_SetWidth(self, 50);
 end
 
 function FCFOptionsDropDown_Initialize(dropDown)
 	-- Window preferences
 	local name, fontSize, r, g, b, a, shown = FCF_GetChatWindowInfo(FCF_GetCurrentChatFrameID());
 	local info;
 
 	local chatFrame = FCF_GetCurrentChatFrame();
 	local isTemporary = chatFrame and chatFrame.isTemporary;
 	
 	-- If level 2
 	if ( UIDROPDOWNMENU_MENU_LEVEL == 2 ) then
 		-- If this is the font size menu then create dropdown
 		if ( UIDROPDOWNMENU_MENU_VALUE == FONT_SIZE ) then
 			-- Add the font heights from the font height table
 			local value;
 			for i=1, #CHAT_FONT_HEIGHTS do
 				value = CHAT_FONT_HEIGHTS[i];
 				info = UIDropDownMenu_CreateInfo();
 				info.text = format(FONT_SIZE_TEMPLATE, value);
 				info.value = value;
 				info.func = FCF_SetChatWindowFontSize;
 
 				local fontFile, fontHeight, fontFlags = FCF_GetCurrentChatFrame():GetFont();
 				if ( value == floor(fontHeight+0.5) ) then
 					info.checked = 1;
 				end
 
 				UIDropDownMenu_AddButton(info, UIDROPDOWNMENU_MENU_LEVEL);
 			end
 			return;
 		end
 		return;
 	end
 	-- Window options
 	info = UIDropDownMenu_CreateInfo();
 	local dropDownChatFrame = FCF_GetCurrentChatFrame(dropDown);
 	if ( dropDownChatFrame and dropDownChatFrame ~= DEFAULT_CHAT_FRAME and dropDownChatFrame.isDocked ) then
 		info.text = UNDOCK_WINDOW;
 	elseif ( dropDownChatFrame and dropDownChatFrame.isLocked ) then
 		info.text = UNLOCK_WINDOW;
 	else
 		info.text = LOCK_WINDOW;
 	end
 	info.func = FCF_ToggleLock;
 	info.notCheckable = 1;
 	UIDropDownMenu_AddButton(info);
 
 	--Add Uninteractable button
 	info = UIDropDownMenu_CreateInfo();
 	if ( FCF_GetCurrentChatFrame(dropDown) and FCF_GetCurrentChatFrame(dropDown).isUninteractable) then
 		info.text = MAKE_INTERACTABLE;
 	else
 		info.text = MAKE_UNINTERACTABLE;
 	end
 	info.func = FCF_ToggleUninteractable;
 	info.notCheckable = 1;
 	UIDropDownMenu_AddButton(info);
 	
 	if ( not isTemporary ) then
 		-- Add name button
 		info = UIDropDownMenu_CreateInfo();
 		info.text = RENAME_CHAT_WINDOW;
 		info.func = FCF_RenameChatWindow_Popup;
 		info.notCheckable = 1;
 		UIDropDownMenu_AddButton(info);
 	end
 	
 	if ( chatFrame == DEFAULT_CHAT_FRAME ) then
 		-- Create new chat window
 		info = UIDropDownMenu_CreateInfo();
 		info.text = NEW_CHAT_WINDOW;
 		info.func = FCF_NewChatWindow;
 		info.notCheckable = 1;
 		if (FCF_GetNumActiveChatFrames() == NUM_CHAT_WINDOWS ) then
 			info.disabled = 1;
 		end
 		UIDropDownMenu_AddButton(info);
 
 		-- Reset Chat windows to default
 		info = UIDropDownMenu_CreateInfo();
 		info.text = RESET_ALL_WINDOWS;
 		info.func = FCF_ResetAllWindows;
 		info.notCheckable = 1;
 		UIDropDownMenu_AddButton(info);
 	end
 
 	-- Close current chat window
 	if ( chatFrame and (chatFrame ~= DEFAULT_CHAT_FRAME and not IsCombatLog(chatFrame)) ) then
 		if ( not chatFrame.isTemporary ) then
 			info = UIDropDownMenu_CreateInfo();
 			info.text = CLOSE_CHAT_WINDOW;
 			info.func = FCF_PopInWindow;
 			info.arg1 = FCF_GetCurrentChatFrame(dropDown);
 			info.notCheckable = 1;
 			UIDropDownMenu_AddButton(info);
 		elseif ( chatFrame.isTemporary and (chatFrame.chatType == "WHISPER" or chatFrame.chatType == "BN_WHISPER") ) then
 			info = UIDropDownMenu_CreateInfo();
 			info.text = CLOSE_CHAT_WHISPER_WINDOW;
 			info.func = FCF_PopInWindow;
 			info.arg1 = FCF_GetCurrentChatFrame(dropDown);
 			info.notCheckable = 1;
 			UIDropDownMenu_AddButton(info);
 		elseif ( chatFrame.isTemporary and (chatFrame.chatType == "BN_CONVERSATION" ) ) then
 			if ( GetCVar("conversationMode") == "popout" or GetCVar("conversationMode") == "popout_and_inline" ) then
 				info = UIDropDownMenu_CreateInfo();
 				info.text = CLOSE_AND_LEAVE_CHAT_CONVERSATION_WINDOW;
 				info.func = FCF_LeaveConversation;
 				info.arg1 = FCF_GetCurrentChatFrame(dropDown);
 				info.notCheckable = 1;
 				UIDropDownMenu_AddButton(info);
 			else
 				info = UIDropDownMenu_CreateInfo();
 				info.text = CLOSE_CHAT_CONVERSATION_WINDOW;
 				info.func = FCF_PopInWindow;
 				info.arg1 = FCF_GetCurrentChatFrame(dropDown);
 				info.notCheckable = 1;
 				UIDropDownMenu_AddButton(info);
 			end
 		elseif ( chatFrame.isTemporary ) then
 			info = UIDropDownMenu_CreateInfo();
 			info.text = CLOSE_CHAT_WINDOW;
 			info.func = FCF_Close;
 			info.arg1 = FCF_GetCurrentChatFrame(dropDown);
 			info.notCheckable = 1;
 			UIDropDownMenu_AddButton(info);
 		else
 			error(format("Unhandled temporary window type. chatType: %s, chatTarget %s", tostring(chatFrame.chatType), tostring(chatFrame.chatTarget)));
 		end
 	end
 
 	-- Display header
 	info = UIDropDownMenu_CreateInfo();
 	info.text = DISPLAY;
 	info.notClickable = 1;
 	info.isTitle = 1;
 	info.notCheckable = 1;
 	UIDropDownMenu_AddButton(info);
 
 	-- Font size
 	info = UIDropDownMenu_CreateInfo();
 	info.text = FONT_SIZE;
 	--info.notClickable = 1;
 	info.hasArrow = 1;
 	info.func = nil;
 	info.notCheckable = 1;
 	UIDropDownMenu_AddButton(info);
 
 	-- Set Background color
 	info = UIDropDownMenu_CreateInfo();
 	info.text = BACKGROUND;
 	info.hasColorSwatch = 1;
 	info.notCheckable = 1;
 	info.r = r;
 	info.g = g;
 	info.b = b;
 	-- Done because the slider is reversed
 	if ( a ) then
 		a = 1- a;
 	end
 	info.opacity = a;
 	info.swatchFunc = FCF_SetChatWindowBackGroundColor;
 	info.func = UIDropDownMenuButton_OpenColorPicker;
 	--info.notCheckable = 1;
 	info.hasOpacity = 1;
 	info.opacityFunc = FCF_SetChatWindowOpacity;
 	info.cancelFunc = FCF_CancelWindowColorSettings;
 	UIDropDownMenu_AddButton(info);
 
 	if ( not isTemporary ) then
 		-- Filter header
 		info = UIDropDownMenu_CreateInfo();
 		info.text = FILTERS;
 		--info.notClickable = 1;
 		info.isTitle = 1;
 		info.notCheckable = 1;
 		UIDropDownMenu_AddButton(info);
 
 		-- Configure settings
 		info = UIDropDownMenu_CreateInfo();
 		info.text = CHAT_CONFIGURATION;
 		info.func = function() ShowUIPanel(ChatConfigFrame); end;
 		info.notCheckable = 1;
 		UIDropDownMenu_AddButton(info);
 	end
 end
 --[[
 function FCFDropDown_LoadServerChannels(...)
 	local checked;
 	local channelList = FCF_GetCurrentChatFrame().channelList;
 	local zoneChannelList = FCF_GetCurrentChatFrame().zoneChannelList;
 	local info, channel;
 
 	-- Server Channels header
 	info = UIDropDownMenu_CreateInfo();
 	info.text = SERVER_CHANNELS;
 	info.notClickable = 1;
 	info.isTitle = 1;
 	UIDropDownMenu_AddButton(info, UIDROPDOWNMENU_MENU_LEVEL);
 
 	info = UIDropDownMenu_CreateInfo();
 	for i=1, select("#", ...) do
 		checked = nil;
 		channel = select(i, ...);
 		if ( channelList ) then
 			for index, value in pairs(channelList) do
 				if ( value == channel ) then
 					checked = 1;
 				end
 			end
 		end
 		if ( zoneChannelList ) then
 			for index, value in pairs(zoneChannelList) do
 				if ( value == channel ) then
 					checked = 1;
 				end
 			end
 		end
 
 		info.text = channel;
 		info.value = channel;
 		info.func = FCFServerChannelsDropDown_OnClick;
 		info.checked = checked;
 		info.keepShownOnClick = 1;
 		UIDropDownMenu_AddButton(info, UIDROPDOWNMENU_MENU_LEVEL);
 	end
 end
 
 function FCFServerChannelsDropDown_OnClick()
 	if ( UIDropDownMenuButton_GetChecked() ) then
 		ChatFrame_RemoveChannel(FCF_GetCurrentChatFrame(), UIDropDownMenuButton_GetName());
 	else
 		JoinPermanentChannel(UIDropDownMenuButton_GetName(), nil, FCF_GetCurrentChatFrameID(), 1);
 		ChatFrame_AddChannel(FCF_GetCurrentChatFrame(), UIDropDownMenuButton_GetName());
 	end
 end
 ]]
 function FCFDropDown_LoadChannels(...)
 	local checked;
 	local channelList = FCF_GetCurrentChatFrame().channelList;
 	local zoneChannelList = FCF_GetCurrentChatFrame().zoneChannelList;
 	local info = UIDropDownMenu_CreateInfo();
 	local channel, tag;
 	for i=1, select("#", ...), 2 do
 		checked = nil;
 		tag = "CHANNEL"..select(i, ...);
 		channel = select(i+1, ...);
 		if ( channelList ) then
 			for index, value in pairs(channelList) do
 				if ( value == channel ) then
 					checked = 1;
 				end
 			end
 		end
 		if ( zoneChannelList ) then
 			for index, value in pairs(zoneChannelList) do
 				if ( value == channel ) then
 					checked = 1;
 				end
 			end
 		end
 		info.text = channel;
 		info.value = tag;
 		info.func = FCFChannelDropDown_OnClick;
 		info.checked = checked;
 		info.keepShownOnClick = 1;
 		-- Color the chat channel
 		local color = ChatTypeInfo[tag];
 		info.hasColorSwatch = 1;
 		info.r = color.r;
 		info.g = color.g;
 		info.b = color.b;
 		-- Set the function the color picker calls
 		info.swatchFunc = FCF_SetChatTypeColor;
 		info.cancelFunc = FCF_CancelFontColorSettings;
 		UIDropDownMenu_AddButton(info, UIDROPDOWNMENU_MENU_LEVEL);
 	end
 end
 
 function FCFChannelDropDown_OnClick()
 	if ( UIDropDownMenuButton_GetChecked() ) then
 		ChatFrame_RemoveChannel(FCF_GetCurrentChatFrame(), UIDropDownMenuButton_GetName());
 	else
 		ChatFrame_AddChannel(FCF_GetCurrentChatFrame(), UIDropDownMenuButton_GetName());
 	end
 end
 
 -- Used to display chattypegroups
 function FCFDropDown_LoadChatTypes(menuChatTypeGroups)
 	local checked, chatTypeInfo;
 	local messageTypeList = FCF_GetCurrentChatFrame().messageTypeList;
 	local info, group;
 	for index, value in pairs(menuChatTypeGroups) do
 		checked = nil;
 		if ( messageTypeList ) then
 			for joinedIndex, joinedValue in pairs(messageTypeList) do
 				if ( value == joinedValue ) then
 					checked = 1;
 				end
 			end
 		end
 		info = UIDropDownMenu_CreateInfo();
 		info.value = value;
 		info.func = FCFMessageTypeDropDown_OnClick;
 		info.checked = checked;
 		-- Set to keep shown on button click
 		info.keepShownOnClick = 1;
 		
 		-- If more than one message type in a Chat Type Group need to show an expand arrow
 		group = ChatTypeGroup[value];
 		if ( getn(group) > 1 ) then
 			info.text = _G[value];
 			info.hasArrow = 1;
 			UIDropDownMenu_AddButton(info, UIDROPDOWNMENU_MENU_LEVEL);
 		else
 			info.text = _G[group[1]];
 			chatTypeInfo = ChatTypeInfo[FCF_StripChatMsg(group[1])];
 			-- If no chatTypeInfo then don't display
 			if ( chatTypeInfo ) then
 				-- Set the function to be called when a color is set
 				info.swatchFunc = FCF_SetChatTypeColor;
 				-- Set the swatch color info
 				info.hasColorSwatch = 1;
 				info.r = chatTypeInfo.r;
 				info.g = chatTypeInfo.g;
 				info.b = chatTypeInfo.b;
 				info.cancelFunc = FCF_CancelFontColorSettings;	
 				UIDropDownMenu_AddButton(info, UIDROPDOWNMENU_MENU_LEVEL);
 			end
 		end
 	end
 end
 
 --  Used to display chatsubtypes
 function FCF_LoadChatSubTypes(chatGroup)
 	if ( chatGroup ) then
 		chatGroup = ChatTypeGroup[chatGroup];
 	else
 		chatGroup = ChatTypeGroup[UIDROPDOWNMENU_MENU_VALUE];
 	end
 	if ( chatGroup ) then
 		local info = UIDropDownMenu_CreateInfo();
 		local chatTypeInfo
 		for index, value in pairs(chatGroup) do
 			chatTypeInfo = ChatTypeInfo[FCF_StripChatMsg(value)];
 			if ( chatTypeInfo ) then
 				info.text = _G[value];
 				info.value = FCF_StripChatMsg(value);
 				-- Disable the button and color the text white
 				info.notClickable = 1;
 				-- Set to be notcheckable
 				info.notCheckable = 1;
 				-- Set the function to be called when a color is set
 				info.swatchFunc = FCF_SetChatTypeColor;
 				-- Set the swatch color info
 				info.hasColorSwatch = 1;
 				info.r = chatTypeInfo.r;
 				info.g = chatTypeInfo.g;
 				info.b = chatTypeInfo.b;
 				-- Set function called when cancel is clicked in the colorpicker
 				info.cancelFunc = FCF_CancelFontColorSettings;
 				UIDropDownMenu_AddButton(info, UIDROPDOWNMENU_MENU_LEVEL);
 			end
 		end
 	end
 end
 
 function FCFMessageTypeDropDown_OnClick(self)
 	if ( UIDropDownMenuButton_GetChecked() ) then
 		ChatFrame_RemoveMessageGroup(FCF_GetCurrentChatFrame(), self.value);
 	else
 		ChatFrame_AddMessageGroup(FCF_GetCurrentChatFrame(), self.value);
 	end
 end
 
 function FCF_OpenNewWindow(name)
 	local count = 1;
 	local chatFrame, chatTab;
 	
 	for i=1, NUM_CHAT_WINDOWS do
 		local _, _, _, _, _, _, shown = FCF_GetChatWindowInfo(i);
 		chatFrame = _G["ChatFrame"..i];
 		chatTab = _G["ChatFrame"..i.."Tab"];
 		if ( (not shown and not chatFrame.isDocked) or (count == NUM_CHAT_WINDOWS) ) then
 			if ( not name or name == "" ) then
 				name = format(CHAT_NAME_TEMPLATE, i);			
 			end
 			
 			-- initialize the frame
 			FCF_SetWindowName(chatFrame, name);
 			FCF_SetWindowColor(chatFrame, DEFAULT_CHATFRAME_COLOR.r, DEFAULT_CHATFRAME_COLOR.g, DEFAULT_CHATFRAME_COLOR.b);
 			FCF_SetWindowAlpha(chatFrame, DEFAULT_CHATFRAME_ALPHA);
-			SetChatWindowLocked(i, nil);
+			SetChatWindowLocked(i, false);
 
 			-- clear stale messages
 			chatFrame:Clear();
 
 			-- Listen to the standard messages
 			ChatFrame_RemoveAllMessageGroups(chatFrame);
 			ChatFrame_RemoveAllChannels(chatFrame);
 			ChatFrame_ReceiveAllPrivateMessages(chatFrame);
 			ChatFrame_ReceiveAllBNConversations(chatFrame);
 			
 			ChatFrame_AddMessageGroup(chatFrame, "SAY");
 			ChatFrame_AddMessageGroup(chatFrame, "YELL");
 			ChatFrame_AddMessageGroup(chatFrame, "GUILD");
 			ChatFrame_AddMessageGroup(chatFrame, "WHISPER");
 			ChatFrame_AddMessageGroup(chatFrame, "BN_WHISPER");
 			ChatFrame_AddMessageGroup(chatFrame, "PARTY");
 			ChatFrame_AddMessageGroup(chatFrame, "PARTY_LEADER");
 			ChatFrame_AddMessageGroup(chatFrame, "CHANNEL");
 
 			--Clear the edit box history.
 			chatFrame.editBox:ClearHistory();
 			
 			-- Show the frame and tab
 			chatFrame:Show();
 			chatTab:Show();
-			SetChatWindowShown(i, 1);
+			SetChatWindowShown(i, true);
 			
 			-- Dock the frame by default
 			FCF_DockFrame(chatFrame, (#FCFDock_GetChatFrames(GENERAL_CHAT_DOCK)+1), true);
 			FCF_FadeInChatFrame(FCFDock_GetSelectedWindow(GENERAL_CHAT_DOCK));
 			return chatFrame;
 		end
 		count = count + 1;
 	end
 end
 
 function FCF_SetTemporaryWindowType(chatFrame, chatType, chatTarget)
 	local chatTab = _G[chatFrame:GetName().."Tab"];
 	--If the frame was already registered, unregister it.
 	if ( chatFrame.isRegistered ) then
 		FCFManager_UnregisterDedicatedFrame(chatFrame, chatFrame.chatType, chatFrame.chatTarget);
 		chatFrame.isRegistered = false;
 	end
 	
 	--Set the title text
 	local name;
 	if ( chatType == "WHISPER" or chatType == "BN_WHISPER" ) then
 		name = chatTarget;
 	elseif ( chatType == "BN_CONVERSATION" ) then
 		name = format(CONVERSATION_NAME, tonumber(chatTarget) + MAX_WOW_CHAT_CHANNELS);
 	elseif ( chatType == "PET_BATTLE_COMBAT_LOG" ) then
 		name = PET_BATTLE_COMBAT_LOG;
 	end
 	FCF_SetWindowName(chatFrame, name);
 	
 	
 	--Set up the window to receive the message types we want.
 	chatFrame.chatType = chatType;
 	chatFrame.chatTarget = chatTarget;
 	
 	ChatFrame_RemoveAllMessageGroups(chatFrame);
 	ChatFrame_RemoveAllChannels(chatFrame);
 	ChatFrame_ReceiveAllPrivateMessages(chatFrame);
 	ChatFrame_ReceiveAllBNConversations(chatFrame);
 	
 	ChatFrame_AddMessageGroup(chatFrame, chatType);
 	
 	-- This is to display "friend is online"/"friend is offline" messages
 	if ( chatType == "BN_WHISPER" ) then
 		ChatFrame_AddSingleMessageType(chatFrame, "CHAT_MSG_BN_INLINE_TOAST_ALERT");
 		ChatFrame_AddSingleMessageType(chatFrame, "CHAT_MSG_BN_WHISPER_PLAYER_OFFLINE");
 	elseif ( chatType == "WHISPER" ) then
 		ChatFrame_AddSingleMessageType(chatFrame, "CHAT_MSG_SYSTEM");
 	elseif ( chatType == "PET_BATTLE_COMBAT_LOG" ) then
 		ChatFrame_AddMessageGroup(chatFrame, "PET_BATTLE_INFO");
 	end
 	
 	chatFrame.editBox:SetAttribute("chatType", chatType);
 	chatFrame.editBox:SetAttribute("stickyType", chatType);
 	
 	if ( chatType == "WHISPER" or chatType == "BN_WHISPER" ) then
 		chatFrame.editBox:SetAttribute("tellTarget", chatTarget);
 		ChatFrame_AddPrivateMessageTarget(chatFrame, chatTarget);
 	elseif ( chatType == "BN_CONVERSATION" ) then
 		chatFrame.editBox:SetAttribute("channelTarget", chatTarget);
 		ChatFrame_AddBNConversationTarget(chatFrame, chatTarget);
 	elseif ( chatType == "PET_BATTLE_COMBAT_LOG" ) then
 		chatFrame.editBox:SetAttribute("chatType", "SAY");
 		chatFrame.editBox:SetAttribute("stickyType", "SAY");
 	end
 	
 	-- Set up the colors
 	local info = ChatTypeInfo[chatType];
 	chatTab.selectedColorTable = { r = info.r, g = info.g, b = info.b };
 	FCFTab_UpdateColors(chatTab, not chatFrame.isDocked or chatFrame == FCFDock_GetSelectedWindow(GENERAL_CHAT_DOCK));
 	
 	--If it's a conversation, create the conversation button
 	if ( chatType == "BN_CONVERSATION" or chatType == "BN_WHISPER" ) then
 		if ( chatFrame.conversationButton ) then
 			BNConversationButton_UpdateTarget(chatFrame.conversationButton);
 			chatFrame.conversationButton:Show();
 		else
 			CreateFrame("Button", chatFrame:GetName().."ConversationButton", chatFrame.buttonFrame, "BNConversationRosterButtonTemplate", chatFrame:GetID());
 		end
 		if ( chatFrame:GetHeight() < CHAT_FRAME_BIGGER_MIN_HEIGHT ) then
 			chatFrame:SetHeight(CHAT_FRAME_BIGGER_MIN_HEIGHT);
 		end
 		chatFrame:SetMinResize(CHAT_FRAME_MIN_WIDTH, CHAT_FRAME_BIGGER_MIN_HEIGHT);
 	else
 		if ( chatFrame.conversationButton ) then
 			chatFrame.conversationButton:Hide();
 		end
 		chatFrame:SetMinResize(CHAT_FRAME_MIN_WIDTH, CHAT_FRAME_NORMAL_MIN_HEIGHT);
 	end
 	
 	--If it's a conversation, get it ready to convert to a whisper if needed.
 	if ( chatType == "BN_CONVERSATION" ) then
 		chatFrame:RegisterEvent("BN_CHAT_CHANNEL_CLOSED");
 	else
 		chatFrame:UnregisterEvent("BN_CHAT_CHANNEL_CLOSED");
 	end
 	
 	--Set the icon
 	local conversationIcon;
 	if ( chatType == "WHISPER" or chatType == "BN_WHISPER" ) then
 		conversationIcon = "Interface\\ChatFrame\\UI-ChatWhisperIcon";
 	elseif ( chatType == "PET_BATTLE_COMBAT_LOG" ) then
 		conversationIcon = "Interface\\Icons\\Tracking_WildPet";
 	else
 		conversationIcon = "Interface\\ChatFrame\\UI-ChatConversationIcon";
 	end
 	
 	chatTab.conversationIcon:SetTexture(conversationIcon);
 	if ( chatFrame.minFrame ) then
 		chatFrame.minFrame.conversationIcon:SetTexture(conversationIcon);
 	end
 	
 	--Register this frame
 	FCFManager_RegisterDedicatedFrame(chatFrame, chatType, chatTarget);
 	chatFrame.isRegistered = true;
 	
 	--The window name may have been updated, so update the dock and tabs.
 	FCF_DockUpdate();
 end
 
 local maxTempIndex = NUM_CHAT_WINDOWS + 1;
 function FCF_OpenTemporaryWindow(chatType, chatTarget, sourceChatFrame, selectWindow)
 	local chatFrame, chatTab, conversationIcon;
 	for _, chatFrameName in pairs(CHAT_FRAMES) do
 		local frame = _G[chatFrameName];
 		if ( frame.isTemporary ) then
 			if ( not frame.inUse and not frame.isDocked ) then
 				chatFrame = frame;
 				chatTab = _G[chatFrame:GetName().."Tab"];
 				break;
 			end
 		end
 	end
 	
 	if ( not chatFrame ) then
 		chatTab = CreateFrame("Button", "ChatFrame"..maxTempIndex.."Tab", UIParent, "ChatTabTemplate", maxTempIndex);
 		
 		conversationIcon = chatTab:CreateTexture(chatTab:GetName().."ConversationIcon", "ARTWORK", "ChatTabConversationIconTemplate");
 		conversationIcon:ClearAllPoints();
 		conversationIcon:SetPoint("RIGHT", chatTab:GetFontString(), "LEFT", 0, -2);
 		chatTab.conversationIcon = conversationIcon;
 		
 		local tabText = _G[chatTab:GetName().."Text"];
 		tabText:SetPoint("LEFT", chatTab.leftTexture, "RIGHT", 10, -6);
 		tabText:SetJustifyH("LEFT");
 		chatTab.sizePadding = 10;
 		
 		chatFrame = CreateFrame("ScrollingMessageFrame", "ChatFrame"..maxTempIndex, UIParent, "FloatingChatFrameTemplate", maxTempIndex);
 		
 		if ( GetCVarBool("chatMouseScroll") ) then
 			chatFrame:SetScript("OnMouseWheel", FloatingChatFrame_OnMouseScroll);
 			chatFrame:EnableMouseWheel(true);
 		end
 
 		maxTempIndex = maxTempIndex + 1;		
 	end
 	
 	--Copy chat settings from the source frame.
 	FCF_CopyChatSettings(chatFrame, sourceChatFrame or DEFAULT_CHAT_FRAME);
 
 	-- clear stale messages
 	chatFrame:Clear();
 	chatFrame.inUse = true;
 	chatFrame.isTemporary = true;
 	
 	FCF_SetTemporaryWindowType(chatFrame, chatType, chatTarget);
 	
 	--Clear the edit box history.
 	chatFrame.editBox:ClearHistory();
 	
 	if ( sourceChatFrame ) then
 		--Copy over messages
 		local accessID = ChatHistory_GetAccessID(chatType, chatTarget);
 		for i = 1, sourceChatFrame:GetNumMessages(accessID) do
 			local text, accessID, lineID, extraData = sourceChatFrame:GetMessageInfo(i, accessID);
 			local cType, cTarget = ChatHistory_GetChatType(extraData);
 
 			local info = ChatTypeInfo[cType];
 			chatFrame:AddMessage(text, info.r, info.g, info.b, lineID, false, accessID, extraData);
 		end
 
 		--Stop displaying this type of chat in the old chat frame.
 		--Remove the messages from the old frame.
 		if (not (chatType == "WHISPER" and GetCVar("whisperMode") == "popout_and_inline")
 			and not (chatType == "BN_WHISPER" and GetCVar("bnWhisperMode") == "popout_and_inline")
 			and not (chatType == "BN_CONVERSATION" and GetCVar("conversationMode") == "popout_and_inline") ) then
 
 			if ( chatType == "WHISPER" or chatType == "BN_WHISPER" ) then
 				ChatFrame_ExcludePrivateMessageTarget(sourceChatFrame, chatTarget);
 			elseif ( chatType == "BN_CONVERSATION" ) then
 				ChatFrame_ExcludeBNConversationTarget(sourceChatFrame, chatTarget);
 			end
 
 			sourceChatFrame:RemoveMessagesByAccessID(accessID);
 		end
 	end
 	
 	--Close the Editbox
 	ChatEdit_DeactivateChat(chatFrame.editBox);
 	
 	-- Show the frame and tab
 	chatFrame:Show();
 	chatTab:Show();
 	
 	-- Dock the frame by default
 	FCF_DockFrame(chatFrame, (#FCFDock_GetChatFrames(GENERAL_CHAT_DOCK)+1), selectWindow);
 	return chatFrame;
 end
 
 function FCF_RemoveAllMessagesFromChanSender(chatFrame, chanSender)
 	local ids = ChatHistory_GetAllAccessIDsByChanSender(chanSender);
 	for i=1, #ids do
 		chatFrame:RemoveMessagesByExtraData(ids[i]);
 	end
 end
 
 function FCF_GetNumActiveChatFrames()
 	local count = 0;
 	local chatFrame;
 	for i=1, NUM_CHAT_WINDOWS do
 		local _, _, _, _, _, _, shown = FCF_GetChatWindowInfo(i);
 		chatFrame = _G["ChatFrame"..i];
 		if ( chatFrame ) then
 			if ( shown or chatFrame.isDocked ) then
 				count = count + 1;
 			end
 		end
 	end
 	return count;
 end
 
 function FCF_RenameChatWindow_Popup()
 	local dialog = StaticPopup_Show("NAME_CHAT");
 	dialog.data = FCF_GetCurrentChatFrameID();
 end
 
 function FCF_NewChatWindow()
 	StaticPopup_Show("NAME_CHAT");
 end
 
 function FCF_ResetAllWindows()
 	StaticPopup_Show("RESET_CHAT");
 end
 
 --[[function FCF_ChatChannels()
 	ToggleFriendsFrame(3);
 end]]--
 
 function FCF_SetWindowName(frame, name, doNotSave)
 	if ( not name or name == "") then
 		-- Hack to initialize the chat window names, since globalstrings are not available on init
 		if ( frame:GetID() == 1 ) then
 			name = GENERAL;
 			doNotSave = nil;
 		elseif ( frame:GetID() == 2 ) then
 			name = COMBAT_LOG;
 			doNotSave = nil;
 		else
 			name = format(CHAT_NAME_TEMPLATE, frame:GetID());
 		end
 	else
 		FCFDock_SetDirty(GENERAL_CHAT_DOCK);
 	end
 	frame.name = name;
 	local tab = _G[frame:GetName().."Tab"];
 	tab:SetText(name);
 	PanelTemplates_TabResize(tab, tab.sizePadding or 0);
 	-- Save this off so we know how big the tab should always be, even if it gets shrunken on the dock.
 	tab.textWidth = _G[tab:GetName().."Text"]:GetWidth();
 	if ( not doNotSave ) then
 		SetChatWindowName(frame:GetID(), name);
 	end
 	if ( frame.minFrame ) then
 		frame.minFrame:SetText(name);
 	end
 end
 
 function FCF_SetWindowColor(frame, r, g, b, doNotSave)
 	local name = frame:GetName();
 	for index, value in pairs(CHAT_FRAME_TEXTURES) do
 		--NOTE - If this is changed, please change the equivalent code in GMChatFrame_OnLoad.
 		local object = _G[name..value];
 		local objectType = object:GetObjectType();
 		if ( objectType == "Button" ) then
 			object:GetNormalTexture():SetVertexColor(r, g, b);
 			object:GetHighlightTexture():SetVertexColor(r, g, b);
 			object:GetPushedTexture():SetVertexColor(r, g, b);
 		elseif ( objectType == "Texture" ) then
 			_G[name..value]:SetVertexColor(r,g,b);
 		else
 			--error("Unhandled frame type...");
 		end
 	end
 	if ( not doNotSave ) then
 		SetChatWindowColor(frame:GetID(), r, g, b);
 	end
 end
 
 function FCF_SetWindowAlpha(frame, alpha, doNotSave)
 	local name = frame:GetName();
 	for index, value in pairs(CHAT_FRAME_TEXTURES) do
 		_G[name..value]:SetAlpha(alpha);
 	end
 	if ( not doNotSave ) then
 		SetChatWindowAlpha(frame:GetID(), alpha);
 	end
 	-- Remember the alpha
-	frame.oldAlpha = alpha;
+	frame.oldAlpha = alpha or DEFAULT_CHATFRAME_ALPHA;
 end
 
 function FCF_GetCurrentChatFrameID()
 	return CURRENT_CHAT_FRAME_ID;
 end
 
 function FCF_GetCurrentChatFrame(child)
 	local currentChatFrame = nil;
 	if ( CURRENT_CHAT_FRAME_ID ) then
 		currentChatFrame = _G["ChatFrame"..CURRENT_CHAT_FRAME_ID];
 	end
 	if ( not currentChatFrame and child ) then
 		currentChatFrame = _G["ChatFrame"..child:GetParent():GetID()];
 	end
 	return currentChatFrame;
 end
 
 function FCF_SetChatTypeColor()
 	local r,g,b = ColorPickerFrame:GetColorRGB();
 	ChangeChatColor(UIDROPDOWNMENU_MENU_VALUE, r, g, b);
 end
 
 function FCF_SetChatWindowBackGroundColor()
 	local r,g,b = ColorPickerFrame:GetColorRGB();
 	FCF_SetWindowColor(FCF_GetCurrentChatFrame(), r, g, b)
 	SetChatWindowColor(FCF_GetCurrentChatFrameID(), r, g, b);
 end
 
 function FCF_SetChatWindowOpacity()
 	local alpha = 1.0 - OpacitySliderFrame:GetValue();
 	FCF_SetWindowAlpha(FCF_GetCurrentChatFrame(), alpha);
 end
 
 function FCF_SetChatWindowFontSize(self, chatFrame, fontSize)
 	if ( not chatFrame ) then
 		chatFrame = FCF_GetCurrentChatFrame();
 	end
 	if ( not fontSize ) then
 		fontSize = self.value;
 	end
 	local fontFile, unused, fontFlags = chatFrame:GetFont();
 	chatFrame:SetFont(fontFile, fontSize, fontFlags);
 	if ( GMChatFrame and chatFrame == DEFAULT_CHAT_FRAME ) then
 		GMChatFrame:SetFont(fontFile, fontSize, fontFlags);
 	end
 	SetChatWindowSize(chatFrame:GetID(), fontSize);
 end
 
 function FCF_CancelFontColorSettings(previousValues)
 	if ( previousValues.r ) then
 		ChangeChatColor(UIDROPDOWNMENU_MENU_VALUE, previousValues.r, previousValues.g, previousValues.b);
 	end
 end
 
 function FCF_CancelWindowColorSettings(previousValues)
 	if ( previousValues.r ) then
 		FCF_SetWindowColor(FCF_GetCurrentChatFrame(), previousValues.r, previousValues.g, previousValues.b)
 		SetChatWindowColor(FCF_GetCurrentChatFrameID(), previousValues.r, previousValues.g, previousValues.b);
 	end
 	if ( previousValues.opacity ) then
 		FCF_SetWindowAlpha(FCF_GetCurrentChatFrame(), 1 - previousValues.opacity);
 	end
 end
 
 function FCF_StripChatMsg(string)
 	if ( strsub(string,1,8) == "CHAT_MSG" ) then
 		return strsub(string,10);
 	else
 		return string;
 	end
 end
 
 function FCF_ToggleLock()
 	local chatFrame = FCF_GetCurrentChatFrame();
 	if ( chatFrame.isLocked ) then
 		-- If unlocking a docked frame then undock it and center it on the screen
 		if ( chatFrame.isDocked and chatFrame ~= DEFAULT_CHAT_FRAME ) then
 			FCF_UnDockFrame(chatFrame);
 			chatFrame:ClearAllPoints();
 			chatFrame:SetPoint("CENTER", "UIParent", "CENTER", 0, 0);
 			FCF_SetTabPosition(chatFrame, 0);
 			chatFrame:Show();
 		end
-		FCF_SetLocked(chatFrame, nil);
+		FCF_SetLocked(chatFrame, false);
 	else
-		FCF_SetLocked(chatFrame, 1);
+		FCF_SetLocked(chatFrame, true);
 	end
 end
 
 function FCF_SetLocked(chatFrame, isLocked)
 	chatFrame.isLocked = isLocked;
 	if ( chatFrame.isUninteractable or isLocked ) then
 		chatFrame.resizeButton:Hide();
 	else
 		chatFrame.resizeButton:Show();
 		--chatFrame.resizeButton:SetAlpha(_G[chatFrame:GetName().."Background"]:GetAlpha());
 	end
 	SetChatWindowLocked(chatFrame:GetID(), isLocked);
 end
 
 function FCF_ToggleUninteractable()
 	local chatFrame = FCF_GetCurrentChatFrame();
 	if ( chatFrame.isUninteractable ) then
 		FCF_SetExpandedUninteractable(chatFrame, false)
 	else
 		FCF_SetExpandedUninteractable(chatFrame, true)
 	end
 end
 
 function FCF_SetExpandedUninteractable(chatFrame, isUninteractable)
 	if ( chatFrame.isDocked ) then
 		for _, frame in pairs(GENERAL_CHAT_DOCK.DOCKED_CHAT_FRAMES) do
 			FCF_SetUninteractable(frame, isUninteractable);
 		end
 	else
 		FCF_SetUninteractable(chatFrame, isUninteractable);
 	end
 end
 
 function FCF_SetUninteractable(chatFrame, isUninteractable)	--No, uninteractable is not really a word.
 	chatFrame.isUninteractable = isUninteractable;
 	SetChatWindowUninteractable(chatFrame:GetID(), isUninteractable);
 	if ( not chatFrame.overrideHyperlinksEnabled ) then
 		chatFrame:SetHyperlinksEnabled(not isUninteractable);
 	end
 	local chatFrameName = chatFrame:GetName();
 	if ( isUninteractable or chatFrame.isLocked ) then
 		_G[chatFrameName.."ResizeButton"]:Hide();
 	else
 		_G[chatFrameName.."ResizeButton"]:Show();
 	end
 end
 
 function FCF_FadeInChatFrame(chatFrame)
 	local frameName = chatFrame:GetName();
 	chatFrame.hasBeenFaded = true;
 	for index, value in pairs(CHAT_FRAME_TEXTURES) do
 		local object = _G[frameName..value];
 		if ( object:IsShown() ) then
 			UIFrameFadeIn(object, CHAT_FRAME_FADE_TIME, object:GetAlpha(), max(chatFrame.oldAlpha, DEFAULT_CHATFRAME_ALPHA));
 		end
 	end
 	if ( chatFrame == FCFDock_GetSelectedWindow(GENERAL_CHAT_DOCK) ) then
 		for _, frame in pairs(FCFDock_GetChatFrames(GENERAL_CHAT_DOCK)) do
 			if ( frame ~= chatFrame ) then
 				FCF_FadeInChatFrame(frame);
 			end
 		end
 		if ( GENERAL_CHAT_DOCK.overflowButton:IsShown() ) then
 			UIFrameFadeIn(GENERAL_CHAT_DOCK.overflowButton, CHAT_FRAME_FADE_TIME, GENERAL_CHAT_DOCK.overflowButton:GetAlpha(), CHAT_FRAME_TAB_SELECTED_MOUSEOVER_ALPHA);
 		end
 	end
 	
 	local chatTab = _G[frameName.."Tab"];
 	UIFrameFadeIn(chatTab, CHAT_FRAME_FADE_TIME, chatTab:GetAlpha(), chatTab.mouseOverAlpha);
 	
 	--Fade in the button frame
 	if ( not chatFrame.isDocked ) then
 		UIFrameFadeIn(chatFrame.buttonFrame, CHAT_FRAME_FADE_TIME, chatFrame.buttonFrame:GetAlpha(), 1);
 	end
 end
 
 function FCF_FadeOutChatFrame(chatFrame)
 	local frameName = chatFrame:GetName();
 	chatFrame.hasBeenFaded = nil;
 	for index, value in pairs(CHAT_FRAME_TEXTURES) do
 		-- Fade out chat frame
 		local object = _G[frameName..value];
 		if ( object:IsShown() ) then
 			UIFrameFadeOut(object, CHAT_FRAME_FADE_OUT_TIME, max(object:GetAlpha(), chatFrame.oldAlpha), chatFrame.oldAlpha);
 		end
 	end
 	if ( chatFrame == FCFDock_GetSelectedWindow(GENERAL_CHAT_DOCK) ) then
 		for _, frame in pairs(FCFDock_GetChatFrames(GENERAL_CHAT_DOCK)) do
 			if ( frame ~= chatFrame ) then
 				FCF_FadeOutChatFrame(frame);
 			end
 		end
 		if ( GENERAL_CHAT_DOCK.overflowButton:IsShown() ) then
 			UIFrameFadeOut(GENERAL_CHAT_DOCK.overflowButton, CHAT_FRAME_FADE_OUT_TIME, GENERAL_CHAT_DOCK.overflowButton:GetAlpha(), CHAT_FRAME_TAB_SELECTED_NOMOUSE_ALPHA);
 		end
 	end
 	
 	local chatTab = _G[frameName.."Tab"];
 	UIFrameFadeOut(chatTab, CHAT_FRAME_FADE_OUT_TIME, chatTab:GetAlpha(), chatTab.noMouseAlpha);
 	
 	--Fade out the ButtonFrame
 	if ( not chatFrame.isDocked ) then
 		UIFrameFadeOut(chatFrame.buttonFrame, CHAT_FRAME_FADE_OUT_TIME, chatFrame.buttonFrame:GetAlpha(), CHAT_FRAME_BUTTON_FRAME_MIN_ALPHA);
 	end
 end
 	
 local LAST_CURSOR_X, LAST_CURSOR_Y;
 function FCF_OnUpdate(elapsed)
 	local cursorX, cursorY = GetCursorPosition();
 	
 	local overSomething = false;
 	for _, frameName in pairs(CHAT_FRAMES) do
 		local chatFrame = _G[frameName];
 		if ( chatFrame:IsShown() ) then
 			local topOffset = 28;
 			if ( IsCombatLog(chatFrame) ) then
 				topOffset = topOffset + CombatLogQuickButtonFrame_Custom:GetHeight();
 			end
 			--Items that will always cause the frame to fade in.
 			if ( MOVING_CHATFRAME or chatFrame.resizeButton:GetButtonState() == "PUSHED" or (chatFrame.isDocked and GENERAL_CHAT_DOCK.overflowButton.list:IsShown())) then	
 				overSomething = true;
 				chatFrame.mouseOutTime = 0;
 				if ( not chatFrame.hasBeenFaded ) then
 					overSomething = true;
 					FCF_FadeInChatFrame(chatFrame);
 				end
 			--Things that will cause the frame to fade in if the mouse is stationary.
 			elseif ( chatFrame:IsMouseOver(topOffset, -2, -2, 2) or	--This should be slightly larger than the hit rect insets to give us some wiggle room.
 				(chatFrame.isDocked and FriendsMicroButton:IsMouseOver()) or
 				(chatFrame.buttonFrame:IsMouseOver())) then
 				overSomething = true;
 				chatFrame.mouseOutTime = 0;
 				if ( cursorX == LAST_CURSOR_X and cursorY == LAST_CURSOR_Y and not chatFrame.hasBeenFaded ) then
 					chatFrame.mouseInTime = (chatFrame.mouseInTime or 0) + elapsed;
 					if ( chatFrame.mouseInTime > CHAT_TAB_SHOW_DELAY ) then
 						FCF_FadeInChatFrame(chatFrame);
 					end
 				else
 					chatFrame.mouseInTime = 0;
 				end
 			elseif ( chatFrame:IsShown() and chatFrame.hasBeenFaded ) then
 				chatFrame.mouseInTime = 0;
 				chatFrame.mouseOutTime = (chatFrame.mouseOutTime or 0) + elapsed;
 				if ( chatFrame.mouseOutTime > CHAT_TAB_HIDE_DELAY ) then
 					FCF_FadeOutChatFrame(chatFrame);
 				end
 			end
 		end
 	end
 	
 	LAST_CURSOR_X, LAST_CURSOR_Y = cursorX, cursorY;
 end
 
 function FCF_SavePositionAndDimensions(chatFrame)
 	local centerX = chatFrame:GetLeft() + chatFrame:GetWidth() / 2;
 	local centerY = chatFrame:GetBottom() + chatFrame:GetHeight() / 2;
 	
 	local horizPoint, vertPoint;
 	local screenWidth, screenHeight = GetScreenWidth(), GetScreenHeight();
 	local xOffset, yOffset;
 	if ( centerX > screenWidth / 2 ) then
 		horizPoint = "RIGHT";
 		xOffset = (chatFrame:GetRight() - screenWidth)/screenWidth;
 	else
 		horizPoint = "LEFT";
 		xOffset = chatFrame:GetLeft()/screenWidth;
 	end
 	
 	if ( centerY > screenHeight / 2 ) then
 		vertPoint = "TOP";
 		yOffset = (chatFrame:GetTop() - screenHeight)/screenHeight;
 	else
 		vertPoint = "BOTTOM";
 		yOffset = chatFrame:GetBottom()/screenHeight;
 	end
 	
 	SetChatWindowSavedPosition(chatFrame:GetID(), vertPoint..horizPoint, xOffset, yOffset);
 	SetChatWindowSavedDimensions(chatFrame:GetID(), chatFrame:GetWidth(), chatFrame:GetHeight());
 end
 
 function FCF_RestorePositionAndDimensions(chatFrame)
 	local width, height = GetChatWindowSavedDimensions(chatFrame:GetID());
 	if ( width and height ) then
 		chatFrame:SetSize(width, height);
 	end
 	
 	local point, xOffset, yOffset = GetChatWindowSavedPosition(chatFrame:GetID());
 	if ( point ) then
 		chatFrame:ClearAllPoints();
 		chatFrame:SetPoint(point, xOffset * GetScreenWidth(), yOffset * GetScreenHeight());
 		chatFrame:SetUserPlaced(true);
 	else
 		chatFrame:SetUserPlaced(false);
 	end
 end
 
 -- Docking handling functions
 function FCF_StopDragging(chatFrame)
 	chatFrame:StopMovingOrSizing();
 
 	_G[chatFrame:GetName().."Tab"]:UnlockHighlight();
 	
 	FCFDock_HideInsertHighlight(GENERAL_CHAT_DOCK);
 	
 	if ( GENERAL_CHAT_DOCK:IsMouseOver(10, -10, 0, 10) ) then
 		local mouseX, mouseY = GetCursorPosition();
 		mouseX, mouseY = mouseX / UIParent:GetScale(), mouseY / UIParent:GetScale();
 		FCF_DockFrame(chatFrame, FCFDock_GetInsertIndex(GENERAL_CHAT_DOCK, chatFrame, mouseX, mouseY), true);
 	else
 		FCF_SetTabPosition(chatFrame, 0);
 	end
 	
 	FCF_SavePositionAndDimensions(chatFrame);
 
 	MOVING_CHATFRAME = nil;
 end
 
 function FCFTab_OnUpdate(self, elapsed)
 	local cursorX, cursorY = GetCursorPosition();
 	cursorX, cursorY = cursorX / UIParent:GetScale(), cursorY / UIParent:GetScale();
 	local chatFrame = _G["ChatFrame"..self:GetID()];
 	if ( chatFrame ~= GENERAL_CHAT_DOCK.primary and GENERAL_CHAT_DOCK:IsMouseOver(10, -10, 0, 10) ) then
 		FCFDock_PlaceInsertHighlight(GENERAL_CHAT_DOCK, chatFrame, cursorX, cursorY);
 	else
 		FCFDock_HideInsertHighlight(GENERAL_CHAT_DOCK);
 	end
 	
 	FCF_UpdateButtonSide(chatFrame);
 	if ( chatFrame == GENERAL_CHAT_DOCK.primary ) then
 		for _, frame in pairs(FCFDock_GetChatFrames(GENERAL_CHAT_DOCK)) do
 			FCF_SetButtonSide(frame, FCF_GetButtonSide(GENERAL_CHAT_DOCK.primary));
 		end
 	end
 	
 	if ( not IsMouseButtonDown(self.dragButton) ) then
 		FCFTab_OnDragStop(self, self.dragButton);
 		self.dragButton = nil;
 		self:SetScript("OnUpdate", nil);
 	end
 
 	if ( BNToastFrame and BNToastFrame:IsShown() ) then
 		BNToastFrame_UpdateAnchor();
 	end	
 end
 
 function FCFTab_OnDragStop(self, button)
 	FCF_StopDragging(_G["ChatFrame"..self:GetID()]);
 end
 
 DEFAULT_TAB_SELECTED_COLOR_TABLE = { r = 1, g = 0.5, b = 0.25 };
 
 function FCFTab_UpdateColors(self, selected)
 	if ( selected ) then
 		self.leftSelectedTexture:Show();
 		self.middleSelectedTexture:Show();
 		self.rightSelectedTexture:Show();
 	else
 		self.leftSelectedTexture:Hide();
 		self.middleSelectedTexture:Hide();
 		self.rightSelectedTexture:Hide();
 	end
 	
 	local colorTable = self.selectedColorTable or DEFAULT_TAB_SELECTED_COLOR_TABLE;
 	
 	if ( self.selectedColorTable ) then
 		self:GetFontString():SetTextColor(colorTable.r, colorTable.g, colorTable.b);
 	else
 		self:GetFontString():SetTextColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b);
 	end
 	
 	self.leftSelectedTexture:SetVertexColor(colorTable.r, colorTable.g, colorTable.b);
 	self.middleSelectedTexture:SetVertexColor(colorTable.r, colorTable.g, colorTable.b);
 	self.rightSelectedTexture:SetVertexColor(colorTable.r, colorTable.g, colorTable.b);
 	
 	self.leftHighlightTexture:SetVertexColor(colorTable.r, colorTable.g, colorTable.b);
 	self.middleHighlightTexture:SetVertexColor(colorTable.r, colorTable.g, colorTable.b);
 	self.rightHighlightTexture:SetVertexColor(colorTable.r, colorTable.g, colorTable.b);
 	self.glow:SetVertexColor(colorTable.r, colorTable.g, colorTable.b);
 	
 	if ( self.conversationIcon ) then
 		self.conversationIcon:SetVertexColor(colorTable.r, colorTable.g, colorTable.b);
 	end
 	
 	local minimizedFrame = _G["ChatFrame"..self:GetID().."Minimized"];
 	if ( minimizedFrame ) then
 		minimizedFrame.selectedColorTable = self.selectedColorTable;
 		FCFMin_UpdateColors(minimizedFrame);
 	end
 end
 
 function FCFTab_UpdateAlpha(chatFrame)
 	local chatTab = _G[chatFrame:GetName().."Tab"];
 	if ( not chatFrame.isDocked or chatFrame == FCFDock_GetSelectedWindow(GENERAL_CHAT_DOCK) ) then
 		chatTab.mouseOverAlpha = CHAT_FRAME_TAB_SELECTED_MOUSEOVER_ALPHA;
 		chatTab.noMouseAlpha = CHAT_FRAME_TAB_SELECTED_NOMOUSE_ALPHA;
 	else
 		if ( chatTab.alerting ) then
 			chatTab.mouseOverAlpha = CHAT_FRAME_TAB_ALERTING_MOUSEOVER_ALPHA;
 			chatTab.noMouseAlpha = CHAT_FRAME_TAB_ALERTING_NOMOUSE_ALPHA;
 		else
 			chatTab.mouseOverAlpha = CHAT_FRAME_TAB_NORMAL_MOUSEOVER_ALPHA;
 			chatTab.noMouseAlpha = CHAT_FRAME_TAB_NORMAL_NOMOUSE_ALPHA;
 		end
 	end
 	
 	-- If this is in the middle of fading, stop it, since we're about to set the alpha
 	UIFrameFadeRemoveFrame(chatTab);
 	
 	if ( chatFrame.hasBeenFaded ) then
 		chatTab:SetAlpha(chatTab.mouseOverAlpha);
 	else
 		chatTab:SetAlpha(chatTab.noMouseAlpha);
 	end
 end
 
 function FCF_HideOnFadeFinished(frame)
 	frame:Hide();
 end
 
 function FCF_IsValidChatFrame(chatFrame)
 	-- Break out all the cases individually because the logic gets convoluted
 	if ( chatFrame == MOVING_CHATFRAME ) then
 		return nil;
 	end
 
 	if ( not chatFrame:IsShown() and not chatFrame.isDocked ) then
 		return nil;
 	end
 	
 	return 1;
 end
 
 function FCF_UpdateButtonSide(chatFrame)
 	local leftDist =  chatFrame:GetLeft();
 	local rightDist = GetScreenWidth() - chatFrame:GetRight();
 	local changed = nil;
 	if (( leftDist > 0 and leftDist <= rightDist ) or rightDist < 0 ) then
 		if ( chatFrame.buttonSide ~= "left" ) then
 			FCF_SetButtonSide(chatFrame, "left");
 			changed = 1;
 		end
 	else
 		if ( chatFrame.buttonSide ~= "right" or leftDist < 0 ) then
 			FCF_SetButtonSide(chatFrame, "right");
 			changed = 1;
 		end
 	end
 	return changed;
 end
 
 function FCF_SetButtonSide(chatFrame, buttonSide, forceUpdate)
 	if ( not forceUpdate and chatFrame.buttonSide == buttonSide  ) then
 		return;
 	end
 	chatFrame.buttonFrame:ClearAllPoints();
 	
 	local topY = 0;
 	if ( IsCombatLog(chatFrame) ) then
 		topY = topY + CombatLogQuickButtonFrame_Custom:GetHeight();
 	end
 
 	if ( buttonSide == "left" ) then
 		chatFrame.buttonFrame:SetPoint("TOPRIGHT", chatFrame, "TOPLEFT", -4, topY);
 		chatFrame.buttonFrame:SetPoint("BOTTOMRIGHT", chatFrame, "BOTTOMLEFT", -4, 0);
 	elseif ( buttonSide == "right" ) then
 		chatFrame.buttonFrame:SetPoint("TOPLEFT", chatFrame, "TOPRIGHT", 4, topY);
 		chatFrame.buttonFrame:SetPoint("BOTTOMLEFT", chatFrame, "BOTTOMRIGHT", 4, 0);
 	end
 	chatFrame.buttonSide = buttonSide;
 	
 	if ( chatFrame == DEFAULT_CHAT_FRAME ) then
 		ChatFrameMenu_UpdateAnchorPoint();
 	end
 end
 
 function FCF_StartAlertFlash(chatFrame)
 	if ( chatFrame.minFrame ) then
 		UIFrameFlash(chatFrame.minFrame.glow, 1.0, 1.0, -1, false, 0, 0, "chat");
 		
 		chatFrame.minFrame.alerting = true;
 	end
 	
 	local chatTab = _G[chatFrame:GetName().."Tab"];
 	UIFrameFlash(chatTab.glow, 1.0, 1.0, -1, false, 0, 0, "chat");
 	
 	chatTab.alerting = true;
 	
 	FCFTab_UpdateAlpha(chatFrame);
 	
 	FCFDockOverflowButton_UpdatePulseState(GENERAL_CHAT_DOCK.overflowButton);
 end
 
 function FCF_StopAlertFlash(chatFrame)
 	if ( chatFrame.minFrame ) then
 		UIFrameFlashStop(chatFrame.minFrame.glow);
 		
 		chatFrame.minFrame.alerting = false;
 	end
 	
 	local chatTab = _G[chatFrame:GetName().."Tab"];
 	UIFrameFlashStop(chatTab.glow);
 	
 	chatTab.alerting = false;
 	
 	FCFTab_UpdateAlpha(chatFrame);
 
 	FCFDockOverflowButton_UpdatePulseState(GENERAL_CHAT_DOCK.overflowButton);
 end
 
 function FCF_GetButtonSide(chatFrame)
 	return chatFrame.buttonSide;
 end
 
 function FCF_DockUpdate()
 	FCFDock_UpdateTabs(GENERAL_CHAT_DOCK, true);
 end
 --[[
 	local numDockedFrames = getn(DOCKED_CHAT_FRAMES);
 	local dockRegion, chatTab, previousDockedFrame;
 	local dockWidth = 0;
 	local previousDockRegion;
 	local name;
 	for index, value in pairs(DOCKED_CHAT_FRAMES) do
 		-- If not the initial chatframe then anchor the frame to the base chatframe
 		name = value:GetName();
 		if ( index ~= 1 ) then
 			value:ClearAllPoints();
 			value:SetPoint("TOPLEFT", DEFAULT_CHAT_FRAME, "TOPLEFT", 0, 0);
 			value:SetPoint("BOTTOMLEFT", DEFAULT_CHAT_FRAME, "BOTTOMLEFT", 0, 0);
 			value:SetPoint("BOTTOMRIGHT", DEFAULT_CHAT_FRAME, "BOTTOMRIGHT", 0, 0);
 		end
 		
 		-- Select or deselect the frame
 		chatTab = _G[value:GetName().."Tab"];
 		-- chatTab.textWidth is the original width of the text name of the tab
 		-- We need to use this as an absolute measure of the text's width is altered when the chat dock gets too small
 		-- If the text is shrunken the original width is lost, unless we save it and use it in the following manner
 		-- This is a fix for Bug ID: 71180
 		PanelTemplates_TabResize(chatTab, 5, nil, nil, nil, chatTab.textWidth);
 		if ( value == SELECTED_DOCK_FRAME ) then
 			value:Show();
 			if ( chatTab:IsShown() ) then
 				chatTab:SetAlpha(1.0);
 			end
 		else
 			value:Hide();
 			if ( chatTab:IsShown() ) then
 				chatTab:SetAlpha(0.5);
 			end
 		end
 		
 		-- If there was a frame before this frame then anchor the tab
 		
 		if ( previousDockedFrame ) then
 			chatTab:ClearAllPoints();
 			FCF_SetTabPosition(value, dockWidth);
 			_G[previousDockedFrame:GetName().."TabDockRegion"]:SetPoint("RIGHT", value:GetName().."Tab", "CENTER", 0, 0);
 		end
 
 		-- If this is the last frame in the dock then extend the dockRegion, otherwise shrink it to the default width
 		dockRegion = _G[chatTab:GetName().."DockRegion"];
 		dockRegion:SetPoint("LEFT", chatTab, "CENTER", 0 , 0);
 		if ( numDockedFrames == index ) then
 			dockRegion:SetPoint("RIGHT", "ChatFrame"..chatTab:GetID(), "RIGHT", 0, 0);
 		end
 		dockRegion:Hide();
 		
 		-- Keep track of the width of the dock for anchoring purposes
 		dockWidth = dockWidth + chatTab:GetWidth();
 		previousDockedFrame = value;
 	end
 	
 	-- Intelligently resize the chat tabs if dockwidth is greater than the window width
 	if ( dockWidth > DEFAULT_CHAT_FRAME:GetWidth() ) then
 		DOCK_COPY = {};
 		-- Copy the array
 		for index, value in pairs(DOCKED_CHAT_FRAMES) do
 			DOCK_COPY[index] = DOCKED_CHAT_FRAMES[index];
 		end
 		sort(DOCK_COPY, FCF_TabCompare);
 		local totalWidth = DEFAULT_CHAT_FRAME:GetWidth();
 		local avgWidth = totalWidth / numDockedFrames;
 		local chatTabWidth;
 		-- Resize the tabs
 		for index, value in pairs(DOCK_COPY) do
 			chatTab = _G[value:GetName().."Tab"];
 			chatTabWidth = chatTab:GetWidth();
 			if ( chatTabWidth < avgWidth ) then
 				-- If tab is smaller than the average then remove it from the list and recalc the average
 				totalWidth = totalWidth - chatTabWidth;
 				numDockedFrames = numDockedFrames - 1;
 				avgWidth = totalWidth / numDockedFrames;
 			else
 				-- Set the tab to the average width
 				PanelTemplates_TabResize(chatTab, 0, avgWidth);
 			end
 		end
 
 		-- Reanchor the tabs
 		previousDockedFrame = nil;
 		dockWidth = 0;
 		for index, value in pairs(DOCKED_CHAT_FRAMES) do
 			-- If there was a frame before this frame then anchor the tab
 			if ( previousDockedFrame ) then
 				FCF_SetTabPosition(value, dockWidth);
 			end
 			chatTab = _G[value:GetName().."Tab"];
 			dockWidth = dockWidth + chatTab:GetWidth();
 			previousDockedFrame = value;
 		end
 	end
 end]]
 
 function FCF_TabCompare(chatFrame1, chatFrame2)
 	local tab1 = _G[chatFrame1:GetName().."Tab"];
 	local tab2 = _G[chatFrame2:GetName().."Tab"];
 	return tab1:GetWidth() < tab2:GetWidth();
 end
 
 function FCF_DockFrame(frame, index, selected)
 	-- Return if already docked
 	if ( frame.isDocked ) then
 		return;
 	end
 
 	FCFDock_AddChatFrame(GENERAL_CHAT_DOCK, frame, index);
 	
 	-- Save docked state
 	FCF_SaveDock();
 	if ( selected ) then
 		--FCF_SelectDockFrame(frame);
 		FCFDock_SelectWindow(GENERAL_CHAT_DOCK, frame);
 	end
 
 	-- Set scroll button side
 	if ( frame == DEFAULT_CHAT_FRAME ) then
 		FCF_UpdateButtonSide(frame);
 	else
 		FCF_SetButtonSide(frame, FCF_GetButtonSide(DEFAULT_CHAT_FRAME));
 	end
 	
 	-- Lock frame
-	FCF_SetLocked(frame, 1);
+	FCF_SetLocked(frame, true);
 	
 	--If the frame that is being docked and the frame it is docking to have different interactable settings, make them both interactable.
 	if ( frame.isUninteractable ~= DEFAULT_CHAT_FRAME.isUninteractable ) then
 		FCF_SetExpandedUninteractable(frame, false)
 	end
 	
 	if ( frame == COMBATLOG ) then
 		Blizzard_CombatLog_Update_QuickButtons();
 	end
 	
 	FCF_DockUpdate();
 end
 
 function FCF_UnDockFrame(frame)
 	if ( frame == DEFAULT_CHAT_FRAME or not frame.isDocked ) then
 		return;
 	end
 	-- Undock frame regardless of whether its docked or not
 	SetChatWindowDocked(frame:GetID(), nil);
 	FCFDock_RemoveChatFrame(GENERAL_CHAT_DOCK, frame);
 
 	FCF_SaveDock();
 	
 	-- Set tab to full alpha
 	local chatTab = _G[frame:GetName().."Tab"];
 	chatTab:SetAlpha(1.0);
 end
 
 function FCF_SelectDockFrame(frame)
 	SELECTED_DOCK_FRAME = frame;
 	-- Stop tab flashing
 	local tabFlash;
 	if ( frame ) then
 		tabFlash = _G["ChatFrame"..frame:GetID().."TabFlash"];
 	end
 	
 	if ( tabFlash ) then
 		UIFrameFlashStop(tabFlash);
 		tabFlash:Hide();
 	end
 	FCFDock_SelectWindow(GENERAL_CHAT_DOCK, frame);
 	FCF_DockUpdate();
 end
 
 function FCF_Tab_OnClick(self, button)
 	local chatFrame = _G["ChatFrame"..self:GetID()];
 	-- If Rightclick bring up the options menu
 	if ( button == "RightButton" ) then
 		chatFrame:StopMovingOrSizing();
 		CURRENT_CHAT_FRAME_ID = self:GetID();
 		ToggleDropDownMenu(1, nil, _G[self:GetName().."DropDown"], self:GetName(), 0, 0);
 		return;
 	end
 	
 	if (button == "MiddleButton") then
 		if ( chatFrame and (chatFrame ~= DEFAULT_CHAT_FRAME and not IsCombatLog(chatFrame)) ) then
 			if ( not chatFrame.isTemporary ) then
 				FCF_PopInWindow(self, chatFrame);
 				return;
 			elseif ( chatFrame.isTemporary and (chatFrame.chatType == "WHISPER" or chatFrame.chatType == "BN_WHISPER") ) then
 				FCF_PopInWindow(self, chatFrame);
 				return;
 			elseif ( chatFrame.isTemporary and ( chatFrame.chatType == "BN_CONVERSATION" ) ) then
 				if ( GetCVar("conversationMode") == "popout" or GetCVar("conversationMode") == "popout_and_inline" ) then
 					FCF_LeaveConversation(self, chatFrame);
 					return;
 				else
 					FCF_PopInWindow(self, chatFrame);
 					return;
 				end
 			elseif ( chatFrame.isTemporary and ( chatFrame.chatType == "PET_BATTLE_COMBAT_LOG" ) ) then
 				FCF_Close(chatFrame);
 			else
 				GMError(format("Unhandled temporary window type. chatType: %s, chatTarget %s", tostring(chatFrame.chatType), tostring(chatFrame.chatTarget)));
 			end
 		end
 		return;
 	end
 
 	-- Close all dropdowns
 	CloseDropDownMenus();
 
 	-- If frame is docked assume that a click is to select a chat window, not drag it
 	SELECTED_CHAT_FRAME = chatFrame;
 	if ( chatFrame.isDocked and FCFDock_GetSelectedWindow(GENERAL_CHAT_DOCK) ~= chatFrame ) then
 		FCF_SelectDockFrame(chatFrame);
 		FCF_FadeInChatFrame(chatFrame);
 		return;
 	else
 		if ( GetCVar("chatStyle") ~= "classic" ) then
 			ChatEdit_SetLastActiveWindow(chatFrame.editBox);
 		end
 		FCF_FadeInChatFrame(chatFrame);
 	end
 	
 end
 
 function FCF_SetTabPosition(chatFrame, x)
 	local chatTab = _G[chatFrame:GetName().."Tab"];
 	chatTab:ClearAllPoints();
 	chatTab:SetPoint("BOTTOMLEFT", chatFrame:GetName().."Background", "TOPLEFT", x+2, 0);
 end
 
 function FCF_SaveDock()
 	for index, value in pairs(FCFDock_GetChatFrames(GENERAL_CHAT_DOCK)) do
 		SetChatWindowDocked(value:GetID(), index);
 	end
 end
 
 function FCF_LeaveConversation(frame, fallback)
 	if ( fallback ) then
 		frame=fallback
 	end
 	if ( not frame ) then
 		frame = FCF_GetCurrentChatFrame();
 	end
 	
 	assert(frame.chatType == "BN_CONVERSATION");
 	BNLeaveConversation(tonumber(frame.chatTarget));
 	
 	FCF_Close(frame);
 end
 
 function FCF_PopInWindow(frame, fallback)
 	if ( fallback ) then
         frame=fallback
     end
 	if ( not frame ) then
 		frame = FCF_GetCurrentChatFrame();
 	end
 	if ( frame == DEFAULT_CHAT_FRAME ) then
 		return;
 	end
 	
 	--Restore any chats this frame had to the DEFAULT_CHAT_FRAME
 	FCF_RestoreChatsToFrame(DEFAULT_CHAT_FRAME, frame);
 	
 	FCF_Close(frame);
 end
 
 function FCF_Close(frame, fallback)
     if ( fallback ) then
         frame=fallback
     end
 	if ( not frame ) then
 		frame = FCF_GetCurrentChatFrame();
 	end
 	if ( frame == DEFAULT_CHAT_FRAME ) then
 		return;
 	end
 	FCF_UnDockFrame(frame);
 	HideUIPanel(frame);
 	_G[frame:GetName().."Tab"]:Hide();
 	FCF_FlagMinimizedPositionReset(frame);
 	if ( frame.minFrame and frame.minFrame:IsShown() ) then
 		frame.minFrame:Hide();
 	end
 	if ( frame.isTemporary ) then
 		FCFManager_UnregisterDedicatedFrame(frame, frame.chatType, frame.chatTarget);
 		frame.isRegistered = false;
 		frame.inUse = false;
 	end
 	if ( PENDING_BN_WHISPER_TO_CONVERSATION_FRAME == frame ) then
 		PENDING_BN_WHISPER_TO_CONVERSATION_FRAME = nil;
 	end
 	
 	--Reset what this window receives.
 	ChatFrame_RemoveAllMessageGroups(frame);
 	ChatFrame_RemoveAllChannels(frame);
 	ChatFrame_ReceiveAllPrivateMessages(frame);
 	ChatFrame_ReceiveAllBNConversations(frame);
 end
 
 function FCF_RestoreChatsToFrame(targetFrame, sourceFrame)
 	--Restore chat types
 	for _, messageType in pairs(sourceFrame.messageTypeList) do
 		ChatFrame_AddMessageGroup(targetFrame, messageType);
 	end
 	
 	--Restore channels
 	for _, channel in pairs(sourceFrame.channelList) do
 		ChatFrame_AddChannel(targetFrame, channel);
 	end
 	
 	--Restore whispers
 	if ( sourceFrame.privateMessageList ) then
 		for name, value in pairs(sourceFrame.privateMessageList) do
 			if ( value ) then
 				ChatFrame_RemoveExcludePrivateMessageTarget(targetFrame, name);
 			end
 		end
 	end
 	
 	if ( sourceFrame.bnConversationList ) then
 		for name, value in pairs(sourceFrame.bnConversationList) do
 			if ( value ) then
 				ChatFrame_RemoveExcludeBNConversationTarget(targetFrame, name);
 			end
 		end
 	end
 end
 
 -- Tab flashing functions
 function FCF_FlashTab(self)
 	local tabFlash = _G[self:GetName().."TabFlash"];
 	if ( not self.isDocked or (self == SELECTED_DOCK_FRAME) or UIFrameIsFlashing(tabFlash) ) then
 		return;
 	end
 	tabFlash:Show();
 	UIFrameFlash(tabFlash, 0.25, 0.25, 60, nil, 0.5, 0.5);
 end
 
 -- Function for repositioning the chat dock depending on if there's a shapeshift bar/stance bar, etc...
 function FCF_UpdateDockPosition()
 	if ( DEFAULT_CHAT_FRAME:IsUserPlaced() ) then
 		return;
 	end
 	
 	local chatOffset = 85;
 	if ( GetNumShapeshiftForms() > 0 or HasPetUI() or PetHasActionBar() ) then
 		if ( MultiBarBottomLeft:IsShown() ) then
 			chatOffset = chatOffset + 55;
 		else
 			chatOffset = chatOffset + 15;
 		end
 	elseif ( MultiBarBottomLeft:IsShown() ) then
 		chatOffset = chatOffset + 15;
 	end
 	DEFAULT_CHAT_FRAME:SetPoint("BOTTOMLEFT", "UIParent", "BOTTOMLEFT", 32, chatOffset);
 	FCF_DockUpdate();
 end
 
 function FCF_Set_NormalChat()
 	ChatFrame2:StartMoving();
 	ChatFrame2:StopMovingOrSizing();
-	FCF_SetLocked(ChatFrame2, nil);
+	FCF_SetLocked(ChatFrame2, false);
 	-- to fix a bug with the combat log not repositioning its tab properly when coming out of
 	-- simple chat, we need to update now
 	FCF_DockUpdate();
 end
 
 -- Functions to set and remove the chat window show delay on mouseover
 function SetChatMouseOverDelay(noDelay)
 	if ( noDelay == "1" ) then
 		CHAT_TAB_SHOW_DELAY = 0;
 		CHAT_FRAME_FADE_TIME = 0;
 	else
 		CHAT_TAB_SHOW_DELAY = 0.2;
 		CHAT_FRAME_FADE_TIME = 0.15;
 	end
 end
 
 -- Reset the chat windows to default
 function FCF_ResetChatWindows()
 	ChatFrame1:ClearAllPoints();
 	ChatFrame1:SetPoint("BOTTOMLEFT", "UIParent", "BOTTOMLEFT", 32, 95);
 	ChatFrame1:SetWidth(430);
 	ChatFrame1:SetHeight(120);
 	ChatFrame1.isInitialized = 0;
 	FCF_SetButtonSide(ChatFrame1, "left")
 	FCF_SetChatWindowFontSize(nil, ChatFrame1, 14);
 	FCF_SetWindowName(ChatFrame1, GENERAL);
 	FCF_SetWindowColor(ChatFrame1, DEFAULT_CHATFRAME_COLOR.r, DEFAULT_CHATFRAME_COLOR.g, DEFAULT_CHATFRAME_COLOR.b);
 	FCF_SetWindowAlpha(ChatFrame1, DEFAULT_CHATFRAME_ALPHA);
 	FCF_UnDockFrame(ChatFrame1);
 	ChatFrame_RemoveAllMessageGroups(ChatFrame1);
 	ChatFrame_RemoveAllChannels(ChatFrame1);
 	ChatFrame_ReceiveAllPrivateMessages(ChatFrame1);
 	ChatFrame_ReceiveAllBNConversations(ChatFrame1);
 	SELECTED_CHAT_FRAME = ChatFrame1;
 	DEFAULT_CHAT_FRAME.chatframe = DEFAULT_CHAT_FRAME;
 
 	FCF_SetChatWindowFontSize(nil, ChatFrame2, 14);
 	FCF_SetWindowName(ChatFrame2, COMBAT_LOG);
 	FCF_SetWindowColor(ChatFrame2, DEFAULT_CHATFRAME_COLOR.r, DEFAULT_CHATFRAME_COLOR.g, DEFAULT_CHATFRAME_COLOR.b);
 	FCF_SetWindowAlpha(ChatFrame2, DEFAULT_CHATFRAME_ALPHA);
 	ChatFrame_RemoveAllMessageGroups(ChatFrame2);
 	ChatFrame_RemoveAllChannels(ChatFrame2);
 	ChatFrame_ReceiveAllPrivateMessages(ChatFrame2);
 	ChatFrame_ReceiveAllBNConversations(ChatFrame2);
 	FCF_UnDockFrame(ChatFrame2);
 	ChatFrame2.isInitialized = 0;
 	for _, chatFrameName in ipairs(CHAT_FRAMES) do
 		if ( chatFrameName ~= "ChatFrame1" ) then
 			local chatFrame = _G[chatFrameName];
 			if ( chatFrame.isTemporary and chatFrame.chatType == "BN_CONVERSATION" and
 				BNGetConversationInfo(tonumber(chatFrame.chatTarget)) and (GetCVar("conversationMode") == "popout" or GetCVar("conversationMode") == "popout_and_inline") ) then
 				--We're still in this conversation, so we just want to reset the position, not remove the frame.
 				FCF_DockFrame(chatFrame, 3);	--Put it after General and Combat Log
 			else
 				chatFrame.isInitialized = 0;
 				FCF_SetTabPosition(chatFrame, 0);
 				FCF_Close(chatFrame);
 				FCF_UnDockFrame(chatFrame);
 				FCF_SetWindowName(chatFrame, "");
 				ChatFrame_RemoveAllMessageGroups(chatFrame);
 				ChatFrame_RemoveAllChannels(chatFrame);
 				ChatFrame_ReceiveAllPrivateMessages(chatFrame);
 				ChatFrame_ReceiveAllBNConversations(chatFrame);
 			end
 			FCF_SetChatWindowFontSize(nil, chatFrame, 14);
 			FCF_SetWindowColor(chatFrame, DEFAULT_CHATFRAME_COLOR.r, DEFAULT_CHATFRAME_COLOR.g, DEFAULT_CHATFRAME_COLOR.b);
 			FCF_SetWindowAlpha(chatFrame, DEFAULT_CHATFRAME_ALPHA);
 		end
 	end
 	ChatFrame1.init = 0;
 	FCF_DockFrame(ChatFrame1, 1, true);
 	FCF_DockFrame(ChatFrame2, 2);
 
 	-- resets to hard coded defaults
 	ResetChatWindows();
 	UIParent_ManageFramePositions();
 	FCFDock_SelectWindow(GENERAL_CHAT_DOCK, ChatFrame1);
 end
 
 function IsCombatLog(frame)
 	if ( frame == ChatFrame2 and IsAddOnLoaded("Blizzard_CombatLog") ) then
 		return true;
 	else
 		return false;
 	end
 end
 
 function FCFClickAnywhereButton_OnLoad(self)
 	self:SetFrameLevel(self:GetParent():GetFrameLevel() - 1);
 	self:RegisterEvent("VARIABLES_LOADED");
 	self:RegisterEvent("CVAR_UPDATE");
 	self:RegisterForClicks("LeftButtonDown", "RightButtonDown");
 	FCFClickAnywhereButton_UpdateState(self);
 end
 
 function FCFClickAnywhereButton_OnEvent(self, event, ...)
 	local arg1 = ...;
 	if ( event == "VARIABLES_LOADED" or
 		(event == "CVAR_UPDATE" and (arg1 == "chatStyle" or arg1 == "CHAT_WHOLE_WINDOW_CLICKABLE")) ) then
 		FCFClickAnywhereButton_UpdateState(self);
 	end
 end
 
 function FCFClickAnywhereButton_UpdateState(self)
 	if ( GetCVar("chatStyle") == "im" and GetCVarBool("wholeChatWindowClickable") and
 		LAST_ACTIVE_CHAT_EDIT_BOX ~=  self:GetParent().editBox ) then
 		self:Show();
 	else
 		self:Hide();
 	end
 end
 
 function FCF_MinimizeFrame(chatFrame, side)
 	local chatTab = _G[chatFrame:GetName().."Tab"];
 	
 	local createdFrame = false;
 	if ( not chatFrame.minFrame ) then
 		chatFrame.minFrame = FCF_CreateMinimizedFrame(chatFrame);
 	end
 	
 	if ( chatFrame.minFrame.resetPosition ) then
 		chatFrame.minFrame:ClearAllPoints();
 		chatFrame.minFrame:SetPoint("TOP"..side, chatFrame, "TOP"..side, 0, 0);
 		chatFrame.minFrame.resetPosition = false;
 	end
 	
 	chatFrame.minimized = true;
 	
 	chatFrame.minFrame:Show();
 	chatFrame:Hide();
 	chatTab:Hide();
 end
 
 function FCF_MaximizeFrame(chatFrame)
 	local minFrame = chatFrame.minFrame;
 	local chatTab = _G[chatFrame:GetName().."Tab"];
 	
 	chatFrame.minimized = false;
 	
 	minFrame:UnlockHighlight();
 	minFrame:Hide();
 	chatFrame:Show();
 	chatTab:Show();
 	
 	FCF_FadeInChatFrame(chatFrame);
 	
 	if ( GetCVar("chatStyle") == "im" ) then
 		ChatEdit_SetLastActiveWindow(chatFrame.editBox);
 	end
 end
 
 function FCF_CreateMinimizedFrame(chatFrame)
 	local chatTab = _G[chatFrame:GetName().."Tab"];
 	
 	local minFrame = CreateFrame("Button", chatFrame:GetName().."Minimized", UIParent, "FloatingChatFrameMinimizedTemplate");
 	minFrame.maxFrame = chatFrame;
 	
 	minFrame:SetText(chatFrame.name);
 
 	--Copy the colors from the minimized frame.
 	minFrame.selectedColorTable = chatTab.selectedColorTable;
 	FCFMin_UpdateColors(minFrame);
 	
 	if ( not chatFrame.isTemporary ) then
 		minFrame.conversationIcon:Hide();
 	else
 		local conversationIcon;
 		if ( chatFrame.chatType == "WHISPER" or chatFrame.chatType == "BN_WHISPER" ) then
 			conversationIcon = "Interface\\ChatFrame\\UI-ChatWhisperIcon";
 		elseif ( chatFrame.chatType == "PET_BATTLE_COMBAT_LOG" ) then
 			conversationIcon = "Interface\\Icons\\Tracking_WildPet";
 		else
 			conversationIcon = "Interface\\ChatFrame\\UI-ChatConversationIcon";
 		end
 		
 		minFrame.conversationIcon:SetTexture(conversationIcon);
 	end
 	
 	if (chatFrame.isTemporary) then
 		minFrame.Text:SetJustifyH("LEFT");
 		minFrame.Text:SetPoint("LEFT", minFrame, "LEFT", 30, 0);
 	end
 	
 	--Make sure the position is reset.
 	minFrame.resetPosition = true;
 	
 	return minFrame;
 end
 
 function FCFMin_UpdateColors(minFrame)
 	--Color it.
 	local colorTable = minFrame.selectedColorTable or DEFAULT_TAB_SELECTED_COLOR_TABLE;
 	
 	if ( minFrame.selectedColorTable ) then
 		minFrame:GetFontString():SetTextColor(colorTable.r, colorTable.g, colorTable.b);
 	else
 		minFrame:GetFontString():SetTextColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b);
 	end
 
 	minFrame.leftHighlightTexture:SetVertexColor(colorTable.r, colorTable.g, colorTable.b);
 	minFrame.middleHighlightTexture:SetVertexColor(colorTable.r, colorTable.g, colorTable.b);
 	minFrame.rightHighlightTexture:SetVertexColor(colorTable.r, colorTable.g, colorTable.b);
 	minFrame.glow:SetVertexColor(colorTable.r, colorTable.g, colorTable.b);
 	
 	minFrame.conversationIcon:SetVertexColor(colorTable.r, colorTable.g, colorTable.b);
 end
 
 --This function just makes the position be reset the next time the minimize frame is shown.
 function FCF_FlagMinimizedPositionReset(chatFrame)
 	if ( chatFrame.minFrame ) then
 		chatFrame.minFrame.resetPosition = true;
 	end
 end
 
 ------Docking related functions for the new docking system
 --[[
 Since we've been discussing allowing multiple docks, this code is designed to be mostly-OO. Please try not to use global variables.
 (Theoretically, all of these functions may be put in a metatable to allow, e.g., "Dock:SelectWindow(chatWindow)".
 To keep with this, please ensure that "dock" is the first argument of every function.)
 ]]
 
 function FCFDock_OnLoad(dock)
 	dock.DOCKED_CHAT_FRAMES = {};
 	dock.isDirty = true;	--You dirty, dirty frame
 end
 
 function FCFDock_OnEvent(dock, event, ...)
 	if ( event == "UPDATE_CHAT_WINDOWS" ) then
 		--FCFDock_ForceTabSort(dock);
 		--FCFDock_ForceReanchoring(dock);
 	end
 end
 
 function FCFDock_GetChatFrames(dock)
 	return dock.DOCKED_CHAT_FRAMES;
 end
 
 function FCFDock_SetPrimary(dock, chatFrame)
 	dock.primary = chatFrame;
 	dock:SetPoint("BOTTOMLEFT", chatFrame, "TOPLEFT", 0, 6);
 	dock:SetPoint("BOTTOMRIGHT", chatFrame, "TOPRIGHT", 0, 6);
 	
 	chatFrame:SetScript("OnSizeChanged", function(self) FCFDock_OnPrimarySizeChanged(dock) end);
 	
 	if ( not FCFDock_GetSelectedWindow(dock) ) then
 		FCFDock_SelectWindow(dock, chatFrame);
 	end
 	
 	FCFDock_ForceReanchoring(dock);
 	
 	FCFDock_AddChatFrame(dock, chatFrame, 1);
 end
 
 function FCFDock_OnPrimarySizeChanged(dock)
 	dock.isDirty = true;
 	
 	--We have to save off the current leftmost-tab before we resize the tabs.
 	dock.leftTab = FCFDockScrollFrame_GetLeftmostTab(dock.scrollFrame);
 	
 	--We have to do it on the next frame to deal with issues caused by resizing the WoW client (frame positions may not be valid)
 	dock:SetScript("OnUpdate", FCFDock_OnUpdate);
 end
 
 function FCFDock_OnUpdate(self)
 	--These may fail if we're resizing the WoW client
 	if ( FCFDock_UpdateTabs(self) and FCFDockScrollFrame_JumpToTab(self.scrollFrame, self.leftTab) ) then
 		self.leftTab = nil;
 		self:SetScript("OnUpdate", nil);
 	end
 end
 
 function FCFDock_ForceReanchoring(dock)
 	for index, chatFrame in pairs(dock.DOCKED_CHAT_FRAMES) do
 		if ( dock.primary ~= chatFrame ) then
 			chatFrame:ClearAllPoints();
 			chatFrame:SetAllPoints(dock.primary);
 		end
 	end
 end
 
 function FCFDock_AddChatFrame(dock, chatFrame, position)
 	if ( not dock.primary ) then
 		error("Need a primary window before another can be added.");
 	end
 	
 	if ( FCFDock_HasDockedChatFrame(dock, chatFrame) ) then
 		return;	--We're already docked...
 	end
 	
 	dock.isDirty = true;
 	chatFrame.isDocked = 1;
 	
 	if ( position and position <= #dock.DOCKED_CHAT_FRAMES + 1 ) then
 		assert(position ~= 1 or chatFrame == dock.primary);
 		tinsert(dock.DOCKED_CHAT_FRAMES, position, chatFrame);
 	else
 		tinsert(dock.DOCKED_CHAT_FRAMES, chatFrame);
 	end
 	
 	FCFDock_HideInsertHighlight(dock);
 	
 	if ( dock.primary ~= chatFrame ) then
 		chatFrame:ClearAllPoints();
 		chatFrame:SetAllPoints(dock.primary);
 		chatFrame:SetMovable(false);
 		chatFrame:SetResizable(false);
 	end
 	
 	if ( chatFrame.conversationButton ) then
 		BNConversationButton_UpdateAttachmentPoint(chatFrame.conversationButton);
 	end
 	
 	chatFrame.buttonFrame.minimizeButton:Hide();
 	chatFrame.buttonFrame:SetAlpha(1.0);
 	
 	dock.overflowButton.list:Hide();
 	FCFDock_UpdateTabs(dock);
 end
 
 function FCFDock_RemoveChatFrame(dock, chatFrame)
 	assert(chatFrame ~= dock.primary or #dock.DOCKED_CHAT_FRAMES == 1);
 	dock.isDirty = true;
 	tDeleteItem(dock.DOCKED_CHAT_FRAMES, chatFrame);
 	local chatTab = _G[chatFrame:GetName().."Tab"];
 	chatFrame.isDocked = nil;
 	chatTab:SetParent(UIParent);
 	chatTab:SetFrameStrata("LOW");
 	chatFrame:SetMovable(true);
 	chatFrame:SetResizable(true);
 	FCFTab_UpdateColors(chatTab, true);
 	PanelTemplates_TabResize(chatTab, chatTab.sizePadding or 0, nil, nil, nil, chatTab.textWidth);
 	if ( FCFDock_GetSelectedWindow(dock) == chatFrame ) then
 		FCFDock_SelectWindow(dock, dock.DOCKED_CHAT_FRAMES[1]);
 	end
 	
 	if ( chatFrame.conversationButton ) then
 		BNConversationButton_UpdateAttachmentPoint(chatFrame.conversationButton);
 	end
 	
 	chatFrame.buttonFrame.minimizeButton:Show();
 	dock.overflowButton.list:Hide();
 	chatFrame:Show();
 	FCFDock_UpdateTabs(dock);
 end
 
 function FCFDock_HasDockedChatFrame(dock, chatFrame)
 	return tContains(dock.DOCKED_CHAT_FRAMES, chatFrame);
 end
 
 function FCFDock_SelectWindow(dock, chatFrame)
 	assert(chatFrame)
 	dock.isDirty = true;
 	dock.selected = chatFrame;
 	dock.overflowButton.list:Hide();
 	FCFDock_UpdateTabs(dock);
 	
 	if ( ChatFrameMenuButton ) then
 		if ( chatFrame.conversationButton and chatFrame.conversationButton:IsShown() ) then
 			ChatFrameMenuButton:Hide();
 		else
 			ChatFrameMenuButton:Show();
 		end
 	end
 end
 
 function FCFDock_GetSelectedWindow(dock)
 	return dock.selected;
 end
 
 function FCFDock_UpdateTabs(dock, forceUpdate)
 	if ( not dock.isDirty and not forceUpdate ) then	--No changes have been made since the last update.
 		return;
 	end
 	
 	local scrollChild = dock.scrollFrame:GetScrollChild();
 	local lastDockedStaticTab = nil;
 	local lastDockedDynamicTab = nil;
 	
 	local numDynFrames = 0;	--Number of dynamicly sized frames.
 	local selectedDynIndex = nil;
 	
 	for index, chatFrame in ipairs(dock.DOCKED_CHAT_FRAMES) do
 		local chatTab = _G[chatFrame:GetName().."Tab"];
 		if ( chatFrame == FCFDock_GetSelectedWindow(dock) ) then
 			chatFrame:Show();
 		else
 			chatFrame:Hide();
 		end
 		FCFTab_UpdateAlpha(chatFrame);
 		chatTab:ClearAllPoints();
 		chatTab:Show();
 		FCFTab_UpdateColors(chatTab, chatFrame == FCFDock_GetSelectedWindow(dock));
 		
 		if ( chatFrame.isStaticDocked ) then
 			chatTab:SetParent(dock);
 			PanelTemplates_TabResize(chatTab, chatTab.sizePadding or 0);
 			if ( lastDockedStaticTab ) then
 				chatTab:SetPoint("LEFT", lastDockedStaticTab, "RIGHT", 0, 0);
 			else
 				chatTab:SetPoint("LEFT", dock, "LEFT", 0, 0);
 			end
 			lastDockedStaticTab = chatTab;
 		else
 			chatTab:SetParent(scrollChild);
 			numDynFrames = numDynFrames + 1;
 			
 			if ( FCFDock_GetSelectedWindow(dock) == chatFrame ) then
 				selectedDynIndex = numDynFrames;
 			end
 			
 			if ( lastDockedDynamicTab ) then
 				chatTab:SetPoint("LEFT", lastDockedDynamicTab, "RIGHT", 0, 0);
 			else
 				chatTab:SetPoint("LEFT", scrollChild, "LEFT", 0, 0);
 			end
 			lastDockedDynamicTab = chatTab;
 		end
 	end
 	
 	local dynTabSize, hasOverflow = FCFDock_CalculateTabSize(dock, numDynFrames);
 	
 	for index, chatFrame in ipairs(dock.DOCKED_CHAT_FRAMES) do
 		if ( not chatFrame.isStaticDocked ) then
 			local chatTab = _G[chatFrame:GetName().."Tab"];
 			PanelTemplates_TabResize(chatTab, chatTab.sizePadding or 0, dynTabSize);
 		end
 	end
 	
 	dock.scrollFrame:SetPoint("LEFT", lastDockedStaticTab, "RIGHT", 0, 0);
 	if ( hasOverflow ) then
 		dock.overflowButton:Show();
 		dock.scrollFrame:SetPoint("BOTTOMRIGHT", dock.overflowButton, "BOTTOMLEFT", 0, 0);
 	else
 		dock.overflowButton:Hide();
 		dock.scrollFrame:SetPoint("BOTTOMRIGHT", dock, "BOTTOMRIGHT", 0, -5);
 	end
 	
 	--Cache some of this data on the scroll frame for animating to the selected tab.
 	dock.scrollFrame.dynTabSize = dynTabSize;
 	dock.scrollFrame.numDynFrames = numDynFrames;
 	dock.scrollFrame.selectedDynIndex = selectedDynIndex;
 	
 	dock.isDirty = false;
 	
 	return FCFDock_ScrollToSelectedTab(dock);
 end
 
 --Returns dynTabSize, hasOverflow
 function FCFDock_CalculateTabSize(dock, numDynFrames)
 	local MIN_SIZE, MAX_SIZE = 60, 90;
 	local scrollSize = dock.scrollFrame:GetWidth() + (dock.overflowButton:IsShown() and dock.overflowButton.width or 0); --We want the total width assuming no overflow button.
 	
 	--First, see if we can fit all the tabs at the maximum size
 	if ( numDynFrames * MAX_SIZE < scrollSize ) then
 		return MAX_SIZE, false;
 	end
 	
 	if ( scrollSize / MIN_SIZE < numDynFrames ) then
 		--Not everything fits, so we'll need room for the overflow button.
 		scrollSize = scrollSize - dock.overflowButton.width;
 	end
 	
 	--Figure out how many tabs we're going to be able to fit at the minimum size
 	local numWholeTabs = min(floor(scrollSize / MIN_SIZE), numDynFrames)
-	
+	if ( scrollSize == 0 ) then
+		return 1, (numDynFrames > 0);
+	end
 	if ( numWholeTabs == 0 ) then
 		return scrollSize, true;
 	end
 	
 	--How big each tab should be.
 	local tabSize = scrollSize / numWholeTabs;
 	
 	return tabSize, (numDynFrames > numWholeTabs);
 end
 
 function FCFDock_ScrollToSelectedTab(dock)
 	if ( FCFDockScrollFrame_GetScrollDistanceNeeded(dock.scrollFrame, dock.scrollFrame.selectedDynIndex) ~= 0) then
 		dock.scrollFrame:SetScript("OnUpdate", FCFDockScrollFrame_OnUpdate);
 		return true;
 	else
 		return FCFDockScrollFrame_JumpToTab(dock.scrollFrame, FCFDockScrollFrame_GetLeftmostTab(dock.scrollFrame));	--Make sure we're exactly aligned with the tab.
 	end
 end
 
 ---These functions deal with the scroll frame handling dynamic tabs.
 function FCFDockScrollFrame_OnUpdate(self, elapsed)
 	local MOVEMENT_SPEED = 10;
 	
 	local totalDistanceNeeded = FCFDockScrollFrame_GetScrollDistanceNeeded(self, self.selectedDynIndex);
 	if ( abs(totalDistanceNeeded) < 1.0 ) then	--Delta chosen through experimentation
 		self:SetScript("OnUpdate", nil);
 		FCFDockScrollFrame_JumpToTab(self, FCFDockScrollFrame_GetLeftmostTab(self));	--Make sure we're exactly aligned with the tab.
 		return;
 	end
 	
 	local currentPosition = self:GetHorizontalScroll();
 	
 	local distanceNoCap = totalDistanceNeeded * MOVEMENT_SPEED * elapsed;
 	local distanceToMove = (totalDistanceNeeded > 0) and min(totalDistanceNeeded, distanceNoCap) or max(totalDistanceNeeded, distanceNoCap);
 	
 	self:SetHorizontalScroll(max(currentPosition + distanceToMove, 0));
 end
 
 function FCFDock_GetInsertIndex(dock, chatFrame, mouseX, mouseY)
 	if ( chatFrame.isStaticDocked ) then
 		local maxPosition = 0;
 		for index, value in ipairs(dock.DOCKED_CHAT_FRAMES) do
 			if ( value.isStaticDocked ) then
 				local tab = _G[value:GetName().."Tab"];
 				if ( mouseX < (tab:GetLeft() + tab:GetRight()) / 2 and	--Find the first tab we're on the left of. (Being on top of the tab, but left of the center counts)
 					tab:GetID() ~= dock.primary:GetID()) then	--We never count as being to the left of the primary tab.
 					return index;
 				end
 				maxPosition = index;
 			end
 		end
 		--We aren't to the left of anything, so we're going into the far-right position.
 		return maxPosition + 1;
 	else
 		--Find the dynamic insertion spot
 		local maxPosition = 9^9;
 		local leftTab = FCFDockScrollFrame_GetLeftmostTab(dock.scrollFrame);
 		local numDynTabsDisplayed = dock.scrollFrame:GetWidth() / dock.scrollFrame.dynTabSize;
 		
 		local currTabNum = 0;
 		for index, value in ipairs(dock.DOCKED_CHAT_FRAMES) do
 			if ( not value.isStaticDocked ) then
 				currTabNum = currTabNum + 1;
 				if ( currTabNum >= leftTab and currTabNum < leftTab + numDynTabsDisplayed ) then
 					local tab = _G[value:GetName().."Tab"];
 					if ( mouseX < (tab:GetLeft() + tab:GetRight())/2 ) then
 						return index;
 					end
 					maxPosition = index;
 				end
 			end
 		end
 		return min(#dock.DOCKED_CHAT_FRAMES + 1, maxPosition + 1);
 	end
 end
 
 function FCFDock_PlaceInsertHighlight(dock, chatFrame, mouseX, mouseY)
 	local insert = FCFDock_GetInsertIndex(dock, chatFrame, mouseX, mouseY);
 	
 	local attachFrame = dock.primary;
 	
 	local leftDynTab = FCFDockScrollFrame_GetLeftmostTab(dock.scrollFrame);
 	local numDynTabsDisplayed = dock.scrollFrame:GetWidth() / dock.scrollFrame.dynTabSize;
 	
 	local dynamicIndex = 0;
 	for index, value in ipairs(dock.DOCKED_CHAT_FRAMES) do
 		if ( index < insert ) then
 			if ( value.isStaticDocked ) then
 				attachFrame = value;
 			else
 				dynamicIndex = dynamicIndex + 1;
 				if ( dynamicIndex >= leftDynTab and dynamicIndex < leftDynTab + numDynTabsDisplayed ) then
 					attachFrame = value;
 				end
 			end
 		end
 	end
 	
 	dock.insertHighlight:ClearAllPoints();
 	dock.insertHighlight:SetPoint("BOTTOMLEFT", _G[attachFrame:GetName().."Tab"], "BOTTOMRIGHT", -15, -4);
 	dock.insertHighlight:Show();
 end
 
 function FCFDock_HideInsertHighlight(dock)
 	dock.insertHighlight:Hide();
 end
 
 function FCFDock_SetDirty(dock)
 	dock.isDirty = true;
 end
 
 function FCFDockScrollFrame_GetScrollDistanceNeeded(scrollFrame, dynFrameIndex)
 	
 	local firstIndex = (scrollFrame:GetHorizontalScroll() / scrollFrame.dynTabSize) + 1;
 	
 	local numDisplayedFrames = scrollFrame:GetWidth() / scrollFrame.dynTabSize;
 	local lastIndex = firstIndex + numDisplayedFrames - 1;
 
 	if ( dynFrameIndex and dynFrameIndex < firstIndex ) then	--Need to scroll left to get to the selected button
 		return (dynFrameIndex - firstIndex) * scrollFrame.dynTabSize;
 	elseif ( dynFrameIndex and dynFrameIndex > lastIndex )	then --Need to scroll right to get to the selected button
 		return (dynFrameIndex - lastIndex) * scrollFrame.dynTabSize;
 	elseif (  firstIndex > 1 and scrollFrame.numDynFrames < lastIndex ) then --Need to scroll left to fill in empty space at the end.
 		return (scrollFrame.numDynFrames - lastIndex) * scrollFrame.dynTabSize;
 	else
 		return 0;
 	end
 end
 
 function FCFDockScrollFrame_GetLeftmostTab(scrollFrame)
 	return floor((scrollFrame:GetHorizontalScroll() / scrollFrame.dynTabSize) + 0.5) + 1;
 end
 
 function FCFDockScrollFrame_JumpToTab(scrollFrame, leftTab)
 	--If we have a selected frame, make sure it's still in view.
 	local numTabsDisplayed = scrollFrame:GetWidth() / scrollFrame.dynTabSize;
 	
 	if ( scrollFrame.selectedDynIndex ) then
 		if ( scrollFrame.selectedDynIndex >= leftTab + numTabsDisplayed ) then
 			leftTab = scrollFrame.selectedDynIndex - numTabsDisplayed + 1;
 		elseif ( scrollFrame.selectedDynIndex < leftTab ) then
 			leftTab = scrollFrame.selectedDynIndex;
 		end
 	end
 	
 	--Make sure, if we can show more frames, we do.
 	leftTab = min(leftTab, scrollFrame.numDynFrames - numTabsDisplayed + 1);
 	
 	--And make sure we never go to the left of 1 (for example, if we have extra space)
 	leftTab = max(leftTab, 1);
 	
 	scrollFrame:SetHorizontalScroll(scrollFrame.dynTabSize * (leftTab - 1));
 	
 	return FCFDockOverflowButton_UpdatePulseState(scrollFrame:GetParent().overflowButton);
 end
 
 --Dock list related functions
 function FCFDockOverflow_CloseLists()
 	local list = GENERAL_CHAT_DOCK.overflowButton.list;
 	if ( list:IsShown() ) then
 		list:Hide();
 		return true;
 	else
 		return false;
 	end
 end
 
 function FCFDockOverflowButton_UpdatePulseState(self)
 	local dock = self:GetParent();
 	local shouldPulse = false;
 	for _, chatFrame in pairs(FCFDock_GetChatFrames(dock)) do
 		local chatTab = _G[chatFrame:GetName().."Tab"];
 		if ( not chatFrame.isStaticDocked and chatTab.alerting) then
 			--Make sure the rects are valid. (Not always the case when resizing the WoW client
 			if ( not chatTab:GetRight() or not dock.scrollFrame:GetRight() ) then
 				return false;
 			end
 			--Check if it's off the screen.
 			local DELTA = 3;	--Chosen through experimentation
 			if ( chatTab:GetRight() < (dock.scrollFrame:GetLeft() + DELTA) or chatTab:GetLeft() > (dock.scrollFrame:GetRight() - DELTA) ) then
 				shouldPulse = true;
 				break;
 			end
 		end
 	end
 	
 	if ( shouldPulse ) then
 		UIFrameFlash(self:GetHighlightTexture(), 1.0, 1.0, -1, true, 0, 0, "chat");
 		self:LockHighlight();
 		self.alerting = true;
 	else
 		UIFrameFlashStop(self:GetHighlightTexture());
 		self:UnlockHighlight();
 		self:GetHighlightTexture():Show();
 		self.alerting = false;
 	end
 	
 	if ( self.list:IsShown() ) then
 		FCFDockOverflowList_Update(self.list, dock);
 	end
 	return true;
 end
 
 function FCFDockOverflowButton_OnClick(self, button)
 	PlaySound("UChatScrollButton");
 	if ( self.list:IsShown() ) then
 		self.list:Hide();
 	else
 		FCFDockOverflowList_Update(self.list, self:GetParent());
 		self.list:Show();
 	end
 end
 
 function FCFDockOverflowButton_OnEvent(self, event, ...)
 	if ( event == "UPDATE_CHAT_COLOR" and self.list:IsShown() ) then
 		FCFDockOverflowList_Update(self.list, self:GetParent());
 	end		
 end
 
 function FCFDockOverflowList_Update(list, dock)
 	local dockedFrames = FCFDock_GetChatFrames(dock);
 	
 	list:SetHeight(#dockedFrames *15 + 35);
 	
 	list.numTabs:SetFormattedText(CHAT_WINDOWS_COUNT, #dockedFrames);
 	
 	for i = 1, #dockedFrames do
 		local button = list.buttons[i];
 		if ( not button ) then
 			list.buttons[i] = CreateFrame("Button", list:GetName().."Button"..i, list, "DockManagerOverflowListButtonTemplate");
 			button = list.buttons[i];
 			
 			if ( not list.buttons[i-1] ) then
 				button:SetPoint("TOPLEFT", list, "TOPLEFT", 5, -19);
 			else
 				button:SetPoint("TOPLEFT", list.buttons[i-1], "BOTTOMLEFT", 0, -3);
 			end
 			button:SetWidth(list:GetWidth() - 10);	-- buttons are 5 pixels in on both sides
 		end
 		
 		FCFDockOverflowListButton_SetValue(button, dockedFrames[i]);
 	end
 	
 	for i = #dockedFrames + 1, #list.buttons do
 		list.buttons[i]:Hide();
 	end
 end
 
 function FCFDockOverflowListButton_SetValue(button, chatFrame)
 	local chatTab = _G[chatFrame:GetName().."Tab"];
 	button.chatFrame = chatFrame;
 	button:SetText(chatFrame.name);
 	
 	local colorTable = chatTab.selectedColorTable or DEFAULT_TAB_SELECTED_COLOR_TABLE;
 	
 	if ( chatTab.selectedColorTable ) then
 		button:GetFontString():SetTextColor(colorTable.r, colorTable.g, colorTable.b);
 	else
 		button:GetFontString():SetTextColor(NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b);
 	end
 	
 	button.glow:SetVertexColor(colorTable.r, colorTable.g, colorTable.b);
 	
 	if ( chatTab.conversationIcon ) then
 		button.conversationIcon:SetVertexColor(colorTable.r, colorTable.g, colorTable.b);
 		button.conversationIcon:Show();
 	else
 		button.conversationIcon:Hide();
 	end
 	
 	if ( chatTab.alerting ) then
 		button.alerting = true;
 		UIFrameFlash(button.glow, 1.0, 1.0, -1, false, 0, 0, "chat");
 	else
 		button.alerting = false;
 		UIFrameFlashStop(button.glow);
 	end
 	
 	button:Show();
 end
 
 function FCFDockOverflowListButton_OnClick(self, button)
 	FCFDock_SelectWindow(self:GetParent():GetParent():GetParent(), self.chatFrame);
 end
 
 ---------------------------------------------------
 -----------Temp Window Manager-------------
 ----------------------------------------------------
 local dedicatedWindows = {};
 
 local function FCFManager_GetToken(chatType, chatTarget)
 	return strlower(chatType)..(chatTarget and ";;"..strlower(chatTarget) or "");
 end
 
 function FCFManager_RegisterDedicatedFrame(chatFrame, chatType, chatTarget)
 	local token = FCFManager_GetToken(chatType, chatTarget);
 	if ( not dedicatedWindows[token] ) then
 		dedicatedWindows[token] = {};
 	end
 	
 	if ( not tContains(dedicatedWindows[token], chatFrame) ) then
 		tinsert(dedicatedWindows[token], chatFrame);
 	end
 end
 
 function FCFManager_UnregisterDedicatedFrame(chatFrame, chatType, chatTarget)
 	local token = FCFManager_GetToken(chatType, chatTarget);
 	local windowList = dedicatedWindows[token];
 	if ( windowList ) then
 		tDeleteItem(windowList, chatFrame);
 	end
 end
 
 function FCFManager_GetNumDedicatedFrames(chatType, chatTarget)
 	local token = FCFManager_GetToken(chatType, chatTarget);
 	local windowList = dedicatedWindows[token];
 	return (windowList and #windowList or 0);
 end
 
 function FCFManager_ShouldSuppressMessage(chatFrame, chatType, chatTarget)
 	--Using GetToken probably isn't the best way to do this due to the string concatenation, but it's the easiest to get in quickly.
 	if ( chatFrame.chatType and FCFManager_GetToken(chatType, chatTarget) == FCFManager_GetToken(chatFrame.chatType, chatFrame.chatTarget) ) then
 		--This frame is a dedicated frame of this type, so we should always display.
 		return false;
 	end
 	
 	if ( (chatType == "BN_CONVERSATION" and GetCVar("conversationMode") == "popout")
 		or (chatType == "BN_WHISPER" and GetCVar("bnWhisperMode") == "popout")
 		or (chatType == "WHISPER" and GetCVar("whisperMode") == "popout") ) then
 		return true;
 	end
 	
 	return false;
 end
 
 function FCFManager_ShouldSuppressMessageFlash(chatFrame, chatType, chatTarget)
 	--Using GetToken probably isn't the best way to do this due to the string concatenation, but it's the easiest to get in quickly.
 	if ( chatFrame.chatType and FCFManager_GetToken(chatType, chatTarget) == FCFManager_GetToken(chatFrame.chatType, chatFrame.chatTarget) ) then
 		--This frame is a dedicated frame of this type, so we should always display.
 		return false;
 	end
 	
 	if ( (chatType == "BN_CONVERSATION" and GetCVar("conversationMode") == "popout_and_inline")
 		or (chatType == "BN_WHISPER" and GetCVar("bnWhisperMode") == "popout_and_inline") 
 		or (chatType == "WHISPER" and GetCVar("whisperMode") == "popout_and_inline") ) then
 		return true;
 	end
 	
 	return false;
 end
 
 function FCFManager_StopFlashOnDedicatedWindows(chatType, chatTarget)
 	local token = FCFManager_GetToken(chatType, chatTarget);
 	local windowList = dedicatedWindows[token];
 	if (windowList) then
 		for i, frame in pairs(windowList) do
 			FCF_StopAlertFlash(frame);
 		end
 	end
 end
 
 function FloatingChatFrameManager_OnLoad(self)
 	--Register for BN_CONVERSATION related messages to be able to spawn off new windows as needed
 	for _, event in pairs(ChatTypeGroup["BN_CONVERSATION"]) do
 		self:RegisterEvent(event);
 	end
 	for _, event in pairs(ChatTypeGroup["BN_WHISPER"]) do
 		self:RegisterEvent(event);
 	end
 	for _, event in pairs(ChatTypeGroup["WHISPER"]) do
 		self:RegisterEvent(event);
 	end
 end
 
 function FloatingChatFrameManager_OnEvent(self, event, ...)
 	local arg1 = ...;
 	if ( strsub(event, 1, 9) == "CHAT_MSG_" ) then
 		local chatType = strsub(event, 10);
 		local chatGroup = Chat_GetChatCategory(chatType);
 		
 		if ( chatGroup == "BN_CONVERSATION" ) then
 			if ( GetCVar("conversationMode") == "popout" or GetCVar("conversationMode") == "popout_and_inline" ) then
 				if( not (event == "CHAT_MSG_BN_CONVERSATION_NOTICE" and arg1 == "YOU_LEFT_CONVERSATION") ) then
 					local chatTarget = tostring(select(8, ...));
 					if ( FCFManager_GetNumDedicatedFrames(chatGroup, chatTarget) == 0 ) then
 						local chatFrame = FCF_OpenTemporaryWindow(chatGroup, chatTarget);
 						chatFrame:GetScript("OnEvent")(chatFrame, event, ...);	--Re-fire the event for the frame.
 					elseif (GetCVar("conversationMode") == "popout_and_inline" and BNIsSelf(select(13, ...))) then
 						FCFManager_StopFlashOnDedicatedWindows(chatGroup, chatTarget);
 					end
 				end
 			end
 		end
 		
 		if ( (chatGroup == "BN_WHISPER" and (GetCVar("bnWhisperMode") == "popout" or GetCVar("bnWhisperMode") == "popout_and_inline"))
 			or (chatGroup == "WHISPER" and (GetCVar("whisperMode") == "popout" or GetCVar("whisperMode") == "popout_and_inline"))) then
 			local chatTarget = tostring(select(2, ...));
 			
 			if ( FCFManager_GetNumDedicatedFrames(chatGroup, chatTarget) == 0 ) then
 				local chatFrame = FCF_OpenTemporaryWindow(chatGroup, chatTarget);
 				chatFrame:GetScript("OnEvent")(chatFrame, event, ...);	--Re-fire the event for the frame.
 
 				-- If you started the whisper, immediately select the tab
 				if ((event == "CHAT_MSG_WHISPER_INFORM" and GetCVar("whisperMode") == "popout")
 					or (event == "CHAT_MSG_BN_WHISPER_INFORM" and GetCVar("bnWhisperMode") == "popout") ) then
 					FCF_SelectDockFrame(chatFrame);
 					FCF_FadeInChatFrame(chatFrame);
 				end
 			else
 				-- While in "Both" mode, if you reply to a whisper, stop the flash on that dedicated whisper tab
 				if ( (chatType == "WHISPER_INFORM" and GetCVar("whisperMode") == "popout_and_inline")
 				or (chatType == "BN_WHISPER_INFORM" and GetCVar("bnWhisperMode") == "popout_and_inline")) then
 					FCFManager_StopFlashOnDedicatedWindows(chatGroup, chatTarget);
 				end
 			end
 		end
 	end
 end