Not sure how to organize so many function in/out options

I’ll probably regret posting this when the forums are so unpopulated… :puzzled: Am I the only one who is online* even more *on weekends? Maybe it’s my lack of a real life… :ponder:

I am working on a Color class. Sadly, I like being a people pleaser, and allow people to use whatever formats for both input and output they like.

This gets really messy… [SIZE=1](that’s what she said - couldn’t help it)[/SIZE]

Even though the Color class only has one single value ever stored (a hexadecimal RGB value), I allow users to make a color based on any type of input, so my “static constructors” look like this, and take up a lot of room:

//This isn't really how they look, but a reenactment. ;)
public static function fromRGB(r:uint, g:uint, b:uint):Color
{ return new Color(Color.RGBtoHEX(r, g, b)); }

//There may also be input like this with an object instead of separate properties
//Maybe even allowing input to be a value from 0 to 1 instead of 0 to 255
public static function fromRGBobject(rgbObj:Object):Color
{ return new Color(Color.RGBtoHEX(rgbObj.r, rgbObj.g, rgbObj.b)); }

public static function fromHSL(h:uint, s:uint, l:uint):Color
{ return new Color(Color.HSLtoHEX(h, s, l)); }

public static function fromHSV(h:uint, s:uint, v:uint):Color
{ return new Color(Color.HSVtoHEX(h, s, v)); }

public static function fromCMY(c:uint, m:uint, y:uint):Color
{ return new Color(Color.CMYtoHEX(c, m, y)); }

public static function fromCMYK(c:uint, m:uint, y:uint, k:uint):Color
 { return new Color(Color.CMYKtoHEX(c, m, y, k)); }

//Actual constructor
public function Color(hexValue:uint)
{
   _value = hexValue;
}

It’s a lot of extra constructors, and a few KBs of extra space, but that’s fine by me. I don’t mind it at all. I have similar functions for “toRGB”, “toHSV”, “toHex”, etc, which is also fine by me. I like allowing versatility.

However, now I’m running into another issue. I’m either adding the color modification options in the same class, or separating it off, yet the problem remains in both.

Let’s take a simple “add” function as an example.

public function add(r:uint, g:uint, b:uint)
{
   //Actually, my code is a bit more efficient than this, 
   //but this is optimized for readability
   this.r = Math.min(this.r + r, 0xFF);
   this.g = Math.min(this.g + g, 0xFF);
   this.b = Math.min(this.b + b, 0xFF);
}

I could have half a dozen functions like:
[INDENT]add_HEX()
add_Color()
add_RGB()
add_HSV()
add_HSL()
add_CMYK() etc
[/INDENT]or I could use namespaces…
myColor.hex::add(0xBBBB00);
myColor.rgb::add(128, 128, 0);

The namespaces are a much cleaner (and doable!) option. But wait! There’s more!

Let’s say I wanted to allow users to get read only values from these functions, without doing any actual modifications to the stored value?

Simple! I add another namespace named “readonly”.

readonly function add(r:uint, g:uint, b:uint)
{
   return {r:Math.min(this.r + r, 0xFF), g:Math.min(this.g + g, 0xFF), b:Math.min(this.b + b, 0xFF);
}

However, what if they want the input or output value in HSV instead of HEX?
I can imagine how my namespaces will look now:
[INDENT]namespace inHEX;
namespace inRGB;
namespace inHEX_outHEX; //Readonly
namespace inRGB_outHEX; //Readonly
namespace inHSV_outHEX; //Readonly
namespace inHEX_outRGB; //Readonly
namespace inHSV_outRGB; //Readonly
… etc … etc … etc … :*([/INDENT]

Is there any logical and organized way of handling so many “in/out” options?
Or perhaps some other way I can set up the class? I have been trying to think this through without success, and I need someone else’s eyes. Perhaps because it is 3:30AM… :puzzled:

I’m starting to think, should I just suck it up, and develop a Henry Ford mentality “You can have it in any color, as long as it’s in RGB”?