package com.hero.ui;

import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.math.BigDecimal;

import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

import com.hero.HeroDesigner;
import com.hero.Template;
import com.hero.ui.widgets.LevelTF;
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 BackgroundPanel extends JPanel {
	private static final long serialVersionUID = 2894271058119575929L;

	private JLabel backgroundLbl;

	private JScrollPane backgroundScroll;

	JTextArea backgroundTA;

	private JLabel campaignUseLbl;

	private JScrollPane campaignUseScroll;

	JTextArea campaignUseTA;

	private JLabel descriptionLbl;

	private JScrollPane descriptionScroll;

	JTextArea descriptionTA;

	private JLabel eyeColorLbl;

	JTextField eyeColorTF;

	private JLabel hairColorLbl;

	JTextField hairColorTF;

	private JLabel heightLbl;

	LevelTF heightTF;

	private JLabel heightValueLbl;

	private JLabel personalityLbl;

	private JScrollPane personalityScroll;

	JTextArea personalityTA;

	private JLabel quoteLbl;

	private JScrollPane quoteScroll;

	JTextArea quoteTA;

	private JLabel tacticsLbl;

	private JScrollPane tacticsScroll;

	JTextArea tacticsTA;

	private JLabel weightLbl;

	LevelTF weightTF;

	private JLabel weightValueLbl;

	public BackgroundPanel() {
		super(new GridBagLayout());
		initWidgets();
		initListeners();
		layoutComponent();
	}

	private void initListeners() {
		heightTF.addPropertyChangeListener("Level",
				new PropertyChangeListener() {
					public void propertyChange(PropertyChangeEvent e) {
						HeroDesigner.getActiveHero().setHeight(
								heightTF.getCurrent());
						updateValues();
					}
				});
		weightTF.addPropertyChangeListener("Level",
				new PropertyChangeListener() {
					public void propertyChange(PropertyChangeEvent e) {
						HeroDesigner.getActiveHero().setWeight(
								weightTF.getCurrent());
						updateValues();
					}
				});
		eyeColorTF.getDocument().addDocumentListener(new DocumentListener() {
			public void changedUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setEyeColor(eyeColorTF.getText());
			}

			public void insertUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setEyeColor(eyeColorTF.getText());
			}

			public void removeUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setEyeColor(eyeColorTF.getText());
			}
		});
		hairColorTF.getDocument().addDocumentListener(new DocumentListener() {
			public void changedUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero()
						.setHairColor(hairColorTF.getText());
			}

			public void insertUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero()
						.setHairColor(hairColorTF.getText());
			}

			public void removeUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero()
						.setHairColor(hairColorTF.getText());
			}
		});
		descriptionTA.getDocument().addDocumentListener(new DocumentListener() {
			public void changedUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setAppearance(
						descriptionTA.getText());
			}

			public void insertUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setAppearance(
						descriptionTA.getText());
			}

			public void removeUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setAppearance(
						descriptionTA.getText());
			}
		});
		backgroundTA.getDocument().addDocumentListener(new DocumentListener() {
			public void changedUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setBackground(
						backgroundTA.getText());
			}

			public void insertUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setBackground(
						backgroundTA.getText());
			}

			public void removeUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setBackground(
						backgroundTA.getText());
			}
		});
		personalityTA.getDocument().addDocumentListener(new DocumentListener() {
			public void changedUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setPersonality(
						personalityTA.getText());
			}

			public void insertUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setPersonality(
						personalityTA.getText());
			}

			public void removeUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setPersonality(
						personalityTA.getText());
			}
		});
		quoteTA.getDocument().addDocumentListener(new DocumentListener() {
			public void changedUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setQuote(quoteTA.getText());
			}

			public void insertUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setQuote(quoteTA.getText());
			}

			public void removeUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setQuote(quoteTA.getText());
			}
		});
		tacticsTA.getDocument().addDocumentListener(new DocumentListener() {
			public void changedUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setTactics(tacticsTA.getText());
			}

			public void insertUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setTactics(tacticsTA.getText());
			}

			public void removeUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setTactics(tacticsTA.getText());
			}
		});
		campaignUseTA.getDocument().addDocumentListener(new DocumentListener() {
			public void changedUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setCampaignUse(
						campaignUseTA.getText());
			}

			public void insertUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setCampaignUse(
						campaignUseTA.getText());
			}

			public void removeUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setCampaignUse(
						campaignUseTA.getText());
			}
		});
	}

	private void initWidgets() {
		heightLbl = new JLabel("Height (in.):");
		if (HeroDesigner.getInstance().getPrefs().isMetric()) {
			heightLbl.setText("Height (cm):");
		}
		heightValueLbl = new JLabel("");
		weightLbl = new JLabel("Weight (lbs.):");
		if (HeroDesigner.getInstance().getPrefs().isMetric()) {
			weightLbl.setText("Weight (kg):");
		}
		weightValueLbl = new JLabel("");
		eyeColorLbl = new JLabel("");
		hairColorLbl = new JLabel("");
		descriptionLbl = new JLabel("");
		backgroundLbl = new JLabel("");
		personalityLbl = new JLabel("");
		quoteLbl = new JLabel("");
		tacticsLbl = new JLabel("");
		campaignUseLbl = new JLabel("");

		heightTF = new LevelTF(0, 999999, 1);
		weightTF = new LevelTF(0, 999999, 1);
		eyeColorTF = new JTextField("", 20);
		hairColorTF = new JTextField("", 20);
		descriptionTA = new JTextArea("", 5, 40);
		descriptionTA.setLineWrap(true);
		descriptionTA.setWrapStyleWord(true);
		descriptionTA.setTabSize(3);
		descriptionScroll = new JScrollPane(descriptionTA);
		backgroundTA = new JTextArea("", 5, 40);
		backgroundTA.setLineWrap(true);
		backgroundTA.setWrapStyleWord(true);
		backgroundTA.setTabSize(3);
		backgroundScroll = new JScrollPane(backgroundTA);
		personalityTA = new JTextArea("", 5, 40);
		personalityTA.setLineWrap(true);
		personalityTA.setWrapStyleWord(true);
		personalityTA.setTabSize(3);
		personalityScroll = new JScrollPane(personalityTA);
		quoteTA = new JTextArea("", 2, 40);
		quoteTA.setLineWrap(true);
		quoteTA.setWrapStyleWord(true);
		quoteTA.setTabSize(3);
		quoteScroll = new JScrollPane(quoteTA);
		tacticsTA = new JTextArea("", 5, 40);
		tacticsTA.setLineWrap(true);
		tacticsTA.setWrapStyleWord(true);
		tacticsTA.setTabSize(3);
		tacticsScroll = new JScrollPane(tacticsTA);
		campaignUseTA = new JTextArea("", 5, 40);
		campaignUseTA.setLineWrap(true);
		campaignUseTA.setWrapStyleWord(true);
		campaignUseTA.setTabSize(3);
		campaignUseScroll = new JScrollPane(campaignUseTA);
		reset();
	}

	private void layoutComponent() {
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 0;
		gbc.gridwidth = 1;
		gbc.gridheight = 1;
		gbc.weightx = 0;
		gbc.weighty = 0;
		gbc.anchor = GridBagConstraints.EAST;
		gbc.fill = GridBagConstraints.NONE;
		gbc.insets = new Insets(5, 5, 5, 5);
		add(heightLbl, gbc);
		gbc.gridx = 2;
		add(weightLbl, gbc);
		gbc.gridy = 1;
		add(hairColorLbl, gbc);
		gbc.gridx = 0;
		add(eyeColorLbl, gbc);
		gbc.gridy = 2;
		gbc.insets = new Insets(0, 5, 5, 5);
		gbc.anchor = GridBagConstraints.NORTHEAST;
		add(backgroundLbl, gbc);
		gbc.gridy = 4;
		add(personalityLbl, gbc);
		gbc.gridy = 6;
		add(quoteLbl, gbc);
		gbc.gridy = 8;
		add(tacticsLbl, gbc);
		gbc.gridy = 10;
		add(campaignUseLbl, gbc);
		gbc.gridy = 12;
		add(descriptionLbl, gbc);
		gbc.gridy = 0;
		gbc.gridx = 1;
		gbc.weightx = 1;
		gbc.insets = new Insets(5, 0, 5, 5);
		gbc.fill = GridBagConstraints.NONE;
		gbc.anchor = GridBagConstraints.WEST;
		JPanel height = new JPanel(new FlowLayout(FlowLayout.LEFT));
		height.add(heightTF);
		height.add(heightValueLbl);
		add(height, gbc);
		gbc.gridx = 3;
		JPanel weight = new JPanel(new FlowLayout(FlowLayout.LEFT));
		weight.add(weightTF);
		weight.add(weightValueLbl);
		add(weight, gbc);
		gbc.gridy = 1;
		add(hairColorTF, gbc);
		gbc.gridx = 1;
		add(eyeColorTF, gbc);
		gbc.gridy = 2;
		gbc.gridx = 1;
		gbc.weighty = 1;
		gbc.fill = GridBagConstraints.BOTH;
		gbc.insets = new Insets(0, 5, 5, 5);
		gbc.gridwidth = GridBagConstraints.REMAINDER;
		add(backgroundScroll, gbc);
		gbc.gridy = 4;
		add(personalityScroll, gbc);
		gbc.gridy = 6;
		add(quoteScroll, gbc);
		gbc.gridy = 8;
		add(tacticsScroll, gbc);
		gbc.gridy = 10;
		add(campaignUseScroll, gbc);
		gbc.gridy = 12;
		add(descriptionScroll, gbc);
	}

	/**
	 * Resets this panel's values....this should be called when the active
	 * character or template is changed.
	 */
	public void reset() {
		Template t = HeroDesigner.getActiveTemplate();
		if (HeroDesigner.getInstance().getPrefs().isMetric()) {
			heightLbl.setText("Height (cm):");
		} else {
			heightLbl.setText("Height (in.):");
		}
		heightTF.setCurrent(HeroDesigner.getActiveHero().getHeight());
		if (!HeroDesigner.getActiveTemplate().isHeightAllowed()) {
			heightLbl.setVisible(false);
			heightValueLbl.setVisible(false);
			heightTF.setVisible(false);
		} else {
			heightLbl.setVisible(true);
			heightValueLbl.setVisible(true);
			heightTF.setVisible(true);
		}

		if (HeroDesigner.getInstance().getPrefs().isMetric()) {
			weightLbl.setText("Weight (kg):");
		} else {
			weightLbl.setText("Weight (lbs.):");
		}
		weightTF.setCurrent(HeroDesigner.getActiveHero().getWeight());
		if (!HeroDesigner.getActiveTemplate().isWeightAllowed()) {
			weightLbl.setVisible(false);
			weightValueLbl.setVisible(false);
			weightTF.setVisible(false);
		} else {
			weightLbl.setVisible(true);
			weightValueLbl.setVisible(true);
			weightTF.setVisible(true);
		}

		if ((t.getEyeColorLabel() != null)
				&& HeroDesigner.getActiveTemplate().isEyeColorAllowed()) {
			eyeColorLbl.setText(t.getEyeColorLabel() + ":");
			eyeColorLbl.setVisible(true);
			eyeColorTF.setText(HeroDesigner.getActiveHero().getEyeColor());
			eyeColorTF.setVisible(true);
		} else {
			eyeColorLbl.setVisible(false);
			eyeColorTF.setVisible(false);
		}

		if ((t.getHairColorLabel() != null)
				&& HeroDesigner.getActiveTemplate().isHairColorAllowed()) {
			hairColorLbl.setText(t.getHairColorLabel() + ":");
			hairColorLbl.setVisible(true);
			hairColorTF.setText(HeroDesigner.getActiveHero().getHairColor());
			hairColorTF.setVisible(true);
		} else {
			hairColorLbl.setVisible(false);
			hairColorTF.setVisible(false);
		}

		if ((t.getAppearanceLabel() != null)
				&& (t.getAppearanceLabel().trim().length() > 0)) {
			descriptionLbl.setText(t.getAppearanceLabel() + ":");
			descriptionLbl.setVisible(true);
			descriptionTA.setText(HeroDesigner.getActiveHero().getAppearance());
			descriptionScroll.setVisible(true);
		} else {
			descriptionLbl.setVisible(false);
			descriptionScroll.setVisible(false);
		}
		if ((t.getBackgroundLabel() != null)
				&& (t.getBackgroundLabel().trim().length() > 0)) {
			backgroundLbl.setText(t.getBackgroundLabel() + ":");
			backgroundLbl.setVisible(true);
			backgroundTA.setText(HeroDesigner.getActiveHero().getBackground());
			backgroundScroll.setVisible(true);
		} else {
			backgroundLbl.setVisible(false);
			backgroundScroll.setVisible(false);
		}
		if ((t.getPersonalityLabel() != null)
				&& (t.getPersonalityLabel().trim().length() > 0)) {
			personalityLbl.setText(t.getPersonalityLabel() + ":");
			personalityLbl.setVisible(true);
			personalityTA
					.setText(HeroDesigner.getActiveHero().getPersonality());
			personalityScroll.setVisible(true);
		} else {
			personalityLbl.setVisible(false);
			personalityScroll.setVisible(false);
		}
		if ((t.getQuoteLabel() != null)
				&& (t.getQuoteLabel().trim().length() > 0)) {
			quoteLbl.setText(t.getQuoteLabel() + ":");
			quoteLbl.setVisible(true);
			quoteTA.setText(HeroDesigner.getActiveHero().getQuote());
			quoteScroll.setVisible(true);
		} else {
			quoteLbl.setVisible(false);
			quoteScroll.setVisible(false);
		}
		if ((t.getTacticsLabel() != null)
				&& (t.getTacticsLabel().trim().length() > 0)) {
			tacticsLbl.setText(t.getTacticsLabel() + ":");
			tacticsLbl.setVisible(true);
			tacticsTA.setText(HeroDesigner.getActiveHero().getTactics());
			tacticsScroll.setVisible(true);
		} else {
			tacticsLbl.setVisible(false);
			tacticsScroll.setVisible(false);
		}
		if ((t.getCampaignUseLabel() != null)
				&& (t.getCampaignUseLabel().trim().length() > 0)) {
			campaignUseLbl.setText(t.getCampaignUseLabel() + ":");
			campaignUseLbl.setVisible(true);
			campaignUseTA
					.setText(HeroDesigner.getActiveHero().getCampaignUse());
			campaignUseScroll.setVisible(true);
		} else {
			campaignUseLbl.setVisible(false);
			campaignUseScroll.setVisible(false);
		}
		updateValues();
	}

	/**
	 * Updates the values for the alternate Height/Weight labels.
	 */
	private void updateValues() {
		double in = HeroDesigner.getActiveHero().getHeight();
		double lbs = HeroDesigner.getActiveHero().getWeight();
		double cm = in * 2.54;
		double g = lbs * 453.5924;

		if (HeroDesigner.getInstance().getPrefs().isMetric()) {
			cm = HeroDesigner.getActiveHero().getHeight();
			g = HeroDesigner.getActiveHero().getWeight() * 1000;
			in = cm / 2.54;
			lbs = g / 453.5924;
		}

		int feet = (int) Rounder.roundHalfUp(in) / 12;
		int inches = (int) Rounder.roundHalfUp(in) % 12;

		BigDecimal hght = new BigDecimal(cm / 100d);
		hght = hght.setScale(2, BigDecimal.ROUND_HALF_UP);
		BigDecimal wght = new BigDecimal(g / 1000d);
		if (HeroDesigner.getInstance().getPrefs().isMetric()) {
			wght = new BigDecimal(lbs);
		}
		wght = wght.setScale(2, BigDecimal.ROUND_HALF_UP);
		String height = feet + "' " + inches + "\" (" + hght.toString() + " m)";
		String weight = "(" + wght.toString() + " kg)";
		if (HeroDesigner.getInstance().getPrefs().isMetric()) {
			height = hght.toString() + " m (" + feet + "' " + inches + "\")";
			weight = "(" + wght.toString() + " lbs)";
		}
		heightValueLbl.setText(height);
		weightValueLbl.setText(weight);
	}
}