package de.gurkenlabs.utiliti.swing;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JButton;
import javax.swing.JColorChooser;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSpinner;
import javax.swing.JTextField;
import javax.swing.LayoutStyle.ComponentPlacement;
import javax.swing.SpinnerNumberModel;

import de.gurkenlabs.litiengine.resources.Resources;
import de.gurkenlabs.litiengine.util.ColorHelper;
import de.gurkenlabs.utiliti.SwingHelpers;

@SuppressWarnings("serial")
public class ColorComponent extends JPanel {
  private final JButton btnSelectColor;
  private final JTextField textFieldColor;
  private JSpinner spinnerAlpha;

  private final transient List<ActionListener> listeners;
  private static final String DEFAULT_COLOR = "#FFFFFFFF";

  public ColorComponent() {
    this.setSize(200, 60);
    this.setPreferredSize(new Dimension(200, 60));
    this.listeners = new ArrayList<>();
    this.textFieldColor = ControlBehavior.apply(new JTextField());
    this.textFieldColor.setEditable(true);
    this.textFieldColor.setColumns(9);
    this.textFieldColor.addActionListener(a -> this.setHexColor(this.textFieldColor.getText()));

    this.btnSelectColor = new JButton();
    this.btnSelectColor.setIcon(Icons.COLORX16);
    this.btnSelectColor.addActionListener(a -> {
      final Color result = JColorChooser.showDialog(null, Resources.strings().get("panel_selectAmbientColor"), ColorHelper.decode(this.textFieldColor.getText()));
      this.setColor(result);
    });

    final JLabel lblAlpha = new JLabel(Resources.strings().get("panel_alpha"));

    this.spinnerAlpha = new JSpinner();

    this.spinnerAlpha.setModel(new SpinnerNumberModel(0, 0, 255, 5));
    this.spinnerAlpha.addChangeListener(a -> {
      final Color oldColor = ColorHelper.decode(this.textFieldColor.getText());
      if (oldColor == null) {
        return;
      }

      final Color newColor = new Color(oldColor.getRed(), oldColor.getGreen(), oldColor.getBlue(), (int) this.spinnerAlpha.getValue());
      this.setColor(newColor);
    });

    ControlBehavior.apply(this.spinnerAlpha);

    GroupLayout groupLayout = new GroupLayout(this);
    groupLayout.setHorizontalGroup(groupLayout.createParallelGroup(Alignment.LEADING).addGroup(groupLayout.createSequentialGroup().addComponent(btnSelectColor, 25, 25, 25).addPreferredGap(ComponentPlacement.RELATED).addComponent(textFieldColor, GroupLayout.DEFAULT_SIZE, 94, Short.MAX_VALUE))
        .addGroup(groupLayout.createSequentialGroup().addComponent(lblAlpha).addPreferredGap(ComponentPlacement.RELATED).addComponent(spinnerAlpha, GroupLayout.DEFAULT_SIZE, 95, Short.MAX_VALUE)));
    groupLayout.setVerticalGroup(groupLayout.createParallelGroup(Alignment.LEADING)
        .addGroup(groupLayout.createSequentialGroup().addGroup(groupLayout.createParallelGroup(Alignment.BASELINE).addComponent(btnSelectColor, GroupLayout.PREFERRED_SIZE, 25, GroupLayout.PREFERRED_SIZE).addComponent(textFieldColor, GroupLayout.PREFERRED_SIZE, 25, GroupLayout.PREFERRED_SIZE))
            .addPreferredGap(ComponentPlacement.RELATED).addGroup(groupLayout.createParallelGroup(Alignment.BASELINE).addComponent(lblAlpha).addComponent(spinnerAlpha, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE)).addContainerGap(15, Short.MAX_VALUE)));
    setLayout(groupLayout);
  }

  public void addActionListener(ActionListener listener) {
    this.listeners.add(listener);
  }

  public void removeActionListener(ActionListener listener) {
    this.listeners.remove(listener);
  }

  public int getAlpha() {
    return (int) this.spinnerAlpha.getValue();
  }

  public String getHexColor() {
    return this.textFieldColor.getText();
  }

  public Color getColor() {
    return ColorHelper.decode(this.textFieldColor.getText());
  }

  public void setHexColor(String color) {
    Color c = ColorHelper.decode(color);
    if (c == null) {
      return;
    }
    this.textFieldColor.setText(color);
    SwingHelpers.updateColorTextField(this.textFieldColor);
    this.spinnerAlpha.setValue(c.getAlpha());
    for (ActionListener listener : this.listeners) {
      listener.actionPerformed(null);
    }
  }

  public void setColor(final Color color) {
    final String h = ColorHelper.encode(color);
    this.setHexColor(h);
  }

  public void clear() {
    this.textFieldColor.setText(DEFAULT_COLOR);
  }
}

@@ -657,16 +657,73 @@
 Helpers;
+%0Aimport de.gurkenlabs.utiliti.swing.panels.PropertyPanel;
 %0A%0A@Suppr
@@ -1048,24 +1048,108 @@
 mponent() %7B%0A
+    int height = (PropertyPanel.CONTROL_HEIGHT + PropertyPanel.CONTROL_MARGIN) * 2;%0A
     this.set
@@ -1158,18 +1158,22 @@
 ze(200, 
-60
+height
 );%0A    t
@@ -1216,10 +1216,14 @@
 00, 
-60
+height
 ));%0A
@@ -2584,16 +2584,25 @@
 LEADING)
+%0A        
 .addGrou
@@ -2672,18 +2672,92 @@
 or, 
-25, 25, 25
+PropertyPanel.CONTROL_HEIGHT, GroupLayout.PREFERRED_SIZE, GroupLayout.PREFERRED_SIZE
 ).ad
@@ -3152,33 +3152,24 @@
 ent.LEADING)
-%0A        
 .addGroup(gr
@@ -3197,24 +3197,33 @@
 ntialGroup()
+%0A        
 .addGroup(gr
@@ -3296,24 +3296,54 @@
 SelectColor,
+ PropertyPanel.CONTROL_HEIGHT,
  GroupLayout
@@ -3350,36 +3350,32 @@
 .PREFERRED_SIZE,
- 25,
  GroupLayout.PRE
@@ -3444,18 +3444,44 @@
 D_SIZE, 
-25
+PropertyPanel.CONTROL_HEIGHT
 , GroupL
@@ -3515,55 +3515,44 @@
     
-    .addPreferredGap(ComponentPlacement.RELATED
+.addGap(PropertyPanel.CONTROL_MARGIN
 ).ad
@@ -3664,34 +3664,36 @@
 ha, 
-GroupLayout.PREFERRED_SIZE
+PropertyPanel.CONTROL_HEIGHT
 , Gr
@@ -3748,45 +3748,8 @@
 ZE))
-.addContainerGap(15, Short.MAX_VALUE)
 ));%0A

Fix ColorComponent spacing and size.