package com.hero.ui;

import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

import com.hero.HeroDesigner;
import com.hero.Template;

/**
 * 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 CharacterInformationPanel extends JPanel {
	private static final long serialVersionUID = 2443386885639126811L;

	private JLabel alternateIdentitiesLbl;

	JTextField alternateIdentitiesTF;

	private JLabel campaignNameLbl;

	JTextField campaignNameTF;

	ImageIcon characterImage;

	JButton characterImageBtn;

	private JLabel characterImageLbl;

	private JLabel characterNameLbl;

	JTextField characterNameTF;

	JButton clearImageBtn;

	private JLabel genreLbl;

	JTextField genreTF;

	private JLabel gmLbl;

	JTextField gmTF;

	private JLabel playerNameLbl;

	JTextField playerNameTF;

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

	private void initListeners() {
		characterNameTF.getDocument().addDocumentListener(
				new DocumentListener() {
					public void changedUpdate(DocumentEvent e) {
						HeroDesigner.getActiveHero().setCharacterName(
								characterNameTF.getText());
					}

					public void insertUpdate(DocumentEvent e) {
						HeroDesigner.getActiveHero().setCharacterName(
								characterNameTF.getText());
					}

					public void removeUpdate(DocumentEvent e) {
						HeroDesigner.getActiveHero().setCharacterName(
								characterNameTF.getText());
					}
				});
		alternateIdentitiesTF.getDocument().addDocumentListener(
				new DocumentListener() {
					public void changedUpdate(DocumentEvent e) {
						HeroDesigner.getActiveHero().setAlternateIdentities(
								alternateIdentitiesTF.getText());
					}

					public void insertUpdate(DocumentEvent e) {
						HeroDesigner.getActiveHero().setAlternateIdentities(
								alternateIdentitiesTF.getText());
					}

					public void removeUpdate(DocumentEvent e) {
						HeroDesigner.getActiveHero().setAlternateIdentities(
								alternateIdentitiesTF.getText());
					}
				});
		playerNameTF.getDocument().addDocumentListener(new DocumentListener() {
			public void changedUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setPlayerName(
						playerNameTF.getText());
			}

			public void insertUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setPlayerName(
						playerNameTF.getText());
			}

			public void removeUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setPlayerName(
						playerNameTF.getText());
			}
		});
		campaignNameTF.getDocument().addDocumentListener(
				new DocumentListener() {
					public void changedUpdate(DocumentEvent e) {
						HeroDesigner.getActiveHero().setCampaignName(
								campaignNameTF.getText());
					}

					public void insertUpdate(DocumentEvent e) {
						HeroDesigner.getActiveHero().setCampaignName(
								campaignNameTF.getText());
					}

					public void removeUpdate(DocumentEvent e) {
						HeroDesigner.getActiveHero().setCampaignName(
								campaignNameTF.getText());
					}
				});
		genreTF.getDocument().addDocumentListener(new DocumentListener() {
			public void changedUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setGenre(genreTF.getText());
			}

			public void insertUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setGenre(genreTF.getText());
			}

			public void removeUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setGenre(genreTF.getText());
			}
		});
		gmTF.getDocument().addDocumentListener(new DocumentListener() {
			public void changedUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setGm(gmTF.getText());
			}

			public void insertUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setGm(gmTF.getText());
			}

			public void removeUpdate(DocumentEvent e) {
				HeroDesigner.getActiveHero().setGm(gmTF.getText());
			}
		});
		characterImageBtn.addActionListener(new ActionListener() {
			private JFileChooser chooser;

			public void actionPerformed(ActionEvent e) {
				if (chooser == null) {
					chooser = new JFileChooser();
					chooser
							.setFileFilter(new javax.swing.filechooser.FileFilter() {
								@Override
								public boolean accept(File file) {
									if (file.isDirectory()) {
										return true;
									}
									if (file.getName().toUpperCase().endsWith(
											".JPG")
											|| file.getName().toUpperCase()
													.endsWith(".GIF")
											|| file.getName().toUpperCase()
													.endsWith(".PNG")) {
										return true;
									} else {
										return false;
									}
								}

								@Override
								public String getDescription() {
									return "Images only";
								}
							});
					chooser.setApproveButtonText("Set Image");
					chooser.setDialogTitle("Choose Character Image");
					chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
					chooser.setMultiSelectionEnabled(false);
					chooser.setAcceptAllFileFilterUsed(false);
				}
				String dir = HeroDesigner.getInstance().getPrefs()
						.getImageDir();
				if ((dir != null) && (dir.trim().length() > 0)) {
					chooser.setCurrentDirectory(new File(dir));
				}
				int ret = chooser.showOpenDialog(characterImageBtn);
				if (ret == JFileChooser.APPROVE_OPTION) {
					File imageFile = chooser.getSelectedFile();
					if (imageFile != null) {
						try {
							byte[] imageData = new byte[(int) imageFile
									.length()];
							FileInputStream fis = new FileInputStream(imageFile);
							fis.read(imageData);
							fis.close();
							HeroDesigner.getActiveHero().setImageData(
									imageData, imageFile);
							HeroDesigner.getInstance().getPrefs().setImageDir(
									imageFile.getParent());
							ImageIcon icon = new ImageIcon(imageFile
									.getAbsolutePath());
							characterImageBtn.setIcon(icon);
							characterImageBtn.setText(null);

							characterImageBtn.setBorderPainted(false);
							characterImageBtn.setFocusPainted(false);
							characterImageBtn.setMargin(new Insets(0, 0, 0, 0));
							clearImageBtn.setVisible(true);
						} catch (FileNotFoundException exp) {
							exp.printStackTrace();
						} catch (IOException exp) {
							exp.printStackTrace();
						}
					} else {
						HeroDesigner.getActiveHero().setImageData(new byte[0],
								null);
						characterImageBtn.setIcon(null);
						characterImageBtn.setText("Click to assign");
						clearImageBtn.setVisible(false);
					}
				}
			}
		});
		clearImageBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				int ret = JOptionPane.showConfirmDialog(
						CharacterInformationPanel.this,
						"Are you sure you want to clear the image?",
						"Are you sure?", JOptionPane.YES_NO_OPTION);
				if (ret == JOptionPane.YES_OPTION) {
					HeroDesigner.getActiveHero()
							.setImageData(new byte[0], null);
					characterImageBtn.setIcon(null);
					characterImageBtn.setText("Click to assign");
					clearImageBtn.setVisible(false);
				}
			}
		});
	}

	private void initWidgets() {
		characterNameLbl = new JLabel();
		alternateIdentitiesLbl = new JLabel();
		playerNameLbl = new JLabel();
		campaignNameLbl = new JLabel();
		genreLbl = new JLabel();
		gmLbl = new JLabel();
		characterImageLbl = new JLabel("Image:");
		if ((HeroDesigner.getActiveHero().getImageData() != null)
				&& (HeroDesigner.getActiveHero().getImageData().length > 0)) {
			characterImage = new ImageIcon(HeroDesigner.getActiveHero()
					.getImageData());
		} else {
			characterImage = new ImageIcon();
		}
		characterImageBtn = new JButton(characterImage);
		clearImageBtn = new JButton("Clear Image...");
		characterNameTF = new JTextField("", 30);
		alternateIdentitiesTF = new JTextField("", 30);
		playerNameTF = new JTextField("", 30);
		campaignNameTF = new JTextField("", 30);
		genreTF = new JTextField("", 30);
		gmTF = new JTextField("", 30);

		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(characterNameLbl, gbc);
		gbc.gridy = 1;
		add(alternateIdentitiesLbl, gbc);
		gbc.gridy = 2;
		add(campaignNameLbl, gbc);
		gbc.gridy = 3;
		add(genreLbl, gbc);
		gbc.gridy = 4;
		add(playerNameLbl, gbc);
		gbc.gridy = 5;
		gbc.weighty = 0;
		gbc.anchor = GridBagConstraints.EAST;
		add(gmLbl, gbc);
		gbc.gridy = 0;
		gbc.gridx = 1;
		gbc.weighty = 0;
		gbc.weightx = 1;
		gbc.fill = GridBagConstraints.NONE;
		gbc.anchor = GridBagConstraints.WEST;
		add(characterNameTF, gbc);
		gbc.gridy = 1;
		add(alternateIdentitiesTF, gbc);
		gbc.gridy = 2;
		add(campaignNameTF, gbc);
		gbc.gridy = 3;
		add(genreTF, gbc);
		gbc.gridy = 4;
		add(playerNameTF, gbc);
		gbc.gridy = 5;
		gbc.weighty = 0;
		gbc.anchor = GridBagConstraints.WEST;
		add(gmTF, gbc);
		gbc.gridy = 6;
		gbc.gridx = 0;
		gbc.weightx = 0;
		gbc.weighty = 1;
		gbc.fill = GridBagConstraints.NONE;
		gbc.anchor = GridBagConstraints.NORTHEAST;
		add(characterImageLbl, gbc);
		gbc.gridx = 1;
		gbc.gridwidth = GridBagConstraints.REMAINDER;
		gbc.fill = GridBagConstraints.NONE;
		gbc.anchor = GridBagConstraints.NORTHWEST;
		add(characterImageBtn, gbc);
		gbc.gridy++;
		gbc.anchor = GridBagConstraints.NORTHWEST;
		add(clearImageBtn, gbc);
		if (!HeroDesigner.getActiveHero().isPrefab()) {
			setBorder(BorderFactory.createTitledBorder("Character Information"));
		} else {
			setBorder(BorderFactory.createTitledBorder("Prefab Information"));
		}
		gbc.weighty = 1;
		gbc.gridx = 0;
		gbc.gridwidth = GridBagConstraints.REMAINDER;
		gbc.fill = GridBagConstraints.BOTH;
		gbc.gridy++;
		add(new JPanel(), gbc);
	}

	/**
	 * Resets the values and displayed fields on this panel based on the
	 * currently active character and template.
	 */
	public void reset() {
		Template t = HeroDesigner.getActiveTemplate();
		boolean prefab = HeroDesigner.getActiveHero().isPrefab();
		if (HeroDesigner.getActiveHero().isPrefab()) {
			characterNameLbl.setText("Prefab Name:");
			characterNameTF.setText(HeroDesigner.getActiveHero()
					.getCharacterName());
			characterNameLbl.setVisible(true);
			characterNameTF.setVisible(true);
		} else if (t.getCharacterNameLabel() != null) {
			characterNameLbl.setText(t.getCharacterNameLabel() + ":");
			characterNameLbl.setVisible(true);
			characterNameTF.setText(HeroDesigner.getActiveHero()
					.getCharacterName());
			characterNameTF.setVisible(true);
		} else {
			characterNameLbl.setVisible(false);
			characterNameTF.setVisible(false);
		}
		if ((t.getAlternateIDsLabel() != null) && !prefab) {
			alternateIdentitiesLbl.setText(t.getAlternateIDsLabel() + ":");
			alternateIdentitiesLbl.setVisible(true);
			alternateIdentitiesTF.setText(HeroDesigner.getActiveHero()
					.getAlternateIdentities());
			alternateIdentitiesTF.setVisible(true);
		} else {
			alternateIdentitiesLbl.setVisible(false);
			alternateIdentitiesTF.setVisible(false);
		}
		if (HeroDesigner.getActiveHero().isPrefab()) {
			playerNameLbl.setText("Created By:");
			playerNameLbl.setVisible(true);
			playerNameTF.setText(HeroDesigner.getActiveHero().getPlayerName());
			playerNameTF.setVisible(true);
		} else if (t.getPlayerNameLabel() != null) {
			playerNameLbl.setText(t.getPlayerNameLabel() + ":");
			playerNameLbl.setVisible(true);
			playerNameTF.setText(HeroDesigner.getActiveHero().getPlayerName());
			playerNameTF.setVisible(true);
		} else {
			playerNameLbl.setVisible(false);
			playerNameTF.setVisible(false);
		}
		if ((t.getCampaignNameLabel() != null) && !prefab) {
			campaignNameLbl.setText(t.getCampaignNameLabel() + ":");
			campaignNameLbl.setVisible(true);
			campaignNameTF.setText(HeroDesigner.getActiveHero()
					.getCampaignName());
			campaignNameTF.setVisible(true);
		} else {
			campaignNameLbl.setVisible(false);
			campaignNameTF.setVisible(false);
		}
		if ((t.getGenreLabel() != null) && !prefab) {
			genreLbl.setText(t.getGenreLabel() + ":");
			genreLbl.setVisible(true);
			genreTF.setText(HeroDesigner.getActiveHero().getGenre());
			genreTF.setVisible(true);
		} else {
			genreLbl.setVisible(false);
			genreTF.setVisible(false);
		}
		if ((t.getGmLabel() != null) && !prefab) {
			gmLbl.setText(t.getGmLabel() + ":");
			gmLbl.setVisible(true);
			gmTF.setText(HeroDesigner.getActiveHero().getGm());
			gmTF.setVisible(true);
		} else {
			gmLbl.setVisible(false);
			gmTF.setVisible(false);
		}
		if (!prefab) {
			characterImageBtn.setVisible(true);
			characterImageLbl.setVisible(true);
			if ((HeroDesigner.getActiveHero().getImageData() == null)
					|| (HeroDesigner.getActiveHero().getImageData().length == 0)) {
				characterImageBtn.setText("Click to assign");
				characterImageBtn.setIcon(null);
				clearImageBtn.setVisible(false);
			} else {
				ImageIcon icon = new ImageIcon(HeroDesigner.getActiveHero()
						.getImageData());
				characterImageBtn.setIcon(icon);
				characterImageBtn.setText(null);
				characterImageBtn.setBorderPainted(false);
				characterImageBtn.setFocusPainted(false);
				characterImageBtn.setMargin(new Insets(0, 0, 0, 0));
				clearImageBtn.setVisible(true);
			}
		} else {
			characterImageBtn.setVisible(false);
			characterImageLbl.setVisible(false);
			clearImageBtn.setVisible(false);
		}

		if (!HeroDesigner.getActiveHero().isPrefab()) {
			setBorder(BorderFactory.createTitledBorder("Character Information"));
		} else {
			setBorder(BorderFactory.createTitledBorder("Prefab Information"));
		}
	}
}