(function($){
  $.fn.colorPicker = function(){    
    if(this.length > 0) buildSelector();
    return this.each(function(i) { buildPicker(this)}); 
  };
  
  var selectorOwner;
  var selectorShowing = false;
  
  buildPicker = function(element){
    control = $("<input class='color_picker'>&nbsp;</input>")
    control.css('background-color', $(element).val());
    control.bind("click", toggleSelector);
    $(element).after(control);
  };
  
  buildSelector = function(){
    selector = $("<div id='color_selector'></div>");
	  $.each($.fn.colorPicker.defaultColors, function(i){
      swatch = $("<div class='color_swatch'>&nbsp;</div>")
      swatch.css("background-color", "#" + this);
      swatch.bind("click", function(e){ changeColor($(this).css("background-color")) });
      swatch.bind("mouseover", function(e){ 
        $(this).css("border-color", "#598FEF"); 
        $("input#color_value").val(toHex($(this).css("background-color")));    
        }); 
      swatch.bind("mouseout", function(e){ 
        $(this).css("border-color", "#000");
        $("input#color_value").val(toHex($(selectorOwner).css("background-color")));
        });  
     swatch.appendTo(selector);
     });
     
     hex_field = $("<label for='color_value'></label><input type='text' size='8' id='color_value'/>");
     hex_field.bind("keydown", function(event){
      if(event.keyCode == 13) {changeColor($(this).val());}
      if(event.keyCode == 27) {toggleSelector()}
     });
     
     $("<div id='color_custom'></div>").append(hex_field).appendTo(selector);

     $("body").append(selector); 
     selector.hide();

  };
  
  checkMouse = function(event){
    var selector = "div#color_selector";
    var selectorParent = $(event.target).parents(selector).length;
    if(event.target == $(selector)[0] || event.target == selectorOwner || selectorParent > 0) return
    hideSelector();   
  }
  
  hideSelector = function(){
    var selector = $("div#color_selector");
    
    $(document).unbind("mousedown", checkMouse);
    selector.hide();
    selectorShowing = false
  }
  
  showSelector = function(){
    var selector = $("div#color_selector");
    selector.css({
      top: $(selectorOwner).offset().top + ($(selectorOwner).outerHeight()),
      left: $(selectorOwner).offset().left
    }); 
    hexColor = $(selectorOwner).next("input").val();
    $("input#color_value").val(hexColor);
    selector.show();
  
    $(document).bind("mousedown", checkMouse);
    selectorShowing = true 
   }
  
  toggleSelector = function(event){
    selectorOwner = this; 
    selectorShowing ? hideSelector() : showSelector();
  }
  
  changeColor = function(value){
    if(selectedValue = toHex(value)){
      $(selectorOwner).css("background-color", selectedValue);
      $(selectorOwner).prev("input").val(selectedValue).change();
    
      //close the selector
      hideSelector();    
    }
  };
  
  
  toHex = function(color){
   
    if(color.match(/[0-9a-fA-F]{3}$/) || color.match(/[0-9a-fA-F]{6}$/)){
      color = (color.charAt(0) == "#") ? color : ("#" + color);
    }
    
    else if(color.match(/^rgb\(([0-9]|[1-9][0-9]|[1][0-9]{2}|[2][0-4][0-9]|[2][5][0-5]),[ ]{0,1}([0-9]|[1-9][0-9]|[1][0-9]{2}|[2][0-4][0-9]|[2][5][0-5]),[ ]{0,1}([0-9]|[1-9][0-9]|[1][0-9]{2}|[2][0-4][0-9]|[2][5][0-5])\)$/)){
      var c = ([parseInt(RegExp.$1),parseInt(RegExp.$2),parseInt(RegExp.$3)]);
      
      var pad = function(str){
            if(str.length < 2){
              for(var i = 0,len = 2 - str.length ; i<len ; i++){
                str = '0'+str;
              }
            }
            return str;
      }

      if(c.length == 3){
        var r = pad(c[0].toString(16)),g = pad(c[1].toString(16)),b= pad(c[2].toString(16));
        color = '#' + r + g + b;
      }
    }
    else color = false;
    
    return color
  }

  $.fn.colorPicker.addColors = function(colorArray){
    $.fn.colorPicker.defaultColors = $.fn.colorPicker.defaultColors.concat(colorArray);
  };
  
  $.fn.colorPicker.defaultColors = 
		[ '190707', '2A0A0A', '3B0B0B', '610B0B', '8A0808', 'B40404', 'DF0101', 'FF0000', 'FE2E2E', 'FA5858', 'F78181', 'F5A9A9', 'F6CECE', 'F8E0E0', 'FBEFEF',  
		  '191007', '2A1B0A', '3B240B', '61380B', '8A4B08', 'B45F04', 'DF7401', 'FF8000', 'FE9A2E', 'FAAC58', 'F7BE81', 'F5D0A9', 'F6E3CE', 'F8ECE0', 'FBF5EF', 
		  '181907', '292A0A', '393B0B', '5E610B', '868A08', 'AEB404', 'D7DF01', 'FFFF00', 'F7FE2E', 'F4FA58', 'F3F781', 'F2F5A9', 'F5F6CE', 'F7F8E0', 'FBFBEF', 
		  '101907', '1B2A0A', '243B0B', '38610B', '4B8A08', '5FB404', '74DF00', '80FF00', '9AFE2E', 'ACFA58', 'BEF781', 'D0F5A9', 'E3F6CE', 'ECF8E0', 'F5FBEF',
		  '071907', '0A2A0A', '0B3B0B', '0B610B', '088A08', '04B404', '01DF01', '00FF00', '2EFE2E', '58FA58', '81F781', 'A9F5A9', 'CEF6CE', 'E0F8E0', 'EFFBEF',
		  '071910', '0A2A1B', '0B3B24', '0B6138', '088A4B', '04B45F', '01DF74', '00FF80', '2EFE9A', '58FAAC', '81F7BE', 'A9F5D0', 'CEF6E3', 'E0F8EC', 'EFFBF5',
		  '071918', '0A2A29', '0B3B39', '0B615E', '088A85', '04B4AE', '01DFD7', '00FFFF', '2EFEF7', '58FAF4', '81F7F3', 'A9F5F2', 'CEF6F5', 'E0F8F7', 'EFFBFB',
		  '071019', '0A1B2A', '0B243B', '0B3861', '084B8A', '045FB4', '0174DF', '0080FF', '2E9AFE', '58ACFA', '81BEF7', 'A9D0F5', 'CEE3F6', 'E0ECF8', 'EFF5FB',
		  '070719', '0A0A2A', '0B0B3B', '0B0B61', '08088A', '0404B4', '0101DF', '0000FF', '2E2EFE', '5858FA', '8181F7', 'A9A9F5', 'CECEF6', 'E0E0F8', 'EFEFFB',
		  '100719', '1B0A2A', '240B3B', '380B61', '4B088A', '5F04B4', '7401DF', '8000FF', '9A2EFE', 'AC58FA', 'BE81F7', 'D0A9F5', 'E3CEF6', 'ECE0F8', 'F5EFFB',
		  '190718', '2A0A29', '3B0B39', '610B5E', '8A0886', 'B404AE', 'DF01D7', 'FF00FF', 'FE2EF7', 'FA58F4', 'F781F3', 'F5A9F2', 'F6CEF5', 'F8E0F7', 'FBEFFB',
		  '190710', '2A0A1B', '3B0B24', '610B38', '8A084B', 'B4045F', 'DF0174', 'FF0080', 'FE2E9A', 'FA58AC', 'F781BE', 'F5A9D0', 'F6CEE3', 'F8E0EC', 'FBEFF5',
		  '000000', '0B0B0B', '151515', '1C1C1C', '2E2E2E', '424242', '585858', '6E6E6E', '848484', 'A4A4A4', 'BDBDBD', 'D8D8D8', 'E6E6E6', 'F2F2F2', 'F2F2F2'
		];

  
})(jQuery);


