//using Java Swing
package sim;

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.*;
import javax.swing.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class Workspace extends JPanel implements ActionListener, ItemListener {

	private JFrame frame;
	private JComboBox dropList;
	private JFileChooser chooser;
	private Vector<String> recent;
	JCheckBox defaultButton;
	private int defaultIndex = -1;
	private String newPath = null;
	private final String DEFAULT_PATH_HEADER = "[Default Workspace]";
	private final String RECENT_PATH_HEADER = "[Recent Workspaces]";

	public Workspace() {
		//GUI
		readConfig();
		//normal case
		if (defaultIndex == -1) {
			initialiseGui();
		} //default check box is set
		else if (defaultIndex == 0) {
			MainWindow.WAIT_BLOCK.countDown();
		} //invalid
		else {
			MainWindow.setWorkspace(null, null);
			MainWindow.WAIT_BLOCK.countDown();
		}
	}

	private void initialiseGui() {
		frame = new JFrame(MainWindow.PROGRAM_NAME + " " + MainWindow.VERSION + " - Please choose a workspace");
		frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		frame.setResizable(false);
		frame.pack();
		frame.setSize(600, 300);
		frame.setLocation(MainWindow.getMiddleOfScreen(frame));

		JPanel panel = (JPanel) frame.getContentPane();
		panel.setLayout(new BorderLayout());

		//description label
		JTextArea description = new JTextArea();
		description.setEditable(false);

		InputStream input = null;
		String str = "";
		try {
			input = Workspace.class.getResourceAsStream("workspace.txt");
			Scanner sc = new Scanner(input);
			while (sc.hasNextLine()) {
				str += sc.nextLine() + "\n";
			}
		} catch (NullPointerException e) {
			System.out.println("Can't find 'workspace.txt'");
		}

		description.setFont(new Font("Arial", Font.PLAIN, 13));
		description.setText(str);

		panel.add(description, BorderLayout.NORTH);

		//textfield label
		JPanel p = new JPanel(new GridBagLayout());
		GridBagConstraints c = new GridBagConstraints();
		//p.setSize(600, 50);
		c.gridx = 0;
		c.gridy = 0;
		JLabel text = new JLabel("Workspace:  ");
		p.add(text, c);

		//dropList
		c.gridx = 1;
		dropList = new JComboBox(recent);
		dropList.setEditable(true);
		dropList.addActionListener(this);
		dropList.setPreferredSize(new Dimension(400, 30));
		p.add(dropList, c);

		//Browse
		c.gridx = 2;
		JButton browse = new JButton("Browse");
		browse.setActionCommand("browse");
		browse.addActionListener(this);
		p.add(browse, c);

		panel.add(p);

		//set as default checkbox
		c.gridy = 1;
		c.gridx = 1;
		defaultButton = new JCheckBox("Set as default and do not ask again");
		defaultButton.setSelected(false);
		defaultButton.addItemListener(this);
		//p.add(defaultButton, c);

		//Clear
		c.gridy = 2;
		c.gridx = 1;
		JButton clear = new JButton("Clear all recent history");
		clear.setActionCommand("clear");
		clear.addActionListener(this);
		p.add(clear, c);

		panel.add(p);

		//OK and Cencel
		p = new JPanel(new FlowLayout());

		JButton ok = new JButton("OK");
		ok.setActionCommand("ok");
		ok.addActionListener(this);
		p.add(ok);

		JButton cancel = new JButton("Cancel");
		cancel.setActionCommand("cancel");
		cancel.addActionListener(this);
		p.add(cancel);

		panel.add(p, BorderLayout.SOUTH);

		//file chooser
		chooser = new JFileChooser();
		chooser.setDialogTitle("Please choose a workspace");
		chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
//		try {
//			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
//
//		} catch (Exception e) {
//			System.err.println("Error: " + e.getMessage());
//		}
		frame.setVisible(true);
	}

	private void readConfig() {
		recent = new Vector<String>();
		try {
			File file = new File("config.ini");
			// config file doesn't exist, return
			if (!file.exists()) {
				return;
			}
			FileReader fr = new FileReader(file.getAbsoluteFile());
			BufferedReader br = new BufferedReader(fr);
			//default path
			String str = br.readLine();
			//default path - incorrect format
			if (!DEFAULT_PATH_HEADER.equals(str)) {
				writeConfig();
				br.close();
				return;
			}
			str = br.readLine();
			if (str == null) {
				writeConfig();
				br.close();
				return;
			}
			defaultIndex = Integer.parseInt(str);
			if (defaultIndex != 0 && defaultIndex != -1) {
				defaultIndex = -1;
				writeConfig();
				br.close();
				return;
			}

			//recent path
			str = br.readLine();
			//recent path - incorrect format
			if (!RECENT_PATH_HEADER.equals(str)) {
				writeConfig();
				br.close();
				return;
			}
			//read first line
			str = br.readLine();
			if (str == null) {
				writeConfig();
				br.close();
				return;
			}
			//set as default - WORKSPACE PATH is found
			if (defaultIndex == 0) {
				File dir = new File(str);
				str = trim(str);
				if (!(str.equals(dir.getAbsoluteFile().toString()))) {
					JOptionPane.showMessageDialog(frame,
							"Please enter a valid path",
							"", JOptionPane.WARNING_MESSAGE);
					defaultIndex = -1;
				} else {
					//exist given folder
					if (dir.exists()) {
						MainWindow.setWorkspace(str, null);
						br.close();
						return;
					}
					//doesn't exist
					//can create
					if (dir.mkdir()) {
						MainWindow.setWorkspace(str, null);
						br.close();
						return;
					} //can't create
					else {
						JOptionPane.showMessageDialog(frame,
								"Fail to open workspace",
								"", JOptionPane.WARNING_MESSAGE);
						defaultIndex = -1;
					}
				}
			}
			while (str != null) {
				recent.add(str);
				str = br.readLine();
			}
			br.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void writeConfig() {
		try {
			File file = new File("config.ini");
			if (file.exists()) {
				file.delete();
			}
			file.createNewFile();

			FileWriter fw = new FileWriter(file.getAbsoluteFile());
			BufferedWriter bw = new BufferedWriter(fw);
			bw.write(DEFAULT_PATH_HEADER + "\n");
			bw.write(defaultIndex + "\n");
			bw.write(RECENT_PATH_HEADER + "\n");
			if (newPath != null) {
				bw.write(newPath + "\n");
			}
			for (int i = recent.size() - 1; i >= 0; i--) {
				if (recent.get(i).equals(newPath)) {
					continue;
				}
				bw.write(recent.get(i) + "\n");
			}
			bw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	private void clearConfig() {
		recent = new Vector<String>();
		defaultIndex = -1;
		dropList.removeAllItems();
		writeConfig();
	}

	private String trim(String str) {
		if (str.charAt(str.length() - 1) == File.separatorChar) {
			return str.substring(0, str.length() - 1);
		} else {
			return str;
		}
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		if (e.getActionCommand().equals("ok")) {
			newPath = dropList.getEditor().getItem().toString();
			//empty path
			if (newPath.equals("")) {
				JOptionPane.showMessageDialog(frame,
						"Please enter a valid path",
						"", JOptionPane.WARNING_MESSAGE);
				return;
			}
			//incorrect path format
			File dir = new File(newPath);
			newPath = trim(newPath);
			if (!(newPath.equals(dir.getAbsoluteFile().toString()))) {
				JOptionPane.showMessageDialog(frame,
						"Please enter a valid path",
						"", JOptionPane.WARNING_MESSAGE);
				return;
			}
			//directory doesn't exist and can't create successfully
			if (!dir.exists() && !dir.mkdir()) {
				JOptionPane.showMessageDialog(frame,
						"Please enter a valid path",
						"", JOptionPane.WARNING_MESSAGE);
				return;
			}
			MainWindow.setWorkspace(newPath, null);
			writeConfig();
			frame.dispose();
			MainWindow.WAIT_BLOCK.countDown();
		}
		if (e.getActionCommand().equals("cancel")) {
			frame.dispose();
			MainWindow.WAIT_BLOCK.countDown();
		}
		if (e.getActionCommand().equals("browse")) {
			if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) {
				dropList.getEditor().setItem(chooser.getSelectedFile().toString());
			}
		}
		if (e.getActionCommand().equals("clear")) {
			clearConfig();
		}
	}

	@Override
	public void itemStateChanged(ItemEvent e) {
		Object source = e.getItemSelectable();
		if (source == defaultButton) {
			if (e.getStateChange() == e.SELECTED) {
				defaultIndex = 0;
			}
			if (e.getStateChange() == e.DESELECTED) {
				defaultIndex = -1;
			}
		}
	}
}
