private List<com.t3.model.campaign.TokenProperty> getPropertyList() {
   if (propertyList == null) {
     propertyList =
         TabletopTool.getCampaign()
             .getTokenPropertyList((String) getPropertyTypeCombo().getSelectedItem());
   }
   return propertyList;
 }
  private void updateSightTypeCombo() {
    List<String> typeList = new ArrayList<String>(TabletopTool.getCampaign().getSightTypes());
    Collections.sort(typeList);

    DefaultComboBoxModel<String> model =
        new DefaultComboBoxModel<String>(typeList.toArray(new String[typeList.size()]));
    getSightTypeCombo().setModel(model);
  }
 private void updatePropertyTypeCombo() {
   List<String> typeList = new ArrayList<String>(TabletopTool.getCampaign().getTokenTypes());
   Collections.sort(typeList);
   DefaultComboBoxModel<String> model =
       new DefaultComboBoxModel<String>(typeList.toArray(new String[typeList.size()]));
   getPropertyTypeCombo().setModel(model);
   getPropertyTypeCombo()
       .addItemListener(
           new ItemListener() {
             @Override
             public void itemStateChanged(ItemEvent e) {
               updatePropertiesTable((String) getPropertyTypeCombo().getSelectedItem());
             }
           });
 }
  private void updateStatesPanel() {
    // Group the states first into individual panels
    List<BooleanTokenOverlay> overlays =
        new ArrayList<BooleanTokenOverlay>(TabletopTool.getCampaign().getTokenStatesMap().values());
    Map<String, JPanel> groups = new TreeMap<String, JPanel>();
    groups.put("", new JPanel(new FormLayout("0px:grow 2px 0px:grow 2px 0px:grow 2px 0px:grow")));
    for (BooleanTokenOverlay overlay : overlays) {
      String group = overlay.getGroup();
      if (group != null && (group = group.trim()).length() != 0) {
        JPanel panel = groups.get(group);
        if (panel == null) {
          panel = new JPanel(new FormLayout("0px:grow 2px 0px:grow 2px 0px:grow 2px 0px:grow"));
          panel.setBorder(BorderFactory.createTitledBorder(group));
          groups.put(group, panel);
        }
      }
    }
    // Add the group panels and bar panel to the states panel
    JPanel panel = getStatesPanel();
    panel.removeAll();
    FormLayout layout = new FormLayout("0px:grow");
    panel.setLayout(layout);
    int row = 1;
    for (JPanel gPanel : groups.values()) {
      layout.appendRow(new RowSpec("pref"));
      layout.appendRow(new RowSpec("2px"));
      panel.add(gPanel, new CellConstraints(1, row));
      row += 2;
    }
    layout.appendRow(new RowSpec("pref"));
    layout.appendRow(new RowSpec("2px"));
    JPanel barPanel = new JPanel(new FormLayout("right:pref 2px pref 5px right:pref 2px pref"));
    panel.add(barPanel, new CellConstraints(1, row));

    // Add the individual check boxes.
    for (BooleanTokenOverlay state : overlays) {
      String group = state.getGroup();
      panel = groups.get("");
      if (group != null && (group = group.trim()).length() != 0) panel = groups.get(group);
      int x = panel.getComponentCount() % 4;
      int y = panel.getComponentCount() / 4;
      if (x == 0) {
        layout = (FormLayout) panel.getLayout();
        if (y != 0) layout.appendRow(new RowSpec("2px"));
        layout.appendRow(new RowSpec("pref"));
      }
      panel.add(new JCheckBox(state.getName()), new CellConstraints(x * 2 + 1, y * 2 + 1));
    }
    // Add sliders to the bar panel
    if (TabletopTool.getCampaign().getTokenBarsMap().size() > 0) {
      layout = (FormLayout) barPanel.getLayout();
      barPanel.setName("bar");
      barPanel.setBorder(BorderFactory.createTitledBorder("Bars"));
      int count = 0;
      row = 0;
      for (BarTokenOverlay bar : TabletopTool.getCampaign().getTokenBarsMap().values()) {
        int working = count % 2;
        if (working == 0) { // slider row
          layout.appendRow(new RowSpec("pref"));
          row += 1;
        }
        JPanel labelPanel = new JPanel(new FormLayout("pref", "pref 2px:grow pref"));
        barPanel.add(labelPanel, new CellConstraints(1 + working * 4, row));
        labelPanel.add(
            new JLabel(bar.getName() + ":"),
            new CellConstraints(1, 1, CellConstraints.RIGHT, CellConstraints.TOP));
        JSlider slider = new JSlider(0, 100);
        JCheckBox hide = new JCheckBox("Hide");
        hide.putClientProperty("JSlider", slider);
        hide.addChangeListener(
            new ChangeListener() {
              @Override
              public void stateChanged(ChangeEvent e) {
                JSlider js = (JSlider) ((JCheckBox) e.getSource()).getClientProperty("JSlider");
                js.setEnabled(!((JCheckBox) e.getSource()).isSelected());
              }
            });
        labelPanel.add(hide, new CellConstraints(1, 3, CellConstraints.RIGHT, CellConstraints.TOP));
        slider.setName(bar.getName());
        slider.setPaintLabels(true);
        slider.setPaintTicks(true);
        slider.setMajorTickSpacing(20);
        slider.createStandardLabels(20);
        slider.setMajorTickSpacing(10);
        barPanel.add(slider, new CellConstraints(3 + working * 4, row));
        if (working != 0) { // spacer row
          layout.appendRow(new RowSpec("2px"));
          row += 1;
        }
        count += 1;
      }
    }
  }
  @Override
  public boolean commit() {
    Token token = getModel();

    if (getNameField().getText().equals("")) {
      TabletopTool.showError("msg.error.emptyTokenName");
      return false;
    }
    if (getSpeechTable().isEditing()) {
      getSpeechTable().getCellEditor().stopCellEditing();
    }
    if (getPropertyTable().isEditing()) {
      getPropertyTable().getCellEditor().stopCellEditing();
    }
    // Commit the changes to the token properties
    if (!super.commit()) {
      return false;
    }
    // SIZE
    token.setSnapToScale(getSizeCombo().getSelectedIndex() != 0);
    if (getSizeCombo().getSelectedIndex() > 0) {
      Grid grid = TabletopTool.getFrame().getCurrentZoneRenderer().getZone().getGrid();
      token.setFootprint(grid, (TokenFootprint) getSizeCombo().getSelectedItem());
    }
    // Other
    token.setPropertyType((String) getPropertyTypeCombo().getSelectedItem());
    token.setSightType((String) getSightTypeCombo().getSelectedItem());

    // Get the states
    Component[] stateComponents = getStatesPanel().getComponents();
    Component barPanel = null;
    for (int j = 0; j < stateComponents.length; j++) {
      if ("bar".equals(stateComponents[j].getName())) {
        barPanel = stateComponents[j];
        continue;
      }
      Component[] components = ((Container) stateComponents[j]).getComponents();
      for (int i = 0; i < components.length; i++) {
        JCheckBox cb = (JCheckBox) components[i];
        String state = cb.getText();
        token.setState(state, cb.isSelected());
      }
    } // endfor

    // BARS
    if (barPanel != null) {
      Component[] bars = ((Container) barPanel).getComponents();
      for (int i = 0; i < bars.length; i += 2) {
        JCheckBox cb = (JCheckBox) ((Container) bars[i]).getComponent(1);
        JSlider bar = (JSlider) bars[i + 1];
        Float value = cb.isSelected() ? null : new Float(bar.getValue() / 100f);
        token.setBar(bar.getName(), value);
      }
    }
    // Ownership
    // If the token is owned by all and we are a player don't alter the ownership list.
    if (TabletopTool.getPlayer().isGM() || !token.isOwnedByAll()) {
      token.clearAllOwners();

      for (int i = 0; i < getOwnerList().getModel().getSize(); i++) {
        DefaultSelectable selectable =
            (DefaultSelectable) getOwnerList().getModel().getElementAt(i);
        if (selectable.isSelected()) {
          token.addOwner((String) selectable.getObject());
        }
      }
      // If we are not a GM and the only non GM owner make sure we can't
      // take our selves off of the owners list
      if (!TabletopTool.getPlayer().isGM()) {
        boolean hasPlayer = false;
        Set<String> owners = token.getOwners();
        if (owners != null) {
          Iterator<Player> playerIter = TabletopTool.getPlayerList().iterator();
          while (playerIter.hasNext()) {
            Player pl = playerIter.next();
            if (!pl.isGM() && owners.contains(pl.getName())) {
              hasPlayer = true;
            }
          }
        }
        if (!hasPlayer) {
          token.addOwner(TabletopTool.getPlayer().getName());
        }
      }
    }
    // SHAPE
    token.setShape((Token.TokenShape) getShapeCombo().getSelectedItem());

    // Macros
    token.setSpeechMap(((KeyValueTableModel) getSpeechTable().getModel()).getMap());

    // Properties
    ((TokenPropertyTableModel) getPropertyTable().getModel()).applyTo(token);

    // Charsheet
    if (getCharSheetPanel().getImageId() != null) {
      T3Util.uploadAsset(AssetManager.getAsset(getCharSheetPanel().getImageId()));
    }
    token.setCharsheetImage(getCharSheetPanel().getImageId());

    // IMAGE
    if (!token.getImageAssetId().equals(getTokenIconPanel().getImageId())) {
      BufferedImage image = ImageManager.getImageAndWait(getTokenIconPanel().getImageId());
      T3Util.uploadAsset(AssetManager.getAsset(getTokenIconPanel().getImageId()));
      token.setImageAsset(null, getTokenIconPanel().getImageId()); // Default image for now
      token.setWidth(image.getWidth(null));
      token.setHeight(image.getHeight(null));
    }
    // PORTRAIT
    if (getPortraitPanel().getImageId() != null) {
      // Make sure the server has the image
      if (!TabletopTool.getCampaign().containsAsset(getPortraitPanel().getImageId())) {
        TabletopTool.serverCommand()
            .putAsset(AssetManager.getAsset(getPortraitPanel().getImageId()));
      }
    }
    token.setPortraitImage(getPortraitPanel().getImageId());

    // LAYOUT
    token.setSizeScale(getTokenLayoutPanel().getSizeScale());
    token.setAnchor(getTokenLayoutPanel().getAnchorX(), getTokenLayoutPanel().getAnchorY());

    // OTHER
    tokenSaved = true;

    // Character Sheet
    //		Map<String, Object> properties = controller.getData();
    //		for (String prop : token.getPropertyNames())
    //			token.setProperty(prop, properties.get(prop));

    // Update UI
    TabletopTool.getFrame().updateTokenTree();
    TabletopTool.getFrame().resetTokenPanels();

    return true;
  }
  @Override
  public void bind(final Token token) {
    // ICON
    getTokenIconPanel().setImageId(token.getImageAssetId());

    // PROPERTIES
    updatePropertyTypeCombo();
    updatePropertiesTable(token.getPropertyType());

    // SIGHT
    updateSightTypeCombo();

    // STATES
    Component barPanel = null;
    updateStatesPanel();
    Component[] statePanels = getStatesPanel().getComponents();
    for (int j = 0; j < statePanels.length; j++) {
      if ("bar".equals(statePanels[j].getName())) {
        barPanel = statePanels[j];
        continue;
      }
      Component[] states = ((Container) statePanels[j]).getComponents();
      for (int i = 0; i < states.length; i++) {
        JCheckBox state = (JCheckBox) states[i];
        state.setSelected(token.hasState(state.getText()));
      }
    }

    // BARS
    if (barPanel != null) {
      Component[] bars = ((Container) barPanel).getComponents();
      for (int i = 0; i < bars.length; i += 2) {
        JCheckBox cb = (JCheckBox) ((Container) bars[i]).getComponent(1);
        JSlider bar = (JSlider) bars[i + 1];
        if (token.getBar(bar.getName()) == null) {
          cb.setSelected(true);
          bar.setEnabled(false);
          bar.setValue(100);
        } else {
          cb.setSelected(false);
          bar.setEnabled(true);
          bar.setValue((int) (token.getBar(bar.getName()) * 100));
        }
      }
    }

    // OWNER LIST
    EventQueue.invokeLater(
        new Runnable() {
          @Override
          public void run() {
            getOwnerList().setModel(new OwnerListModel());
          }
        });

    // SPEECH TABLE
    EventQueue.invokeLater(
        new Runnable() {
          @Override
          public void run() {
            getSpeechTable().setModel(new SpeechTableModel(token));
          }
        });

    //		Player player = TabletopTool.getPlayer();
    //		boolean editable = player.isGM() ||
    // !TabletopTool.getServerPolicy().useStrictTokenManagement() ||
    // token.isOwner(player.getName());
    //		getAllPlayersCheckBox().setSelected(token.isOwnedByAll());

    // OTHER
    getShapeCombo().setSelectedItem(token.getShape());
    setSizeCombo(token);

    getPropertyTypeCombo().setSelectedItem(token.getPropertyType());
    getSightTypeCombo()
        .setSelectedItem(
            token.getSightType() != null
                ? token.getSightType()
                : TabletopTool.getCampaign().getCampaignProperties().getDefaultSightType());
    getCharSheetPanel().setImageId(token.getCharsheetImage());
    getPortraitPanel().setImageId(token.getPortraitImage());
    getTokenLayoutPanel().setToken(token);

    // we will disable the Owner only visible check box if the token is not
    // visible to players to signify the relationship
    ActionListener tokenVisibleActionListener =
        new ActionListener() {
          @Override
          public void actionPerformed(ActionEvent actionEvent) {
            AbstractButton abstractButton = (AbstractButton) actionEvent.getSource();
            boolean selected = abstractButton.getModel().isSelected();
            getVisibleOnlyToOwnerCheckBox().setEnabled(selected);
            getVisibleOnlyToOwnerLabel().setEnabled(selected);
          }
        };
    getVisibleCheckBox().addActionListener(tokenVisibleActionListener);

    // Character Sheets
    //		controller = null;
    //		String form = TabletopTool.getCampaign().getCharacterSheets().get(token.getPropertyType());
    //		if (form == null)
    //			return;
    //		URL formUrl = getClass().getClassLoader().getResource(form);
    //		if (formUrl == null)
    //			return;
    //		controller = new CharSheetController(formUrl, null);
    //		HashMap<String, Object> properties = new HashMap<String, Object>();
    //		for (String prop : token.getPropertyNames())
    //			properties.put(prop, token.getProperty(prop));
    //		controller.setData(properties);
    //		controller.getPanel().setName("characterSheet");
    //		replaceComponent("sheetPanel", "characterSheet", controller.getPanel());

    super.bind(token);
  }