/** **********************************************************************
 *
 * Copyright 2024, 2025 Alexander Adam
 *
 * Use is subject to license terms.
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy
 * of the License at http://www.apache.org/licenses/LICENSE-2.0.
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *********************************************************************** */
package a.simpleMustangGui;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.FileDialog;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Vector;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JEditorPane;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.JViewport;
import javax.swing.UIManager;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.text.BadLocationException;

import org.apache.pdfbox.Loader;
import org.apache.pdfbox.io.RandomAccessReadBufferedFile;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.mustangproject.ZUGFeRD.ZUGFeRDImporter;
import org.mustangproject.validator.ZUGFeRDValidator;

/**
 * Stand alone Java Swing/AWT GUI
 *  for ZUGFeRD / mustangproject
 *  
 * @author Alexander Adam
 * 
 * History:
 * 1.0.0 
 * - Add QuickInfo for BIC, IBAN, etc.
 * - Add ZUGFeRDValidator
 * - Add LANG de (e.g. LANG=de_DE.UTF-8)
 * 1.0.1
 * - enhanced QuickInfo
 * - use FileDialog for Open
 */
public class SimpleMustangGui extends JPanel {
	private static final long serialVersionUID = 1L;
	private static final String lang = Locale.getDefault().getLanguage();
	private static final String lang_de = Locale.GERMAN.getLanguage();			
	private static final SimpleDateFormat sdf_issue_date = new SimpleDateFormat("yyyyMMdd");
	private static final SimpleDateFormat sdf_issue_date_de = new SimpleDateFormat("dd.MM.yyyy");

	// Variables
	private File currentFile = null;
	private File openDirectory = null;
	// private String filePrefix = null;

	// Components
	private JMenuBar menubar;
	private JToolBar toolbar;
	private JLabel status;
	private JButton pdfPreviewButton;
	private JTextField searchTextField;
	
	// Dialogs
	private JDialog helphelpDialog;
	
	// TextFields (Use JEditorPane since JTextArea has CRLF position bug)
	private JEditorPane textArea;

	// Menu Enabler(Disabler)
	private ComponentEnabler searchEnabler = new ComponentEnabler(false);
	private ComponentEnabler quickInfoEnabler = new ComponentEnabler(false);
	private ComponentEnabler validateEnabler = new ComponentEnabler(false);

	// Misc
	private PDDocument pdfDocument = null;	
	private ZUGFeRDImporter zi = null;
	private byte[] xmlContent = null;
	private List<ImageIcon> pdfPreviewImageIconList = new ArrayList<ImageIcon>();
	private int currentPreviewImageIconIndex = -1;
	
	// Constants final static
	
	// Initial application size
	private final static int appSizeX = 1440;
	private final static int appSizeY = 810;
	private final static int helpSizeX = 640;
	private final static int helpSizeY = 360;

	private final static int defaultAppFontSize = 14;
	
	// Language Strings
	private static char cFile = 'F';
	private static char cOpen = 'O';
	private static char cExit = 'x';
	private static char cHelp = 'H';
	private static char cAbout = 'A';
	private static char cValidate = 'V';
	private static char cQuickInfo = 'Q';
	
	private static String sFile = "File";
	private static String sOpen = "Open";
	private static String sExit = "Exit";
	private static String sHelp = "Help";
	private static String sAbout = "About";
	private static String sValidate = "Validate";
	private static String sQuickInfo = "QuickInfo";
	
	private static String sTitle = "Simple Mustang GUI";
	private static String sHelpTitle = sTitle + " " +sHelp;
	private static String sAboutDialogText = sTitle + " v 1.0.1. (C) Copyright 2024, 2025 Alexander Adam";
	private static String sAboutDialogTitle = sAbout+" "+sTitle;
	
	private static String sTipOpen = "Open (PDF)";
	private static String sTipValidate = "Call ZUGFeRDValidator";
	private static String sTipQuickInfo = "Show QuickInfo";
	private static String sTipHelp = "Show help";
	private static String sTipPdfNextPage = "[click for next page ...]";
	private static String sInitialSearchText = "enter search text here (overwrite)";
	private static String sSearchButtonText = "Search >>> ";

	private static String sPDF = "PDF";
	private static String sTextXmlLine = "Text/XML Line";
	private static String sNoZugferdXml = "No ZUGFeRD XML found in PDF file.";


	private static String sHtmlHelpText = "<!DOCTYPE html>"
			+ "<html>" 
			+ "<head>"
			+ "<title>Help</title>" 
			+ "</head>" 
			+ "<body>" 
			+ "<h1>Help</h1>"
			+ "Simple tool to view and validate (ZUGFeRD) PDF files and show optional XML content."
			+ "<p>If PDF has multiple pages, you can click on the current PDF page, to switch to the next page."
			+ "<p>To <b>search</b> in XML, overwrite search input field with search text and press the ["+sSearchButtonText+"] button."
			+ "<p>"+sQuickInfo+" gives values like BIC, IBAN, etc."
			+ "<p>Note: The validation messages are subject to the Mustangproject method ZUGFeRDValidator."
			+ "</body>" 
			+ "</html>";

	/**
	   * SimpleGui()
	   *  constructor
	   *  sets main application layout
	   *  sets all ActionListeners
	   */
	  SimpleMustangGui() {
	    super(true);
	    
	    // Settings

	    // Set up System Look&Feel
	    try {
	      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
	    } catch ( Exception ex ) {
	      JOptionPane.showMessageDialog( null, ex.toString() );
	    }

	    // Layout
	    setLayout(new BorderLayout());
	    
	    textArea = new JEditorPane();
	    textArea.setEditable(false);
		textArea.setFont(new Font(Font.MONOSPACED, Font.PLAIN, defaultAppFontSize));
		
		textArea.addCaretListener(new TextCaretListener());
		
		Font font = new Font(getFont().getFontName(), getFont().getStyle(), defaultAppFontSize);
		setFont(font);
	    
	    JScrollPane scrollPaneMessageArea = new JScrollPane(textArea);
	    
	    // Create menu
	    menubar = createMenubar();

	    // Create inner panel
	    JPanel panel = new JPanel();
	    panel.setLayout(new BorderLayout());
	    panel.add("North", createToolbar());
	    panel.add("Center", scrollPaneMessageArea );
	    panel.add("West", createPdfPreview());
	    
	    // Setup main panel
	    add("North", menubar);
	    add("Center", panel);
	    add("South", createStatusbar());
	  }

	/**
	 * main() creates a JFrame creates instance of SimpleGui and add it
	 * to the frame
	 * @param args String[]
	 */
	public static void main(String[] args) {
		try {
			// Language / Strings
			if (lang_de.equals(lang)) {
				cFile = 'D';
				cOpen = 'Ö';
				cExit = 'B';
				cHelp = 'H';
				cAbout = 'P';
				cValidate = 'Ü';
				cQuickInfo = 'K';
				
				sFile = "Datei";
				sOpen = "Öffnen";
				sExit = "Beenden";
				sHelp = "Hilfe";
				sAbout = "Programminfo";
				sValidate = "Überprüfung";
				sQuickInfo = "KurzInfo";
				
				sTitle = "Simple Mustang GUI";
				sHelpTitle = sTitle + " " +sHelp;
				sAboutDialogText = sTitle + ". (C) Copyright 2024, 2025 Alexander Adam";
				sAboutDialogTitle = sAbout+" "+sTitle;
				
				sTipOpen = "PDF-Datei öffnen";
				sTipValidate = "ZUGFeRDValidator Prüfung";
				sTipQuickInfo = "KurzInfos anzeigen";
				sTipHelp = "Hilfe anzeigen";
				sTipPdfNextPage = "[Drücken für nexte Seite ...]";
				sInitialSearchText = "Suchtext hier eingeben (überschreiben)";
				sSearchButtonText = "Suchen >>> ";

				sPDF = "PDF";
				sTextXmlLine = "Text/XML Zeile";
				sNoZugferdXml = "No ZUGFeRD XML found in PDF file.";
				
				sHtmlHelpText = "<!DOCTYPE html>"
						+ "<html>" 
						+ "<head>"
						+ "<title>Hilfe</title>" 
						+ "</head>" 
						+ "<body>" 
						+ "<h1>Hilfe</h1>"
						+ "Ein einfach gehaltenes Programm zur Ansicht und Überprüfung von (ZUGFeRD) PDF-Dateien."
						+ "<br>Sofern vorhanden, zeigt das Programm auch die XML Daten aus der PDF-Datei."
						+ "<p>Besteht die <b>PDF-Datei aus mehreren Seiten</b>, kann man mittels Maus-Click weiter blättern."
						+ "<p>Zur einfachen <b>Text-Suche</b> in den XML Daten, den Suchtext in das Suchfeld eingeben und die Suche mittels ["+sSearchButtonText+"] starten."
						+ "<p>Mit "+sQuickInfo+" werden Werte wie BIC, IBAN usw. angezeigt."
						+ "<p>Hinweis: Die Meldungen der Überprüfung unterliegen der Mustangproject Methode ZUGFeRDValidator."
						+ "</body>" 
						+ "</html>";
			}
			
			JFrame frame = new JFrame();

			SimpleMustangGui appPane = new SimpleMustangGui();

			URL urlAppPaneIcon = appPane.getClass().getResource("/simpleMustangGui.png");
			if (urlAppPaneIcon != null) {
				frame.setIconImage(Toolkit.getDefaultToolkit().getImage(urlAppPaneIcon));
			}

			Font font = new Font(appPane.getFont().getFontName(), appPane.getFont().getStyle(), defaultAppFontSize);
			frame.setFont(font);
			
			frame.setTitle(sTitle);
			frame.setBackground(Color.lightGray);
			frame.getContentPane().setLayout(new BorderLayout());
			frame.getContentPane().add("Center", appPane);
			frame.addWindowListener(new AppWindowAdapter());
			frame.pack();
			frame.setSize(appSizeX, appSizeY);
			frame.setVisible(true);
		} catch (Exception ex) {
			JOptionPane.showMessageDialog(null, ex.toString());
		}
	}

	/**
	 * AppWindowAdapter() applications WindowAdapter
	 */
	private static final class AppWindowAdapter extends WindowAdapter {
		public void windowClosing(WindowEvent e) {
			Close();
		}

		public void windowActivated(WindowEvent e) {
			e.getWindow().repaint();
		}
	}

	/**
	 * Close() close (up) function
	 */
	private static void Close() {
		System.exit(0);
	}

	/**
	 * getTopFrame() find top-level frame
	 */
	private Frame getTopFrame() {
		for (Container p = getParent(); p != null; p = p.getParent()) {
			if (p instanceof Frame) {
				return (Frame) p;
			}
		}
		return null;
	}

	/**
	 * createMenubar() create the menubar add Mnemonics add ToolTips add
	 * ActionListeners setup ComponentEnablers
	 */
	private JMenuBar createMenubar() {
		JMenuBar mb = new JMenuBar();

		JMenu menuFile = new JMenu(sFile);
		JMenuItem itemFileOpen = new JMenuItem(sOpen, cOpen);
		JMenuItem itemFileQuickInfo = new JMenuItem(sQuickInfo, cQuickInfo);
		JMenuItem itemFileValidate = new JMenuItem(sValidate, cValidate);
		JMenuItem itemFileExit = new JMenuItem(sExit, cExit);

		JMenu menuHelp = new JMenu(sHelp);
		JMenuItem itemHelpHelp = new JMenuItem(sHelp, cHelp);
		JMenuItem itemHelpAbout = new JMenuItem(sAbout, cAbout);

		menuFile.setMnemonic(cFile);
		menuHelp.setMnemonic(cHelp);

		itemFileOpen.setToolTipText(sTipOpen);
		itemFileQuickInfo.setToolTipText(sTipQuickInfo);
		itemFileValidate.setToolTipText(sTipValidate);
		itemHelpHelp.setToolTipText(sTipHelp);

		itemFileOpen.addActionListener(new FileOpenListener());
		itemFileValidate.addActionListener(new ZUGFeRDValidationListener());
		itemFileQuickInfo.addActionListener(new QuickInfoListener());
		itemFileExit.addActionListener(new FileExitListener());
		
		itemHelpHelp.addActionListener(new HelpHelpListener());
		itemHelpAbout.addActionListener(new HelpAboutListener());

		validateEnabler.add(itemFileValidate);
		validateEnabler.update();
		
		quickInfoEnabler.add(itemFileQuickInfo);
		quickInfoEnabler.update();
		
		menuFile.add(itemFileOpen);
		menuFile.add(itemFileQuickInfo);
		menuFile.add(itemFileValidate);
		menuFile.addSeparator();
		menuFile.add(itemFileExit);

		menuHelp.add(itemHelpHelp);
		menuHelp.add(itemHelpAbout);

		mb.add(menuFile);
		mb.add(menuHelp);

		return mb;
	}

	/**
	 * createToolbar() create the toolbar add ToolTips add ActionListeners setup
	 * ComponentEnablers
	 */
	private Component createToolbar() {
		toolbar = new JToolBar();

		searchTextField = new JTextField(sInitialSearchText);
		
		JButton searchButton = new JButton(sSearchButtonText);
		searchButton.addActionListener(new SearchListener());

		JButton tbuttonOpen = new JButton(sOpen);

		tbuttonOpen.setToolTipText(sTipOpen);

		tbuttonOpen.addActionListener(new FileOpenListener());

		searchEnabler.add(searchButton);
		searchEnabler.add(searchTextField);
		searchEnabler.update();
		
		toolbar.add(tbuttonOpen);
		toolbar.addSeparator();
		toolbar.add(searchButton);
		toolbar.add(searchTextField);
		
		return toolbar;
	}

	/**
	 * createStatusbar() creates and initialize statusbar (label)
	 */
	private JLabel createStatusbar() {
		status = new JLabel();
		return status;
	}
	
	/**
	 * createButtonWest() creates and initialize button area (west/left)
	 */
	private JButton createPdfPreview() {
		pdfPreviewButton = new JButton(sPDF, null);
		pdfPreviewButton.addActionListener(new PreviewButtonActionListener());
		return pdfPreviewButton;
	}

	/**
	 * class ComponentEnabler helper class to enable/disable - menuItems (JMenuItem)
	 * - buttons (JButton) extends Vector to keep a 'list' of 'Components' to handle
	 */
	private class ComponentEnabler extends Vector<Component> {

		private static final long serialVersionUID = 1L;
		private boolean enabled;

		/**
		 * ComponentEnabler() constructor sets enable flag
		 */
		ComponentEnabler(boolean enable) {
			super();
			this.enabled = enable;
		}

		/**
		 * set enable flag and update
		 */
		void setEnabled(boolean enable) {
			this.enabled = enable;
			update();
		}

		/**
		 * update all components
		 */
		void update() {
			for (int i = 0; i < elementCount; i++) {
				get(i).setEnabled(enabled);
			}
		}
	}
	
	private class TextCaretListener implements CaretListener {
		
		@Override
		public void caretUpdate(CaretEvent e) {
			String text = textArea.getText().replace("\r\n", "\n").substring(0, e.getDot());
			int line = 1 + e.getDot() - text.replace("\n", "").length();
			if (currentFile != null) { 
				status.setText(sFile+": "+currentFile.getPath()+" "+sTextXmlLine+": "+line);
			} else {
				status.setText(sTextXmlLine+": "+line);
			}
		}
	}

	/**
	 * class PreviewButtonActionListener ActionListener for PreviewButton clicked
	 */
	private class PreviewButtonActionListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			if (!pdfPreviewImageIconList.isEmpty()) {
				currentPreviewImageIconIndex = (currentPreviewImageIconIndex + 1) % pdfPreviewImageIconList.size();
				pdfPreviewButton.setIcon(pdfPreviewImageIconList.get(currentPreviewImageIconIndex));
			}
		}
	}

	/**
	 * class FileExitListener ActionListener for FileExit
	 */
	private class FileExitListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			Close();
		}
	}

	private void searchTextAndPositionCaret(JEditorPane editorPane, JTextField searchTextField) {
		try {
			int currentCaretPos = editorPane.getCaretPosition();
			int length = editorPane.getDocument().getLength();
			String searchText = searchTextField.getText();
			String docText     = editorPane.getDocument().getText(0, length);
			String docTextRest = docText.substring(currentCaretPos);

			int spos = -1;
			int sposRest = docTextRest.indexOf(searchText);
			
			if (sposRest != -1) {
				spos = currentCaretPos+sposRest;
			} else {
				// wrap
				spos = docText.indexOf(searchText);
			}
			
			if (spos != -1) {
				editorPane.setCaretPosition(spos);
				editorPane.select(spos, spos+searchText.length());
				editorPane.grabFocus();
			}
		} catch (BadLocationException e1) {
			status.setText(e1.getMessage());
		}
	}
	
	/**
	 * class SearchListener ActionListener for Search
	 */
	private class SearchListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			// JButton searchButton = (JButton)e.getSource();
			searchTextAndPositionCaret(textArea, searchTextField);
		}
	}

	/**
	 * class HelpHelpListener ActionListener for HelpHelp This is a very simple
	 * implementation of a help window
	 */
	private class HelpHelpListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {

			Frame frame = getTopFrame();

			if (helphelpDialog == null) {
				helphelpDialog = new JDialog(frame, sHelpTitle, false);

				HtmlHelpPanel htmlHelpPanel = new HtmlHelpPanel();

				helphelpDialog.getContentPane().add(htmlHelpPanel, BorderLayout.CENTER);
				helphelpDialog.pack();
			}

			helphelpDialog.setSize(helpSizeX, helpSizeY);
			helphelpDialog.setVisible(true);
		}
	}

	public class HtmlHelpPanel extends JPanel {
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;
		JEditorPane html;

		public HtmlHelpPanel() {

			String helpFile = "/SimpleMustangGui.html";
			if (lang.equals(lang_de)) {
				helpFile = "/SimpleMustangGui_de.html";
			}
			
			setLayout(new BorderLayout());

			try {
				URL urlHelpFile = getClass().getResource(helpFile);

				if (urlHelpFile != null) {
					html = new JEditorPane(urlHelpFile);
				} else {
					// URL or HTML File not found, use static String instead
					html = new JEditorPane("text/html", sHtmlHelpText);
				}

				html.setEditable(false);
				JScrollPane scroller = new JScrollPane();
				JViewport vp = scroller.getViewport();
				vp.add(html);
				add(scroller, BorderLayout.CENTER);

			} catch (MalformedURLException ex) {
				JOptionPane.showMessageDialog(null, ex.toString());
			} catch (IOException ex) {
				JOptionPane.showMessageDialog(null, ex.toString());
			}
		}
	}

	/**
	 * class HelpAboutListener ActionListener for HelpAbout
	 */
	private class HelpAboutListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			JOptionPane.showMessageDialog(null, sAboutDialogText, sAboutDialogTitle, JOptionPane.INFORMATION_MESSAGE);
		}
	}

	/**
	 * class FileOpenListener ActionListener for FileOpen
	 */
	private class FileOpenListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			Frame topFrame = getTopFrame();
			FileDialog fd = new FileDialog(topFrame, sOpen, FileDialog.LOAD);
			if (openDirectory == null) {
				// if nothing is set, initialize with directory from where the program was
				// started
				openDirectory = new File(System.getProperty("user.dir"));
			}
			fd.setDirectory(openDirectory.getPath());
			fd.setFile("");
			fd.setMultipleMode(false);
			fd.setVisible(true);

			File files[] = fd.getFiles();

			if (files != null && files.length > 0) {
				File file = files[0]; // get the first selected file
				
				// Reset after Open
				pdfPreviewImageIconList.clear();
				pdfPreviewButton.setToolTipText("");
				
				searchEnabler.setEnabled(false);
				quickInfoEnabler.setEnabled(false);
				validateEnabler.setEnabled(false);
				
				pdfDocument = null;
				zi = null;
				xmlContent = null;
				
				try {
					pdfDocument = Loader.loadPDF(new RandomAccessReadBufferedFile(file.getPath()));
					quickInfoEnabler.setEnabled(true);
					PDFRenderer pdfRenderer = new PDFRenderer(pdfDocument);
					for (int page = 0; page < pdfDocument.getNumberOfPages(); page++) {
						pdfPreviewImageIconList.add(new ImageIcon(pdfRenderer.renderImage(page)));
					}
					
					if (pdfPreviewImageIconList.size() > 0) {
						currentPreviewImageIconIndex = 0;
						pdfPreviewButton.setText("");
						pdfPreviewButton.setIcon(pdfPreviewImageIconList.get(currentPreviewImageIconIndex));
						if (pdfPreviewImageIconList.size() > 1) {
							pdfPreviewButton.setToolTipText(sTipPdfNextPage);
						}
					} else {
						pdfPreviewButton.setText(sPDF);
						currentPreviewImageIconIndex = -1;
					}
					
					openDirectory = file.getParentFile();
					
					zi = new ZUGFeRDImporter(file.getPath());
					if (zi != null) {
						xmlContent = zi.getRawXML();
					}
					if (xmlContent == null) {
						textArea.setText("");
						searchEnabler.setEnabled(false);
						status.setText(sFile+": "+file.getName()+". "+sNoZugferdXml);
					} else {
						textArea.setText(new String(xmlContent));
						searchEnabler.setEnabled(true);
						validateEnabler.setEnabled(true);
					}
					currentFile = file;
					textArea.setCaretPosition(0);
					
				} catch (IOException ex) {
					textArea.setText("");
					searchEnabler.setEnabled(false);
					pdfPreviewButton.setIcon(null);
					status.setText("File: "+file.getName()+". PDFRenderer: "+ex.getMessage());
				}
			}
		}
	}
	
	/**
	 * class ZUGFeRD Validation ActionListener for ZUGFeRDValidator
	 */
	private class ZUGFeRDValidationListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			if (null != currentFile && null != xmlContent) {
				ZUGFeRDValidator zfv = new ZUGFeRDValidator();
				String validationResult = zfv.validate(currentFile.getPath());
				textArea.setText(String.format("%s\n%s", new String(xmlContent), validationResult));
				int statusPos = validationResult.lastIndexOf("<summary status=");
				/*
				 * No language-conversion since ZUGFeRDValidator is 'english'
				 */
				if (statusPos > 0) {
					if (validationResult.substring(statusPos).startsWith("<summary status=\"invalid\"/>")) {
						JOptionPane.showMessageDialog(null, "ZUGFeRDValidator XML summary: Status is invalid!");
					}
					if (validationResult.substring(statusPos).startsWith("<summary status=\"valid\"/>")) {
						JOptionPane.showMessageDialog(null, "ZUGFeRDValidator XML summary: Status is valid!");
					}
				}
			}
		}
	}

	/**
	 * class Quick Info ActionListener for ZUGFeRDImporter
	 */
	private class QuickInfoListener implements ActionListener {

		public void actionPerformed(ActionEvent e) {
			String quickInfo = "";
			
			if (null != pdfDocument) {
				PDDocumentInformation pdfDocumentInformation = pdfDocument.getDocumentInformation();
				quickInfo += "PDF Version: " + pdfDocument.getVersion() + "\n";
				if (null != pdfDocumentInformation) {
					if (null != pdfDocumentInformation.getCreator()) {
						quickInfo += "PDF Creator: " + pdfDocumentInformation.getCreator() + "\n";
					}
				}
				
				quickInfo += "\n";
			}
			
			if (null != zi) {
			
				if (zi.getRawXML() == null) {
					quickInfo += sNoZugferdXml;
				} else {
					String sIssueDate = zi.getIssueDate();
					String sIBAN = zi.getIBAN();
					if (sIBAN != null) {
						if (!sIBAN.equals(sIBAN.replace(" ", ""))) {
							sIBAN +=  " (" + zi.getIBAN().replace(" ", "") + ")";
						}
					}
					
					if (lang.equals(lang_de)) {
						try {
							Date issueDate = sdf_issue_date.parse(sIssueDate);
							sIssueDate = sdf_issue_date_de.format(issueDate);
						} catch (ParseException e1) {
						}
						quickInfo += "BIC: " + zi.getBIC()
								+ "\nIBAN: " + sIBAN
								+ "\nKontoinhaber: " + zi.getHolder()
								+ "\nRechnungsnr: " + zi.getForeignReference()
								+ "\nRechnungsdatum: " + sIssueDate
								+ "\nFälliger Betrag: " + zi.getAmount().replace('.', ','); 
					} else {
						quickInfo += "BIC: " + zi.getBIC()
								+ "\nIBAN: " + sIBAN
								+ "\nHolder: " + zi.getHolder()
								+ "\nForeignReference: " + zi.getForeignReference()
								+ "\nIssueDate: " + sIssueDate
								+ "\nAmount: " + zi.getAmount(); 
					}
				}
				JTextArea infoTextArea = new JTextArea(quickInfo);
				JOptionPane.showMessageDialog(null, infoTextArea);
			}
		}
	}
}
