/*******************************************************************************
 * 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";
	
    static JLabel prototypeLabel = new JLabel("Prototype", new EmptyIcon(17), SwingConstants.LEADING);

    /** 
	 * 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";
	
	/** 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");
    }
    
	/** 
	 * 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";
			}
		};
	}
	
	/**
	 * 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";
			}
        };
    }
    
    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");
			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");
				arrowButton.getModel().setPressed(false);
			}
			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
			}
		}
		
		/**
		 * 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
				}
			}
		}
	}
}
