/**
   * The constructor that will add the items to this panel.
   *
   * @param freeColClient The <code>FreeColClient</code> for the game.
   */
  @SuppressWarnings("unchecked") // FIXME in Java7
  public ReportProductionPanel(FreeColClient freeColClient) {
    super(freeColClient, Messages.message("reportProductionAction.name"));

    // TODO: can we extend this to cover farmed goods?
    goodsTypes = new ArrayList<GoodsType>();
    List<String> goodsNames = new ArrayList<String>();
    goodsNames.add(Messages.message("nothing"));
    for (GoodsType goodsType : getSpecification().getGoodsTypeList()) {
      if (!goodsType.isFarmed()) {
        goodsTypes.add(goodsType);
        goodsNames.add(Messages.message(goodsType.getNameKey()));
      }
    }

    String[] model = goodsNames.toArray(new String[goodsTypes.size() + 1]);
    for (int index = 0; index < NUMBER_OF_GOODS; index++) {
      boxes[index] = new JComboBox(model);
    }

    selectLabel = new JLabel(Messages.message("report.production.selectGoods"));
    selectButton = new JButton(Messages.message("report.production.update"));
    selectButton.addActionListener(
        new ActionListener() {
          public void actionPerformed(ActionEvent event) {
            update();
          }
        });

    reportPanel.setLayout(new MigLayout("gap 0 0", "[fill]", "[fill]"));
    update();
  }
    public GoodsPanel() {
      super(new GridLayout(0, 4, MARGIN, MARGIN));

      for (GoodsType goodsType : getSpecification().getGoodsTypeList()) {
        if (goodsType.isStorable()) {
          CargoLabel label = new CargoLabel(goodsType);
          add(label);
        }
      }
      setOpaque(false);
      setBorder(Utility.localizedBorder("goods"));
      addMouseListener(TradeRouteInputPanel.this.dropListener);
    }
  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();
  }
  /**
   * Selects the most desirable goods from the colony.
   *
   * @param target The colony.
   * @return The goods to demand.
   */
  public Goods selectGoods(Colony target) {
    final Specification spec = getSpecification();
    Tension.Level tension = getUnit().getOwner().getTension(target.getOwner()).getLevel();
    int dx = spec.getInteger(GameOptions.NATIVE_DEMANDS) + 1;
    final GoodsType food = spec.getPrimaryFoodType();
    Goods goods = null;
    int amount = capAmount(target.getGoodsCount(food), dx);
    if (tension.compareTo(Tension.Level.CONTENT) <= 0 && target.getGoodsCount(food) >= amount) {
      return new Goods(getGame(), target, food, amount);
    } else if (tension.compareTo(Tension.Level.DISPLEASED) <= 0) {
      Market market = target.getOwner().getMarket();
      int value = 0;
      for (Goods currentGoods : target.getCompactGoods()) {
        int goodsValue = market.getSalePrice(currentGoods);
        if (currentGoods.getType().isFoodType() || currentGoods.getType().isMilitaryGoods()) {
          continue;
        } else if (goodsValue > value) {
          value = goodsValue;
          goods = currentGoods;
        }
      }
      if (goods != null) {
        goods.setAmount(capAmount(goods.getAmount(), dx));
        return goods;
      }
    } else {
      // Military goods
      for (GoodsType preferred : spec.getGoodsTypeList()) {
        if (preferred.isMilitaryGoods()) {
          amount = target.getGoodsCount(preferred);
          if (amount > 0) {
            return new Goods(getGame(), target, preferred, capAmount(amount, dx));
          }
        }
      }
      // Storable building materials (what do the natives need tools for?)
      for (GoodsType preferred : spec.getStorableGoodsTypeList()) {
        if (preferred.isBuildingMaterial()) {
          amount = target.getGoodsCount(preferred);
          if (amount > 0) {
            return new Goods(getGame(), target, preferred, capAmount(amount, dx));
          }
        }
      }
      // Trade goods
      for (GoodsType preferred : spec.getStorableGoodsTypeList()) {
        if (preferred.isTradeGoods()) {
          amount = target.getGoodsCount(preferred);
          if (amount > 0) {
            return new Goods(getGame(), target, preferred, capAmount(amount, dx));
          }
        }
      }
      // Refined goods
      for (GoodsType preferred : spec.getStorableGoodsTypeList()) {
        if (preferred.isRefined()) {
          amount = target.getGoodsCount(preferred);
          if (amount > 0) {
            return new Goods(getGame(), target, preferred, capAmount(amount, dx));
          }
        }
      }
    }

    // Have not found what we want
    Market market = target.getOwner().getMarket();
    int value = 0;
    for (Goods currentGoods : target.getCompactGoods()) {
      int goodsValue = market.getSalePrice(currentGoods);
      if (goodsValue > value) {
        value = goodsValue;
        goods = currentGoods;
      }
    }
    if (goods != null) {
      goods.setAmount(capAmount(goods.getAmount(), dx));
    }
    return goods;
  }