--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--
--|	GypsyMod Library - Gypsy_Color.lua
--|	Color pallette
--|	Color usage tools
--|	Respect to Dhargo, creator of Flexbar, for the meta table usage
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--

-- Isolated file version
local version = 1.05;

--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--
--|	Version History
--|	1.00 - Original library with full complement of functions
--|	1.05 - Added keyword searching to the Parse method to make it neater and more
--|		efficient to use.
--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--

-- Load only if the library has not been loaded previously, or if previously loaded versions are older
if (not Gypsy_Color or not Gypsy_Color.version or Gypsy_Color.version < version) then
	Gypsy_Color = {};
	Gypsy_Color.version = version;
	-- Standard chat color close code
	Gypsy_Color.close = "|r";
	
	--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--
	--|	Gypsy_Color:New
	--|	Used to make this library available for use locally from script files. 
	--|		Usage: local color = Gypsy_Color:New();
	--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--
	
	function Gypsy_Color:New ()			
		local object = {};
		setmetatable(object, self);
		self.__index = self;
		return object;
	end
	
	--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--
	--|	Gypsy_Color:Parse
	--|	Accepts a string of comma delimited RGB values and returns their seperated values
	--|	or nil if the string is invalid. This method is used to seperate RGB values from
	--|	color registration values, and to check registrations for vailidity. This is
	--|	usable in any script file after the usage in Gypsy_Color:New is followed.
	--|		Usage: r, g, b = color:Parse(str);
	--|		Further Example: 
	--|			object:SetTextColor(color:Parse(object.color));
	--|		This second example works, as SetTextColor() accepts three arguments, and
	--|		Parse() returns three. Handy!
	--|
	--|	Now also accepts key words. A key word must be the 'name' of a color that has
	--|	been added using the :Add method. Using keywords is also much more efficient,
	--|	and recomended, as this function can be called VERY often.
	--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--
	
	function Gypsy_Color:Parse (str)
		if (str) then
			if (self[str]) then
				return self[str].r, self[str].g, self[str].b;
			end
			
			-- Each valid string will have 3 values seperated by 2 commas and no spaces, so check for the commas
			local first = nil;
			local second = nil;
			first = string.find(str, ",");
			if (first) then
				second = string.find(str, ",", first+1);
				if (second) then
					local r = nil; 
					local g = nil;
					local b = nil;
					r = strsub(str, 1, first-1);
					g = strsub(str, first+1, second-1);
					b = strsub(str, second+1);
					if (r and g and b) then
						return r, g, b;
					else
						return nil;
					end
				else
					return nil;
				end
			else
				return nil;
			end
		else
			return nil;
		end
	end
	
	--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--
	--|	Gypsy_Color:ToHex
	--|	Accepts a number value or convertable string value and returns it's hexidecimal
	--|	value. This is usable in any script file after the usage in Gypsy_Color:New is
	--|	followed.
	--|		Usage: str = color:ToHex(num);
	--|		Further Example:
	--|			local color1 = 1.0; 
	--|			local hex = color:ToHex(color1);
	--|		Hex would be "FF", which is equivalent to 1.0.
	--|
	--|	Hex values are used for chat message intra-line color changes.
	--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--
	
	function Gypsy_Color:ToHex (num)
		if (not num) then	return nil;	end
		-- If it's not a number or can't be converted to one, return nil
		if (type(num) ~= "number" and not tonumber(num)) then	return nil;	end
		local str = string.format("%2x", tonumber(num)*255);
		-- Pesky leading null characters need to be replaced
		if (string.byte(str,1) == 32) then
			str = "0"..strsub(str,2);
		end
		return str;
	end
	
	--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--
	--|	Gypsy_Color:RGBToHex
	--|	Accepts a comma delimited string RGB value and returns the hexidecimal values for
	--|	R, G, and B individually. This is usable in any script file after the usage in
	--|	Gypsy_Color:New is followed.
	--|		Usage: hexstr = color:RGBToHex(str);
	--|		Further Example:
	--|			local red = color.red.rgb;		-- Comma delimited value, 1.0,0.0,0.0
	--|			local code = color:RGBToHex(red);
	--|		Code would then equal "ff0000".
	--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--
	
	function Gypsy_Color:RGBToHex (str)
		if (not str) then	return nil;	end
		local r, g, b = self:Parse(str);
		if (r and g and b) then
			return self:ToHex(r), self:ToHex(g), self:ToHex(b);
		else
			return nil;
		end
	end
	
	--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--
	--|	Gypsy_Color:Add
	--|	This is a convenience function for adding colors to the library. The function
	--|	requires a name string, with optional RGB value arguments. If R is not passed, it
	--|	will default to 1 (white). If G or B are not passed, it will set them to equal to
	--|	R. So, for adding greyscale colors, only the red value is required. 
	--|
	--|	Data is added to the library in a number of ways. The RGB values are stored both
	--|	seperately, and as a single comma delimited string. The function will also auto-
	--|	matically get the hexidecimal equivalents and add them with the prefix "|c", for
	--|	chat format color code usage.
	--|	
	--|	Here's an example of how to instatiate the color library, of how to call up the
	--|	color data, and what the data would look like:
	--|
	--|		local color = Gypsy_Color:New();
	--|		color:Add("white", 1.0, 1.0, 1.0);
	--|		color.white.rgb = "1.0,1.0,1.0";
	--|		color.white.r = "1.0";
	--|		color.white.g = "1.0";
	--|		color.white.b = "1.0";
	--|		color.white.code = "|cffffffff";
	--=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=--
	
	function Gypsy_Color:Add (name, r, g, b)
		if (not name) then
			return;
		else
			if (not r) then		r = 1.0;	end
			if (not g) then		g = r;		end
			if (not b) then		b = r;		end
			self[name] = {};
			self[name].rgb = r..","..g..","..b;
			self[name].r = r;
			self[name].g = g;
			self[name].b = b;
			local hexR, hexG, hexB = self:RGBToHex(self[name].rgb);
			-- Leading "ff" is for the alpha value, possible to make this customizable later
			self[name].code = "|c".."ff"..hexR..hexG..hexB;
		end
	end
	
	--= Color Pallette =--
	
	-- Blizzard normal gold
	Gypsy_Color:Add("normal", NORMAL_FONT_COLOR.r, NORMAL_FONT_COLOR.g, NORMAL_FONT_COLOR.b);
	-- Standard colors
	Gypsy_Color:Add("white", 1.0);
	Gypsy_Color:Add("lightgrey", 0.9);
	Gypsy_Color:Add("grey", 0.5);
	Gypsy_Color:Add("darkgrey", 0.1);
	Gypsy_Color:Add("black", 0.0);
	Gypsy_Color:Add("red", 1.0, 0.0, 0.0);
	Gypsy_Color:Add("green", 0.0, 1.0, 0.0);
	Gypsy_Color:Add("blue", 0.0, 0.0, 1.0);
	Gypsy_Color:Add("orange", 1.0, 0.5, 0.0);
	Gypsy_Color:Add("purple", 1.0, 0.0, 1.0);
	Gypsy_Color:Add("yellow", 1.0, 1.0, 0.0);
	Gypsy_Color:Add("lightblue", 0.5, 0.5, 1.0);
	-- Custom GypsyMod colors
	Gypsy_Color:Add("frad", 1.0, 0.89, 0.01);
end		