-- RedOut Script
-- by jINx of Purgatory LAN Organization

-- Description:
-- Shades Out the Action Bar buttons when they are out of range

-- Version 1.0
-- * First Released Version
-- * Created Options frame to allow Enable/Disable and Custom Color
-- * Fixed an Issue that was causing Usability to not take into account
-- * Verified and created functionality for the following bars:
-- * .... Standard Bar
-- * .... BiB Toolbars
-- * .... CT Bar Mod
-- * .... Gypsy Bars
-- * .... Edit by 黑眼圈

RedOut = {}
local RedOutEnabled = ""
local RedOutColor = {};

local function SetHook(myFunction, HookFunc)
	local oldFunction = getglobal(HookFunc);
	local newFunction =
		function(e)
			oldFunction(e);
			myFunction(e);
		end
	setglobal(HookFunc, newFunction);
end

function RedOutOptions_Show()
	local string = getglobal("RedOutOptionsFrame_CheckButton1Text");
	string:SetText("开启 Red Out");

	local frame = getglobal("RedOutOptionsFrame1");
	local swatch = getglobal("RedOutOptionsFrame1_ColorSwatchNormalTexture");
	string = getglobal("RedOutOptionsFrame1_ColorSwatchText");
	string:SetText("选择Red Out使用的颜色");

	frame.r = RedOutColor.r;
	frame.g = RedOutColor.g;
	frame.b = RedOutColor.b;
	frame.swatchFunc = RedOutOptions_SetColor;
	swatch:SetVertexColor(RedOutColor.r, RedOutColor.g, RedOutColor.b);
	
	local button = getglobal("RedOutOptionsFrame_CheckButton1");
	button:SetChecked(RedOutEnabled);
end

function RedOutOptions_Hide()
	RedOutOptions:Hide();
end

function RedOutAction_OnLoad()
	this:RegisterEvent("VARIABLES_LOADED");

	--add event and Cmd by 黑眼圈 
	SlashCmdList["REDOUTCMD"] = function(msg)
		RedOut_Command(msg);
	end
	SLASH_REDOUTCMD1 = "/redout";

	-- Hook Standard Buttons
	SetHook(RedOutAction_OnUpdate, "ActionButton_OnUpdate");
	local hooks = "Standard Bar";

	-- Bib Toolbars are supported by the Standard, this just displays if its using them
	if (type(PressBibActionButton) == 'function') then
		hooks = "BiB Toolbars";
	end
	
	-- CT Mod
	if (type(CT_ActionButton_OnUpdate) == 'function') then
		SetHook(RedOutAction_CT_OnUpdate, "CT_ActionButton_OnUpdate");
		hooks = hooks..", CT ToolBars";	
	end

	-- Gypsy Bars
	if (type(Gypsy_ActionButtonOnUpdate) == 'function') then
		SetHook(RedOutAction_OnUpdate, "Gypsy_ActionButtonOnUpdate");
		hooks = hooks..", Gypsy Toolbars";
	end

end

-- Command parser
function RedOut_Command(msg)
-- add "on" and "off" by 黑眼圈 
	local cmd = string.lower(msg);
	if ( cmd == nil or cmd == "") then
		RedOutOptions:Show();
	elseif ( cmd == "on") then
		RedOutEnabled = 1;
		RedOut["Enabled"] = 1;
	elseif ( cmd == "off") then
		RedOutEnabled = 0;
		RedOut["Enabled"] = 0;
	end
end

-- Update Function, sent elapsed time since last update (ms)
function RedOutAction_OnUpdate(elapsed)
	
	if (not RedOutEnabled or RedOutEnabled == 0 ) then
		return;
	end

	-- Original Func is run in the inline function of SetHook

	-- Get the Icon and Normal Texture for the Action Button
	local icon = getglobal(this:GetName().."Icon");
	local normalTexture = getglobal(this:GetName().."NormalTexture");

	-- Check if its usable (from original func) no sense in range checking if its not
	local isUsable, notEnoughMana = IsUsableAction(ActionButton_GetPagedID(this));
	if ( isUsable ) then
		local inRange = true;
		if ( this.rangeTimer and (IsActionInRange(ActionButton_GetPagedID(this)) == 0)) then
			inRange = false;
		end
		if ( inRange ) then
			icon:SetVertexColor(1.0, 1.0, 1.0);
			normalTexture:SetVertexColor(1.0, 1.0, 1.0);
		else
			icon:SetVertexColor(1.0, 0.5, 0.5);
			normalTexture:SetVertexColor(1.0, 0.5, 0.5);
		end
	elseif ( notEnoughMana ) then
		icon:SetVertexColor(0.5, 0.5, 1.0);
		normalTexture:SetVertexColor(0.5, 0.5, 1.0);
	else
		icon:SetVertexColor(0.4, 0.4, 0.4);
		normalTexture:SetVertexColor(1.0, 1.0, 1.0);
	end
end

function RedOutAction_CT_OnUpdate(elapsed)	
	if (not RedOutEnabled or RedOutEnabled == 0 ) then
		return;
	end

	-- Original Func is run in the inline function of SetHook

	-- Get the Icon and Normal Texture for the Action Button
	local icon = getglobal(this:GetName().."Icon");
	local normalTexture = getglobal(this:GetName().."NormalTexture");

	-- Check if its usable (from original func) no sense in range checking if its not
	local isUsable, notEnoughMana = IsUsableAction(CT_ActionButton_GetPagedID(this));

	if ( this.rangeTimer ) then
		if ( this.rangeTimer < 0 ) then
			if ( IsActionInRange(CT_ActionButton_GetPagedID(this)) == 0 ) then
				icon:SetVertexColor(RedOutColor.r, RedOutColor.g, RedOutColor.b);
				normalTexture:SetVertexColor(RedOutColor.r, RedOutColor.g, RedOutColor.b);
			else
				if ( isUsable ) then
					icon:SetVertexColor(1.0, 1.0, 1.0);
					normalTexture:SetVertexColor(1.0, 1.0, 1.0);
				elseif ( notEnoughMana ) then
					icon:SetVertexColor(0.5, 0.5, 1.0);
					normalTexture:SetVertexColor(0.5, 0.5, 1.0);
				else
					icon:SetVertexColor(0.4, 0.4, 0.4);
					normalTexture:SetVertexColor(1.0, 1.0, 1.0);
				end
			end
		end
	end
end

function Red_OnEvent(event)
	if ( event == "VARIABLES_LOADED") then
		Red_LoadConfig();
	end
end

function Red_LoadConfig()
	-- Set Default
	if (not RedOut["Enabled"] ) then
		RedOutEnabled = 1;
	else
		RedOutEnabled = RedOut["Enabled"];
	end

	-- Set Default color
	if (not RedOut["Color"]) then
		RedOutColor = { 1, r = 0.82, g = 0.0, b = 0.0 };
	else
		RedOutColor = RedOut["Color"];
	end

	-- Red_Register();
end

-- function Red_Register()
--   gLim_RegisterButton (
-- 	"Red Out",			--名称(英文，用于内部识别和同级排序时使用)
-- 	"施法距离",			--说明(鼠标移到设置按上的提示)
-- 	"Interface\\AddOns\\RedOut\\Icon", --图标(设置按钮的图标)
-- 	function()			--事件(按下按钮时触发的事件)
-- 		gLimModSecBookShowConfig("gLimRedOut");
-- 	end,
-- 	2,				--类型(按钮的分类共分为四大类(1,界面设置,2,战斗、职业,3 生活、商业技能 4 其它)外加所有，共五个按钮)
-- 	3				--排序(按钮排序的优先级 1~10 数字越小级别越高。越优先在前面显示)
-- 	);

--   gLim_RegisterConfigClass(
-- 	"gLimRedOut",
-- 	"Red Out",
-- 	"黑眼圈"
-- 	);
--   gLim_RegisterConfigSection(
-- 	"gLimRedOutSection",
-- 	"施法距离",
-- 	"施法距离 by 黑眼圈(gLim开发小组)",
-- 	"黑眼圈",
-- 	"gLimRedOut");
--   gLim_RegisterConfigCheckBox(
-- 	"gLim_RedOut",
-- 	"开启施法距离",
-- 	"在技能不可用的情况下,使技能按钮成禁用颜色",
-- 	RedOutEnabled,
-- 	RedOutEnabler,
-- 	"gLimRedOut"
-- 	);
-- end

function RedOutOptions_SetColor()
	local r,g,b = ColorPickerFrame:GetColorRGB();
	local swatch,frame;
	frame = getglobal("RedOutOptionsFrame1");
	swatch = getglobal("RedOutOptionsFrame1_ColorSwatchNormalTexture");
	swatch:SetVertexColor(r,g,b);
	frame.r = r;
	frame.g = g;
	frame.b = b;
	RedOutColor.r = r;
	RedOutColor.g = g;
	RedOutColor.b = b;
end

function RedOutEnabler(toggle)

	if ( toggle == 1 ) then
		RedOutEnabled = 1;
		RedOut["Enabled"] = RedOutEnabled;
	else
		RedOutEnabled = 0;
		RedOut["Enabled"] = RedOutEnabled;
	end

end

function RedOutOptionsFrame_CheckButton1_OnClick()

	if ( RedOutEnabled == 0 or RedOutEnabled == nil or RedOutEnabled == "" ) then
		RedOutEnabler(1);
	else
		RedOutEnabler(0);
	end

end

function RedOutOptions_Defaults()
	RedOutEnabled = 1;
	RedOut["Enabled"] = RedOutEnabled;
	RedOutColor = { 1, r = 0.82, g = 0.0, b = 0.0 };
	RedOut["Color"] = RedOutColor;
	RedOutOptions_Show();
end