package com.hero.ui.dialog;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
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.MouseAdapter;
import java.awt.event.MouseEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;

import javax.swing.JButton;
import javax.swing.JEditorPane;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.SwingUtilities;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.filechooser.FileFilter;

import com.hero.HeroDesigner;
import com.hero.util.HTMLWriter;

/**
 * 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 ExportTemplateDialog extends JFileChooser {

	private class ExportListItem {
		String name;

		String description;

		String path;

		ExportListItem(String n, String d, String p) {
			name = n;
			if (n == null) {
				name = "[unknown]";
			}
			description = d;
			if (d == null) {
				description = "No description available.";
			}
			path = p;
		}

		public String getDescription() {
			return description;
		}

		public String getName() {
			return name;
		}

		public String getPath() {
			return path;
		}

		@Override
		public String toString() {
			return name + " (" +(new File(path)).getName()+")";
		}
	}

	private static final long serialVersionUID = -4653550701748791856L;

	JList availableList;

	JScrollPane availableScroll;

	JEditorPane descriptionTA;

	JScrollPane descriptionScroll;

	JLabel availableLbl;

	JLabel descriptionLbl;

	JButton selectBtn;

	JButton cancelBtn;

	String extension;

	boolean cancelButtonClicked;

	private File dir;

	public ExportTemplateDialog() {
		this(".HDE");
	}

	/**
	 * The extension to look for on valid files (default is ".HDE" but can also
	 * be ".HCR")
	 * 
	 * @param ex
	 */
	public ExportTemplateDialog(String ex) {
		super();
		extension = ex;
		initWidgets();
		initListeners();
		layoutComponent();
		setControlButtonsAreShown(false);
		setDialogTitle("Select Export Template");
		setMultiSelectionEnabled(false);
		setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		String sel = HeroDesigner.getInstance().getPrefs()
				.getExportTemplateDir();
		if (sel == null) {
			sel = "ExportTemplates";
		}
		File check = new File(sel);
		if (check.exists()) {
			setCurrentDirectory(check.getAbsoluteFile());
			setSelectedFile(check.getAbsoluteFile());
			try {
				setListItems();
			} catch (Exception exp) {

			}
		}

		FileFilter filter = new FileFilter() {
			@Override
			public boolean accept(File file) {
				if (file.isDirectory()) {
					try {
						// setListItems();
						return true;
					} catch (Exception exp) {
						return false;
					}
				} else {
					return false;
				}
			}

			@Override
			public String getDescription() {
				return "Export Template Directories";
			}
		};
		setFileFilter(filter);
		setMaximumSize(HeroDesigner.getAppFrame().getSize());
		if (availableList.getSelectedValue() == null) {
			if (availableList.getModel().getSize() > 0) {
				descriptionTA.setText("Please select a template...");
			} else {
				descriptionTA
						.setText("Please select a directory which contains Export Templates ("
								+ extension + " files)");
			}
		}
	}

	/**
	 * True if the user clicked the cancel button or the "X"
	 * 
	 * @return
	 */
	public boolean canceled() {
		return cancelButtonClicked;
	}

	/**
	 * Returns the absolute path to the selected template. May be null.
	 * 
	 * @return
	 */
	public String getSelectedPath() {
		if (cancelButtonClicked || (availableList.getSelectedValue() == null)) {
			return null;
		} else {
			ExportListItem item = (ExportListItem) availableList
					.getSelectedValue();
			return item.getPath();
		}
	}

	private void initListeners() {
		addPropertyChangeListener(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY,
				new PropertyChangeListener() {
					public void propertyChange(PropertyChangeEvent e) {
						try {
							setListItems();
							if (availableList.getSelectedValue() == null) {
								if (availableList.getModel().getSize() > 0) {
									descriptionTA
											.setText("Please select a template...");
								} else {
									descriptionTA
											.setText("Please select a directory which contains Export Templates ("
													+ extension + " files)");
								}
							}
						} catch (Exception exp) {

						}
					}
				});
		cancelBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				cancelButtonClicked = true;
				cancelSelection();
			}
		});
		selectBtn.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				cancelButtonClicked = false;
				approveSelection();
			}
		});
		availableList.addListSelectionListener(new ListSelectionListener() {
			public void valueChanged(ListSelectionEvent e) {
				if (availableList.getSelectedValue() != null) {
					ExportListItem item = (ExportListItem) availableList
							.getSelectedValue();
					descriptionTA.setText(item.getDescription());
					SwingUtilities.invokeLater(new Runnable() {
						public void run() {
							try {
								Thread.sleep(500);
							} catch (InterruptedException e) {
							}
							descriptionScroll.getVerticalScrollBar()
									.setValue(0);
							selectBtn.setEnabled(true);
						}
					});
				} else {
					if (availableList.getModel().getSize() > 0) {
						descriptionTA.setText("Please select a template...");
					} else {
						descriptionTA
								.setText("Please select a directory which contains Export Templates ("
										+ extension + " files)");
					}
					selectBtn.setEnabled(false);
				}
			}
		});
		availableList.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if (e.getClickCount() == 2) {
					selectBtn.doClick();
				}
			}
		});
	}

	private void initWidgets() {
		availableList = new JList();
		availableList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
		availableScroll = new JScrollPane(availableList);
		availableScroll.setPreferredSize(new Dimension(400, 200));
		descriptionTA = new JEditorPane();
		descriptionTA.setContentType("text/html");
		descriptionTA.setEditable(false);
		descriptionTA.setBackground(Color.white);
		descriptionScroll = new JScrollPane(descriptionTA);
		descriptionScroll.setPreferredSize(new Dimension(400, 200));
		availableLbl = new JLabel("Available:");
		descriptionLbl = new JLabel("Description:");
		selectBtn = new JButton("Select");
		selectBtn.setEnabled(false);
		cancelBtn = new JButton("Cancel");
	}

	private void layoutComponent() {
		JPanel panel = new JPanel(new GridBagLayout());
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.gridx = 0;
		gbc.gridy = 0;
		gbc.gridwidth = 1;
		gbc.gridheight = 1;
		gbc.insets = new Insets(5, 5, 2, 10);
		gbc.fill = GridBagConstraints.NONE;
		gbc.anchor = GridBagConstraints.SOUTHWEST;
		gbc.weightx = 0;
		gbc.weighty = 0;
		panel.add(availableLbl, gbc);
		gbc.gridy = 2;
		gbc.weighty = 0;
		gbc.weightx = 0;
		panel.add(descriptionLbl, gbc);
		gbc.gridy = 1;
		gbc.fill = GridBagConstraints.BOTH;
		gbc.weighty = 1;
		gbc.weightx = 1;
		gbc.insets = new Insets(2, 10, 5, 5);
		panel.add(availableScroll, gbc);
		gbc.gridy = 3;
		panel.add(descriptionScroll, gbc);
		gbc.gridy = 4;
		gbc.gridwidth = GridBagConstraints.REMAINDER;
		gbc.anchor = GridBagConstraints.CENTER;
		gbc.weighty = 0;
		gbc.weightx = 0;
		JPanel buttons = new JPanel(new FlowLayout(FlowLayout.CENTER));
		buttons.add(selectBtn);
		buttons.add(cancelBtn);
		panel.add(buttons, gbc);
		setAccessory(panel);
	}

	private void setListItems() throws Exception {
		ArrayList<ExportListItem> vec = new ArrayList<ExportListItem>();
		File check = getSelectedFile();
		if ((dir != null) && (check != null)
				&& check.getAbsolutePath().equals(dir.getAbsolutePath())) {
			return;
		}
		dir = check;
		if (dir == null) {
			availableList
					.setListData(new ArrayList<ExportListItem>().toArray());
			return;
		}
		if (!dir.isDirectory()) {
			dir = dir.getAbsoluteFile().getParentFile();
		}
		File[] templates = dir.listFiles(new java.io.FileFilter() {
			public boolean accept(File path) {
				if (path.getName().toUpperCase().endsWith(extension)) {
					return true;
				} else {
					return false;
				}
			}
		});
		if (templates == null) {
			availableList.setListData(new ArrayList().toArray());
			return;
		}
		for (int i = 0; i < templates.length; i++) {
			HTMLWriter writer = new HTMLWriter(templates[i]);
			ExportListItem item = new ExportListItem(writer.getName(), writer
					.getDescription(), templates[i].getAbsolutePath());
			vec.add(item);
		}
		Collections.sort(vec, new Comparator() {
			public int compare(Object o1, Object o2) {
				return o1.toString().compareTo(o2.toString());
			}
		});
		availableList.setListData(vec.toArray());
		return;
	}
}