package com.approximatrix.draco.application.plugin.ui;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;

import com.approximatrix.draco.application.plugin.PluginSimpleOption;
import com.approximatrix.draco.application.plugin.SimpleOptionList;
import com.approximatrix.draco.datamodel.Constant;
import com.approximatrix.draco.datamodel.StatTableModel;

class PluginOptionDialog extends JDialog implements ActionListener {

	private static final int WIDTH = 350;
	private static final int HEIGHT = 400;
	
    private SimpleOptionList options = null;
    private StatTableModel stmodel = null;
    
    private String[] variables = null;
    private String[] constants = null;
    
    private JButton closeButton = null;
    
    private ArrayList<OptionComponent> optionWidgets = null;

    public PluginOptionDialog(PluginWindow parent, SimpleOptionList options) {
        super(parent.getMainWindow(),true);
        this.options = options;
        this.stmodel = parent.getMainWindow().getWindowTableModel();
        
        optionWidgets = new ArrayList<OptionComponent>();
        
        buildNameArrays(this.stmodel);
        
        this.setTitle(parent+" Options");
        
        this.getContentPane().setLayout(new BorderLayout());

        JPanel bPanel = new JPanel();
        bPanel.setLayout(new FlowLayout(FlowLayout.RIGHT));
        closeButton = new JButton("Close");
        closeButton.addActionListener(this);
        bPanel.add(closeButton);
        this.getContentPane().add(bPanel,BorderLayout.SOUTH);
        
        JPanel optTable = getOptionPanel();
        
        JPanel holder = new JPanel();
        holder.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        holder.setLayout(new BorderLayout());
        
        this.setSize(WIDTH, HEIGHT);
        if(options.size() > 5) {
        	holder.add(new JScrollPane(optTable),BorderLayout.CENTER);
        	this.getContentPane().add(holder,BorderLayout.CENTER);
        } else {
        	holder.add(optTable,BorderLayout.CENTER);
        	this.getContentPane().add(holder,BorderLayout.NORTH);
        }
        
        this.setLocationRelativeTo(parent);
        
        this.setVisible(true);
    }
    
    private void buildNameArrays(StatTableModel model) {
    	variables = model.getColumnNames();
        ArrayList<Constant> cobjs = model.getConstants();
        constants = new String[cobjs.size()];
        int i=0;
        for(Constant one : cobjs) {
            constants[i] = one.getName();
            i++;
        }
    }

    private JPanel getOptionPanel() {
        JPanel master = new JPanel();
        master.setLayout(new GridLayout(0,1));
        
        for(PluginSimpleOption option : options) {
        	JComponent toAdd = null;
        	switch(option.getType()) {
        	
        	case PluginSimpleOption.CHECKBOX:
        		toAdd = new OptionCheckBox(option);
        		break;
        	case PluginSimpleOption.VARIABLE:
        		toAdd = buildTwoColumnPanel(option.getLabel(), new OptionComboBox(option,variables));
        		break;
        	case PluginSimpleOption.CONSTANT:
        		toAdd = buildTwoColumnPanel(option.getLabel(), new OptionComboBox(option,constants));
        		break;
        	case PluginSimpleOption.FLOAT:
        	case PluginSimpleOption.INTEGER:
        	case PluginSimpleOption.STRING:
        	default:
        		toAdd = buildTwoColumnPanel(option.getLabel(), new OptionTextBox(option));
        		break;            	
        	}
        	if(toAdd != null) {
        		optionWidgets.add((OptionComponent)toAdd);
        		master.add(toAdd);
        	}
        }
        
        
        return master;
    }
    
    private JPanel buildTwoColumnPanel(String label, JComponent chooser) {
    	JPanel panel = new JPanel();
    	panel.setLayout(new GridLayout(1,2));
    	
    	JPanel lPanel = new JPanel();
    	lPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
    	lPanel.add(new JLabel(label));
    	panel.add(lPanel);
    	
    	JPanel compPanel = new JPanel();
    	compPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
    	//chooser.setPreferredSize(new Dimension(30))
    	compPanel.add(chooser);
    	panel.add(compPanel);
    	
    	return panel;
    }
    
    private interface OptionComponent {
    	public void saveOption();
    }
    
    private class OptionTextBox extends JTextField implements OptionComponent {
        
        private PluginSimpleOption option = null;
    
        public OptionTextBox(PluginSimpleOption option) {
            super();
            this.option = option;
            super.setText(option.getString());
        }

        public void saveOption() {
            option.setString(this.getText());
        }
    }

    private class OptionCheckBox extends JCheckBox implements OptionComponent {
    
        private PluginSimpleOption option = null;
    
        public OptionCheckBox(PluginSimpleOption option) {
            super(option.getLabel());
            this.option = option;
            super.setSelected(option.getBoolean());
        }

        public void saveOption() {
        	option.setString(new Boolean(this.isSelected()).toString());
        }
        
    }

    private class OptionComboBox extends JComboBox implements OptionComponent {
    
        private PluginSimpleOption option = null;
    
        public OptionComboBox(PluginSimpleOption option, String[] selections) {
            super(selections);
            this.option = option;
            super.setSelectedItem(option.getString());
        }

        public void saveOption() {
        	option.setString(this.getSelectedItem().toString());
        }
    }

	public void actionPerformed(ActionEvent e) {
		if(e.getSource() == closeButton) {
			for(OptionComponent option : optionWidgets)
				option.saveOption();
			dispose();
		}
	}
    
}
