--[[
	Basic RuneWatch GUI Skin: Full Skin
	Author: Voorije (ReAn)
	Last Edited: 2009-02-19T10:24:20Z
]]

assert(RuneWatch, "Unable to locate RuneWatch Addon Object.");

local Full = RuneWatch:NewModule("Skin_Full", RuneWatch.SkinBase, "AceConsole-3.0", "AceEvent-3.0")

local SkinArt = 
{
	Base = 
	{
		Generic = "Interface\\AddOns\\RuneWatch\\Artwork\\Skin-Full\\Base",
		Frost = "Interface\\AddOns\\RuneWatch\\Artwork\\Skin-Full\\Base",
		Unholy = "Interface\\AddOns\\RuneWatch\\Artwork\\Skin-Full\\Base",
		Blood = "Interface\\AddOns\\RuneWatch\\Artwork\\Skin-Full\\Base",
	},
	BarBorder = 
	{
		Generic = "Interface\\AddOns\\RuneWatch\\Artwork\\Skin-Full\\BarBorder",
		Frost = "Interface\\AddOns\\RuneWatch\\Artwork\\Skin-Full\\BarBorder",
		Unholy = "Interface\\AddOns\\RuneWatch\\Artwork\\Skin-Full\\BarBorder",
		Blood = "Interface\\AddOns\\RuneWatch\\Artwork\\Skin-Full\\BarBorder",
	},
	Bar = 
	{
		Generic = "Interface\\AddOns\\RuneWatch\\Artwork\\Skin-Full\\Bar",
		Frost = "Interface\\AddOns\\RuneWatch\\Artwork\\Skin-Full\\Bar",
		Unholy = "Interface\\AddOns\\RuneWatch\\Artwork\\Skin-Full\\Bar",
		Blood = "Interface\\AddOns\\RuneWatch\\Artwork\\Skin-Full\\Bar",
	},
	Orb = 
	{
		Generic = "Interface\\AddOns\\RuneWatch\\Artwork\\Shared\\Orb-Generic",
		Frost = "Interface\\AddOns\\RuneWatch\\Artwork\\Shared\\Orb-Frost",
		Unholy = "Interface\\AddOns\\RuneWatch\\Artwork\\Shared\\Orb-Unholy",
		Blood = "Interface\\AddOns\\RuneWatch\\Artwork\\Shared\\Orb-Blood",
	}
}

function Full:OnInitialize()	
	self.ID = "full";
	self.Name = "Full";
	self.Description = "The Full User-Interface for RuneWatch. This UI is designed to support all the features of RuneWatch.";
	self.Themes = 
	{
		Generic = true,
		Frost = true,
		Unholy = true,
		Blood = true
	}
	self.Orientations =
	{
		Bottom = true,
		Left = true,
		Right = true,
		Top = true
	}
	
	-- Events
	RuneWatch.RegisterMessage(Full, "RuneWatch_Gui_Update");
	RuneWatch.RegisterMessage(Full, "RuneWatch_Skins_Assign");
	RuneWatch.RegisterMessage(Full, "RuneWatch_RunicPower_Update");
	RuneWatch.RegisterMessage(Full, "RuneWatch_Gui_DragEnable");
	
	Full:InitSkinData();
	Full:InitConfig();
	Full:InitGui();
	
	RuneWatch.Skins:Register(self.ID, self);
	
	self:Super("OnInitialize");
end

function Full:OnEnable()
	self:Super("OnEnable");
end

function Full:OnDisable()
	self:Super("OnDisable");
end

function Full:RegisterMount(mount, orientation, _x, _y)
	RuneWatch.Mounts:Register(mount, mount); -- Make sure RuneWatch is aware of all Mount Types

	local ori = orientation or "_Generic";
	self.Mounts[mount] = {}
	self.Mounts[mount][ori] = { x = _x, y = _y }
end

function Full:InitSkinData()

	-- Orientations
	self.Orientations = 
	{
		["bottom"] = "Bottom",
		["top"] = "Top"
	}
	self.Themes = 
	{
		["Generic"] = "Generic",
		["Blood"] = "Blood",
		["Unholy"] = "Unholy",
		["Frost"] = "Frost"
	}

	for i = 1,6 do
		RuneWatch.Mounts:Register("RUNE"..i, "Rune #"..i);
	end
	
	self.Mounts = {}
	for i = 1,6 do
		self.Mounts["RUNE"..i] = { }
	end
	
	-- bottom
	self.Mounts["RUNE1"]["bottom"] = { x = -108, y = -2 }
	self.Mounts["RUNE2"]["bottom"] = { x = -69, y = -35 }
	self.Mounts["RUNE3"]["bottom"] = { x = -24, y = -50 }
	self.Mounts["RUNE4"]["bottom"] = { x = 24, y = -50 }
	self.Mounts["RUNE5"]["bottom"] = { x = 69, y = -35 }
	self.Mounts["RUNE6"]["bottom"] = { x = 108, y = -2 }
	
	-- top
	self.Mounts["RUNE1"]["top"] = { x = -108, y = 2 }
	self.Mounts["RUNE2"]["top"] = { x = -69, y = 35 }
	self.Mounts["RUNE3"]["top"] = { x = -24, y = 50 }
	self.Mounts["RUNE4"]["top"] = { x = 24, y = 50 }
	self.Mounts["RUNE5"]["top"] = { x = 69, y = 35 }
	self.Mounts["RUNE6"]["top"] = { x = 108, y = 2 }
	
	self.Mounts["TOP"] = {}
	self.Mounts["TOP"]["bottom"] = { x = 0, y = 100 }
	self.Mounts["TOP"]["top"] = { x = 0, y = -100 }
	
	-- Bar Texture Transforms
	self.Bar = {}
	self.Bar.Transforms = {}
	self.Bar.Transforms["bottom"] = function(tex, perc)
		tex:SetTexCoord(0,0,0,1, perc, 0, perc, 1);
	end;
	self.Bar.Transforms["top"] = function(tex, perc)
		tex:SetTexCoord(0,1,0,0, perc, 1, perc, 0);
	end;

end

function Full:InitConfig()
	-- Full Skin Specific Configuration Options
	local options = {
		type = "group",
		name = "Full",
		desc = self.Description,
		args = {
			dsc = {
				type = "description",
				order = 0,
				cmdHidden = true,
				dropdownHidden = true,
				name = "Configuration options for RuneWatch Skin: Full"
			}
		}
	}
	
	Full.Options = options;
end

function Full:InitGui()
	local Gui = Full.Gui;
	
	-- Base
	Gui.Base = Full:BuildBase();
	Gui.Bar = Full:BuildBar(Gui.Base);
	Gui.Base.Bar = Gui.Bar
	-- Register the GUI
	self.GuiBase = Gui.Base;
end

function Full:BuildBase()
	
	local frame = CreateFrame("frame", "RuneWatch_Full", UIParent);
	frame:SetFrameStrata("LOW");
	frame:SetFrameLevel(0);
	frame:SetWidth(300);
	frame:SetHeight(150);
	frame:Show();
	
	local base = frame:CreateTexture("$parent_T_Base", "BACKGROUND");
	base:SetAllPoints(frame);
	base:Show();
	
	local orb = frame:CreateTexture("$parent_T_Orb", "BORDER");
	orb:SetAllPoints(frame);
	orb:Show();
	
	frame.Art = base;
	frame.Orb = orb;
	
	local rp = frame:CreateFontString("$parent_F_RP", "ARTWORK", "SystemFont_OutlineThick_Huge4");
	rp:SetText("0");
	rp:SetTextColor(1,0.5,0,1);	

	rp:SetPoint("CENTER", frame, "CENTER", 0, 25)
	rp:SetWidth(70);
	rp:SetHeight(70);
	rp:SetJustifyH("CENTER");
	rp:SetJustifyV("MIDDLE");
	
	frame.Counter = rp;
	
	return frame;
end

function Full:BuildBar(base)
	local frame = CreateFrame("frame", "$parent_Bar", base);
	frame:SetFrameStrata("LOW");
	frame:SetFrameLevel(0);
	frame:SetWidth(300);
	frame:SetHeight(150);
	frame:Show();
	
	local bar = frame:CreateTexture("$parent_T_Bar", "BORDER");
	bar:SetWidth(300);
	bar:SetHeight(150);
	bar:SetPoint("LEFT", base.Art, "LEFT");
	bar:Show();
	
	frame.Art = bar;
	
	local border = frame:CreateTexture("$parent_T_Border", "ARTWORK");
	border:SetWidth(300);
	border:SetHeight(150);
	border:SetPoint("LEFT", base.Art, "LEFT");
	border:Show();
	
	frame.Border = border;
	
	return frame;
end

-- Updates the Gui
function Full:UpdateGui()
	if (not Full:IsActive(Full.ID)) then
		return
	end
	
	local skinOptions = RuneWatch.db.skin;
	local Gui = _G["RuneWatch_Full"];
	
	if (skinOptions.orientation == "top") then
		Full:UpdateOriTop();
	else
		Full:UpdateOriBottom();
	end
	
	local perc = UnitMana("player") / UnitManaMax("player");
	Full.Bar.Transforms[skinOptions.orientation](Gui.Bar.Art, perc);
	
	RuneWatch:UpdateDrag();
end

function Full:UpdateOriTop()
	local skinOptions = RuneWatch.db.skin;
	local theme = skinOptions.theme;

	--[===[ Base Frame ]===]--
	local frame = _G["RuneWatch_Full"];
	
	frame:SetWidth(300);
	frame:SetHeight(150);
	
	-- Base Frame
	local base = frame.Art;
	base:ClearAllPoints();
	base:SetWidth(300);
	base:SetHeight(150);
	base:SetPoint("CENTER", frame, "CENTER");
	base:SetTexCoord(0,1,0,0,1,1,1,0);
	base:SetTexture(SkinArt.Base[theme]); -- Texture
	
	-- ORb
	local orb = frame.Orb;
	orb:ClearAllPoints();
	orb:SetWidth(170);
	orb:SetHeight(170);
	orb:SetPoint("CENTER", frame, "CENTER", 0, -30);
	orb:SetTexture(SkinArt.Orb[theme]);
	
	local cnt = frame.Counter;
	cnt:SetWidth(70);
	cnt:SetHeight(70);
	cnt:SetPoint("CENTER", frame, "CENTER", 0, -30);
	
	--[===[ Bar Frame ]===]--
	frame = _G["RuneWatch_Full_Bar"];
	
	frame:SetWidth(300);
	frame:SetHeight(150);
	frame:SetPoint("CENTER", _G["RuneWatch_Full"], "CENTER");
	
	local art = frame.Art;
	art:SetWidth(300);
	art:SetHeight(150);
	art:SetPoint("LEFT", _G["RuneWatch_Full"].Art, "LEFT");
	art:SetTexture(SkinArt.Bar[theme]);
	
	local bord = frame.Border;
	bord:SetTexCoord(0,1,0,0,1,1,1,0);
	bord:SetTexture(SkinArt.BarBorder[theme]);
	bord:SetAllPoints(_G["RuneWatch_Full"].Art);
end

function Full:UpdateOriBottom()
	local skinOptions = RuneWatch.db.skin;
	local theme = skinOptions.theme;

	--[===[ Base Frame ]===]--
	local frame = _G["RuneWatch_Full"];
	
	frame:SetWidth(300);
	frame:SetHeight(150);
	
	-- Base Frame
	local base = frame.Art;
	base:ClearAllPoints();
	base:SetWidth(300);
	base:SetHeight(150);
	base:SetPoint("CENTER", frame, "CENTER");
	base:SetTexCoord(0,0,0,1,1,0,1,1);
	base:SetTexture(SkinArt.Base[theme]); -- Texture
	
	-- ORb
	local orb = frame.Orb;
	orb:ClearAllPoints();
	orb:SetWidth(170);
	orb:SetHeight(170);
	orb:SetPoint("CENTER", frame, "CENTER", 0, 30);
	orb:SetTexture(SkinArt.Orb[theme]);
	
	local cnt = frame.Counter;
	cnt:SetWidth(70);
	cnt:SetHeight(70);
	cnt:SetPoint("CENTER", frame, "CENTER", 0, 30);
	
	--[===[ Bar Frame ]===]--
	frame = _G["RuneWatch_Full_Bar"];
	
	frame:SetWidth(300);
	frame:SetHeight(150);
	frame:SetPoint("CENTER", _G["RuneWatch_Full"], "CENTER");
	
	local art = frame.Art;
	art:SetWidth(300);
	art:SetHeight(150);
	art:SetPoint("LEFT", _G["RuneWatch_Full"].Art, "LEFT");
	art:SetTexture(SkinArt.Bar[theme]);
	
	local bord = frame.Border;
	bord:SetTexCoord(0,0,0,1,1,0,1,1);
	bord:SetTexture(SkinArt.BarBorder[theme]);
	bord:SetAllPoints(_G["RuneWatch_Full"].Art);
end

function Full:UpdateStructure()
	if (not Full:IsActive(Full.ID)) then
		return
	end

	local ori = RuneWatch.db.skin.orientation;
	local theme = RuneWatch.db.skin.theme;
	
	local frame = Full.Gui.Base;
	
	-- Base
	if (ori == "left") then
		-- NYI
	elseif (ori == "right") then
		-- NYI
	else -- TOP / BOTTOM / ERROR
		frame:SetWidth(300);
		frame:SetHeight(150);
		frame.Art:SetWidth(300);
		frame.Art:SetHeight(150);
		frame.Art:SetPoint("CENTER", frame, "CENTER");
	end
	
	frame = Full.Gui.Bar;
	
	-- Bar / Border
	if (ori == "left") then
		-- NYI
	elseif (ori == "right") then
		-- NYI
	else -- TOP / BOTTOM / ERROR
		frame:SetPoint("CENTER", Full.Gui.Base, "CENTER");
	
		frame:SetWidth(300);
		frame:SetHeight(150);
		frame.Art:SetPoint("LEFT", frame, "LEFT");
		frame.Art:SetWidth(300);
		frame.Art:SetHeight(150);
		frame.Border:SetAllPoints(Full.Gui.Base.Art);
	end
	
	frame = Full.Gui.Base.Counter;
	
	-- Counter
	if (ori == "top") then
		-- NYI
		frame:SetPoint("CENTER", Full.Gui.Base, "CENTER", 0, -25);
	elseif (ori == "left") then
		-- NYI
	elseif (ori == "right") then
		-- NYI
	else -- BOTTOM / ERROR
		frame:SetPoint("CENTER", Full.Gui.Base, "CENTER", 0, 25);
	end
end

--[[ ================ Events ============= ]]

function Full:RuneWatch_Gui_Update()
	Full:UpdateGui();
end

function Full:RuneWatch_Skins_Assign(event, skinID)
	if (skinID == "full") then
		Full.State.IsActive = true;
	else
		Full.State.IsActive = false;
	end
end

function Full:RuneWatch_RunicPower_Update(event, ...)
	local rp, rpm, perc, col = ...;
	
	local perci = perc * (1 - (2 * 0.02734)) + 0.02734;
	local wid = perc * 300;
	
	local bar = Full.Gui.Bar;
	if (rp == 0) then
		bar.Art:Hide();
	else
		bar.Art:Show();
		bar.Art:SetWidth(wid);
		local tf = Full.Bar.Transforms[RuneWatch.db.skin.orientation];
		
		if (tf ~= nil) then
			tf(bar.Art, perc);
		end
		
		bar.Art:SetVertexColor(col.r, col.g, col.b, col.a);
	end
	
	
	local f = _G["RuneWatch_Full"];
	-- Update Numerical Counter
	local cnt = f.Counter;
	cnt:SetText(rp);
end

function Full:RuneWatch_Gui_DragEnable(event, ...)
	if (not Full:IsActive(Full.ID)) then
		return
	end
	
	local dframe = ...;
	dframe:SetAllPoints(_G["RuneWatch_Full"]);
end
