/**
 * 
 */
package de.lazyzero.NazeWiiConf.gui;

import static lu.tudor.santec.i18n.Translatrix._;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.IOException;
import java.util.Iterator;
import java.util.Vector;
import java.util.logging.Level;

import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import com.jgoodies.forms.layout.CellConstraints;
import com.jgoodies.forms.layout.FormLayout;

import de.lazyzero.NazeWiiConf.NazeWiiConf;
import de.lazyzero.NazeWiiConf.gui.widget.NazeWiiPanel;
import de.lazyzero.NazeWiiConf.utils.NazeCommunicator;
import de.lazyzero.NazeWiiConf.utils.NazeConfiguration;
import de.lazyzero.NazeWiiConf.utils.NazePort;
import de.lazyzero.NazeWiiConf.utils.NazeWiiLogger;
import de.lazyzero.NazeWiiConf.utils.PortScanner;

/**
 * @author moll
 * 
 */
public class MainPanel extends JPanel implements ActionListener {

	private static final long serialVersionUID = 1L;
	private int baudrate = 115200;
	private NazeWiiConf nazeWiiConf;
	private NazeWiiLogger logger;
	private JLabel serialSelectLabel;
	private JButton serialConnectButton;
	private Vector<String> availablePorts = new Vector<String>();
	private JComboBox serialConnectionComboBox;
	private JTabbedPane tabbedPane;
	private NazePort np;
	private NazeBaseConfPanel nazeBaseConfPanel;
	private NazeConfiguration nazeConfiguration;
	private NazeCommunicator nazeCommunicator;
	private Vector<NazeWiiPanel> nazeWiiPanels = new Vector<NazeWiiPanel>();
	protected int selectedTab;
	private NazeSettingsPanel nazeSettingsPanel;
	protected static final int BASECONFTAB = 0;
	protected static final int SETTINGSTAB = 1;
	protected static final int UPDATETAB = 2;

	public MainPanel(NazeWiiConf nazeWiiConf) {
		this.nazeWiiConf = nazeWiiConf;
		this.nazeConfiguration = new NazeConfiguration();
		this.logger = this.nazeWiiConf.getLogger();

		initGui();
		
		updateSerialPorts();
	}

	private void initGui() {
		// create the CellContraints
		CellConstraints cc = new CellConstraints();

		// create the Layout for Panel this
		String panelColumns = "3dlu, pref, 3dlu, pref, 3dlu, pref, fill:pref:grow, 3dlu";
		String panelRows = "3dlu, pref, 3dlu, fill:pref:grow";
		FormLayout panelLayout = new FormLayout(panelColumns, panelRows);
		this.setLayout(panelLayout);
		
		
		this.availablePorts  = PortScanner.listSerialPorts();
		
		this.serialSelectLabel = new JLabel(_("serial.selectLabel") + ":");
		this.serialConnectButton = new JButton(_("serial.connect"));
		this.serialConnectionComboBox = new JComboBox(availablePorts);
		
		this.tabbedPane = new JTabbedPane();
		
		this.add(serialSelectLabel, cc.xy(2, 2));
		this.add(serialConnectionComboBox, cc.xy(4, 2));
		this.add(serialConnectButton, cc.xy(6, 2));
		this.add(tabbedPane, cc.xyw(1, 4, 8));
		
		
		this.serialConnectButton.addActionListener(this);
		
	}
	
	public void addTab(NazeWiiPanel tab) {
		this.nazeWiiPanels.add(tab);
		this.tabbedPane.add(tab.getTitle(), new JScrollPane(tab));
		
	}
	
	public void addTabChangeListener() {
		tabbedPane.addChangeListener(new ChangeListener() {
		    
		    public void stateChanged(ChangeEvent evt) {
		        JTabbedPane pane = (JTabbedPane)evt.getSource();

		        selectedTab = pane.getSelectedIndex();
		        
		        switch (selectedTab) {
				case BASECONFTAB:
					try {
//						openPort(false);
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
					break;
				case SETTINGSTAB:
					try {
//						openPort(false);
					} catch (Exception e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					
				case UPDATETAB:
					break;
				default:
					break;
				}
		    }
		});
	}
	
	public NazeConfiguration getNazeConfiguration() {
		return nazeConfiguration;
	}
	
	public NazeCommunicator getNazeCommunicator() {
		return nazeCommunicator;
	}

	@Override
	public void actionPerformed(ActionEvent action) {
		if (action.getSource().equals(serialConnectButton)) {
			openPort(true);
		}
	}

	public void openPort(boolean buttonPressed) {
		if (np == null) {
			np = new NazePort((String)MainPanel.this.serialConnectionComboBox.getSelectedItem(), 115200);
			nazeConfiguration = new NazeConfiguration();
		}
		if (NazeWiiConf.isNaze) {
			for (NazeWiiPanel tab : nazeWiiPanels) {
				if (tab instanceof NazeBaseConfPanel) {
					nazeBaseConfPanel = (NazeBaseConfPanel)tab;
				} else if (tab instanceof NazeSettingsPanel) {
					nazeSettingsPanel = (NazeSettingsPanel) tab;
				}
			}
			
			if (np.isPortOpened() || buttonPressed) {
				if (selectedTab == BASECONFTAB || selectedTab == SETTINGSTAB) {
					nazeBaseConfPanel.enableAllButtons(false);
					nazeSettingsPanel.enableAllButtons(false);
					
					nazeCommunicator = new NazeCommunicator(nazeBaseConfPanel, nazeSettingsPanel, nazeConfiguration, np);
					nazeCommunicator.setListener(nazeCommunicator);
					
					try {
						if (!np.isPortOpened()) {
							np.openPort();
						}
					} catch (Exception e) {
						e.printStackTrace();
					}
					
					nazeCommunicator.start();
					
					nazeCommunicator.openCLI();
					sleep(300);
					nazeCommunicator.readFeatureList();
					sleep(300);
					nazeCommunicator.readMixerList();
					sleep(300);
					nazeCommunicator.readMap();
					sleep(50);
					nazeCommunicator.readSettings();
					sleep(300);
					nazeCommunicator.readEnabledFeatures();
					sleep(150);
					nazeCommunicator.readEnabledMixer();
					sleep(150);
					nazeCommunicator.readStatus();
					sleep(150);
					nazeCommunicator.readVersion();
					sleep(150);
					nazeBaseConfPanel.enableAllButtons(true);
					nazeSettingsPanel.enableAllButtons(true);
					logger.log(Level.INFO, _("baseConfPanel.mainPanel.settingsLoad"), true);
				}
			}
		} else if (NazeWiiConf.isMWC) {
			
		}
	}

	private void sleep(int millis) {
		try {
			Thread.sleep(millis);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void closeSerialPort() throws IOException, NullPointerException{
		
		nazeCommunicator.closeCLI();
		np.close();
		nazeBaseConfPanel.enableAllButtons(false);
	}

	public String getPort() {
		return (String)MainPanel.this.serialConnectionComboBox.getSelectedItem();
	}

	public int getBaudrate() {
		return this.baudrate;
	}

	public NazeSettingsPanel getNazeSettingsPanel() {
		return this.nazeSettingsPanel;
	}
	
	private void updateSerialPorts() {
		Thread t = new Thread() {
			public void run() {
				String selectedItem;
				Vector<String> list;
				
				while(true) {
					selectedItem = (String)serialConnectionComboBox.getSelectedItem();
					list = PortScanner.listSerialPorts();
					
					for (Iterator iterator = list.iterator(); iterator.hasNext();) {
						String port = (String) iterator.next();
						if (!availablePorts.contains(port)) {
							System.out.println("add port to list: " + port);
							availablePorts.add(port);
							serialConnectionComboBox.setModel(new DefaultComboBoxModel(availablePorts));
							serialConnectionComboBox.setSelectedItem(selectedItem);
						}
					}
					try {
						sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
				}
			}
		};
		t.start();
	}

}
