/**
 * Select assignees
 */
jQuery.fn.selectAssignees = function(s) {
  var settings = jQuery.extend({
    'assignees' : null, 
    
    'choose_responsible' : false,
    'responsible_user_id' : 0,
    
    'choose_subscribers' : false, 
    'subscribers_name' : 'subscribers', 
    'subscribers' : null
  }, s);
  
  /**
   * Renders the control
   * 
   * @param Object data
   */
  var render_control = function (data) {
    var wrapper = $(this).addClass('select_asignees');
    wrapper.append('<input type="hidden" class="no_other_assignees" value="" name="' + s.name + '">');
    $.each(data, function (company_name) {
      if (this && typeof(this) == 'object') {
        var group = '<div class="user_group">';
        group += '<label><input type="checkbox" name="" class="group_checkbox">  ' + company_name + '</label>';
        group += '<ul class="group_users">';
        $.each(this, function (user_id) {
          group += '<li user_id="' + user_id + '" class="group_user" can_see_private="' + ($.inArray(user_id, s.can_see_private) == -1 ? 0 : 1) + '"><span class="subscription_toggler"></span><input type="checkbox" name="' + s.name + '[]" class="user_checkbox" value="' + user_id + '"> <span class="user_label">' + this + '</span></li>';
        });
        group += '</ul>';
        group += '</div>';
        wrapper.append(group);
      } // if
    });
    
    if (settings['choose_responsible']) {
      wrapper.append('<input type="hidden" class="responsible_user_id" value="0" name="' + s.responsible_name + '">');
    } // if
    
    if (!settings['choose_subscribers']) {
      wrapper.find('span.subscription_toggler').remove();
    } // if
  }; // render_control
  
  
  return this.each(function() {
    var wrapper = $(this).disableSelection();

    // render control first
    render_control.apply(this, [s.data, s.name, s.responsible_name]);
    
    if(settings['choose_responsible']) {
      var responsible_user_input = wrapper.find('input.responsible_user_id');
    } // if
    
    /**
     * Set user as responsible
     * 
     * @param jQuery user
     */
    var set_as_responsible = function(user) {
      if(user.find('input.user_checkbox:checked').length < 1) {
        user.find('input.user_checkbox').attr('checked', 'checked');
      } // if
      
      if(settings['choose_subscribers'] && !user.is('.subscribed')) {
        user.addClass('subscribed');
      } // if
      
      responsible_user_input.val(user.attr('user_id'));
      
      wrapper.find('li.group_user').removeClass('responsible');
      user.addClass('responsible');
    }; // set_as_responsible
    
    /**
     * Update responsible user ID
     */
    var update_responsible = function() {
      var first_user_checkbox = wrapper.find('input.user_checkbox:checked:first');
      
      if(first_user_checkbox.length > 0) {
        var responsible_user_id = parseInt(responsible_user_input.val());
        
        if(responsible_user_id > 0) {
          var responsible_user = wrapper.find('li.group_user[user_id=' + responsible_user_id + ']');
          
          if(responsible_user.find('input:checked').length < 1) {
            set_as_responsible(first_user_checkbox.parent());
          } // if
        } else {
          set_as_responsible(first_user_checkbox.parent());
        } // if
      } else {
        responsible_user_input.val(0);
        wrapper.find('li.group_user').removeClass('responsible');
      } // if
    }; // update_responsible
    
    /**
     * Select given user row
     * 
     * @param jQuery user
     * @param boolean bulk
     */
    var select_user = function(user, bulk) {
      if(user.find('input.user_checkbox:checked').length < 1) {
        user.find('input.user_checkbox').attr('checked', 'checked');
      } // if
      
      subscribe_user(user);
      
      if(!bulk) {
        update_responsible();
      } // if
    }; // select_user
    
    /**
     * Deselect given user row
     * 
     * @param jQuery user
     */
    var deselect_user = function(user, bulk) {
      if(user.find('input.user_checkbox:checked').length == 1) {
        user.find('input.user_checkbox').removeAttr('checked');
      } // if
      
      unsubscribe_user(user);
      
      if(!bulk) {
        update_responsible();
      } // if
    }; // deselect_user
    
    /**
     * Mark selected user as subscribed
     * 
     * @param jQuery user
     */
    var subscribe_user = function(user) {
      if (!user.hasClass('subscribed')) {
        user.addClass('subscribed');
      } // if
        
      if(wrapper.find('input.user_subscription[value=' + user.attr('user_id') + ']').length < 1) {
        wrapper.append('<input type="hidden" name="' + settings['subscribers_name'] + '[]" value="' + user.attr('user_id') + '" class="user_subscription">');
      } // if
    }; // subscribe_user
    
    /**
     * Mark seleted user as not subsscribed
     * 
     * @param jQuery user 
     */
    var unsubscribe_user = function(user) {
      if(user.find('input.user_checkbox').is(':checked')) {
        return false;
      } // if
      
      // Mark as no longer subscribed
      user.removeClass('subscribed');
      
      // Remove subscriptions
      var subscriber = wrapper.find('input.user_subscription[value=' + user.attr('user_id') + ']');
      if(subscriber.length > 0) {
        subscriber.remove();
      } // if
    }; // unsubscribe_user
    
    wrapper.find('div.user_group').each(function() {
      var group = $(this);
      
      // Handle group checkbox click
      group.find('input.group_checkbox').click(function() {
        var group_selected = this.checked;
        
        group.find('li.group_user').each(function() {
          if(group_selected) {
            select_user($(this), true);
          } else {
            deselect_user($(this), true);
          } // if
        });
        
        update_responsible();
      });
      
      // Handle user checkbox click
      group.find('li.group_user').each(function() {
        var user = $(this);
        
        // Checkbox click
        user.find('input.user_checkbox').click(function() {
          if(this.checked) {
            select_user(user, false);
          } else {
            deselect_user(user, false);
          } // if
          
          if(group.find('input.user_checkbox').length == group.find('input.user_checkbox:checked').length) {
            group.find('input.group_checkbox').attr('checked', 'checked');
          } else {
            group.find('input.group_checkbox').removeAttr('checked');
          } // if
        });
        
        // Label click
        user.find('span.user_label').click(function() {
          select_user(user, true);
          set_as_responsible(user);
          
          if(group.find('input.user_checkbox').length == group.find('input.user_checkbox:checked').length) {
            group.find('input.group_checkbox').attr('checked', 'checked');
          } else {
            group.find('input.group_checkbox').removeAttr('checked');
          } // if
        });
        
        // Subscription click
        var subscription_toggler = user.find('span.subscription_toggler');
        
        if(subscription_toggler.length > 0) {
          subscription_toggler.click(function() {
            if(user.is('.subscribed')) {
              unsubscribe_user(user);
            } else {
              subscribe_user(user);
            } // if
          });
        } // if
      });
    });
    
    // Set responsible
    if(settings['choose_responsible'] && settings['responsible_user_id']) {
      var responsible_user = wrapper.find('li.group_user[user_id=' + settings['responsible_user_id'] + ']');
      
      if(responsible_user.length == 1) {
        set_as_responsible(responsible_user);
      } // if
    } // if
    
    if(typeof(settings['assignees']) && settings['assignees']) {
      for(var i in settings['assignees']) {
        var assignee = wrapper.find('li.group_user[user_id=' + settings['assignees'][i] + ']');
        
        if(assignee.length == 1) {
          select_user(assignee, true);
        } // if
      } // for
    } // if
    
    if(settings['choose_subscribers'] && typeof(settings['subscribers']) == 'object' && settings['subscribers']) {
      for(var i in settings['subscribers']) {
        var subscriber = wrapper.find('li.group_user[user_id=' + settings['subscribers'][i] + ']');

        if(subscriber.length == 1) {
          subscribe_user(subscriber);
        } // if
      } // for
    } // if
    
    /**
     * filter list by visibility
     * 
     * @param integer visibility
     * @return null
     */
    var filter_by_visibility = function (visibility) {
      var wrapper = $(this);
      
      wrapper.find('div.user_group').each(function () {
        var group = $(this);
        group.show();
        
        if (visibility == 1) {
          group.find('li').show();
        } else {
          group.find('li[can_see_private="0"]').hide();
          group.find('li[can_see_private="1"]').show();
        } // if
        
        if (group.find('li:visible').length) {
          group.show();
        } else {
          group.hide();          
        } // if
      });
      
      // uncheck and unsubscribe hidden checked users
      wrapper.find('input[type="checkbox"]:not(:visible):checked').each(function () {
        var checkbox = $(this);
        checkbox.attr('checked', false);
        unsubscribe_user(checkbox.parents('li:first'));
      });
      
      // update responsible
      var responsible_hidden = wrapper.find('li.responsible:hidden');
      if (responsible_hidden.length) {
        responsible_hidden.removeClass('responsible');
        update_responsible();
      } // if
    }; // filter_by_visibility
    
    // provide public interface for this function
    this.filterByVisibility = filter_by_visibility;
  });
  
};