function ColorPicker(func){
  if(!func || func.constructor != Function) return null;
  ColorPicker.prototype.ids++;
  this.proxies = false;
  this.proxyIds = [];
  this.id = this.ids;
  this.color_scale_Y = 1;
  this.callBack = func;
  this.cur_hue = 0.0;   //<-- hue
  this.cur_x_frac = 1.0;//<-- saturation
  this.cur_y_frac = 0.0;//<-- value
  this.curColor = this.hsv_to_hex(this.cur_hue,this.cur_x_frac,this.cur_y_frac);
  var colorPicker = make_el('DIV',{unselectable:true,
				   id:'color-picker-'+this.id,
				   className:'color-picker',
				   style:{width:'188px',
					  height:'178px',
					  zIndex:2000,
					  fonSize:0,
					  position:'absolute'}});

  var alpha_img_holder = make_el("DIV",{unselectable:true,
					id:'color-picker-alpha-img-holder-'+this.id,
					style:{border:"1px solid #999",
					       position: 'absolute',
					       top: '10px',
					       left: '10px',
					       backgroundColor: '#'+this.curColor,
					       width: "128px",
					       height: "128px"}},colorPicker);

  var alpha_img = make_el('DIV',{unselectable:true,
				 isAlphaImg: true,
				 id:'color-picker-alpha-img-'+this.id,
				 style:{width: "128px",
					position:'relative',
					display:'block',
					background:'none',
					height: "128px"}},alpha_img_holder);

  if(isIE) alpha_img.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='http://static.yuku.com/editor/bypass/images/alpha_mask.png')";
  else alpha_img.style.backgroundImage="url(/editor/bypass/images/alpha_mask.png)";

  var color_scale = make_el('DIV',{unselectable:true,
				   isColorScale:true,
				   id:'color-picker-color-scale-'+this.id,
				   style:{backgroundImage: 'url(http://static.yuku.com/editor/bypass/images/color_scale.gif)',
					  border:"1px solid #999",
					  position: 'absolute',
					  top: '10px',
					  left: '156px',
					  width:'15px',
					  height:'128px'}}, colorPicker);
  if(isIE) {
    color_scale.style.width = '16px';
    color_scale.style.height = '130px';
  };
  var color_scale_picker = make_el('DIV',{unselectable:true,
					  isColorScalePicker:true,
					  id:'color-picker-color-scale-picker-'+this.id,
					  style:{position:"absolute",
						 backgroundImage: 'url(http://static.yuku.com/editor/bypass/images/scale_picker.gif)',
						 backgroundRepeat: 'no-repeat',
						 width:'31px',
						 height:'9px',
						 marginTop:'-4px',
						 top: 0,
						 left:'-8px'}},color_scale);

  var color_preview = make_el('DIV',{unselectable:true,
				     id:'color-picker-color-preview'+this.id,
				     style:{width: "166px",
					    position:'absolute',
					    top: '148px',
					    left: '10px',
					    height: "20px",
					    border:"1px solid #999",
					    backgroundColor: '#'+this.curColor}}, colorPicker);
  this.addColorPickerEvents(colorPicker,'mousedown','colorPickerMouseDown');
  return colorPicker;
};
ColorPicker.prototype = new Color();
ColorPicker.prototype.ids = 0;
ColorPicker.prototype.current = null;

ColorPicker.prototype.addColorPickerEvents = function(el,event,method) {
  var me = this;
  addEvent(el,event,function(e){me[method](e);},false);
  el = null;
};

ColorPicker.prototype.colorPickerMouseDown = function(e) {
  preventDefault(e);
  var srcEl = get_srcEl(e);
  if(srcEl.isAlphaImg
     || srcEl.isColorScale
     || srcEl.isColorScalePicker) {
    ColorPicker.prototype.current = this;
    if(srcEl.isAlphaImg) {
      addEvent(srcEl, 'mousemove', this.alphaImgMove,false);
      this.alphaImgMove(e);
    }
    else {
      var color_scale = document.getElementById('color-picker-color-scale-'+this.id);
      this.color_scale_Y = FindXY(color_scale).y;
      addEvent(document, 'mousemove', this.hueMove, false);
      this.hueMove(e);
    }
    addEvent(document, 'mouseup', this.mouseUp, false);
  };
};

ColorPicker.prototype.mouseUp = function(e) {
  var me = ColorPicker.prototype.current;
  var aImg = get_by_id('color-picker-alpha-img-'+me.id);
  removeEvent(aImg, 'mousemove', me.alphaImgMove,false);
  removeEvent(document, 'mousemove', me.hueMove, false);
  removeEvent(document, 'mouseup', me.mouseUp, false);
  me.removeProxies();
  me.callBack(me.curColor);
  ColorPicker.prototype.current = null;
};

ColorPicker.prototype.addProxies = function() {
  this.proxies = true;
  var iframes = get_by_tag('IFRAME');
  for(var i=0,l=iframes.length;i<l;i++) {
    var xy = FindXY(iframes[i]);
    var div = document.createElement('DIV');
    div.id = 'color-picker-proxy-'+i;
    div.className = 'proxy';
    div.style.top = xy.y+'px';
    div.style.left = xy.x+'px';
    div.style.width = iframes[i].offsetWidth+'px';
    div.style.height = iframes[i].offsetHeight+'px';
    this.proxyIds[i] = div.id;
    document.body.appendChild(div);
  }
};

ColorPicker.prototype.removeProxies = function() {
  while(this.proxyIds.length) {
    var el = get_by_id(this.proxyIds.shift());
    remove_el(el);
    el = null;
  };
  this.proxies = false;
};

ColorPicker.prototype.alphaImgMove = function(e){
  e = e || event;
  var me = ColorPicker.prototype.current;
  var x = (e.layerX || e.offsetX)/128.0;
  var y = (e.layerY || e.offsetY)/128.0;
  me.cur_x_frac = x > 1.0?1.0:x < 0.0?0.0:x;
  me.cur_y_frac = y > 1.0?1.0:y < 0.0?0.0:y;
  me.recalculateColor();
};

ColorPicker.prototype.hueMove = function(e) {
  var me = ColorPicker.prototype.current;
  if(!me.proxies) me.addProxies();
  var mY = FindMouseXY(e).y;
  mY = mY - me.color_scale_Y;
  mY = mY > 128?128: mY < 0 ? 0 : mY;
  me.cur_hue = mY/128.00;
  me.cur_hue = me.cur_hue >= 1.0 ? 0.0 : me.cur_hue < 0.0 ? 0.0 : me.cur_hue;
  var scalePicker = document.getElementById('color-picker-color-scale-picker-'+me.id);
  scalePicker.style.top = mY+'px';
  me.recalculateColor(true);
};


ColorPicker.prototype.recalculateColor = function(arg) {
  this.curColor = this.hsv_to_hex(this.cur_hue,this.cur_x_frac,this.cur_y_frac);
  document.getElementById('color-picker-color-preview'+this.id).style.backgroundColor
  = '#' + this.curColor;
  if(arg) {
    var hue  = this.hsv_to_hex(this.cur_hue,1.0,0.0);
    document.getElementById('color-picker-alpha-img-holder-'+this.id).style.backgroundColor
      = '#' + hue;
  };
};
