package delig;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.util.LinkedList;

import javax.swing.BorderFactory;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTextPane;
import javax.swing.UIManager;
import javax.swing.border.BevelBorder;
import javax.swing.border.TitledBorder;
import javax.swing.text.BadLocationException;
import javax.swing.text.Style;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;

/**
 * DeLig disables misplaced ligatures in LaTeX documents
 * using a dictionary approach. 
 * 
 * DeLig is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * It may be copied or modified under the terms of the
 * GNU General Public License version 3
 * as published by the Free Software Foundation
 * (http://www.gnu.org/copyleft/gpl.html).
 *
 * This version is intended for German language texts only. 
 * DeLig is partially based on the Perl script rmligs by Björn Jacke, 
 * in particular the wordlist data is based on his igerman98 dictionary.
 * 
 * @author Daniel Warner, delig@nospam@daniel-warner.de
 * @version 2008-03-09
 */
public class DeLigGUI extends JFrame implements ActionListener {
    static final long serialVersionUID = 0;

    private static final String newline = System.getProperty("line.separator");

    private class DeLigPipe extends DeLig {
	protected void println() {
	    println("");
	}

	protected void println(String output) {
	    print(output + newline);
	}

	protected void print(String output) {
	    updateTextPane(output);
	}
    }

    private class DeLigThread extends Thread {
	public void run() {
	    statusBar.setText("Processing file(s)...");
	    jTextPane.setText("");
	    for (String filename : fileList) {
		try {
		    new DeLigPipe().process(new String[] { filename, filename + "." + outputExtension });
		} catch (DeLigException ex) {
		    updateTextPane(ex.getMessage() + newline);
		}
		updateTextPane(newline + "**************************************************" + newline);
	    }
	    fileList.clear();
	    jMenuStart.setEnabled(true);
	    statusBar.setText("Ready...");
	}
    }

    private File[] selectedFiles;

    public static final String outputExtension = "delig";

    private LinkedList<String> fileList = new LinkedList<String>();

    private Color backgroundColor = Color.white;

    private Style style;

    private JScrollPane jScrollPane = new JScrollPane();

    private JTextPane jTextPane = new JTextPane();

    private StyledDocument doc = (StyledDocument) jTextPane.getDocument();

    private JMenuBar jMenuBar = new JMenuBar();

    private JMenuItem jMenuStart;

    protected JLabel statusBar = new JLabel();

    public DeLigGUI() {
	// Set title of application
	super("DeLig GUI");

	// Set look and feel
	try {
	    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
	} catch (Exception e) {
	    e.printStackTrace();
	}

	// Set layout manager
	getContentPane().setLayout(new BorderLayout());

	// Set style for console output
	style = doc.addStyle("input", null);
	StyleConstants.setFontFamily(style, "Courier New");
	StyleConstants.setFontSize(style, 12);
	StyleConstants.setBackground(style, backgroundColor);
	StyleConstants.setForeground(style, Color.blue);

	// Initialize jTextPane and jScrollPane for console output
	jTextPane.setEditable(false);
	jTextPane.setBackground(backgroundColor);
	jTextPane.setAutoscrolls(true);
	jTextPane.setDoubleBuffered(true);
	jTextPane.setOpaque(false);
	jTextPane.setText("");

	jScrollPane.getViewport().setBackground(backgroundColor);
	jScrollPane.setAutoscrolls(true);
	jScrollPane.setBorder(new TitledBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED, Color.white, Color.white, new Color(103, 101, 98), new Color(148, 145, 140)), "Output"));
	jScrollPane.setOpaque(false);
	jScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
	jScrollPane.getViewport().add(jTextPane);
	getContentPane().add(jScrollPane, BorderLayout.CENTER);

	// Create menu
	JMenu jMenuFile = new JMenu("File");
	jMenuFile.setMnemonic(KeyEvent.VK_F);
	JMenuItem jMenuOpen = new JMenuItem("Open input file(s)");
	jMenuOpen.setMnemonic(KeyEvent.VK_O);
	jMenuOpen.setActionCommand("open");
	jMenuOpen.addActionListener(this);
	jMenuStart = new JMenuItem("Start DeLig");
	jMenuStart.setMnemonic(KeyEvent.VK_S);
	jMenuStart.setActionCommand("start");
	jMenuStart.addActionListener(this);
	JMenuItem jMenuExit = new JMenuItem("Exit");
	jMenuExit.setMnemonic(KeyEvent.VK_X);
	jMenuExit.setActionCommand("exit");
	jMenuExit.addActionListener(this);
	jMenuFile.add(jMenuOpen);
	jMenuFile.add(jMenuStart);
	jMenuFile.add(jMenuExit);
	jMenuBar.add(jMenuFile);
	setJMenuBar(jMenuBar);

	// Create status bar

	statusBar.setBorder(BorderFactory.createEtchedBorder());
	statusBar.setDebugGraphicsOptions(0);
	statusBar.setDoubleBuffered(true);
	statusBar.setOpaque(false);
	statusBar.setVerifyInputWhenFocusTarget(true);
	statusBar.setText("Ready...");
	getContentPane().add(statusBar, BorderLayout.SOUTH);

	// Center the window
	setSize(new Dimension(500, 400));
	Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
	Dimension frameSize = getSize();
	if (frameSize.height > screenSize.height) {
	    frameSize.height = screenSize.height;
	}
	if (frameSize.width > screenSize.width) {
	    frameSize.width = screenSize.width;
	}
	setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);

	// Add window listener
	addWindowListener(new WindowAdapter() {
	    public void windowClosing(WindowEvent e) {
		System.exit(0);
	    }
	});

	// Make frame visible
	setVisible(true);
    }

    public void actionPerformed(ActionEvent e) {
	if (e.getActionCommand().equals("open")) {
	    JFileChooser fileChooser = new JFileChooser();
	    fileChooser.setMultiSelectionEnabled(true);
	    fileChooser.setSelectedFiles(selectedFiles);
	    fileChooser.setDialogTitle("Open input file(s)");
	    fileChooser.setCurrentDirectory(new File(System.getProperty("user.dir")));

	    if (fileChooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
		selectedFiles = fileChooser.getSelectedFiles();
		fileList.clear();
		for (File file : selectedFiles) {
		    fileList.add(file.getAbsolutePath());
		}
	    }
	} else if (e.getActionCommand().equals("start")) {
	    jMenuStart.setEnabled(false);
	    new DeLigThread().start();
	} else if (e.getActionCommand().equals("exit")) {
	    System.exit(0);
	}
    }

    private void updateTextPane(String text) {
	try {
	    doc.insertString(doc.getLength(), text, style);
	} catch (BadLocationException e) {
	    e.printStackTrace();
	}
	repaint();
    }

    public static void main(String[] args) {
	new DeLigGUI();
    }
}
