/**
 * This software is released as part of the Pumpernickel project.
 * 
 * All com.pump resources in the Pumpernickel project are distributed under the
 * MIT License:
 * https://github.com/mickleness/pumpernickel/raw/master/License.txt
 * 
 * More information about the Pumpernickel project is available here:
 * https://mickleness.github.io/pumpernickel/
 */
package com.pump.plaf;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.LayoutManager;
import java.util.HashMap;
import java.util.Map;

import javax.swing.AbstractButton;
import javax.swing.JSpinner;
import javax.swing.SpinnerModel;
import javax.swing.SpinnerNumberModel;
import javax.swing.border.EmptyBorder;

import com.pump.blog.ResourceSample;
import com.pump.swing.NavigationButtons;

/**
 * This includes the previous and next buttons and a label in a single row. This
 * was originally used in the <code>PrintLayoutPreviewPanel</code>.
 * 
 * <!-- ======== START OF AUTOGENERATED SAMPLES ======== -->
 * <p>
 * <img src=
 * "https://github.com/mickleness/pumpernickel/raw/master/resources/samples/CompactNavigationPanelUI/sample.png"
 * alt="com.pump.plaf.CompactNavigationPanelUI.createDemo()"> <!-- ======== END
 * OF AUTOGENERATED SAMPLES ======== -->
 */
@ResourceSample(sample = { "com.pump.plaf.CompactNavigationPanelUI.createDemo()" })
public class CompactNavigationPanelUI extends NavigationPanelUI {

	/** Create a minimal demo for the javadoc. */
	public static JSpinner createDemo() {
		JSpinner spinner = new JSpinner(new SpinnerNumberModel(4, 0, 10, 1));
		spinner.putClientProperty(NavigationPanelUI.PROPERTY_DESCRIPTOR,
				new NumberSpinnerDescriptor(spinner, "Page"));
		spinner.setUI(new CompactNavigationPanelUI());
		spinner.setBorder(new EmptyBorder(5, 5, 5, 5));
		return spinner;
	}

	@Override
	protected Component createPreviousButton() {
		AbstractButton button = NavigationButtons.createPrev();
		button.setName(PREV_BUTTON_NAME);
		installPreviousButtonListeners(button);
		return button;
	}

	@Override
	protected Component createNextButton() {
		AbstractButton button = NavigationButtons.createNext();
		button.setName(NEXT_BUTTON_NAME);
		installNextButtonListeners(button);
		return button;
	}

	@Override
	protected LayoutManager createLayout() {
		return new CompactFlowLayout();
	}

	static class CompactFlowLayout implements LayoutManager {

		Map<String, Component> constraintMap = new HashMap<>();

		@Override
		public void addLayoutComponent(String name, Component component) {
			constraintMap.put(name, component);
		}

		@Override
		public void removeLayoutComponent(Component comp) {
			constraintMap.values().remove(comp);
		}

		@Override
		public Dimension preferredLayoutSize(Container parent) {
			Component prev = constraintMap.get("Previous");
			Component next = constraintMap.get("Next");
			Component editor = constraintMap.get("Label");

			int width = 0;
			int height = 0;
			if (prev != null && prev.isVisible()) {
				Dimension prevD = prev.getPreferredSize();
				width += prevD.width;
				height = Math.max(prevD.height, height);
			}
			if (next != null && next.isVisible()) {
				Dimension nextD = next.getPreferredSize();
				width += nextD.width;
				height = Math.max(nextD.height, height);
			}
			width += 8;
			if (editor != null && editor.isVisible()) {
				Dimension editorD = editor.getPreferredSize();

				if (parent instanceof JSpinner) {
					SpinnerModel model = ((JSpinner) parent).getModel();
					if (model instanceof SpinnerNumberModel) {
						SpinnerNumberModel numberModel = (SpinnerNumberModel) model;
						Comparable max = numberModel.getMaximum();
						// TODO: incorporate max
					}
				}

				width += editorD.width;
				height = Math.max(editorD.height, height);

				width += 3;
			}
			return new Dimension(width, height);
		}

		@Override
		public Dimension minimumLayoutSize(Container parent) {
			return preferredLayoutSize(parent);
		}

		@Override
		public void layoutContainer(Container parent) {
			Component prev = constraintMap.get("Previous");
			Component next = constraintMap.get("Next");
			Component editor = constraintMap.get("Label");

			int x = 0;
			if (prev != null && prev.isVisible()) {
				Dimension prevD = prev.getPreferredSize();
				prev.setBounds(x, parent.getHeight() / 2 - prevD.height / 2,
						prevD.width, prevD.height);
				x += prevD.width;
			}
			if (next != null && next.isVisible()) {
				Dimension nextD = next.getPreferredSize();
				next.setBounds(x, parent.getHeight() / 2 - nextD.height / 2,
						nextD.width, nextD.height);
				x += nextD.width;
			}
			if (editor != null && editor.isVisible()) {
				Dimension editorD = editor.getPreferredSize();
				x += 8;
				editor.setBounds(x,
						parent.getHeight() / 2 - editorD.height / 2,
						parent.getWidth() - x, editorD.height);
			}
		}
	}
}