/*
 * $Id: NamedKeyStrokeArrayConfigurer.java 2893 2008-01-27 20:15:23Z uckelman $
 *
 * Copyright (c) 2004-2008 by Rodney Kinney, Brent Easton
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Library General Public
 * License (LGPL) as published by the Free Software Foundation.
 *
 * This library 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
 * Library General Public License for more details.
 *
 * You should have received a copy of the GNU Library General Public
 * License along with this library; if not, copies are available
 * at http://www.opensource.org.
 */
package VASSAL.configure;

import java.awt.Component;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;

import javax.swing.Box;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;

import VASSAL.tools.NamedKeyStroke;
import VASSAL.tools.SequenceEncoder;

/**
 * Configures an array of {@link NamedKeyStrokes}
 */
public class NamedKeyStrokeArrayConfigurer extends Configurer {
  private List<NamedHotKeyConfigurer> configs = new ArrayList<NamedHotKeyConfigurer>();
  private Box controls;

  public NamedKeyStrokeArrayConfigurer(String key, String name) {
    super(key, name);
  }

  public NamedKeyStrokeArrayConfigurer(String key, String name, NamedKeyStroke[] val) {
    super(key, name, val);
  }

  public Component getControls() {
    if (controls == null) {
      controls = Box.createVerticalBox();
      Box b = Box.createHorizontalBox();
      controls.add(b);
      JLabel l = new JLabel(getName());
      b.add(l);
      JButton button = new JButton("Add");
      b.add(button);
      button.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
          addKey(null);
        }
      });
      NamedKeyStroke[] keyStrokes = (NamedKeyStroke[]) value;
      if (keyStrokes != null) {
        for (int i = 0; i < keyStrokes.length; i++) {
          addKey(keyStrokes[i]);
        }
      }
      addKey(null);
    }
    return controls;
  }

  private void addKey(NamedKeyStroke keyStroke) {
    NamedHotKeyConfigurer config = new NamedHotKeyConfigurer(null, null, keyStroke);
    configs.add(config);
    controls.add(config.getControls());
    Window w = SwingUtilities.getWindowAncestor(controls);
    if (w != null) {
      w.pack();
    }
  }

  public String getValueString() {
    return encode(getKeyStrokes());
  }

  public void setValue(String s) {
    setValue(decode(s));
  }

  public void setValue(Object o) {
    super.setValue(o);
    if (controls != null) {
      NamedKeyStroke[] keyStrokes = (NamedKeyStroke[]) o;
      if (keyStrokes == null) {
        keyStrokes = new NamedKeyStroke[0];
      }

      for (int i = 0; i < keyStrokes.length; ++i) {
        if (i > configs.size()) {
          addKey(keyStrokes[i]);
        }
        else {
          configs.get(i).setValue(keyStrokes[i]);
        }
      }

      for (int i = keyStrokes.length; i < configs.size(); ++i) {
        configs.get(i).setValue(null);
      }
    }
  }

  public NamedKeyStroke[] getKeyStrokes() {
    ArrayList<NamedKeyStroke> l = new ArrayList<NamedKeyStroke>();
    for (NamedHotKeyConfigurer hotKeyConfigurer : configs) {
      NamedKeyStroke value = hotKeyConfigurer.getValueNamedKeyStroke();
      if (value != null) {
        l.add(value);
      }
    }
    return l.toArray(new NamedKeyStroke[l.size()]);
  }

  public static NamedKeyStroke[] decode(String s) {
    if (s == null) {
      return null;
    }
    ArrayList<NamedKeyStroke> l = new ArrayList<NamedKeyStroke>();
    SequenceEncoder.Decoder st = new SequenceEncoder.Decoder(s, ',');
    while (st.hasMoreTokens()) {
      l.add(NamedHotKeyConfigurer.decode(st.nextToken()));
    }
    return l.toArray(new NamedKeyStroke[l.size()]);
  }

  public static String encode(NamedKeyStroke[] keys) {
    if (keys == null) {
      return null;
    }
    SequenceEncoder se = new SequenceEncoder(',');
    for (int i = 0; i < keys.length; i++) {
      NamedKeyStroke key = keys[i];
      se.append(NamedHotKeyConfigurer.encode(key));
    }
    return se.getValue() != null ? se.getValue() : "";
  }
}

@@ -826,25 +826,84 @@
 ava.awt.
-Component
+BorderLayout;%0D%0Aimport java.awt.Component;%0D%0Aimport java.awt.Dimension
 ;%0D%0Aimpor
@@ -1134,16 +1134,77 @@
 Label;%0D%0A
+import javax.swing.JPanel;%0D%0Aimport javax.swing.JScrollPane;%0D%0A
 import j
@@ -1549,16 +1549,41 @@
 ntrols;%0D
+%0A  private JPanel panel;%0D
 %0A%0D%0A  pub
@@ -1842,24 +1842,21 @@
     if (
-controls
+panel
  == null
@@ -1870,43 +1870,152 @@
     
-controls = Box.createVerticalBox();
+panel = new JPanel(new BorderLayout());%0D%0A      controls = Box.createVerticalBox();%0D%0A      final JScrollPane scroll = new JScrollPane(controls); 
 %0D%0A  
@@ -2354,24 +2354,87 @@
 %0A      %7D);%0D%0A
+      %0D%0A      panel.add(scroll, BorderLayout.CENTER);%0D%0A      %0D%0A
       NamedK
@@ -2665,24 +2665,21 @@
  return 
-controls
+panel
 ;%0D%0A  %7D%0D%0A
@@ -2880,24 +2880,202 @@
 ntrols());%0D%0A
+    if (configs.size() %3E 5) %7B%0D%0A      panel.setPreferredSize(new Dimension(panel.getPreferredSize().width, 150));%0D%0A     %7D%0D%0A    else %7B%0D%0A      panel.setPreferredSize(null);%0D%0A    %7D%0D%0A
     Window w

Add scrollbars to keylist in NamedKeyStrokeConfigurer