/**
   * Create a new <code>SetBuildQueueMessage</code> for the supplied colony and queue.
   *
   * @param colony The <code>Colony</code> where the queue is.
   * @param queue A list of <code>BuildableType</code>s to build.
   */
  public SetBuildQueueMessage(Colony colony, List<BuildableType> queue) {
    super(getXMLElementTagName());

    this.colonyId = colony.getId();
    this.queue = new String[queue.size()];
    for (int i = 0; i < queue.size(); i++) {
      this.queue[i] = queue.get(i).getId();
    }
  }
  /**
   * Create a panel to define trade route cargos.
   *
   * @param freeColClient The <code>FreeColClient</code> for the game.
   * @param newRoute The <code>TradeRoute</code> to operate on.
   */
  public TradeRouteInputPanel(FreeColClient freeColClient, TradeRoute newRoute) {
    super(freeColClient, new MigLayout("wrap 4, fill", "[]20[fill]rel"));

    final Game game = freeColClient.getGame();
    final Player player = getMyPlayer();
    final TradeRoute tradeRoute = newRoute.copy(game, TradeRoute.class);

    this.newRoute = newRoute;
    this.cargoHandler = new CargoHandler();
    this.dragListener = new DragListener(freeColClient, this);
    this.dropListener = new DropListener();

    this.stopListModel = new DefaultListModel<>();
    for (TradeRouteStop stop : tradeRoute.getStops()) {
      this.stopListModel.addElement(stop);
    }

    this.stopList = new JList<>(this.stopListModel);
    this.stopList.setCellRenderer(new StopRenderer());
    this.stopList.setFixedCellHeight(48);
    this.stopList.setDragEnabled(true);
    this.stopList.setTransferHandler(new StopListHandler());
    this.stopList.addKeyListener(
        new KeyListener() {

          @Override
          public void keyTyped(KeyEvent e) {
            if (e.getKeyChar() == KeyEvent.VK_DELETE) {
              deleteCurrentlySelectedStops();
            }
          }

          @Override
          public void keyPressed(KeyEvent e) {} // Ignore

          @Override
          public void keyReleased(KeyEvent e) {} // Ignore
        });
    this.stopList.addListSelectionListener(this);
    JScrollPane tradeRouteView = new JScrollPane(stopList);

    JLabel nameLabel = Utility.localizedLabel("tradeRouteInputPanel.nameLabel");
    this.tradeRouteName = new JTextField(tradeRoute.getName());

    JLabel destinationLabel = Utility.localizedLabel("tradeRouteInputPanel.destinationLabel");
    this.destinationSelector = new JComboBox<>();
    this.destinationSelector.setRenderer(new DestinationCellRenderer());
    StringTemplate template = StringTemplate.template("tradeRouteInputPanel.allColonies");
    this.destinationSelector.addItem(Messages.message(template));
    if (player.getEurope() != null) {
      this.destinationSelector.addItem(player.getEurope().getId());
    }
    for (Colony colony : freeColClient.getMySortedColonies()) {
      this.destinationSelector.addItem(colony.getId());
    }

    this.messagesBox = new JCheckBox(Messages.message("tradeRouteInputPanel.silence"));
    this.messagesBox.setSelected(tradeRoute.isSilent());
    this.messagesBox.addActionListener(
        (ActionEvent ae) -> {
          tradeRoute.setSilent(messagesBox.isSelected());
        });

    this.addStopButton = Utility.localizedButton("tradeRouteInputPanel.addStop");
    this.addStopButton.addActionListener(
        (ActionEvent ae) -> {
          addSelectedStops();
        });

    this.removeStopButton = Utility.localizedButton("tradeRouteInputPanel.removeStop");
    this.removeStopButton.addActionListener(
        (ActionEvent ae) -> {
          deleteCurrentlySelectedStops();
        });

    this.goodsPanel = new GoodsPanel();
    this.goodsPanel.setTransferHandler(this.cargoHandler);
    this.goodsPanel.setEnabled(false);
    this.cargoPanel = new CargoPanel();
    this.cargoPanel.setTransferHandler(this.cargoHandler);

    JButton cancelButton = Utility.localizedButton("cancel");
    cancelButton.setActionCommand(CANCEL);
    cancelButton.addActionListener(this);
    setCancelComponent(cancelButton);

    add(Utility.localizedHeader("tradeRouteInputPanel.editRoute", false), "span, align center");
    add(tradeRouteView, "span 1 5, grow");
    add(nameLabel);
    add(this.tradeRouteName, "span");
    add(destinationLabel);
    add(this.destinationSelector, "span");
    add(this.messagesBox);
    add(this.addStopButton);
    add(this.removeStopButton, "span");
    add(this.goodsPanel, "span");
    add(this.cargoPanel, "span, height 80:, growy");
    add(okButton, "newline 20, span, split 2, tag ok");
    add(cancelButton, "tag cancel");

    // update cargo panel if stop is selected
    if (this.stopListModel.getSize() > 0) {
      this.stopList.setSelectedIndex(0);
      TradeRouteStop selectedStop = this.stopListModel.firstElement();
      this.cargoPanel.initialize(selectedStop);
    }

    // update buttons according to selection
    updateButtons();

    getGUI().restoreSavedSize(this, getPreferredSize());
  }
  private void update() {

    List<GoodsType> selectedTypes = new ArrayList<GoodsType>();

    reportPanel.removeAll();

    reportPanel.add(selectLabel, "span, split " + (NUMBER_OF_GOODS + 2));

    for (int index = 0; index < NUMBER_OF_GOODS; index++) {
      reportPanel.add(boxes[index]);
      int selectedIndex = boxes[index].getSelectedIndex();
      if (selectedIndex > 0) {
        selectedTypes.add(goodsTypes.get(selectedIndex - 1));
      }
    }

    reportPanel.add(selectButton, "wrap 20");

    if (!selectedTypes.isEmpty()) {

      TypeCountMap<BuildingType> buildingCount = new TypeCountMap<BuildingType>();
      List<List<BuildingType>> basicBuildingTypes = new ArrayList<List<BuildingType>>();
      for (GoodsType goodsType : selectedTypes) {
        List<BuildingType> buildingTypes = new ArrayList<BuildingType>();
        for (BuildingType buildingType : getSpecification().getBuildingTypeList()) {
          if (goodsType.equals(buildingType.getProducedGoodsType())
              || !buildingType.getModifierSet(goodsType.getId()).isEmpty()) {
            BuildingType firstLevel = buildingType.getFirstLevel();
            if (!buildingTypes.contains(firstLevel)) {
              buildingTypes.add(firstLevel);
            }
          }
        }
        basicBuildingTypes.add(buildingTypes);
      }

      JLabel newLabel;

      // labels
      newLabel = new JLabel(Messages.message("Colony"));
      newLabel.setBorder(FreeColPanel.TOPLEFTCELLBORDER);
      reportPanel.add(newLabel, "newline 20");

      for (int index = 0; index < selectedTypes.size(); index++) {
        newLabel = localizedLabel(selectedTypes.get(index).getNameKey());
        newLabel.setBorder(FreeColPanel.TOPCELLBORDER);
        reportPanel.add(newLabel);

        for (BuildingType buildingType : basicBuildingTypes.get(index)) {
          newLabel = localizedLabel(buildingType.getNameKey());
          newLabel.setBorder(FreeColPanel.TOPCELLBORDER);
          reportPanel.add(newLabel);
        }
      }

      int[] totalProduction = new int[selectedTypes.size()];
      for (Colony colony : getFreeColClient().getMySortedColonies()) {
        // colonyButton
        JButton colonyButton = GUI.getLinkButton(colony.getName(), null, colony.getId());
        colonyButton.setBorder(FreeColPanel.LEFTCELLBORDER);
        colonyButton.addActionListener(this);
        reportPanel.add(colonyButton, "newline");

        // production
        for (int index = 0; index < selectedTypes.size(); index++) {
          GoodsType goodsType = selectedTypes.get(index);
          int newValue = colony.getNetProductionOf(goodsType);
          totalProduction[index] += newValue;
          Goods goods = new Goods(colony.getGame(), colony, goodsType, newValue);
          GoodsLabel goodsLabel = new GoodsLabel(goods, getGUI());
          goodsLabel.setHorizontalAlignment(JLabel.LEADING);
          goodsLabel.setBorder(FreeColPanel.CELLBORDER);
          reportPanel.add(goodsLabel);

          for (BuildingType buildingType : basicBuildingTypes.get(index)) {
            Building building = colony.getBuilding(buildingType);
            if (building == null) {
              newLabel = new JLabel();
              newLabel.setBorder(FreeColPanel.CELLBORDER);
              reportPanel.add(newLabel);
            } else {
              buildingCount.incrementCount(building.getType(), 1);
              BuildingPanel buildingPanel = new BuildingPanel(getFreeColClient(), building);
              buildingPanel.setBorder(FreeColPanel.CELLBORDER);
              buildingPanel.initialize();
              reportPanel.add(buildingPanel);
            }
          }
        }
      }
    }
    revalidate();
    repaint();
  }