/*******************************************************************************
 * Copyright (c) 2007, 2008 Oracle. All rights reserved.
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0, which accompanies this distribution
 * and is available at http://www.eclipse.org/legal/epl-v10.html.
 * 
 * Contributors:
 *     Oracle - initial API and implementation
 ******************************************************************************/
package org.eclipse.jpt.utility.internal.swing;

import java.awt.BorderLayout;
import java.awt.Font;
import javax.swing.AbstractListModel;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListCellRenderer;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.border.Border;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.eclipse.jpt.utility.internal.SimpleStringMatcher;
import org.eclipse.jpt.utility.internal.StringConverter;
import org.eclipse.jpt.utility.internal.StringMatcher;

/**
 * This panel presents an entry field and a list box of choices that
 * allows the user to filter the entries in the list box by entering
 * a pattern in the entry field.
 * 
 * By default, two wildcards are allowed in the pattern:
 * 	'*' will match any set of zero or more characters
 * 	'?' will match any single character
 * 
 * The panel consists of 4 components that can be customized:
 * 	- 1 text field
 * 	- 1 list box
 * 	- 2 labels, one for each of the above
 * 
 * Other aspects of the panel's behavior can be changed:
 * 	- the string converter determines how the objects in the
 * 		list are converted to strings and compared to the pattern
 * 		entered in the text field; by default the converter simply
 * 		uses the result of the object's #toString() method
 * 		(if you replace the string converter, you will probably
 * 		want to replace the list box's cell renderer also)
 * 	- the string matcher can also be changed if you would
 * 		like different pattern matching behavior than that
 * 		described above
 * 	- you can specify the maximum size of the list - this may
 * 		force the user to enter a pattern restrictive enough
 * 		to result in a list smaller than the maximum size; the
 * 		default is -1, which disables the restriction
 * 
 * This panel is not a typical panel, in the sense that it does not share
 * its model with clients via value models. Instead, this panel's model
 * is set and queried directly because it is designed to be used in a
 * dialog that directs the user's behavior (as opposed to a "normal"
 * window).
 */
public class FilteringListPanel<T> extends JPanel {

	/**
	 * The complete list of available choices
	 * (as opposed to the partial list held by the list box).
	 */
	private Object[] completeList;

	/**
	 * An adapter used to convert the objects in the list
	 * to strings so they can be run through the matcher
	 * and displayed in the text field.
	 */
	StringConverter<T> stringConverter;

	/** The text field. */
	private JTextField textField;
	private JLabel textFieldLabel;
	private DocumentListener textFieldListener;

	/** The list box. */
	private JList listBox;
	private JLabel listBoxLabel;

	/** The maximum number of entries displayed in the list box. */
	private int maxListSize;

	/**
	 * The matcher used to filter the list against
	 * the pattern entered in the text field. By default,
	 * this allows the two wildcard characters described in
	 * the class comment.
	 */
	private StringMatcher stringMatcher;

	/**
	 * Performance tweak: We use this buffer instead of
	 * a temporary variable during filtering so we don't have
	 * to keep re-allocating it.
	 */
	private Object[] buffer;

	private static final Border TEXT_FIELD_LABEL_BORDER = BorderFactory.createEmptyBorder(0, 0, 5, 0);
	private static final Border LIST_BOX_LABEL_BORDER = BorderFactory.createEmptyBorder(5, 0, 5, 0);


	// ********** constructors **********

	/**
	 * Construct a FilteringListPanel with the specified list of choices
	 * and initial selection. Use the default string converter to convert the
	 * choices and selection to strings (which simply calls #toString() on
	 * the objects).
	 */
	public FilteringListPanel(Object[] completeList, Object initialSelection) {
		this(completeList, initialSelection, StringConverter.Default.<T>instance());
	}

	/**
	 * Construct a FilteringListPanel with the specified list of choices
	 * and initial selection. Use the specified string converter to convert the
	 * choices and selection to strings.
	 */
	public FilteringListPanel(Object[] completeList, Object initialSelection, StringConverter<T> stringConverter) {
		super(new BorderLayout());
		this.completeList = completeList;
		this.stringConverter = stringConverter;
		this.initialize(initialSelection);
	}


	// ********** initialization **********

	private void initialize(Object initialSelection) {
		this.maxListSize = this.defaultMaxListSize();
		this.buffer = this.buildBuffer();

		this.textFieldListener = this.buildTextFieldListener();

		this.stringMatcher = this.buildStringMatcher();

		this.initializeLayout(initialSelection);
	}

	private Object[] buildBuffer() {
		return new Object[this.max()];
	}

	/**
	 * Return the current max number of entries allowed in the list box.
	 */
	private int max() {
		if (this.maxListSize == -1) {
			return this.completeList.length;
		}
		return Math.min(this.maxListSize, this.completeList.length);
	}

	/**
	 * Build a listener that will listen to changes in the text field
	 * and filter the list appropriately.
	 */
	private DocumentListener buildTextFieldListener() {
		return new DocumentListener() {
			public void insertUpdate(DocumentEvent e) {
				FilteringListPanel.this.filterList();
			}
			public void changedUpdate(DocumentEvent e) {
				FilteringListPanel.this.filterList();
			}
			public void removeUpdate(DocumentEvent e) {
				FilteringListPanel.this.filterList();
			}
			@Override
			public String toString() {
				return "text field listener";
			}
		};
	}

	private int defaultMaxListSize() {
		return -1;
	}

	private StringMatcher buildStringMatcher() {
		return new SimpleStringMatcher<T>();
	}

	private void initializeLayout(Object initialSelection) {
		// text field
		JPanel textFieldPanel = new JPanel(new BorderLayout());
		this.textFieldLabel = new JLabel();
		this.textFieldLabel.setBorder(TEXT_FIELD_LABEL_BORDER);
		textFieldPanel.add(this.textFieldLabel, BorderLayout.NORTH);

		this.textField = new JTextField();
		this.textField.getDocument().addDocumentListener(this.textFieldListener);
		this.textFieldLabel.setLabelFor(this.textField);
		textFieldPanel.add(this.textField, BorderLayout.CENTER);

		this.add(textFieldPanel, BorderLayout.NORTH);

		// list box
		JPanel listBoxPanel = new JPanel(new BorderLayout());
		this.listBoxLabel = new JLabel();
		this.listBoxLabel.setBorder(LIST_BOX_LABEL_BORDER);
		listBoxPanel.add(this.listBoxLabel, BorderLayout.NORTH);

		this.listBox = new JList();
		this.listBox.setDoubleBuffered(true);
		this.listBox.setModel(this.buildPartialArrayListModel(this.completeList, this.max()));
		this.listBox.getSelectionModel().setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		// performance tweak(?)
		this.listBox.setPrototypeCellValue(this.prototypeCellValue());
		this.listBox.setPrototypeCellValue(null);
		this.listBox.setCellRenderer(this.buildDefaultCellRenderer());
		this.listBoxLabel.setLabelFor(this.listBox);
		// bug 2777802 - scroll bars shouldn't be on the tab sequence
		JScrollPane listBoxScrollPane = new JScrollPane(this.listBox);
		listBoxScrollPane.getHorizontalScrollBar().setFocusable(false);
		listBoxScrollPane.getVerticalScrollBar().setFocusable(false);
		listBoxPanel.add(listBoxScrollPane, BorderLayout.CENTER);

		// initialize the widgets
		this.listBox.setSelectedValue(initialSelection, true);
		this.textField.select(0, this.textField.getText().length());

		this.add(listBoxPanel, BorderLayout.CENTER);
	}


	// ********** public API **********

	public Object selection() {
		return this.listBox.getSelectedValue();
	}

	public void setSelection(Object selection) {
		this.listBox.setSelectedValue(selection, true);
	}

	public Object[] completeList() {
		return this.completeList;
	}

	/**
	 * rebuild the filtering buffer and re-apply the filter
	 * to the new list
	 */
	public void setCompleteList(Object[] completeList) {
		this.completeList = completeList;
		if (this.buffer.length < this.max()) {
			// the buffer will never shrink - might want to re-consider...  ~bjv
			this.buffer = this.buildBuffer();
		}
		this.filterList();
	}

	public int maxListSize() {
		return this.maxListSize;
	}

	public void setMaxListSize(int maxListSize) {
		this.maxListSize = maxListSize;
		if (this.buffer.length < this.max()) {
			// the buffer will never shrink - might want to re-consider...  ~bjv
			this.buffer = this.buildBuffer();
		}
		this.filterList();
	}

	public StringConverter<T> stringConverter() {
		return this.stringConverter;
	}

	/**
	 * apply the new filter to the list
	 */
	public void setStringConverter(StringConverter<T> stringConverter) {
		this.stringConverter = stringConverter;
		this.filterList();
	}

	/**
	 * allow client code to access the text field
	 * (so we can set the focus)
	 */
	public JTextField textField() {
		return this.textField;
	}

	/**
	 * allow client code to access the text field label
	 */
	public JLabel textFieldLabel() {
		return this.textFieldLabel;
	}

	/**
	 * convenience method
	 */
	public void setTextFieldLabelText(String text) {
		this.textFieldLabel.setText(text);
	}

	/**
	 * allow client code to access the list box
	 * (so we can add mouse listeners for double-clicking)
	 */
	public JList listBox() {
		return this.listBox;
	}

	/**
	 * convenience method
	 */
	public void setListBoxCellRenderer(ListCellRenderer renderer) {
		this.listBox.setCellRenderer(renderer);
	}

	/**
	 * allow client code to access the list box label
	 */
	public JLabel listBoxLabel() {
		return this.listBoxLabel;
	}

	/**
	 * convenience method
	 */
	public void setListBoxLabelText(String text) {
		this.listBoxLabel.setText(text);
	}

	/**
	 * convenience method
	 */
	public void setComponentsFont(Font font) {
		this.textFieldLabel.setFont(font);
		this.textField.setFont(font);
		this.listBoxLabel.setFont(font);
		this.listBox.setFont(font);
	}

	public StringMatcher stringMatcher() {
		return this.stringMatcher;
	}

	/**
	 * re-apply the filter to the list
	 */
	public void setStringMatcher(StringMatcher stringMatcher) {
		this.stringMatcher = stringMatcher;
		this.filterList();
	}


	// ********** internal methods **********

	/**
	 * Allow subclasses to disable performance tweak
	 * by returning null here.
	 */
	protected String prototypeCellValue() {
		return "==========> A_STRING_THAT_IS_DEFINITELY_LONGER_THAN_EVERY_STRING_IN_THE_LIST <==========";
	}

	/**
	 * By default, use the string converter to build the text
	 * used by the list box's cell renderer.
	 */
	protected ListCellRenderer buildDefaultCellRenderer() {
		return new SimpleListCellRenderer() {
			@Override
			@SuppressWarnings("unchecked")
			protected String buildText(Object value) {
				return FilteringListPanel.this.stringConverter.convertToString((T) value);
			}
		};
	}

	/**
	 * Something has changed that requires us to filter the list.
	 * 
	 * This method is synchronized because a fast typist can
	 * generate events quicker than we can filter the list. (?  ~bjv)
	 */
	synchronized void filterList() {
		// temporarily stop listening to the list box selection, since we will
		// be changing the selection during the filtering and don't want
		// that to affect the text field
		this.filterList(this.textField.getText());
	}

	/**
	 * Filter the contents of the list box to match the
	 * specified pattern.
	 */
	private void filterList(String pattern) {
		if (pattern.length() == 0) {
			this.listBox.setModel(this.buildPartialArrayListModel(this.completeList, this.max()));
		} else {
			this.stringMatcher.setPatternString(pattern);
			int j = 0;
			int len = this.completeList.length;
			int max = this.max();
			for (int i = 0; i < len; i++) {
				if (this.stringMatcher.matches(this.stringConverter.convertToString(this.entry(i)))) {
					this.buffer[j++] = this.completeList[i];
				}
				if (j == max) {
					break;
				}
			}
			this.listBox.setModel(this.buildPartialArrayListModel(this.buffer, j));
		}

		// after filtering the list, determine the appropriate selection
		if (this.listBox.getModel().getSize() == 0) {
			this.listBox.getSelectionModel().clearSelection();
		} else {
			this.listBox.getSelectionModel().setAnchorSelectionIndex(0);
			this.listBox.getSelectionModel().setLeadSelectionIndex(0);
			this.listBox.ensureIndexIsVisible(0);
		}
	}

	/**
	 * minimize scope of suppressed warnings
	 */
	@SuppressWarnings("unchecked")
	private T entry(int index) {
		return (T) this.completeList[index];
	}

	/**
	 * Build a list model that wraps only a portion of the specified array.
	 * The model will include the array entries from 0 to (size - 1).
	 */
	private ListModel buildPartialArrayListModel(final Object[] array, final int size) {
		return new AbstractListModel() {
			public int getSize() {
				return size;
			}
			public Object getElementAt(int index) {
				return array[index];
			}
		};
	}
}
