package games.strategy.engine.framework.networkMaintenance;

import java.awt.Component;
import java.awt.event.ActionEvent;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.List;

import javax.swing.AbstractAction;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;

import games.strategy.debug.ClientLogger;
import games.strategy.engine.data.properties.GameProperties;
import games.strategy.engine.data.properties.IEditableProperty;
import games.strategy.engine.data.properties.PropertiesUI;
import games.strategy.engine.framework.startup.mc.IServerStartupRemote;

public class ChangeGameOptionsClientAction extends AbstractAction {
  private static final long serialVersionUID = -6419002646689952824L;
  private final Component m_parent;
  private final IServerStartupRemote m_serverRemote;

  public ChangeGameOptionsClientAction(final Component parent, final IServerStartupRemote serverRemote) {
    super("Edit Game Options");
    m_parent = JOptionPane.getFrameForComponent(parent);
    m_serverRemote = serverRemote;
  }

  @Override
  public void actionPerformed(final ActionEvent e) {
    final byte[] oldBytes = m_serverRemote.getGameOptions();
    if (oldBytes == null || oldBytes.length == 0) {
      return;
    }
    try {
      final List<IEditableProperty> properties = GameProperties.streamToIEditablePropertiesList(oldBytes);
      final PropertiesUI pui = new PropertiesUI(properties, true);
      final JScrollPane scroll = new JScrollPane(pui);
      scroll.setBorder(null);
      scroll.getViewport().setBorder(null);
      final JOptionPane pane = new JOptionPane(scroll, JOptionPane.PLAIN_MESSAGE);
      final String ok = "OK";
      final String cancel = "Cancel";
      pane.setOptions(new Object[] {ok, cancel});
      final JDialog window = pane.createDialog(JOptionPane.getFrameForComponent(m_parent), "Map Options");
      window.setVisible(true);
      final Object buttonPressed = pane.getValue();
      if (buttonPressed != null && !buttonPressed.equals(cancel)) {
        // ok was clicked. changing them in the ui changes the underlying properties,
        // but it doesn't change the hosts, so we need to send it back to the host.
        byte[] newBytes = null;
        try (final ByteArrayOutputStream sink = new ByteArrayOutputStream(1000)) {
          GameProperties.toOutputStream(sink, properties);
          newBytes = sink.toByteArray();
        } catch (final IOException ex) {
          ClientLogger.logQuietly(ex);
        }
        if (newBytes != null) {
          m_serverRemote.changeToGameOptions(newBytes);
        }
      }
    } catch (final ClassNotFoundException | IOException | ClassCastException ex) {
      ClientLogger.logQuietly(ex);
    }
  }
}
