(function($){
  $.fn.colorpicker = function(opts){
    options[opts.prefix] = $.extend({}, opts);
    if(options[opts.prefix].defaultColors)
{
      colors[opts.prefix] = $.fn.colorpicker.defaultColors = options[opts.prefix].defaultColors;
}
    if(this.length > 0) buildSelector(opts.prefix);
    return this.each(function(i) { buildPicker(this, opts.prefix)}); 
  };
  
  var colors = $.fn.colorpicker.defaultColors = [{ hex:'#ff0000', name:'red' }, { hex: '#00ff00', name:'green' }, { hex: '#0000ff', name: 'blue' }],
      current = [],
      control = [],
      expanded = false,
      selectorOwner,
      options = [];

  if( "function" !== typeof $.fn.colorpicker.is )
    $.fn.colorpicker.is = function( a, b )
    {
      return ( a.hex === b.hex )
          || ( a.name === b.name );
    };
  var is = $.fn.colorpicker.is;
  
  function select( prefix, colorValue ) {
	control[prefix] = $('#'+prefix+'color-picker-control');

    for( var color in colors[prefix] )
      if( is( colors[prefix][ color ], colorValue ) )
        current[prefix] = colors[prefix][ color ];

    if( !current[prefix] ) return;
    control[prefix].css( 'background-color', current[prefix].hex );
    
    if( 'function' === typeof options[prefix].select )
      options[prefix].select( current[prefix], prefix );
    
    $('.'+prefix+'jquery-simple-colorpicker-name').html( current[prefix].name )
  }
  
  function buildPicker( el, prefix ) {
    var $el = $(el);
    // build the control
    control = $('<div class="jquery-simple-colorpicker" id="'+prefix+'color-picker-control"></div>');
    // set the css for the width and height of the colorpicker
    if(options[prefix].width)
      control.css( 'width', options[prefix].width );
    if(options[prefix].height)
      control.css( 'height', options[prefix].height );

    // bind the click event to the color picker
    control.bind( 'click.jquery-simple-colorpicker', function(event) {toggleSelector(prefix);});

    // hide the input, add the colorPicker
    $el.hide().bind( 'change.jquery-simple-colorpicker', function() {
      select( prefix, { hex:$el.val() } );
    }).after( control );

    // set the default color:
    select( prefix, { hex:$el.val() } );
  }
  
  function buildSelector(prefix) {
    var palette = $('<div id="'+prefix+'jquery-simple-colorpicker"></div>');
    // add the color swatches

	var cls = colors[prefix];
    $.each( cls, function(){

      var swatch = $('<div class="jquery-simple-colorpicker-swatch"></div>'),
          color = this;
	      swatch.css( 'background-color', this.hex )
            .bind( 'click.jquery-simple-colorpicker', function(e){
              select( prefix, color );
              hideSelector();
            })
            .bind( 'mouseover.jquery-simple-colorpicker', function(e){
              $('.'+prefix+'jquery-simple-colorpicker-name', palette).html( color.name );
            })
            .bind( 'mouseout.jquery-simple-colorpicker', function(e){
              $('.'+prefix+'jquery-simple-colorpicker-name', palette).html( current[prefix].name );
            })
            
      swatch.appendTo( palette );
    });
    
    palette.append('<div class="'+prefix+'jquery-simple-colorpicker-name jquery-simple-colorpicker-name"></div>');
    
    $('body').append( palette );
    palette.hide();
  }
  
  //converts RGB string to HEX - inspired by http://code.google.com/p/jquery-color-utils
  function toHex( color ) {
    //valid HEX code is entered
    if(color.match(/[0-9a-fA-F]{3}$/) || color.match(/[0-9a-fA-F]{6}$/)){
      color = (color.charAt(0) == "#") ? color : ("#" + color);
    }
    //rgb color value is entered (by selecting a swatch)
    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;
  }
  function hideSelector(prefix){
	var selector = $("div#"+prefix+"jquery-simple-colorpicker");
	hideLightbox(prefix);
	$(document).unbind("mousedown.jquery-simple-colorpicker", checkMouse);
//    selector.slideUp('fast');
	expanded = false
  };
  
  function showSelector(prefix){
	control = $('.'+prefix+'jquery-simple-colorpicker');
    var selector = $("div#"+prefix+"jquery-simple-colorpicker");
/*    
    selector.css({
      top: $(selectorOwner).offset().top + ($(selectorOwner).outerHeight()),
      left: $(selectorOwner).offset().left
    }); 
*/
    hexColor = $(selectorOwner).next("input").val();
    $("input#_color_value").val(hexColor);
//    selector.slideDown('fast');
	showLightbox(selector, prefix);
    
    //bind close event handler
global_picker_prefix = prefix;
    $(document).bind("mousedown.jquery-simple-colorpicker", checkMouse);
    expanded = true 
   };

   function checkMouse(event){
     //check the click was on selector itself or on selectorOwner
     var selector = "div#"+global_picker_prefix+"jquery-simple-colorpicker";
     var selectorParent = $(event.target).parents(selector).length;
     if(event.target == $(selector)[0] || event.target == selectorOwner || selectorParent > 0) return

     hideSelector();   
   };
  
  function toggleSelector(prefix){
    selectorOwner = this; 
    expanded ? hideSelector(prefix) : showSelector(prefix);
  };
})(jQuery);
