/*
 * Copyright 2013 Yuichiro Moriguchi
 *
 * 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 net.morilib.sed.gui;

import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.io.PushbackReader;
import java.io.StringReader;
import java.util.LinkedList;
import java.util.List;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
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.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

import net.morilib.sed.Sed;
import net.morilib.sed.SedCommandBundle;
import net.morilib.sed.SedParser;
import net.morilib.sed.SedPatternEngine;
import net.morilib.sed.SedSyntaxException;
import net.morilib.sed.parser.SedSimpleCommandParser;
import net.morilib.sed.pattern.JavaStandardSedPatternEngine;
import net.morilib.sed.pattern.SedBasicRegexEngine;
import net.morilib.unix.glob.WildcardFileFilter;
import net.morilib.unix.regex.BasicPatternSyntaxException;

public class GrepFrame extends JFrame {

	private JTextField t1 = new JTextField(50);
	private JTextField t2 = new JTextField(50);
	private JComboBox c3 = new JComboBox();
	private JFileChooser f1 = new JFileChooser();
	private JCheckBox c1 = new JCheckBox("apply for subfolders");
	private JComboBox c4 = new JComboBox();
	private CharsetComboBox cs1 = new CharsetComboBox();

	private JMenuBar mb = new JMenuBar();

	private SedOutputDialog dialog;

	private SedCommandBundle bundle;
	private SedQuestionCommand qcmd;

	boolean addfs(List<File> fs, File f, boolean dir) {
		if(f.isDirectory()) {
			for(File g : f.listFiles()) {
				if(g.isFile() || (g.isDirectory() && dir))  fs.add(g);
			}
			return false;
		} else {
			return true;
		}
	}

	void warnbox(String s) {
		JOptionPane.showMessageDialog(
				this, s, "grepafter", JOptionPane.WARNING_MESSAGE);
	}

	void errbox(String s) {
		JOptionPane.showMessageDialog(
				this, s, "grepafter", JOptionPane.ERROR_MESSAGE);
	}

	void infobox(String... ss) {
		StringBuffer b = new StringBuffer();

		for(String s : ss)  b.append(s).append('\n');
		JOptionPane.showMessageDialog(
				this, b.toString(), "grepafter",
				JOptionPane.INFORMATION_MESSAGE);
	}

	void exec1() {
		List<File> fs = new LinkedList<File>();
		WildcardFileFilter ff;
		String s = t1.getText();
		Object sf = c3.getSelectedItem();
		PushbackReader r;
		File f;

		if(s == null || s.equals("")) {
			warnbox("path required");
			return;
		} else if(sf == null || sf.equals("")) {
			warnbox("file filter required");
			return;
		}

		try {
			r = new PushbackReader(new StringReader(t2.getText()));
			SedParser.parseLines(r);
			if(r.read() >= 0) {
				errbox("invaild line");
				return;
			}
		} catch(IOException e) {
			throw new RuntimeException(e);
		}

		dialog.inittable();
		ff = new WildcardFileFilter(sf.toString());
		try {
			fs.add(new File(t1.getText()));
			while(!fs.isEmpty()) {
				f = fs.remove(0);
				if(addfs(fs, f, c1.isSelected()) && ff.accept(f)) {
					qcmd.path = f.toString();
					Sed.executeOnlyInput(
							bundle,
							t2.getText() + "?",
							f,
							cs1.getSelectedCharset(),
							(SedPatternEngine)c4.getSelectedItem(),
							false);
				}
			}
			dialog.showDialog();
			infobox("execute completed");
		} catch(IOException e) {
			errbox("I/O error");
		} catch(SedSyntaxException e) {
			errbox("invalid line");
		} catch(BasicPatternSyntaxException e) {
			errbox("invalid regular expression");
		}
	}

	GrepFrame() {
		super("grepafter");

		//
		Container cp;
		GridBagConstraints ct = new GridBagConstraints();
		JPanel p1 = new JPanel();
		JMenu m1;
		JMenuItem i1;
		JButton b1, b2;

		setDefaultCloseOperation(EXIT_ON_CLOSE);
		setMinimumSize(new Dimension(200, 300));
		setSize(600, 30);
		cp = getContentPane();
		cp.setLayout(new BorderLayout());
		p1.setLayout(new GridBagLayout());
		f1.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);

		ct.gridwidth = ct.gridheight = 1;
		ct.weightx = ct.weighty = 1;
		ct.fill = GridBagConstraints.BOTH;
		p1.add(new JLabel("Path:"), ct);

		ct.weightx = 8;
		p1.add(t1, ct);

		ct.weightx = 1;
		ct.gridwidth = GridBagConstraints.REMAINDER;
		b1 = new JButton("File");
		b1.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				File f;

				f1.showDialog(GrepFrame.this, "open");
				f = f1.getSelectedFile();
				if(f != null)  t1.setText(f.toString());
			}

		});
		p1.add(b1, ct);

		ct.gridwidth = 1;
		p1.add(new JLabel("Filter:"), ct);

		ct.gridwidth = GridBagConstraints.REMAINDER;
		c3.addItem("*");
		c3.setEditable(true);
		p1.add(c3, ct);

		ct.gridwidth = GridBagConstraints.REMAINDER;
		p1.add(c1, ct);

		ct.gridwidth = 1;
		p1.add(new JLabel("Line:"), ct);

		ct.gridwidth = GridBagConstraints.REMAINDER;
		p1.add(t2, ct);

		ct.gridwidth = GridBagConstraints.REMAINDER;
		c4.addItem(SedBasicRegexEngine.getInstance());
		c4.addItem(JavaStandardSedPatternEngine.getInstance());
		p1.add(c4, ct);

		ct.gridwidth = GridBagConstraints.REMAINDER;
		p1.add(cs1, ct);

		cp.add(p1, BorderLayout.NORTH);

		b2 = new JButton("execute");
		b2.addActionListener(new ActionListener() {

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

		});
		cp.add(b2, BorderLayout.SOUTH);

		m1 = new JMenu("Help");
		i1 = new JMenuItem("About Sedafter");
		i1.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent e) {
				infobox("Sedafter Version 0.0.0",
						"Copyright 2013 Yuichiro Moriguchi",
						"This software under Apache 2.0 License");
			}

		});
		m1.add(i1);
		mb.add(m1);
		setJMenuBar(mb);

		dialog = new SedOutputDialog(this);
		bundle = SedCommandBundle.newInstance();
		qcmd   = new SedQuestionCommand();
		qcmd.dialog = dialog;
		bundle.put('?', new SedSimpleCommandParser(qcmd));
	}

}
