package users.swing;

import users.*;

import javax.swing.*;
import java.awt.*;
import java.util.*;

/**
  * A list box that will display all users managed by a UserManager.
  *
  * @see UserManager
  * @see User
  *
  * @author Steffen Zschaler
  * @version 2.0 05/05/1999
  * @since v2.0
  */
public class JUserList extends JList {

  /**
    * Create a new JUserList displaying the set of users managed by the global
    * UserManager. All Users will be displayed and they will be
    * sorted by their names.
    */
  public JUserList() {
    this (UserManager.getGlobalUM());
  }

  /**
    * Create a new JUserList displaying the set of users managed by a given UserManager. All Users will be
    * displayed and they will be sorted by their names.
    *
    * @param um the UserManager to be displayed.
    */
  public JUserList (UserManager um) {
    this (um, null, null);
  }

  /**
    * Create a new JUserList modelling the global UserManager.
    *
    * @param uf a filter that defines the set of users to be displayed. If <code>null</code>, no filtering will
    * occur.
    * @param cmp a Comparator that defines the order of the users to be displayed. The objects to be compared
    * by this comparator will be Users. If <code>null</code>, users will be ordered by their names.
    */
  public JUserList (UserFilter uf,
                    Comparator cmp) {
    this (UserManager.getGlobalUM(),
          uf,
          cmp);
  }

  /**
    * Create a new JUserList modelling a given UserManager.
    *
    * @param um the UserManager to be modelled.
    * @param uf a filter that defines the set of users to be displayed. If <code>null</code>, no filtering will
    * occur.
    * @param cmp a Comparator that defines the order of the users to be displayed. The objects to be compared
    * by this comparator will be Users. If <code>null</code>, users will be ordered by their names.
    */
  public JUserList (UserManager um,
                    UserFilter uf,
                    Comparator cmp) {
    super();

    setModel (new UserListModel (um, uf, cmp));

    setCellRenderer (new UserListCellRenderer());
  }


  /**
    * The list cell renderer to render {@link User} objects in list cells.
    *
    * <p>This list cell renderer can be used with JComboBoxes as well.</p>
    *
    * @author Steffen Zschaler
    * @version 2.0 05/05/1999
    * @since v2.0
    */
  public static class UserListCellRenderer extends JLabel implements ListCellRenderer {

    /**
      * Create a new UserListCellRenderer.
      */
    public UserListCellRenderer() {
      setOpaque(true);
    }

    /**
      * Configure this list cell renderer to display the given user's data and return
      * <code>this</code>.
      *
      * @param list the list in which to render the User object
      * @param value assumed to be the User object to be rendered
      * @param index the position in the list at which to render the User object.
      * @param isSelected true if the User object is to be rendered in a selected state
      * @param cellHasFocus true if the cell to be rendered has the input focus.
      *
      * @return this list cell renderer configured to render the given User object.
      *
      * @override Sometimes
      */
    public Component getListCellRendererComponent (JList list,
                                                  Object value,
                                                  int index,
                                                  boolean isSelected,
                                                  boolean cellHasFocus) {
      if (value != null) {
        setText (((User) value).getName());
      }
      else {
        setText ("");
      }

      setFont (list.getFont());

      setBackground(isSelected ? list.getSelectionBackground() : Color.white);
      setForeground(isSelected ? list.getSelectionForeground() : Color.black);

      return this;
    }
  }

  /**
    * Convenience method returning the currently selected user.
    *
    * @return the currently selected user.
    *
    * @override Never
    */
  public User getSelectedUser() {
    return (User) getSelectedValue();
  }
}