package com.hero.ui.widgets;

import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

import com.hero.HeroDesigner;
import com.hero.objects.Adder;
import com.hero.objects.GenericObject;
import com.hero.objects.modifiers.Modifier;
import com.hero.objects.powers.ChangeEnvironment;
import com.hero.objects.powers.Clairsentience;
import com.hero.objects.powers.Entangle;
import com.hero.objects.powers.Power;
import com.hero.objects.powers.Sense;
import com.hero.objects.powers.SenseAdder;
import com.hero.objects.powers.SenseAffectingPower;
import com.hero.ui.dialog.GenericDialog;
import com.hero.util.Rounder;

/**
 * Copyright (c) 2000 - 2005, CompNet Design, Inc. All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, is prohibited unless the following conditions are met: 1.
 * Express written consent of CompNet Design, Inc. is obtained by the developer.
 * 2. Redistributions must retain this copyright notice. THIS SOFTWARE IS
 * PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
 * EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * @author CompNet Design, Inc.
 * @version $Revision$
 */

public class AdderPanel extends JPanel {
	private static final long serialVersionUID = -3290019588585813848L;

	Adder adder;

	AdderPanel parentPanel;

	AdderPanel childPanel;

	GenericObject parent;

	GenericDialog main;

	JCheckBox checkbox;

	JComboBox combo;

	JLabel inputLbl;

	JComboBox examples;

	LevelTF levelTF;

	FractionTF fractionTF;

	JTextField aliasTF;

	JLabel adderLbl;

	JButton helpBtn;

	JLabel pointsLbl;

	ArrayList<ActionListener> listeners;

	ActionListener checkboxListener;

	LevelTF valueTF;

	boolean isChild;

	boolean selectionLocked = false;

	public AdderPanel(GenericObject object, Adder ad, AdderPanel parentPanel,
			GenericDialog dialog) {
		this(object, ad, parentPanel, dialog, false);
	}

	AdderPanel(GenericObject object, Adder ad, AdderPanel panel,
			GenericDialog dialog, boolean isChild) {
		super();
		setLayout(new GridBagLayout());
		setOpaque(true);
		listeners = new ArrayList<ActionListener>();
		setBackground(Color.white);
		adder = ad;
		parent = object;
		parentPanel = panel;
		this.isChild = isChild;
		main = dialog;
		adder.setLevels(adder.getLevels());
		if (!adder.isSelectable()) {
			adderLbl = new JLabel(adder.getAlias());
			adderLbl.setOpaque(false);
		} else {
			aliasTF = new JTextField(adder.getAlias());
			aliasTF.setOpaque(false);
			aliasTF.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
			aliasTF.getDocument().addDocumentListener(new DocumentListener() {
				public void changedUpdate(DocumentEvent e) {
					adder.setAlias(aliasTF.getText());
					GenericObject.lastEdit = System.currentTimeMillis();
				}

				public void insertUpdate(DocumentEvent e) {
					adder.setAlias(aliasTF.getText());
					GenericObject.lastEdit = System.currentTimeMillis();
				}

				public void removeUpdate(DocumentEvent e) {
					adder.setAlias(aliasTF.getText());
					GenericObject.lastEdit = System.currentTimeMillis();
				}
			});
			checkbox = new JCheckBox();
			checkbox.setOpaque(false);
			checkbox.setSelected(adder.isSelected());
			aliasTF.setFont(checkbox.getFont());
			if (checkbox.isSelected()) {
				if (!adder.isExclusive() && (childPanel == null)
						&& !main.hasAvailable(adder.getXMLID())) {
					setChildVisibility(true);
				}
			}
			checkboxListener = new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					if (checkbox.isSelected()) {
						// uncheck any "excluded" adders
						for (String s : adder.getExcludes()) {
							String id = s.trim().toUpperCase();
							Adder ad = main.getAdderFromList(id, main
									.getObject().getAssignedAdders());
							if ((ad != null) && ad.isSelected()) {
								for (AdderPanel p : main.getAdderPanels()) {
									if (p.getAdder().getXMLID().trim()
											.toUpperCase().equals(id)) {
										p.setSelected(false);
									}
								}
							}
						}

						addToParent();
					} else {
						removeFromParent();
					}
					setChildVisibility(checkbox.isSelected());
					revalidate();
					dispatch(true);
					if ((parent instanceof SenseAdder)
							|| (parent instanceof Sense)) {
						Power.lastSenseEdit = System.currentTimeMillis();
					}
					if ((parent instanceof SenseAdder)
							|| (parent instanceof Sense)
							|| (parent instanceof SenseAffectingPower)
							|| (parent instanceof Clairsentience)
							|| (parent instanceof ChangeEnvironment)) {
						main.layoutExtrasPanel();
						if (main.optionsCB.getSelectedItem() instanceof Adder) {
							Adder ad = (Adder) main.optionsCB.getSelectedItem();
							if (!ad.equals(parent.getSelectedOption())) {
								main.optionsCB.setSelectedItem(parent
										.getSelectedOption());
							}
						}
					}
					GenericObject.lastEdit = System.currentTimeMillis();
				}
			};
			checkbox.addActionListener(checkboxListener);
		}
		if ((adder.getDefinition() != null)
				&& (adder.getDefinition().trim().length() > 0)) {
			helpBtn = new JButton(" ? ");
			helpBtn.setOpaque(false);
			helpBtn.setMargin(new Insets(0, 0, 0, 0));
			helpBtn.setBorderPainted(false);
			helpBtn.setFocusPainted(false);
			helpBtn.setContentAreaFilled(false);
			helpBtn.setForeground(Color.blue);
			helpBtn.addActionListener(new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					if (adder == null) {
						return;
					}
					if (adder.getDefinition() == null) {
						return;
					}
					if (adder.getDefinition().trim().length() == 0) {
						return;
					}
					PopupMessage popup = PopupMessage.getInstance(HeroDesigner
							.getAppFrame(), helpBtn, adder.getDefinition(),
							false);
					popup.setVisible(true);
				}
			});
		}
		if (adder.getOptions().size() > 0) {
			combo = new JComboBox(adder.getOptions().toArray());
			combo.setBackground(Color.white);
			combo.setSelectedItem(combo.getSelectedItem());
			combo.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {
					if (!(combo.getSelectedItem() instanceof Adder)) {
						return;
					}
					Adder opt = (Adder) combo.getSelectedItem();
					adder.setSelectedOption(opt);
					updateValues();
					dispatch(true);
					opt.setAlias(opt.getDisplay());
					((JTextField) combo.getEditor().getEditorComponent())
							.setText(opt.getDisplay());
					GenericObject.lastEdit = System.currentTimeMillis();
				}
			});
			combo.setEditable(true);
			((JTextField) combo.getEditor().getEditorComponent()).getDocument()
					.addDocumentListener(new DocumentListener() {
						public void changedUpdate(DocumentEvent e) {
							if (adder.getSelectedOption() != null) {
								adder.getSelectedOption().setAlias(
										((JTextField) combo.getEditor()
												.getEditorComponent())
												.getText());
								GenericObject.lastEdit = System
										.currentTimeMillis();
							}
						}

						public void insertUpdate(DocumentEvent e) {
							if (adder.getSelectedOption() != null) {
								adder.getSelectedOption().setAlias(
										((JTextField) combo.getEditor()
												.getEditorComponent())
												.getText());
								GenericObject.lastEdit = System
										.currentTimeMillis();
							}
						}

						public void removeUpdate(DocumentEvent e) {
							if (adder.getSelectedOption() != null) {
								adder.getSelectedOption().setAlias(
										((JTextField) combo.getEditor()
												.getEditorComponent())
												.getText());
								GenericObject.lastEdit = System
										.currentTimeMillis();
							}
						}
					});
		}
		if (adder.isUserInput()) {
			inputLbl = new JLabel(adder.getInputLabel());
			if (adder.getExamples() != null) {
				examples = new JComboBox(adder.getExamples().toArray());
			} else {
				examples = new JComboBox();
			}
			examples.setBackground(Color.white);
			examples.addItemListener(new ItemListener() {
				public void itemStateChanged(ItemEvent e) {
					if (examples.getSelectedItem() != null) {
						String ex = examples.getSelectedItem().toString();
						adder.setInput(ex);
						GenericObject.lastEdit = System.currentTimeMillis();
						dispatch(false);
					}
				}
			});
			if (adder.otherInputAllowed()) {
				examples.setEditable(true);
				((JTextField) examples.getEditor().getEditorComponent())
						.getDocument().addDocumentListener(
								new DocumentListener() {
									public void changedUpdate(DocumentEvent e) {
										String input = ((JTextField) examples
												.getEditor()
												.getEditorComponent())
												.getText();
										adder.setInput(input);
										GenericObject.lastEdit = System
												.currentTimeMillis();
										dispatch(false);
									}

									public void insertUpdate(DocumentEvent e) {
										String input = ((JTextField) examples
												.getEditor()
												.getEditorComponent())
												.getText();
										adder.setInput(input);
										GenericObject.lastEdit = System
												.currentTimeMillis();
										dispatch(false);
									}

									public void removeUpdate(DocumentEvent e) {
										String input = ((JTextField) examples
												.getEditor()
												.getEditorComponent())
												.getText();
										adder.setInput(input);
										GenericObject.lastEdit = System
												.currentTimeMillis();
										dispatch(false);
									}
								});
				((JTextField) examples.getEditor().getEditorComponent())
						.setText(adder.getInput());
			} else {
				examples.setSelectedItem(adder.getInput());
			}
		}
		if ((adder.getLevelCost() > 0) && (adder.getLevelValue() != 0)) {
			if (parent instanceof Entangle) {
				levelTF = new LevelTF(adder.getLevels(), adder.getMaxLevel(),
						adder.getMinimumLevel());
			} else {
				levelTF = new LevelTF(adder.getLevels(), 999, adder
						.getMinimumLevel());
			}
			levelTF.addPropertyChangeListener("Level",
					new PropertyChangeListener() {
						public void propertyChange(PropertyChangeEvent e) {
							adder.setLevels(levelTF.getCurrent());
							GenericObject.lastEdit = System.currentTimeMillis();
							dispatch(false);
						}
					});
		}
		if ((parent instanceof Modifier)
				&& (adder.getMinimumCost() != adder.getMaxCost())) {
			fractionTF = new FractionTF(adder.getBaseCost(),
					adder.getMaxCost(), adder.getMinimumCost());
			fractionTF.addPropertyChangeListener(new PropertyChangeListener() {
				public void propertyChange(PropertyChangeEvent e) {
					adder.setBaseCost(fractionTF.getCurrent());
					GenericObject.lastEdit = System.currentTimeMillis();
					dispatch(true);
				}
			});

		}
		if (adder.isFixedValue()) {
			pointsLbl = new JLabel("("
					+ Rounder.roundUp(adder.getTotalCost(true))
					+ (Rounder.roundUp(adder.getTotalCost(true)) != 1 ? " pts)"
							: " pt)"));
			pointsLbl.setPreferredSize(new JLabel("(9999 pts)")
					.getPreferredSize());
			pointsLbl.setHorizontalTextPosition(SwingConstants.RIGHT);
			pointsLbl.setHorizontalAlignment(SwingConstants.RIGHT);
		} else {
			valueTF = new LevelTF((int) adder.getBaseCost(), (int) adder
					.getMaxCost(), (int) adder.getMinimumCost());
			valueTF.addPropertyChangeListener("Level",
					new PropertyChangeListener() {
						public void propertyChange(PropertyChangeEvent e) {
							adder.setBaseCost(valueTF.getCurrent());
							if (adder.getSelectedOption() != null) {
								adder.getSelectedOption().setBaseCost(
										valueTF.getCurrent());
							}
							GenericObject.lastEdit = System.currentTimeMillis();
							dispatch(false);
						}
					});
		}
		if (parent instanceof Modifier) {
			pointsLbl.setText("("
					+ ((Modifier) parent).getFraction(adder
							.getDoubleTotal(false)) + ")");
		}
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 0;
		gbc.weightx = 0;
		gbc.weighty = 1;
		gbc.gridwidth = 1;
		gbc.gridheight = 1;
		gbc.fill = GridBagConstraints.NONE;
		gbc.anchor = GridBagConstraints.NORTHWEST;
		gbc.insets = new Insets(0, 5, 0, 3);
		if (adder.isSelectable()) {
			add(checkbox, gbc);
			gbc.gridx++;
			gbc.insets = new Insets(0, 0, 0, 3);
			gbc.fill = GridBagConstraints.BOTH;
			gbc.weightx = 1;
			gbc.weighty = 1;
			add(aliasTF, gbc);
			gbc.gridx++;
			gbc.weightx = 0;
			gbc.fill = GridBagConstraints.NONE;
		} else {
			gbc.fill = GridBagConstraints.HORIZONTAL;
			gbc.weightx = 1;
			add(adderLbl, gbc);
			gbc.insets = new Insets(0, 0, 0, 3);
			gbc.gridx++;
			gbc.weightx = 0;
			gbc.fill = GridBagConstraints.NONE;
		}
		gbc.gridx++;
		if (adder.getOptions().size() > 0) {
			add(combo, gbc);
			gbc.gridx++;
		}
		if (adder.isUserInput()) {
			add(inputLbl, gbc);
			gbc.gridx++;
			add(examples, gbc);
			gbc.gridx++;
		}
		if ((adder.getLevelCost() > 0) && (adder.getLevelValue() > 0)) {
			add(levelTF, gbc);
			gbc.gridx++;
		}
		gbc.insets = new Insets(0, 10, 0, 10);
		if ((adder.getDefinition() != null)
				&& (adder.getDefinition().trim().length() > 0)) {
			add(helpBtn, gbc);
		}
		gbc.gridx++;
		gbc.insets = new Insets(0, 10, 0, 5);
		if (adder.isSelectable()) {
			if ((parent instanceof Modifier)
					&& !((adder.getLevelCost() > 0) && (adder.getLevelValue() > 0))
					&& (fractionTF != null)) {
				add(fractionTF, gbc);
			} else if (adder.isFixedValue()) {
				add(pointsLbl, gbc);
			} else {
				add(valueTF, gbc);
			}
		}

		if (parent instanceof Adder) {
			Adder check = (Adder) parent;
			if (check.isSelected()) {
				setEnabled(false);
				checkbox.removeActionListener(checkboxListener);
				checkbox.setSelected(true);
			} else {
				setEnabled(true);
			}
		}
		addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				main.updateValues();
			}
		});
		if (adder.getOptions().size() > 0) {
			String alias = adder.getSelectedOption().getAlias();
			combo.setSelectedItem(adder.getSelectedOption());
			((JTextField) combo.getEditor().getEditorComponent())
					.setText(alias);
		}
		adder.setSelectedOption(adder.getSelectedOption());
		if (!adder.isSelectable() && (adder.getTotalCost(true) != 0)) {
			setEnabled(adder.isSelectable());
		}
	}

	/**
	 * Adds an ActionListener, fired when the checkbox state is changed.
	 * 
	 * @param listener
	 */
	public void addActionListener(ActionListener listener) {
		listeners.add(listener);
	}

	private void addChild() {
		if (!adder.isExclusive() && (childPanel == null)
				&& !main.hasAvailable(adder.getXMLID())) {
			GridBagConstraints gbc = new GridBagConstraints();
			gbc.gridx = 0;
			gbc.gridy = 1;
			gbc.gridwidth = GridBagConstraints.REMAINDER;
			gbc.fill = GridBagConstraints.HORIZONTAL;
			gbc.anchor = GridBagConstraints.WEST;
			Adder add = (Adder) adder.clone();
			add.setAlias(add.getDisplay());
			add.setBaseCost(add.getOrigBaseCost());
			if (add.getSelectedOption() != null) {
				Adder op = add.getSelectedOption();
				op.setAlias(op.getDisplay());
				op.setBaseCost(op.getOrigBaseCost());
				add.setSelectedOption(op);
			}
			add.setInput("");
			add.resetID();
			add.setSelected(false);
			add.setLevels(0);
			childPanel = new AdderPanel(parent, add, AdderPanel.this, main,
					true);
			add(childPanel, gbc);
		}
	}

	private void addToParent() {
		adder.setSelected(checkbox != null ? checkbox.isSelected() : false);
		
		if (parent.getAssignedAdders().contains(adder)) {
			parent.getAssignedAdders().remove(adder);
		}
		adder.resetID();
		if (parent.canAdd(adder)) {
			parent.getAssignedAdders().add(adder);
		}
		if (parent instanceof Adder) { // not done until it's in the
			// main object
			parentPanel.addToParent();
		} else {
			GenericObject.lastEdit = System.currentTimeMillis();
		}
	}

	/**
	 * Multithreaded update.
	 * 
	 * @param updateModifier
	 */
	private void dispatch(boolean updateModifier) {
		if (parent instanceof Modifier) {
			Modifier mod = (Modifier) parent;
			if (updateModifier) {
				mod.setRefreshAddersOnUpdate(true);
			}
		}

		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				if (parent instanceof Modifier) {
					if (adder.isSelected() && adder.isFixedValue()) {
						pointsLbl.setText("("
								+ ((Modifier) parent).getFraction(adder
										.getDoubleTotal()) + ")");
					} else if (adder.isFixedValue()) {
						pointsLbl.setText("("
								+ ((Modifier) parent).getFraction(adder
										.getDoubleTotal(false)) + ")");
					}
					// fix for Clips issue on Charges:
					Modifier mod = (Modifier) parent;
					if (mod.refreshAddersOnUpdate()) {
						mod.setSelectedOption(mod.getSelectedOption());
					}
				} else {
					if (adder.isFixedValue()) {
						pointsLbl
								.setText("("
										+ Rounder.roundUp(adder
												.getTotalCost(true))
										+ (Rounder.roundUp(adder
												.getTotalCost(true) - .5) != 1 ? " pts)"
												: " pt)"));
					}
				}
				for (ActionListener listener : listeners) {
					listener.actionPerformed(null);
				}
			}
		});
	}

	/**
	 * The Adder that this panel contains.
	 * 
	 * @return
	 */
	public Adder getAdder() {
		return adder;
	}

	/**
	 * Returns true if this AdderPanel or one of its children is unselected.
	 * 
	 * @return
	 */
	public boolean hasAvailable() {
		if (!isSelected() && isVisible()) {
			return true;
		}
		if (childPanel != null) {
			return childPanel.hasAvailable();
		}
		return false;
	}

	private boolean isChildSelected() {
		if (adder.isSelected()) {
			return true;
		}
		if (childPanel != null) {
			return childPanel.isChildSelected();
		} else {
			return false;
		}
	}

	/**
	 * Whether the checkbox is selected or not.
	 * 
	 * @return
	 */
	public boolean isSelected() {
		if (checkbox != null) {
			return checkbox.isSelected();
		} else {
			return false;
		}
	}

	private boolean parentIsAvailable() {
		AdderPanel check = parentPanel;
		while (check != null) {
			if (!check.isSelected()) {
				return true;
			}
			check = check.parentPanel;
		}
		return false;
	}

	private void removeFromParent() {
		adder.setSelected(checkbox != null ? checkbox.isSelected() : false);
		if (!adder.isSelected()) {
			if (adder.getAssignedAdders().size() == 0) {
				parent.getAssignedAdders().remove(adder);
			}
			if (parent instanceof Adder) { // not done until it's the
				// main object
				parentPanel.removeFromParent();
			}
		}
	}

	private void setChildVisibility(boolean visible) {
		if (childPanel == null) {
			if (visible && isSelected() && parent.canAdd(adder)) {
				addChild();
			}
			return;
		}
		if (!visible) {
			if (!childPanel.isSelected()) {
				childPanel.setVisible(false);
			}
			childPanel.setChildVisibility(false);
		} else {
			childPanel.setVisible(parent.canAdd(adder) && !parentIsAvailable());
			if (childPanel.isSelected()) {
				childPanel.setChildVisibility(visible);
			} else {
				childPanel.setChildVisibility(false);
			}
		}
	}

	/**
	 * Whether the Adder is enabled/selectable.
	 */
	@Override
	public void setEnabled(boolean enabled) {
		if (checkbox != null) {
			checkbox.setEnabled(enabled);
		}
		if (combo != null) {
			combo.setEnabled(enabled);
		}
		if (inputLbl != null) {
			inputLbl.setEnabled(enabled);
		}
		if (examples != null) {
			examples.setEnabled(enabled);
		}
		if (levelTF != null) {
			levelTF.setEnabled(enabled);
		}
		if (fractionTF != null) {
			fractionTF.setEnabled(enabled);
		}
		if (aliasTF != null) {
			aliasTF.setEnabled(enabled);
		}
		if (adderLbl != null) {
			adderLbl.setEnabled(enabled);
		}
		if ((adder.getDefinition() != null)
				&& (adder.getDefinition().trim().length() > 0)) {
			helpBtn.setEnabled(true);
		}
		if (adder.isFixedValue()) {
			pointsLbl.setEnabled(enabled);
		}
		if (childPanel != null) {
			childPanel.setEnabled(enabled);
		}
	}

	/**
	 * Sets whether the Adder is selected or not.
	 * 
	 * @param selected
	 */
	public void setSelected(boolean selected) {

		if (checkbox != null) {
			checkbox.setSelected(selected);
		}
		adder.setSelected(selected);
		if (selected) {
			addToParent();
		} else {
			removeFromParent();
		}
		if ((parent instanceof SenseAdder) || (parent instanceof Sense)) {
			Power.lastSenseEdit = System.currentTimeMillis();
		}
	}

	/**
	 * If the selection is locked, the user is unable to change the state of the
	 * checkbox.
	 * 
	 * @param val
	 */
	public void setSelectionLocked(boolean val) {
		selectionLocked = val;
	}

	/**
	 * Sets the visibility of this widget.
	 */
	@Override
	public void setVisible(boolean visible) {
		if (visible) {
			super.setVisible(visible);
		}
		if (isChildSelected()) {
			return;
		} else {
			super.setVisible(visible);
		}
	}

	/**
	 * Updates the values/costs for this Adder.
	 */
	public void updateValues() {
		if (aliasTF != null) {
			aliasTF.setText(adder.getAlias());
		}
		if ((parent instanceof Adder) && !selectionLocked) {
			Adder check = (Adder) parent;
			if (check.isSelected() && !isChild) {
				setEnabled(false);
				if (checkbox != null) {
					checkbox.removeActionListener(checkboxListener);
					checkbox.setSelected(true);
					checkbox.addActionListener(checkboxListener);
				}
			} else {
				setEnabled(true);
				if (checkbox != null) {
					checkbox.removeActionListener(checkboxListener);
					checkbox.setSelected(parent.getAssignedAdders().contains(
							adder)
							&& adder.isSelected());
					checkbox.addActionListener(checkboxListener);
				}
			}
		} else {
			if (checkbox != null) {
				checkbox.removeActionListener(checkboxListener);
				checkbox.setSelected(parent.getAssignedAdders().contains(adder)
						&& adder.isSelected());
				checkbox.addActionListener(checkboxListener);
			}
		}
		if (parent instanceof Modifier) {
			if (adder.isSelected() && adder.isFixedValue()) {
				pointsLbl.setText("("
						+ ((Modifier) parent).getFraction(adder
								.getDoubleTotal()) + ")");
			} else if (adder.isFixedValue()) {
				pointsLbl.setText("("
						+ ((Modifier) parent).getFraction(adder
								.getDoubleTotal(false)) + ")");
			}
		} else {
			if (adder.isFixedValue()) {
				pointsLbl
						.setText("("
								+ Rounder.roundUp(adder.getTotalCost(true))
								+ (Rounder.roundUp(adder.getTotalCost(true)) != 1 ? " pts)"
										: " pt)"));
			} else if ((valueTF != null)
					&& (valueTF.getCurrent() != adder.getBaseCost())) {
				valueTF.setCurrent((int) adder.getBaseCost());
				valueTF.setMax((int) adder.getMaxCost());
				valueTF.setMin((int) adder.getMinimumCost());
			}
		}

		if (childPanel != null) {
			childPanel.updateValues();
		}
	}
}