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

local L = LibStub("AceLocale-3.0"):GetLocale("RuneWatch");

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

local _Events = RuneWatch.Callbacks;

local Skin = 
{ 
	ID = "skinbase",
	Name = "SkinBase", 
	Description = "Basic Skin",
	Themes = {},
	Orientations = {},
	State =
	{
		IsActive = false
	},
	Mounts = {},
	Options = {},
	Gui = {},
	GuiBase = {}
}

function Skin:Super(t)
	local sup = getmetatable(self)["__index"]
	return sup[t](sup == Skin and self or sup)
end

function Skin:OnInitialize()

end

function Skin:OnEnable()
	--@debug@
	RuneWatch:Print("[Skin] "..self.Name.." Loaded...");
	--@debug-end@
end

function Skin:OnDisable()

end

function Skin:IsActive(skinID)
	if (RuneWatch.db.skin.active == skinID) then
		return true;
	else
		return false;
	end
end

RuneWatch.SkinBase = Skin;

--[[============================= SKIN: API =============================]]



RuneWatch.Skins = {}
RuneWatch.Skins.List = {}
RuneWatch.Skins.Registry = {}
RuneWatch.Skins.configOptions = {}

local _S = RuneWatch.Skins


local _SkinHandler = {}

function _SkinHandler:ListSkins(info)
	return _S.List;
end

function _SkinHandler:ListOrientations(info)
	return { bottom = "Bottom", left = "Left", right = "Right", top = "Top" }
end

function _SkinHandler:ListThemes(info)
	local skinID = _S:GetCurrentID();
	local skinObj = _S:GetSkin(skinID);
	
	return skinObj.Themes or { generic = "Generic" };
end

function _SkinHandler:ValidateOrientation(info, v)
	local skinID = _S:GetCurrentID();
	local skinObj = _S:GetSkin(skinID);
	
	if (skinObj.Orientations[v] == nil) then
		return L["That orientation is not availiable for '"]..skinObj.Name.."'.";
	end
	
	return true;
end

function _SkinHandler:ValidateTheme(info, v)
	local skinID = _S:GetCurrentID();
	local skinObj = _S:GetSkin(skinID);
	
	if (skinObj.Themes[v] == nil) then
		return L["That theme is not availiable for '"]..skinObj.Name.."'.";
	end
	
	return true;
end

function _SkinHandler:SetOrientation(info, v)
	RuneWatch.db.skin.orientation = v;
	RuneWatch:UpdateGui();
end

function _SkinHandler:SetTheme(info, v)
	RuneWatch.db.skin.theme = v;
	RuneWatch:UpdateGui();
end

--[===[ Registration ]===]--
function RuneWatch.Skins:Register(id, obj)
	_S.List[id] = obj.Name;
	_S.Registry[id] = obj;
	
	if (obj.Options.type ~= nil) then
		_S.configOptions[id] = obj.Options;
	end
end

function RuneWatch.Skins:InitOptions()
	local args = {
		generic = {
			type = "group",
			name = L["Skin Selection"],
			desc = L["Select your skin and theme"],
			order = 0,
			inline = true,
			args = {
				active_skin = {
					type = "select",
					name = L["Active Skin"],
					handler = _SkinHandler,
					width = "double",
					order = 10,
					desc = L["Currently active skin"],
					values = "ListSkins",
					get = function(info) return RuneWatch.db.skin.active; end,
					set = function(info,v) _S:Select(v); end
				},
				orientation = {
					type = "select",
					name = L["Orientation"],
					handler = _SkinHandler,
					validate = "ValidateOrientation",
					--width = "double",
					order = 20,
					desc = L["Current skin's orientation"],
					values = "ListOrientations",
					get = function(info) return RuneWatch.db.skin.orientation; end,
					set = "SetOrientation"
				},
				theme = {
					type = "select",
					name = L["Theme"],
					handler = _SkinHandler,
					validate = "ValidateTheme",
					--width = "double",
					order = 30,
					desc = L["Current skin's theme"],
					values = "ListThemes",
					get = function(info) return RuneWatch.db.skin.theme; end,
					set = "SetTheme"
				}
			}
		}
	}
	
	_S.configOptions = args;
	
	return args;
end

function RuneWatch.Skins:Init()
	RuneWatch:SendMessage("RuneWatch_Skins_Init");
	
	local skinInfo = RuneWatch.db.skin;
	
	if (_S.Registry[skinInfo.active] == nil) then
		-- Our previous skin was not found, grab the first one.
		skn = nil;
		for k,v in pairs(_S.Registry) do
			skn = k;
			break;
		end
		
		if (skn == nil) then
			error("No Skins Loaded!");
		end
		
		skinInfo.active = skn; -- Assign us a new skin.
	end
	
	-- Attach All GUIs
	for _,v in pairs(_S.Registry) do
		local b = v.GuiBase;
		b:SetParent(RuneWatch.Gui.Anchor);
		b:SetPoint("CENTER", RuneWatch.Gui.Anchor, "CENTER");
	end
	
	local skinID = skinInfo.active;
	_S:Select(skinID);
end

-- Selects a specific skin
function RuneWatch.Skins:Select(skinID)
	RuneWatch.db.skin.active = skinID;
	
	local skinGUI
	local skinObj = _S.Registry[skinID];
	
	if (skinObj ~= nil) then
	
		skinGUI = skinObj.GuiBase;
		
		-- Check that a GUI was successfully created
		if (skinGUI == nil) then
			error("Selected skin is missing a GUI.");
		end
		
		-- Fire the skin initialization event, this event signals all mods whom aren't skinID to ignore update commands, and signals the skinID skin to start listening.
		RuneWatch:SendMessage("RuneWatch_Skins_Assign", skinID);
		
		-- Hide all skin guis
		for _,v in pairs(_S.Registry) do
			v.GuiBase:Hide();
		end
		
		-- Show the selected gui
		skinGUI:Show();
		
		-- Force a gui update
		RuneWatch:UpdateGui();
		
		RuneWatch:UpdateDrag();
	end
end

function RuneWatch.Skins:GetSkin(skinID)
	local sk = _S.Registry[skinID];
	
	return sk;
end

function RuneWatch.Skins:GetCurrentID()
	return RuneWatch.db.skin.active;
end
