package org.minimalj.frontend.impl.swing.toolkit;

import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.LayoutManager;
import java.awt.Rectangle;

import javax.swing.BorderFactory;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.UIManager;

import org.minimalj.frontend.Frontend.IComponent;
import org.minimalj.frontend.Frontend.IList;
import org.minimalj.frontend.action.Action;
import org.minimalj.frontend.impl.swing.toolkit.SwingFrontend.SwingActionText;


public class SwingList extends JPanel implements IList {
	private static final long serialVersionUID = 1L;
	
	private final int actionCount;

	private Component[] disabledChildren;
	
	public SwingList(Action... actions) {
		super(null, true);
		setLayout(new VerticalLayoutManager());
		if (actions != null) {
			for (Action action : actions) {
				add(new SwingActionText(action), "");
			}
			actionCount = actions.length;
		} else {
			actionCount = 0;
		}
	}
	
	@Override
	public void updateUI() {
		super.updateUI();
		setBackground(UIManager.getColor("TextField.background"));
		setOpaque(true);
	}

	@Override
	public void setEnabled(boolean enabled) {
		if (isEnabled() && !enabled) {
			disabledChildren = getComponents();
			removeAll();
			revalidate();
		} else if (!isEnabled() && enabled) {
			for (Component c: disabledChildren) {
				add(c, "");
			}
			revalidate();
		} else {
			return; // avoid fireChange in super
		}
		super.setEnabled(enabled);
	}

	@Override
	public void clear() {
		for (int i = getComponentCount() - actionCount - 1; i >= 0; i--) {
			remove(i);
		}
		disabledChildren = new Component[0];
		revalidate();
	}

	@Override
	public void add(IComponent component, Action... actions) {
		boolean enabled = isEnabled();
		setEnabled(true);
		
		int existingComponents = getComponentCount();
		super.add((Component) component, "", getComponentCount() - actionCount); // empty string need otherwise LayoutManager doesn't get the component
		for (Action action : actions) {
			super.add(new SwingActionText(action), "", getComponentCount() - actionCount);
		}
		if (actionCount > 0 && getComponentCount() > 0) {
			// if global actions exist: create border at the end of this component+actions
			JComponent lastLabel = (JComponent) super.getComponent(getComponentCount() - actionCount - 1);
			lastLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 8, 0));
		} else if (existingComponents > 0) {
			// no global actions, but not the first add: create border at the end of the previous component+actions 
			JComponent lastLabel = (JComponent) super.getComponent(existingComponents - 1);
			lastLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 8, 0));
		}
		
		setEnabled(enabled);
		repaint();
		revalidate();
	}

	private class VerticalLayoutManager implements LayoutManager {

		private Dimension preferredSize;
		private Rectangle lastParentBounds = null;
		
		public VerticalLayoutManager() {
		}

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

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

		@Override
		public void layoutContainer(Container parent) {
			if (lastParentBounds != null && lastParentBounds.equals(parent.getBounds())) return;
			lastParentBounds = parent.getBounds();

			int preferredHeight = 0;
			for (Component component : getComponents()) {
				int height = component.getPreferredSize().height;
				preferredHeight += height;
			}
			int verticalRest = parent.getHeight() - preferredHeight;
			int verticalInset = verticalRest > 8 ? 4 : verticalRest / 2;
			int y = verticalInset;
			int x = verticalInset > 0 ? 1 : 0;
			int width = parent.getWidth();
			int widthWithoutIns = width - x;
			for (Component component : getComponents()) {
				int height = component.getPreferredSize().height;
				component.setBounds(x, y, widthWithoutIns, height);
				y += height;
			}
			preferredSize = new Dimension(width, preferredHeight);
		}

		@Override
		public void addLayoutComponent(String name, Component comp) {
			lastParentBounds = null;
		}

		@Override
		public void removeLayoutComponent(Component comp) {
			lastParentBounds = null;
		}
	}
}

@@ -182,16 +182,41 @@
 ctangle;
+%0Aimport java.util.Arrays;
 %0A%0Aimport
@@ -1300,33 +1300,16 @@
 eAll();%0A
-%09%09%09revalidate();%0A
 %09%09%7D else
@@ -1336,24 +1336,24 @@
  enabled) %7B%0A
+
 %09%09%09for (Comp
@@ -1406,25 +1406,8 @@
 %09%09%7D%0A
-%09%09%09revalidate();%0A
 %09%09%7D 
@@ -1457,16 +1457,32 @@
 per%0A%09%09%7D%0A
+%09%09revalidate();%0A
 %09%09super.
@@ -1629,16 +1629,20 @@
 ;%0A%09%09%7D%0A%09%09
+if (
 disabled
@@ -1654,27 +1654,146 @@
 ren 
+!
 = n
-ew Component%5B0%5D;
+ull) %7B%0A%09%09%09disabledChildren = Arrays.copyOfRange(disabledChildren, disabledChildren.length - actionCount, disabledChildren.length);%0A%09%09%7D
 %0A%09%09r
@@ -2246,24 +2246,24 @@
 Count);%0A%09%09%7D%0A
+
 %09%09if (action
@@ -2273,35 +2273,8 @@
 nt %3E
- 0 && getComponentCount() %3E
  0) 

fix exceptions when clear