/*******************************************************************************
 * 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.AWTEvent;
import java.awt.AWTException;
import java.awt.Component;
import java.awt.EventQueue;
import java.awt.Point;
import java.awt.Robot;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
import javax.swing.SwingConstants;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.plaf.basic.BasicComboBoxUI;
import org.eclipse.jpt.utility.internal.ClassTools;

/**
 * This component provides a way to handle selecting an item from a
 * list that may grow too large to be handled conveniently by a combo-box. 
 * If the list's size is less than the designated "long" list size, 
 * the choice list will be displayed in a normal combo-box popup; 
 * otherwise, a dialog will be used to prompt the user to choose a selection.
 * 
 * To change the browse mechanism, subclasses may 
 * 	- override the method #buildBrowser()
 *  - override the method #browse(), in which case the method 
 * 		#buildBrowser() may be ignored.
 */
public class ListChooser 
	extends JComboBox
{
	
	/** the size of a "long" list - anything smaller is a "short" list */
	int longListSize = DEFAULT_LONG_LIST_SIZE;
	
	/** the default size of a "long" list, which is 20 (to match JOptionPane's behavior) */
	public static final int DEFAULT_LONG_LIST_SIZE = 20;
	
	/** property change associated with long list size */
	public static final String LONG_LIST_SIZE_PROPERTY = "longListSize"; //$NON-NLS-1$
	
    static JLabel prototypeLabel = new JLabel("Prototype", new EmptyIcon(17), SwingConstants.LEADING); //$NON-NLS-1$

    /** 
	 * whether the chooser is choosable.  if a chooser is not choosable,
	 * it only serves as a display widget.  a user may not change its 
	 * selected value.
	 */
	boolean choosable = true;
	
	/** property change associated with choosable */
	public static final String CHOOSABLE_PROPERTY = "choosable"; //$NON-NLS-1$
	
	/** the browser used to make a selection from the long list - typically via a dialog */
	private ListBrowser browser;
	
    private NodeSelector nodeSelector;
    
	/** INTERNAL - The popup is being shown.  Used to prevent infinite loop. */
	boolean popupAlreadyInProgress;
	
	
	// **************** Constructors ******************************************
	
	/**
	 * Construct a list chooser for the specified model.
	 */
	public ListChooser(ComboBoxModel model) {
		this(model, new NodeSelector.DefaultNodeSelector());
	}
	
    public ListChooser(CachingComboBoxModel model) {
        this(model, new NodeSelector.DefaultNodeSelector());
    }
    
	public ListChooser(ComboBoxModel model, NodeSelector nodeSelector) {
        this(new NonCachingComboBoxModel(model), nodeSelector);
    }
    
    public ListChooser(CachingComboBoxModel model, NodeSelector nodeSelector) {
        super(model);
        this.initialize();
        this.nodeSelector = nodeSelector;
    }
	// **************** Initialization ****************************************
	
	protected void initialize() {
		this.addPopupMenuListener(this.buildPopupMenuListener());
		this.setRenderer(new DefaultListCellRenderer());
        this.addKeyListener(buildF3KeyListener());
        
        //These are used to workaround problems with Swing trying to 
        //determine the size of a comboBox with a large model
        setPrototypeDisplayValue(prototypeLabel);
        listBox().setPrototypeCellValue(prototypeLabel);
	}
	
    
    private JList listBox() {
        return (JList) ClassTools.fieldValue(this.ui, "listBox"); //$NON-NLS-1$
    }
    
	/** 
	 * When the popup is about to be shown, the event is consumed, and 
	 * PopupHandler determines whether to reshow the popup or to show
	 * the long list browser.
	 */
	private PopupMenuListener buildPopupMenuListener() {
		return new PopupMenuListener() {
			public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
				ListChooser.this.aboutToShowPopup();
			}
			public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
				// do nothing
			}
			public void popupMenuCanceled(PopupMenuEvent e) {
				// do nothing
			}
			@Override
			public String toString() {
				return "pop-up menu listener"; //$NON-NLS-1$
			}
		};
	}
	
	/**
	 * If this code is being reached due to the PopupHandler already being in progress,
	 * then do nothing.  Otherwise, set the flag to true and launch the PopupHandler.
	 */
	void aboutToShowPopup() {
		if (this.popupAlreadyInProgress) {
			return;
		}
		
		this.popupAlreadyInProgress = true;
		EventQueue.invokeLater(new PopupHandler());
	}
 
    
	private KeyListener buildF3KeyListener() {
        return new KeyAdapter() {
            @Override
			public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_F3) {
                    goToSelectedItem();
                }                
            }
			@Override
			public String toString() {
				return "F3 key listener"; //$NON-NLS-1$
			}
        };
    }
    
    public void goToSelectedItem() {
        if (getSelectedItem() != null) {
            ListChooser.this.nodeSelector.selectNodeFor(getSelectedItem());
        }
    }
    
	// **************** Browsing **********************************************
	
	/** 
	 * Lazily initialize because subclasses may have further initialization to do
	 * before browser can be built.
	 */
	protected void browse() {
		if (this.browser == null) {
			this.browser = this.buildBrowser();
		}
		
		this.browser.browse(this);
	}
	
	/**
	 * Return the "browser" used to make a selection from the long list,
	 * typically via a dialog.
	 */
	protected ListChooser.ListBrowser buildBrowser() {
		return new SimpleListBrowser();
	}
	
	
	// **************** Choosable functionality *******************************
	
	/** override behavior - consume selection if chooser is not choosable */
	@Override
	public void setSelectedIndex(int anIndex) {
		if (this.choosable) {
			super.setSelectedIndex(anIndex);
		}
	}
	
	private void updateArrowButton() {
		try {
			BasicComboBoxUI comboBoxUi = (BasicComboBoxUI) ListChooser.this.getUI();
			JButton arrowButton = (JButton) ClassTools.fieldValue(comboBoxUi, "arrowButton"); //$NON-NLS-1$
			arrowButton.setEnabled(this.isEnabled() && this.choosable);
		}
		catch (Exception e) {
			// this is a huge hack to try and make the combo box look right,
			// so if it doesn't work, just swallow the exception
		}
	}
	
	
    // **************** List Caching *******************************

    void cacheList() {
        ((CachingComboBoxModel) getModel()).cacheList();
    }
    
    void uncacheList() {
        ((CachingComboBoxModel) getModel()).uncacheList();
    }

    boolean listIsCached() {
        return ((CachingComboBoxModel) getModel()).isCached();
    }
    
	// **************** Public ************************************************
	
	public int longListSize() {
		return this.longListSize;
	}
	
	public void setLongListSize(int newLongListSize) {
		int oldLongListSize = this.longListSize;
		this.longListSize = newLongListSize;
		this.firePropertyChange(LONG_LIST_SIZE_PROPERTY, oldLongListSize, newLongListSize);
	}
	
	public boolean isChoosable() {
		return this.choosable;
	}
	
	public void setChoosable(boolean newValue) {
		boolean oldValue = this.choosable;
		this.choosable = newValue;
		this.firePropertyChange(CHOOSABLE_PROPERTY, oldValue, newValue);
		this.updateArrowButton();
	}
	
	// **************** Handle selecting null as a value **********************

	private boolean selectedIndexIsNoneSelectedItem(int index) {
		return index == -1 &&
				 getModel().getSize() > 0 &&
				 getModel().getElementAt(0) == null;
	}

	@Override
	public int getSelectedIndex() {
        boolean listNotCached = !listIsCached();
        if (listNotCached) {
            cacheList();
        }
        
		int index = super.getSelectedIndex();

		// Use index 0 to show the <none selected> item since the actual value is
		// null and JComboBox does not handle null values
		if (selectedIndexIsNoneSelectedItem(index)) {
			index = 0;
        }

        if (listNotCached) {
            uncacheList();
        }
		return index;
   }
	
	//wrap the renderer to deal with the prototypeDisplayValue
    @Override
	public void setRenderer(final ListCellRenderer aRenderer) {
        super.setRenderer(new ListCellRenderer(){
            public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
                if (value == prototypeLabel) {
                    return prototypeLabel;
                }
                return aRenderer.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            }
        });
    }
    
    
	// **************** Member classes ****************************************
	
	/**
	 * Define the API required by this ListChooser when it must
	 * prompt the user to select an item from the "long" list.
	 */
	public interface ListBrowser 
	{
		/**
		 * Prompt the user to make a selection from the specified
		 * combo-box's model.
		 */
		void browse(ListChooser parentChooser);
	}
	
	
	/**
	 * Runnable class that consumes popup window and determines whether
	 * to reshow popup or to launch browser, based on the size of the list.
	 */
	private class PopupHandler
		implements Runnable
	{
		/** The mouse event */
		private MouseEvent lastMouseEvent;
		
		/** The component from which the last mouse event was thrown */
		private JComponent eventComponent;
		
		/** The location of the component at the time the last mouse event was thrown */
		private Point componentLocation;
		
		/** The location of the mouse at the time the last mouse event was thrown */
		private Point mouseLocation;
		
		
		PopupHandler() {
			this.initialize();
		}
		
		private void initialize() {
			AWTEvent event = EventQueue.getCurrentEvent();
			
			if (event instanceof MouseEvent) {
				this.lastMouseEvent = (MouseEvent) event;
				this.eventComponent = (JComponent) this.lastMouseEvent.getSource();
				this.componentLocation = this.eventComponent.getLocationOnScreen();
				this.mouseLocation = this.lastMouseEvent.getPoint();
			}
			else {
				this.eventComponent = null;
				this.componentLocation = null;
				this.mouseLocation = null;
			}
		}
		
		public void run() {
			ListChooser.this.hidePopup();
			
            cacheList();
			if (ListChooser.this.choosable == true) {
				// If the combo box model is of sufficient length, the browser will be shown.
				// Asking the combo box model for its size should be enough to ensure that 
				//  its size is recalculated.
				if (ListChooser.this.getModel().getSize() > ListChooser.this.longListSize) {
					this.checkComboBoxButton();
					ListChooser.this.browse();
				}
				else {
					ListChooser.this.showPopup();
					this.checkMousePosition();
				}
			}
            if (listIsCached()) {
                uncacheList();
            }
			
			ListChooser.this.popupAlreadyInProgress = false;
		}
		
		/** If this is not done, the button never becomes un-pressed */
		private void checkComboBoxButton() {
			try {
				BasicComboBoxUI comboBoxUi = (BasicComboBoxUI) ListChooser.this.getUI();
				JButton arrowButton = (JButton) ClassTools.fieldValue(comboBoxUi, "arrowButton"); //$NON-NLS-1$
				arrowButton.getModel().setPressed(false);
			}
			catch (Exception ex) {
				// this is a huge hack to try and make the combo box look right,
				// so if it doesn't work, just swallow the exception
				this.handleException(ex);
			}
		}

		private void handleException(@SuppressWarnings("unused") Exception ex) {
			// do nothing for now
		}
		
		/**
		 * Moves the mouse back to its original position before any jiggery pokery that we've done.
		 */
		private void checkMousePosition() {
			if (this.eventComponent == null) {
				return;
			}
			
			final Point newComponentLocation = this.eventComponent.getLocationOnScreen();
			boolean componentMoved = 
				newComponentLocation.x - this.componentLocation.x != 0
				|| newComponentLocation.y - this.componentLocation.y != 0;
			
			if (componentMoved) {
				try {
					new Robot().mouseMove(
						newComponentLocation.x + this.mouseLocation.x,
						newComponentLocation.y + this.mouseLocation.y
					);
				}
				catch (AWTException ex) {
					// move failed - do nothing
				}
			}
		}
	}
}
