package com.approximatrix.draco.general.ui.preferences;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSpinner;
import javax.swing.SpinnerNumberModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import com.approximatrix.draco.application.preferences.PluginPreferences;

public class PluginPreferencesPanel extends JPanel implements PreferencesPanel,ActionListener, ChangeListener {

	public static final String TAB_TITLE = "Plugins";
	
	private static final String HELP_KEY = "pluginpreferences";
	
	private static final int GUI_MAX_THREADS = 1024;
	
	private PluginPreferences prefs = null;
	
	private JList list = null;
	private JButton addButton = null;
	private JButton removeButton = null;
	
	private JCheckBox parallelMultiply = null;
	private JCheckBox parallelInverse = null;
	private JSpinner threadSpin = null; 
	
	public PluginPreferencesPanel(PluginPreferences prefs) {
		this.prefs = prefs;
		initialize();
	}
	
	private void initialize() {
		this.setLayout(new BorderLayout());
		
		list = new JList();
		this.add(new JScrollPane(list),BorderLayout.CENTER);
		
		JPanel bpanel = new JPanel();
		bpanel.setLayout(new FlowLayout(FlowLayout.CENTER));
		bpanel.add(new JLabel("Plugin Directories: "));
		addButton = new JButton("Add");
		addButton.addActionListener(this);
		removeButton = new JButton("Remove");
		removeButton.addActionListener(this);
		
		bpanel.add(addButton);
		bpanel.add(removeButton);
		this.add(bpanel, BorderLayout.NORTH);
		
		JPanel checkPanel = new JPanel();
		checkPanel.setLayout(new BoxLayout(checkPanel,BoxLayout.Y_AXIS));
		parallelMultiply = new JCheckBox("Use parallel matrix multiply");
		parallelMultiply.addChangeListener(this);
		parallelInverse = new JCheckBox("Use parallel matrix inversion");
		parallelInverse.addChangeListener(this);
		
		// For now, parallel inverse is disabled
		parallelInverse.setEnabled(false);
		
		checkPanel.add(parallelMultiply);
		checkPanel.add(parallelInverse);
		
		JPanel tpanel = new JPanel();
		tpanel.setLayout(new FlowLayout(FlowLayout.CENTER));
		tpanel.add(new JLabel("Maximum allowable threads: "));
		threadSpin = new JSpinner(new SpinnerNumberModel(prefs.getThreadLimit(),1,GUI_MAX_THREADS,1));
		threadSpin.addChangeListener(this);
		tpanel.add(threadSpin);
		
		checkPanel.add(tpanel);
		checkPanel.doLayout();
		this.add(checkPanel,BorderLayout.SOUTH);
		
		populateDirList();
	}

	private void populateDirList() {
		list.clearSelection();
		list.setListData(prefs.getDirectories().toArray());
	}
	
	private void addDirectory() {
		JFileChooser chooser = new JFileChooser();
		chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
		chooser.setDialogTitle("Select a Directory to Scan for Plugins");
		chooser.setDialogType(JFileChooser.OPEN_DIALOG);
		if(prefs.getDirectories().size() > 0)
			chooser.setCurrentDirectory(new File(prefs.getDirectories().get(prefs.getDirectories().size()-1)));
		int ret = chooser.showDialog(this, "Select");
		if(ret == JFileChooser.APPROVE_OPTION)
			prefs.addDirectory(chooser.getSelectedFile().getAbsolutePath());
	}
	
	public void actionPerformed(ActionEvent e) {
		if(e.getSource() == removeButton && list.getSelectedValue() != null) {
			try {
				String value = (String)list.getSelectedValue();
				prefs.removeDirectory(value);
			} catch(ClassCastException cce) {
				cce.printStackTrace();
			}
		} else if(e.getSource() == addButton) {
			addDirectory();
		}
		
		populateDirList();
	}

	public void stateChanged(ChangeEvent e) {
		if(e.getSource() == parallelMultiply)
			prefs.setParallelMultiplyEnabled(parallelMultiply.isSelected());
		else if(e.getSource() == parallelInverse)
			prefs.setParallelInverseEnabled(parallelInverse.isSelected());
		else if(e.getSource() == threadSpin)
			prefs.setThreadLimit(((SpinnerNumberModel)threadSpin.getModel()).getNumber().intValue());
	}
	
	public String getHelpKey() {
		return HELP_KEY;
	}
}
