local addonName = "SimpleRunesBar";

if(select(2, UnitClass('player')) ~= 'DEATHKNIGHT') then return DisableAddOn(addonName); end

local displayLvl = 1;-- -1 = no output / range 10 (-1 through 9)
local function sa(value) return(tostring(value) or "~NIL~"); end
local function ToChat(msg, msgLvl)
	msgLvl = (tonumber(msgLvl) or 0);
	if(msgLvl > displayLvl) then
		DEFAULT_CHAT_FRAME:AddMessage("|cFFFF0000" .. addonName .. " (" .. msgLvl .. "):|r " .. sa(msg));
	elseif(msgLvl == 0) then--normal output
		DEFAULT_CHAT_FRAME:AddMessage(addonName .. ": " .. sa(msg));
	end
end

local UPDATE_RATE = 0.5;--1/2 second

local ANCHOR_WIDTH = 140;
local ANCHOR_HEIGHT = 20;
local ANCHOR_TEXT = "Simple Runes Bar Anchor";
local ANCHOR_BACKGROUND = "Interface\\Tooltips\\UI-Tooltip-Background";
local ANCHOR_BORDER = "Interface\\Tooltips\\UI-Tooltip-Border";

local BAR_TEXTURE = "Interface\\AddOns\\SimpleRunesBar\\Flat_Bar";

local NUM_RUNES = 6;

--2009/09/24 - changed to match Blizzard order.
local RUNETYPE_BLOOD = 1;
local RUNETYPE_UNHOLY = 2;
local RUNETYPE_FROST = 3;
local RUNETYPE_DEATH = 4;
--eoc

local runeColorsTable =
{
	[RUNETYPE_BLOOD] = 	{r = 1.0,	g = 0.0, b = 0.0},
	[RUNETYPE_DEATH] = 	{r = 0.0,	g = 0.5, b = 0.0},
	[RUNETYPE_FROST] = 	{r = 0.0,	g = 1.0, b = 1.0},
	[RUNETYPE_UNHOLY] = {r = 0.8, g = 0.1, b = 1.0},
}

--local RUNE_WIDTH = 		28;
local RUNE_PADDING = 	 1.5;
--local RUNE_HEIGHT = 	 12;

local dbDefaultsTable = {
	showAnchor = true,
	width = 28,
	height = 12,
}

local SimpleRunesBar = {};--table: Simple Runes Bars object

--------------------------------------------------------------------------------
function SimpleRunesBar:Initialize()
	self.anchor = self:BuildAnchor();
	self.anchor:SetScript("OnEvent", function(self, event, ...) SimpleRunesBar:OnLoad(event, ...) end);
	self.anchor:RegisterEvent("ADDON_LOADED");
end

function SimpleRunesBar:LoadDB(db, defaultTable)
	for key, value in pairs(defaultTable) do
		if(db[key] == nil) then
			db[key] = value;
		end
	end
	return db;
end

function SimpleRunesBar:SetDefaults()
	for key, value in pairs(dbDefaultsTable) do
		self.db[key] = value;
	end
	ToChat("All settings have been reset", 0);
	self.anchor:ClearAllPoints();
	self.anchor:SetPoint("CENTER");
	self:ShowAnchor(self.db.showAnchor);
	self:UpdateRuneSize();
end

function SimpleRunesBar:OnLoad(event, addon)
	if(addon == addonName) then
		_G["RuneFrame"]:Hide();

		if(not SimpleRunesBarDB) then SimpleRunesBarDB = {}; end
		self.db = self:LoadDB(SimpleRunesBarDB, dbDefaultsTable);

		self:ShowAnchor(self.db.showAnchor);

		SLASH_SIMPLERUNESBAR1 = "/simplerunesbar";
		SLASH_SIMPLERUNESBAR2 = "/srb";
		SlashCmdList["SIMPLERUNESBAR"] = function(cmd) self:CommandHandler(cmd); end;

		self.runes = self:BuildRunes(self.anchor, self.db.width, self.db.height);

		self.anchor:SetScript("OnEvent", function(self, event, ...) SimpleRunesBar:OnEvent(event, ...);	end);
		self.anchor:RegisterEvent("RUNE_POWER_UPDATE");--Fired when a rune's state switches from usable to un-usable or visa-versa.
		self.anchor:RegisterEvent("RUNE_TYPE_UPDATE");--Fired when a rune's type is changed / updated.
		self.anchor:RegisterEvent("PLAYER_ENTERING_WORLD");
	end
end

function SimpleRunesBar:OnEvent(event, ...)
	if(event == "PLAYER_ENTERING_WORLD") then
		self:UpdateAll();
	elseif(event == "RUNE_TYPE_UPDATE") then
		local runeID = ...;
		if(runeID ~= 7 and runeID ~= 8) then self:UpdateRuneType(self.runes[runeID]) end;
	elseif(event == "RUNE_POWER_UPDATE") then
		local runeID, isUsable = ...;
		if(not isUsable) then	self:UpdateRune(self.runes[runeID]); end
	end
end


--------------------------------------------------------------------------------
function SimpleRunesBar:BuildAnchor()
	local frame = CreateFrame("Frame", addonName .. "Frame", UIParent);
	frame:SetBackdrop({	bgFile = ANCHOR_BACKGROUND,	tile = true, tileSize = 16,
											edgeFile = ANCHOR_BORDER, edgeSize = 8,
											insets = {left = 2, right = 2, top = 2, bottom = 2}
											});
	frame:SetBackdropColor(0.6, 0, 0.6, 1);

	frame:SetWidth(ANCHOR_WIDTH);
	frame:SetHeight(ANCHOR_HEIGHT);
	frame:SetPoint("CENTER");

	frame.text = frame:CreateFontString(addonName .. "Anchor_Font", "OVEDRLAY", "GameFontNormalSmall");
	frame.text:SetPoint("CENTER");
	frame.text:SetText(ANCHOR_TEXT);

	frame:SetMovable(true);
	frame:SetUserPlaced(true);

	frame:SetScript("OnMouseDown", function() frame:StartMoving() end);
	frame:SetScript("OnMouseUp", function() frame:StopMovingOrSizing(); end);
	frame:SetScript("OnHide", function() frame:StopMovingOrSizing(); end);
	frame:SetScript("OnEnter", function()
		GameTooltip:SetOwner(this, "ANCHOR_TOPLEFT");
		GameTooltip:AddLine("Simple Runes Bar Anchor");
		GameTooltip:AddLine("Drag this to reposition the rune bars.");
		GameTooltip:AddLine("Type '/srb lock' to lock your bar in place.");
		GameTooltip:Show();
	end);
	frame:SetScript("OnLeave", function() GameTooltip:Hide() end);

	return frame;
end

function SimpleRunesBar:BuildRunes(anchor, width, height)
	local runes = {};

	for i = 1, NUM_RUNES, 1 do
		local rune = CreateFrame("Frame", addonName .. "_Rune" .. i, UIParent);
		rune.lastUpdate	= 0;
		rune.runeID = i;

		rune:SetBackdrop({bgFile = BAR_TEXTURE,	tile = true, tileSize = 16,
											edgeFile = nil, edgeSize = 0,
											insets = {left = 0, right = 0, top = 0, bottom = 0}
											});
		rune:SetBackdropColor(0, 0, 0, 1);
		rune:ClearAllPoints();
		rune:SetWidth(width);
		rune:SetHeight(height);
		if(i == 1) then
			rune:SetPoint("TOPLEFT", anchor, "BOTTOMLEFT", 0, 0);
		else
			rune:SetPoint("LEFT", runes[i - 1], "RIGHT", -RUNE_PADDING, 0);
		end

		rune.bar = CreateFrame("StatusBar", addonName .. "_Rune" .. i .. "Bar", rune);
		rune.bar:SetStatusBarTexture(BAR_TEXTURE);
		rune.bar:SetMinMaxValues(0, 1);
		rune.bar:SetOrientation('HORIZONTAL');
		rune.bar:ClearAllPoints();
		rune.bar:SetPoint("TOPLEFT", rune, "TOPLEFT", RUNE_PADDING, -RUNE_PADDING);
		rune.bar:SetPoint("BOTTOMRIGHT", rune, "BOTTOMRIGHT", -RUNE_PADDING, RUNE_PADDING);

		rune.bar.texture = rune.bar:CreateTexture(nil, "BACKGROUND");
		rune.bar.texture:SetTexture(BAR_TEXTURE);
		rune.bar.texture:SetVertexColor(0.3, 0.3, 0.3, 1);
		rune.bar.texture:ClearAllPoints();
		rune.bar.texture:SetAllPoints(rune.bar);

--		self:UpdateRuneType(rune);
		rune:SetScript("OnUpdate", function(self, elapsed) SimpleRunesBar:UpdateRune(self, elapsed) end);
		runes[i] = rune;
	end

	return runes;
end


--------------------------------------------------------------------------------
function SimpleRunesBar:UpdateRuneSize()
	for i = 1, NUM_RUNES, 1 do
		self.runes[i]:SetWidth(self.db.width);
		self.runes[i]:SetHeight(self.db.height);
	end
end

function SimpleRunesBar:UpdateAll()
	for i = 1, NUM_RUNES, 1 do
		self:UpdateRune(self.runes[i]);
		self:UpdateRuneType(self.runes[i]);
	end
end

function SimpleRunesBar:UpdateRune(rune, elapsed)
	elapsed = elapsed or 0;--hmmmmmmm
	if(not rune.lastUpdate) then
		rune.lastUpdate = elapsed;
	else
		rune.lastUpdate = (rune.lastUpdate + elapsed);
	end

	while(rune.lastUpdate > UPDATE_RATE) do
		local start, duration, runeReady = GetRuneCooldown(rune.runeID);
		local timeElapsed = (GetTime() - start);

		if(not runeReady or (timeElapsed < duration)) then
			rune.bar:SetValue(timeElapsed / duration);
		else
			rune.bar:SetValue(1);
		end

		self:UpdateRuneType(rune);
		rune.lastUpdate = (rune.lastUpdate - UPDATE_RATE);
	end
end

function SimpleRunesBar:UpdateRuneType(rune)
	local runeType = GetRuneType(rune.runeID);
	local color = runeColorsTable[runeType];
	rune.bar:SetStatusBarColor(color.r, color.g, color.b, 1);
end


--------------------------------------------------------------------------------
function SimpleRunesBar:CommandHandler(cmd)
	local command, value = cmd:match("^([^%s]+)%s*(.*)$");
	if(command) then command = string.upper(command) end

	if(command == "LOCK") then
		if(self.anchor:IsShown()) then
			self:ShowAnchor(false);
			ToChat("Anchor frame is now locked.", 0);
		else
			self:ShowAnchor(true);
			ToChat("Anchor frame is now unlocked.", 0);
		end
	elseif(command == "WIDTH") then
		if(value ~= "") then
			self.db.width = value;
			self:UpdateRuneSize();
			ToChat("Width is now set to " .. value, 0);
		else
			ToChat("Width is currently: " .. self.db.width, 0);
		end
	elseif(command == "HEIGHT") then
		if(value ~= "") then
			self.db.height = value;
			self:UpdateRuneSize();
			ToChat("Height is now set to " .. value, 0);
		else
			ToChat("Height is currently: " .. self.db.height, 0);
		end
	elseif(command == "DEFAULTS") then
		self:SetDefaults();
	else--must be nil
		ToChat("Options", 0);
		ToChat("  'Lock' = Toggles the anchor lock", 0);
		ToChat("  'Width number' = The width (number) of each rune bar.", 0);
		ToChat("  'Height number' = The height (number) of each rune bar.", 0);
		ToChat("  'Defaults' = Reset all settings back to their defaults.", 0);
	end
end

function SimpleRunesBar:ShowAnchor(showAnchor)
	self.db.showAnchor = showAnchor;
	if(showAnchor) then self.anchor:Show(); else self.anchor:Hide(); end
	self.anchor:EnableMouse(showAnchor);
end




--------------------------------------------------------------------------------
SimpleRunesBar:Initialize();