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

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

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedInputStream;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;
import java.util.Vector;
import java.util.logging.Level;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.TitledBorder;

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.Firmware;
import de.lazyzero.NazeWiiConf.utils.NazeWiiLogger;
import de.lazyzero.NazeWiiConf.utils.ProgressListener;
import de.lazyzero.NazeWiiConf.utils.STMLoader;
import de.lazyzero.NazeWiiConf.utils.SVN;
import de.lazyzero.NazeWiiConf.utils.Utils;

/**
 * @author moll
 * 
 */
public class NazeUploadPanel extends NazeWiiPanel implements ActionListener, ProgressListener {

	private static final long serialVersionUID = 1L;
	
	private SVN svn;
	private String svnURL = "http://afrodevices.googlecode.com/svn";
	private String svnFile = "/trunk/baseflight/obj/baseflight.hex";
	
	private SimpleDateFormat sdf = new SimpleDateFormat("dd MMMM yyyy");
	
	private NazeWiiLogger logger = NazeWiiConf.getInstance().getLogger();
	
	private JLabel revisionLabel;
	private JComboBox revisionComboBox;
	private JButton refreshButton;
	private JLabel authorTitleLabel;
	private JLabel authorLabel;
	private JLabel dateTitleLabel;
	private JLabel dateLabel;
	private JLabel descriptionArea;
	private JScrollPane descriptionPane;
	private JProgressBar progressBar;
	private JButton uploadButton;

	private TreeMap<Long, Firmware> firmwares;

	private Firmware revision;

	protected int count;

	protected int errorcount;

	private STMLoader stmLoader;

	public NazeUploadPanel(String title, NazeWiiConf instance) {
		super(title, instance);
		stmLoader = new STMLoader(instance, this);
		initGUI();
	}

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

		// create the Layout for Panel this
		String panelColumns = "pref, 3dlu, pref:grow(6), 3dlu, pref, 3dlu, pref:grow(6), pref, fill:pref:grow, 3dlu, pref";
		String panelRows = "pref, 3dlu, pref, 3dlu, fill:pref:grow, 3dlu, pref";
		FormLayout panelLayout = new FormLayout(panelColumns, panelRows);
		this.setLayout(panelLayout);
		
		//first line elements
		this.revisionLabel = new JLabel(_("firmwarePanel.revision") + ": ");
		this.revisionComboBox = new JComboBox();
		this.revisionComboBox.addItem(_("firmwarePanel.updateList"));
		this.revisionComboBox.setSelectedIndex(0);
		this.revisionComboBox.addActionListener(this);
		this.setRefreshButton(new JButton(_("firmwarePanel.refreshButton")));
		this.getRefreshButton().addActionListener(this);
		
		//second line elements
		this.authorTitleLabel = new JLabel(_("firmwarePanel.author") +": ");
		this.authorLabel = new JLabel(_("na"));
		this.dateTitleLabel = new JLabel(_("firmwarePanel.date") + ": ");
		this.dateLabel = new JLabel(_("na"));
		
		//third line elements
		this.descriptionArea = new JLabel();
//		this.descriptionArea.setEditable(false);
		this.descriptionArea.setVerticalAlignment(JLabel.TOP);
		this.descriptionPane = new JScrollPane(descriptionArea);
		this.descriptionPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
		this.descriptionPane.setBorder(new TitledBorder(_("firmwarePanel.description") + ": "));
		
		//forth line elements
		this.progressBar = new JProgressBar(0, 100);
		this.progressBar.setForeground(Color.blue);
		this.setUploadButton(new JButton(_("firmwarePanel.uploadButton")));
		this.getUploadButton().setEnabled(false);
		this.getUploadButton().addActionListener(this);
		
		this.add(revisionLabel, cc.xy(1,1));
		this.add(revisionComboBox, cc.xyw(3, 1, 5));
		this.add(getRefreshButton(), cc.xy(8, 1));
		
		this.add(authorTitleLabel, cc.xy(1, 3));
		this.add(authorLabel, cc.xy(3, 3));
		this.add(dateTitleLabel, cc.xy(5, 3));
		this.add(dateLabel, cc.xy(7, 3));
		
		this.add(descriptionPane, cc.xyw(1, 5, 11));
		
		this.add(progressBar, cc.xyw(1, 7, 9));
		this.add(getUploadButton(), cc.xy(11, 7));
		
		
	}

	@Override
	public void actionPerformed(ActionEvent action) {
		if (action.getSource().equals(this.getRefreshButton())) {
			try {
				updateProgress(0);
				getUploadButton().setEnabled(false);
				svn = new SVN(svnURL, svnFile);
				logger.log(Level.INFO, "SVN fetched.");
				NazeUploadPanel.this.instance.setOffline(false);
				revisionComboBox.removeAllItems();
				
				firmwares = svn.getFirmwares();
				
				Set<Long> keys = firmwares.descendingKeySet();
				System.out.println(keys.size());
				for (Iterator<Long> key = keys.iterator(); key.hasNext();) {
					long rev = (Long) key.next();
					Firmware firmware = firmwares.get(rev);
					revisionComboBox.addItem(firmware.toString());
				}
				if (Utils.isLinux() || Utils.isMac()) getUploadButton().setEnabled(true);
			} catch (Exception e) {
				logger.log(Level.WARNING, e.getMessage());
				NazeUploadPanel.this.instance.setOffline(true);
				getUploadButton().setEnabled(false);
			}
		} else if (action.getSource().equals(this.revisionComboBox)) {
			String item = (String)this.revisionComboBox.getSelectedItem();
			if (item != null) {
				if (!item.equals(_("firmwarePanel.updateList"))) {
					String[] sItem = item.split(": ");
					String rev = sItem[0].trim().replace('r', ' ');
					rev = rev.trim();
					this.revision = firmwares.get(Long.parseLong(rev));
					
					this.authorLabel.setText(revision.getAuthor());
					this.dateLabel.setText(sdf.format(revision.getDate())+"");
					this.descriptionArea.setText(revision.getMessage());
					logger.log(Level.INFO, "Revision r" + rev + " selected.");
				}
			}
		} else if (action.getSource().equals(this.getUploadButton())) {
			updateProgress(0);
			getRefreshButton().setEnabled(false);
			svn.getFirmware(this.revision.getRevision());
			updateProgress(10);
			

			
			try {
				instance.getMainPanel().closeSerialPort();
			} catch (IOException e) {
				logger.log(Level.WARNING, _("nazeUploadPanel.unable2ClosePort"), true);
				e.printStackTrace();
			} catch (NullPointerException e) {
				logger.log(Level.INFO, "port already closed");
			}
			
			(new Thread() {
				public void run() {
					try {
						stmLoader.flashFirmware(revision);
					} catch (IOException e) {
						logger.log(Level.WARNING,
								_("nazeUploadPanel.flashFeiled"), true);
						logger.log(Level.WARNING, e.getMessage());
						e.printStackTrace();
					}
				}
			}).start();
			
			
		}
	}

	

	@Override
	public void updateProgress(final int value) {
		System.err.println("value: +" + value);
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				System.err.println("progress: " + value);
				progressBar.setValue(value);
			}
		});
		

	}

	@Override
	public void updateProgressBy(final int value) {
		System.err.println("by: +" + value);
		SwingUtilities.invokeLater(new Runnable() {
			public void run() {
				System.err.println("progress: " + value);
				progressBar.setValue(progressBar.getValue() + value);
			}
		});
	}

	public JButton getRefreshButton() {
		return refreshButton;
	}

	public void setRefreshButton(JButton refreshButton) {
		this.refreshButton = refreshButton;
	}

	public JButton getUploadButton() {
		return uploadButton;
	}

	public void setUploadButton(JButton uploadButton) {
		this.uploadButton = uploadButton;
	}



}
