package charactermanaj.util;

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dialog;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.HeadlessException;
import java.awt.Window;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

import charactermanaj.ui.util.ScaleSupport;

/**
 * 例外を表示するダイアログ.<br>
 * ログにも記録される.<br>
 * @author seraphy
 */
public final class ErrorMessageHelper {

	/**
	 * ロガー
	 */
	private static final Logger logger = Logger.getLogger(ErrorMessageHelper.class.getName());


	private ErrorMessageHelper() {
		super();
	}

	/**
	 * 例外が発生したことを示すダイアログを表示し、ログに記録する.<br>
	 * @param parent ダイアログを表示する親、null可
	 * @param ex 例外、nullの場合はなにもせずに戻る.
	 */
	public static void showErrorDialog(Component parent, Throwable ex) {
		if (ex == null) {
			return;
		}

		// ログに記録する.
		logger.log(Level.SEVERE, ex.getLocalizedMessage(), ex);

		// 例外を表示するパネルの生成
		JTextArea textArea = new JTextArea();

		StringWriter sw = new StringWriter();
		PrintWriter pw = new PrintWriter(sw);
		ex.printStackTrace(pw); // 例外のコールスタックをパネルに表示できるように出力
		pw.close();

		textArea.setText(sw.toString());

		textArea.setSelectionStart(0);
		textArea.setSelectionEnd(0);
		textArea.setEditable(false);

		JScrollPane scr = new JScrollPane(textArea);
		scr.setPreferredSize(new Dimension(400, 150));
		scr.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
		scr.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

		// ダイアログの表示
		//JOptionPane.showMessageDialog(parent, scr, "ERROR", JOptionPane.ERROR_MESSAGE);

		// 以下、JOptionPaneの既定の処理を真似つつ、リサイズ可能なダイアログを作成する

		JOptionPane pane = new JOptionPane(scr, JOptionPane.ERROR_MESSAGE);

		Window window = getWindowForComponent(parent);

		final JDialog dialog;
		String title = "ERROR";
		if (window instanceof Frame) {
			dialog = new JDialog((Frame) window, title, true);
		} else {
			dialog = new JDialog((Dialog) window, title, true);
		}
		Container contentPane = dialog.getContentPane();

		// xボタンでダイアログを破棄する
		dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);

		contentPane.setLayout(new BorderLayout());
		contentPane.add(pane, BorderLayout.CENTER);
		dialog.setResizable(true);

		ScaleSupport scaleSupport = ScaleSupport.getInstance(dialog);
		Dimension wnddim = dialog.getPreferredSize();
		wnddim = scaleSupport.manualScaled(wnddim);
		dialog.setSize(wnddim);
		dialog.setLocationRelativeTo(parent);

        pane.addPropertyChangeListener(JOptionPane.VALUE_PROPERTY, new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent event) {
                if (dialog.isVisible() && event.getNewValue() != null) {
                	// ボタン押下等によりダイアログの結果が確定したらダイアログを破棄する
                    dialog.dispose();
                }
            }
        });

        dialog.setVisible(true);
	}

	static Window getWindowForComponent(Component parentComponent)
			throws HeadlessException {
		if (parentComponent == null)
			return JOptionPane.getRootFrame();
		if (parentComponent instanceof Frame || parentComponent instanceof Dialog)
			return (Window) parentComponent;
		return getWindowForComponent(parentComponent.getParent());
	}
}
