(function($) {
  $.imageselect = { version: '0.1' };
  $.fn.imageselect = function(options) {
    $.imageselect = $.extend({
      auto_width: true,
      color: '#000',
      background_color: '#fff',
      hover_color: '#fff',
      hover_background_color: '#ffddaa'
    }, options || {});
    return $(this).map(create_select);
  };

  function create_select() {
    var select = $(this), select_width, t_width, multiple, options, ns, menu, selected, sid, menu_item, isid;
    if (select.attr('id') == null || select.attr('id').length == 0) throw 'id attribute must be present.';
    if ($('#__imageselect_'+select.attr('id')+'_hide').length) {
      return $('#__imageselect_'+select.attr('id')).get(0);
    }
    select_width = select.width();
    if (select.get(0).tagName.toLowerCase() != 'ul') throw 'object was not ul element.';
    selected = select.find('.imageselect_menuitem_selected');
    options = select.find('li');
    sid = '__imageselect_'+select.attr('id')+'_value';
    ns = $('<div></div>').attr('class', select.attr('class')).attr('id', select.attr('id')).html('<div class="imageselect_button"></div><div id="'+sid+'"></div>').addClass('imageselect_select');
    if (selected.length == 0) {
      ns.find('#'+sid).eq(0).html(options.eq(0).html());
    } else {
      ns.find('#'+sid).eq(0).html(selected.eq(0).html());
    }
    select = select.replaceWith(ns);
    isid = select.attr('id');
    select.empty().attr('id', isid+'_hide').appendTo($('body')).hide();
    if ($.imageselect.auto_width) {
      t_width = select_width - ns.find('.imageselect_button').width();
      if ($.browser.msie) t_width--;  // adjust size for ie
      ns.width(t_width);
    }
    ns.find('span').eq(0).css('padding-top', Math.floor((select.height() - 16)/2)).css('cursor', 'pointer');

    menu = $('<div></div>').attr('id', '__imageselect_'+isid).width(ns.width()).addClass('imageselect_menu').appendTo(document.body);
    menu.click(none);
    options.each(function(i, v) {
      menu_item = $('<div></div>').html(v.innerHTML).addClass('imageselect_menuitem').appendTo(menu);
      if (i == 0 && selected.length == 0) {
        menu_item.addClass('imageselect_menuitem_selected');
      }
    });
    menu.find('.imageselect_menuitem').hover(menu_mouseover, menu_mouseout)
      .click(menu_click);
    ns.click(none);
    ns.mousedown(ns_mousedown);
    return ns.get(0);
  }

  function none(e) {
    e.preventDefault();return false;
  }
  function ns_mousedown(e) {
    e.preventDefault();
    $(this).imageselect_toggle($(this).width());
    return false;
  }
  function menu_mouseover(e) {
    $(this).css('background-color', $.imageselect.hover_background_color).css('color', $.imageselect.hover_color);
  }
  function menu_mouseout(e) {
    if (!$(this).hasClass('imageselect_menuitem_selected')) $(this).css('background-color', $.imageselect.background_color).css('color', $.imageselect.color);
  }
  function menu_click(e) {
    e.preventDefault();
    var parent = $(this).parent(), text = $('#'+parent.attr('id')+'_value');
    parent.find('.imageselect_menuitem_selected')
      .removeClass('imageselect_menuitem_selected')
        .css('background-color', '#fff');
    $(this).addClass('imageselect_menuitem_selected');
    text.html($(this).html());
    text.parent().imageselect_toggle();
    text.parent().trigger('change');
    return true;
  }

  $.fn.imageselect_hide = function() {
    $(this).each(function(e) {
      var self = $('#__imageselect_'+$(this).attr('id').replace(/_hide$/, ''));
      if (self.is(':visible')) self.slideUp('fast');
    });
  };

  $.fn.imageselect_show = function() {
    $(this).each(function(e) {
      var self = $('#__imageselect_'+$(this).attr('id').replace(/_hide$/, ''));
      if (!self.is(':visible')) {
        var dim = $(this).offset();
        self.css({top:(dim.top+$(this).height())+'px', left:dim.left+'px'}).slideDown('fast');
      }
    });
  };

  $.fn.imageselect_toggle = function(width) {
    $('.imageselect_menu').each(function() {if ($(this) != self && $(this).is(':visible')) $(this).slideUp('fast');});
    $(this).each(function(e) {
      var self = $('#__imageselect_'+$(this).attr('id'));
      if (self.is(':visible')) self.slideUp('fast');
      else {
        var dim = $(this).offset();
        if (typeof(width) != 'undefined')
          self.width(width);
        self.css({top:(dim.top+$(this).height())+'px', left:dim.left+'px'}).slideDown('fast');
      }
    });
  };

  $.fn.imageselect_selected = function() {
    var self = $('#__imageselect_'+$(this).attr('id').replace(/_hide$/, '')),
    selected = self.find('.imageselect_menuitem'), i = 0;
    for (i=0;i<selected.length;i++) {
      if (selected.eq(i).hasClass('imageselect_menuitem_selected')) return i;
    }
    return -1;
  };
})(jQuery);

