/*
ɫ֪ʶ,Բο:
http://space.flash8.net/space/?18713/action_viewspace_itemid_385613.html
ñʵֵɫʰȡ:
http://wfsr.net/widgets/colorpicker.html
ɫתĴ:
http://easyrgb.com/math.php?MATH=M21#text21
*/
//ɫش
var Color = new Native({
  
 //캯,Ҫ
 //colorΪtypeָʽµɫʾֵ
 initialize: function(color, type){
  //3,rgbʾ,ǰΪɫֵ
  if (arguments.length >= 3){
   type = "rgb"; color = Array.slice(arguments, 0, 3);
  //colorΪַ,תΪRGB
  } else if (typeof color == 'string'){
   //rgbʾ
   if (color.match(/rgb/)) color = color.rgbToHex().hexToRgb(true);
   //hsbʾ
   else if (color.match(/hsb/)) color = color.hsbToRgb();
   //ʮƱʾ
   else color = color.hexToRgb(true);
  }
  //ɫʾ,ĬΪrgb
  type = type || 'rgb';
  switch (type){
   //hsbʾ
   case 'hsb':
    var ld = color;
    //תΪRGB
    color = color.hsbToRgb();
    color.hsb = old;
   break;
   //ʮƱʾ
   case 'hex': color = color.hexToRgb(true); break;
  }
  color.rgb = color.slice(0, 3);
  color.hsb = color.hsb || color.rgbToHsb();
  color.hex = color.rgbToHex();
  //չĶ,ʵ
  return $extend(color, this);
 }

});

//Colorչʵ
Color.implement({

 //͸Ȼ϶ɫ
 mix: function(){
  var colors = Array.slice(arguments);
  //ȡ͸
  var alpha = ($type(colors.getLast()) == 'number') ? colors.pop() : 50;
  //ȡǰɫRGBʾ
  var rgb = this.slice();
  //
  colors.each(function(color){
   //͵ǰɫ
   color = new Color(color);
   //ɫ㷨,ȡǰɫĲ͸ȸǰɫ͸֮
   for (var i = 0; i < 3; i++) rgb[i] = Math.round((rgb[i] / 100 * (100 - alpha)) + (color[i] / 100 * alpha));
  });
  //ػ֮ɫ
  return new Color(rgb, 'rgb');
 },

 //ɫת,RGBֱֵȡ255Ĳ
 invert: function(){
  return new Color(this.map(function(value){
   //ȡԭֵ
   return 255 - value;
  }));
 },

 //ɫ,HSBеHֵ,ȡֵ0-360
 setHue: function(value){
  return new Color([value, this.hsb[1], this.hsb[2]], 'hsb');
 },

 //ñͶ,HSBеSֵ,ȡֵ0-100
 setSaturation: function(percent){
  return new Color([this.hsb[0], percent, this.hsb[2]], 'hsb');
 },

 //,HSBеBֵ,ȡֵ0-100
 setBrightness: function(percent){
  return new Color([this.hsb[0], this.hsb[1], percent], 'hsb');
 }

});

//RGBʽColorʵĿݷʽ
function $RGB(r, g, b){
 return new Color([r, g, b], 'rgb');
};

//HSBʽColorʵĿݷʽ
function $HSB(h, s, b){
 return new Color([h, s, b], 'hsb');
};

//HEXʽColorʵĿݷʽ
function $HEX(hex){
 return new Color(hex, 'hex');
};

//ColorҪ,ΪArrayӵչʵ
Array.implement({

 //rgbתhsb㷨
 rgbToHsb: function(){
  var red = this[0], green = this[1], blue = this[2];
  var hue, saturation, brightness;
  var max = Math.max(red, green, blue), min = Math.min(red, green, blue);
  var delta = max - min;
  brightness = max / 255;
  saturation = (max != 0) ? delta / max : 0;
  if (saturation == 0){
   hue = 0;
  } else {
   var rr = (max - red) / delta;
   var gr = (max - green) / delta;
   var br = (max - blue) / delta;
   if (red == max) hue = br - gr;
   else if (green == max) hue = 2 + rr - br;
   else hue = 4 + gr - rr;
   hue /= 6;
   if (hue < 0) hue++;
  }
  return [Math.round(hue * 360), Math.round(saturation * 100), Math.round(brightness * 100)];
 },

 //hsbתrgb㷨
 hsbToRgb: function(){
  var br = Math.round(this[2] / 100 * 255);
  if (this[1] == 0){
   return [br, br, br];
  } else {
   var hue = this[0] % 360;
   var f = hue % 60;
   var p = Math.round((this[2] * (100 - this[1])) / 10000 * 255);
   var q = Math.round((this[2] * (6000 - this[1] * f)) / 600000 * 255);
   var t = Math.round((this[2] * (6000 - this[1] * (60 - f))) / 600000 * 255);
   switch (Math.floor(hue / 60)){
    case 0: return [br, t, p];
    case 1: return [q, br, p];
    case 2: return [p, br, t];
    case 3: return [p, q, br];
    case 4: return [t, p, br];
    case 5: return [br, p, q];
   }
  }
  return false;
 }

});

//ColorҪ,ΪStringӵչʵ
String.implement({

 //rgbתhsb
 rgbToHsb: function(){
  var rgb = this.match(/\d{1,3}/g);
  return (rgb) ? hsb.rgbToHsb() : null;
 },
 
 //hsbתrgb
 hsbToRgb: function(){
  var hsb = this.match(/\d{1,3}/g);
  return (hsb) ? hsb.hsbToRgb() : null;
 }

});

