/*
 * This file is part of muCommander, http://www.mucommander.com
 *
 * muCommander is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 3 of the License, or
 * (at your option) any later version.
 *
 * muCommander is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */

package com.mucommander.ui.quicklist;

import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.Point;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.util.Vector;

import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.border.LineBorder;

import com.mucommander.ui.quicklist.item.QuickListHeaderItem;

/**
 * This abstract class contains some common features to all file table's popups:
 * 1. add HeaderMenuItem as the first item.
 * 2. set custom line border.
 * 3. does the calculations needed in order to show the popup in the center of the
 * 	  invoker FolderPanel. 
 * 
 * @author Arik Hadas
 */

public abstract class QuickList extends JPopupMenu implements FocusListener {
	private static final int PADDING = 2;
	protected QuickListHeaderItem headerMenuItem;
	private java.util.List<Component> items = new Vector<Component>();
	private QuickListContainer container;
	
	protected QuickList(QuickListContainer container, String header) {
		super();
		
		this.container = container;
		
		setBorder(new PopupsBorder());
		add(headerMenuItem = new QuickListHeaderItem(header));		
		setFocusTraversalKeysEnabled(false);
	}
	
	protected Component nextFocusableComponent() {
		return container.nextFocusableComponent();
	}
	
	/**
	 * This function is called before showing quick-list.
	 * If the return value is true, the quick list will be shown. Otherwise, it won't be shown.
	 */
	protected abstract boolean prepareForShowing(QuickListContainer container);
	
	public void show() {
        
		if (prepareForShowing(container)) {
			// Note: the actual popup menu's size is not known at this stage so we use the component's preferred size
	        Dimension dim = getPreferredSize();

	        Point location = container.calcQuickListPosition(dim);
	        
	        show(container.containerComponent(), location.x, location.y);
	        getFocus();
		}
	}
	
	@Override
    public Component add(Component comp) {
		items.add(comp);
		return super.add(comp);
	}
	
	@Override
    public JMenuItem add(JMenuItem comp) {
		items.add(comp);
		return super.add(comp);
	}
	
	@Override
    public Dimension getPreferredSize() {
		double width = PADDING, height = PADDING;

		for (Component item : items) {
			width = Math.max(width, item.getPreferredSize().getWidth());
			height += item.getPreferredSize().getHeight();
		}
		
		return new Dimension((int) Math.ceil(
				Math.max(container == null ? 0 : container.getWidth() / 2, width * 1.05))
				, (int) Math.ceil(height));
	}
	
	public void focusGained(FocusEvent arg0) {}

	public void focusLost(FocusEvent arg0) {
		setVisible(false);		
	}
	
	/**
	 * Get focus for the desired subcomponent. Only subclasses know which
	 * component to focus, so they must implement it.
	 */
	protected abstract void getFocus();
	
	public static class PopupsBorder extends LineBorder {
		public PopupsBorder() {
			super(Color.gray);		
		}
		
		@Override
        public Insets getBorderInsets(Component c) {
			return new Insets(1,1,1,1);
		}
		
		@Override
        public Insets getBorderInsets(Component c, Insets i) {
			return new Insets(1,1,1,1);
		}
	}	
}
