
/////////////////////////////////////////////////////////////////////////
// Color object with alpha
/////////////////////////////////////////////////////////////////////////
function AColor( r, g, b, a )
{
  this.r = r;
  this.g = g;
  this.b = b;
  this.a = a;
}

AColor.prototype.clone = function()
{
  var color = new Color( this.r, this.g, this.b, this.a );
  return color;
}

AColor.prototype.toString = function()
{
  if ( this.stringValue == null ) this.stringValue = 'AColor{'+this.r+','+this.g+','+this.b+','+this.a+'}';
  return this.stringValue;
}

AColor.hexCache = new Object();
AColor.parseCache = new Object();
AColor.color2Hex = function(n)
{
  return (n.toString(16).length < 2) ? '0' + n.toString(16) : n.toString(16);
}
AColor.parse = function(str)
{
  if (AColor.parseCache[str] != null) return AColor.parseCache[str];

  var color = null;
  if (str.indexOf("#") == 0) color = AColor.hex2AColor(str);
  if (str.indexOf("rgb") == 0) color = AColor.rgb2AColor(str);
  AColor.parseCache[str] = color;
  return color;
}

AColor.rgb2AColor = function(rgb)
{
  return new AColor(parseInt(rgb.substring(4,7))/255,
                    parseInt(rgb.substring(9,12))/255,
                    parseInt(rgb.substring(14,17))/255,
                    1);
}
AColor.hex2AColor = function(hex)
{
  return new AColor(parseInt(hex.substring(1,3), 16)/255,
                    parseInt(hex.substring(3,5), 16)/255,
                    parseInt(hex.substring(5,7), 16)/255,
                    1);
}
AColor.prototype.toHex = function()
{
  if (AColor.hexCache[this.toString()] != null) return AColor.hexCache[this.toString()];
  var hexValue = '#' + AColor.color2Hex(Math.floor(255*this.r)) + AColor.color2Hex(Math.floor(255*this.g)) + AColor.color2Hex(Math.floor(255*this.b));
  AColor.hexCache[this.toString()] = hexValue;
  return hexValue;
}
AColor.prototype.merge = function(color)
{
    return new AColor(
        (1-color.a)*this.r + color.a*color.r,
        (1-color.a)*this.g + color.a*color.g,
        (1-color.a)*this.b + color.a*color.b,
        Math.max(this.a,color.a) );
}
AColor.prototype.remove = function(color)
{
    return new AColor(
        (this.r - color.a*color.r)/(1 - color.a),
        (this.g - color.a*color.g)/(1 - color.a),
        (this.b - color.a*color.b)/(1 - color.a),
        Math.max(this.a,color.a) );
};