package org.ourfilesystem.simpleui;

/*
OurFileSystem is a peer2peer file sharing program.
Copyright (C) 2012  Robert Gass

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.

*/

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.util.LinkedList;
import java.util.List;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SpinnerListModel;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import net.miginfocom.swing.MigLayout;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JCheckBox;

import org.ourfilesystem.com.OFSConnector;
import org.ourfilesystem.com.OFSI2PConnector;
import org.ourfilesystem.com.OFSI2PServerSocket;
import org.ourfilesystem.com.OFSServerSocket;
import org.ourfilesystem.com.SimpleServerSocket;
import org.ourfilesystem.com.SimpleConnector;
import javax.swing.JTabbedPane;
import javax.swing.JSpinner;

public class NetworkConfigDialog extends JDialog {
	private static final long serialVersionUID = 1L;
	
	private static String I2PKey       = "USEI2P";
	private static String ProxyAddrKey = "PROXYADDR";
	private static String ProxyPortKey = "PROXYPORT";
	private static String ProxyUseKey  = "PROXYUSE";
	private static String PeerPortKey  = "PEERPORT";
	
	private JTextField textField;
	private JTextField textField_1;
	private JCheckBox useproxy;
	
	private boolean SimpleStarted;
	private boolean I2PStarted;
	
	private boolean UseI2P;
	private boolean UseProxy;
	private String ProxyAddr;
	private int ProxyPort;
	private int PeerPort;
	
	private SimpleServerSocket SimpleServer;
	private SimpleConnector SimpleConnector;
	private OFSI2PServerSocket I2PServer;
	private OFSI2PConnector I2PConnector;
	
	private String BaseDir;
	
	private SimpleGUI GUI;
	
	private File I2PConfigFile;
	private File ConfigFile;
	private JTextField peerPort;
	private JCheckBox UseI2PBox;
	private JTextField inboundNickname;
	private JTextField outboundNickname;
	private JTextField i2cpUsername;
	private JTextField i2cpHost;
	private JTextField i2cpPort;
	private JSpinner inboundQuantity;
	private JSpinner outboundQuantity;
	private JSpinner inboundLength;
	private JSpinner outboundLength;
	private JSpinner inboundVariance;
	private JSpinner outboundVariance;
	private JSpinner inboundBackup;
	private JSpinner outboundBackupQuantity;
	private JCheckBox inboundAllowZeroHop;
	private JCheckBox outboundAllowZeroHop;
	private JSpinner inboundIPRestriction;
	private JSpinner outboundIPRestriction;
	private JCheckBox i2cpDontPublishLeaseSet;
	private JCheckBox i2cpSSL;
	private JTextField Password;
	
	private void LoadI2PConfig() {
		if (I2PConfigFile.exists()) {
			try {
				FileInputStream fis = new FileInputStream(I2PConfigFile);
				Properties p = new Properties();
				p.load(fis);
				fis.close();
				loadProperties(p);
			}
			catch (Exception e) {
				e.printStackTrace();
			}
		}
	}
	
	private void saveI2PConfig() {
		try {
			FileOutputStream fos = new FileOutputStream(I2PConfigFile);
			Properties p = getProperties();
			p.store(fos, "do not manually edit please");
			fos.close();
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	private boolean LoadConfig() {
		boolean loadedok = false;
		Properties p = new Properties();
		if (ConfigFile.exists()) {
			try {
				FileInputStream fis = new FileInputStream(ConfigFile);
				p.load(fis);
				fis.close();
				loadedok = true;
			} catch (Exception e) {
				e.printStackTrace();
				throw new RuntimeException("Could not read the proxy configuration file!");
			}		
		}
		UseI2P = Boolean.valueOf(p.getProperty(I2PKey, "false"));
		UseProxy = Boolean.valueOf(p.getProperty(ProxyUseKey, "true"));
		ProxyAddr = p.getProperty(ProxyAddrKey, "127.0.0.1");
		ProxyPort = Integer.valueOf(p.getProperty(ProxyPortKey, "9050"));
		PeerPort = Integer.valueOf(p.getProperty(PeerPortKey, "9140"));
		return loadedok;
	}
	
	private void SaveConfig() {
		Properties p = new Properties();
		p.setProperty(I2PKey, Boolean.toString(UseI2P));
		p.setProperty(ProxyUseKey, Boolean.toString(UseProxy));
		p.setProperty(ProxyAddrKey, ProxyAddr);
		p.setProperty(ProxyPortKey, Integer.toString(ProxyPort));
		p.setProperty(PeerPortKey, Integer.toString(PeerPort));
		try {
			FileOutputStream fos = new FileOutputStream(ConfigFile);
			p.store(fos, "proxy configuration for ofs");
			fos.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public OFSServerSocket getServerSocket() {
		if (SimpleServer == null) {
			try {
				SimpleServer = new SimpleServerSocket(new ServerSocket(PeerPort));
			} catch (IOException e) {
				e.printStackTrace();
			}
			return SimpleServer;
		}
		return SimpleServer;
	}
	
	public OFSConnector getConnector() {
		if (SimpleConnector == null) {
			SimpleConnector = new SimpleConnector(UseProxy, ProxyAddr, ProxyPort);
		}
		SimpleConnector.setProxyAddr(ProxyAddr);
		SimpleConnector.setUseProxy(UseProxy);
		SimpleConnector.setProxyPort(ProxyPort);
		return SimpleConnector;
	}

	/**
	 * Create the dialog.
	 */
	public NetworkConfigDialog(SimpleGUI gui, String bd) {
		GUI = gui;
		SimpleStarted = false;
		I2PStarted = false;
		BaseDir = bd;
		File basedir = new File(BaseDir);
		if (!basedir.exists()) {
			basedir.mkdirs();
		}
		
		I2PConfigFile = new File(BaseDir + File.separator + "i2p.cfg");
		ConfigFile = new File(BaseDir + File.separator + "proxy.cfg");
		boolean justgo = LoadConfig();
		
		setTitle("Network Configuration");
		setBounds(100, 100, 492, 604);
		getContentPane().setLayout(new BorderLayout());
		{
			JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
			getContentPane().add(tabbedPane, BorderLayout.NORTH);
			{
				JPanel panel = new JPanel();
				tabbedPane.addTab("Basic", null, panel, null);
				panel.setLayout(new MigLayout("", "[][grow,fill]", "[][][][][][]"));
				{
					UseI2PBox = new JCheckBox("Use I2P");
					panel.add(UseI2PBox, "cell 1 0");
					UseI2PBox.setSelected(UseI2P);
				}
				{
					JLabel lblSocksProxyAddress = new JLabel("SOCKS Proxy address");
					panel.add(lblSocksProxyAddress, "cell 0 2");
				}
				{
					textField = new JTextField();
					panel.add(textField, "cell 1 2");
					textField.setColumns(10);
					textField.setText(getProxyAddr());
				}
				{
					JLabel lblSocksProxyPort = new JLabel("SOCKS Proxy Port");
					panel.add(lblSocksProxyPort, "cell 0 3");
				}
				{
					textField_1 = new JTextField();
					panel.add(textField_1, "cell 1 3");
					textField_1.setColumns(10);
					textField_1.setText(Integer.toString(getProxyPort()));
				}
				{
					useproxy = new JCheckBox("Enable SOCKS Proxy");
					panel.add(useproxy, "cell 1 4");
					useproxy.setSelected(isUseProxy());
				}
				{
					JLabel lblPeerPort = new JLabel("Peer Port");
					panel.add(lblPeerPort, "cell 0 5");
				}
				{
					peerPort = new JTextField();
					panel.add(peerPort, "cell 1 5");
					peerPort.setColumns(10);
					peerPort.setText(Integer.toString(getPeerPort()));
				}
				{
					JPanel panel_1 = new JPanel();
					tabbedPane.addTab("I2P Advanced", null, panel_1, null);
					panel_1.setLayout(new MigLayout("", "[][grow,fill]", "[][][][][][][][][][][][][][][][][][][][]"));
					{
						JLabel lblInboundquantity = new JLabel("inbound.quantity");
						panel_1.add(lblInboundquantity, "cell 0 0,alignx trailing");
					}
					{
						List<String> lst = new LinkedList<String>();
						lst.add("Default");
						lst.add("1");
						lst.add("2");
						lst.add("3");
						lst.add("4");
						lst.add("5");
						lst.add("6");
						lst.add("7");
						lst.add("8");
						lst.add("9");
						lst.add("10");
						lst.add("11");
						lst.add("12");
						lst.add("13");
						lst.add("14");
						lst.add("15");
						lst.add("16");
						SpinnerListModel mod = new SpinnerListModel(lst);
						inboundQuantity = new JSpinner(mod);
						panel_1.add(inboundQuantity, "cell 1 0");
					}
					{
						JLabel lblOutboundquantity = new JLabel("outbound.quantity");
						panel_1.add(lblOutboundquantity, "cell 0 1,alignx trailing");
					}
					{
						List<String> lst = new LinkedList<String>();
						lst.add("Default");
						lst.add("1");
						lst.add("2");
						lst.add("3");
						lst.add("4");
						lst.add("5");
						lst.add("6");
						lst.add("7");
						lst.add("8");
						lst.add("9");
						lst.add("10");
						lst.add("11");
						lst.add("12");
						lst.add("13");
						lst.add("14");
						lst.add("15");
						lst.add("16");
						SpinnerListModel mod = new SpinnerListModel(lst);
						outboundQuantity = new JSpinner(mod);
						panel_1.add(outboundQuantity, "cell 1 1");
					}
					{
						JLabel lblInboundlength = new JLabel("inbound.length");
						panel_1.add(lblInboundlength, "cell 0 2,alignx trailing");
					}
					{
						List<String> lst = new LinkedList<String>();
						lst.add("Default");
						lst.add("0");
						lst.add("1");
						lst.add("2");
						lst.add("3");
						lst.add("4");
						lst.add("5");
						lst.add("6");
						lst.add("7");
						SpinnerListModel mod = new SpinnerListModel(lst);
						inboundLength = new JSpinner(mod);
						panel_1.add(inboundLength, "cell 1 2");
					}
					{
						JLabel lblOutboundlength = new JLabel("outbound.length");
						panel_1.add(lblOutboundlength, "cell 0 3,alignx trailing");
					}
					{
						List<String> lst = new LinkedList<String>();
						lst.add("Default");
						lst.add("0");
						lst.add("1");
						lst.add("2");
						lst.add("3");
						lst.add("4");
						lst.add("5");
						lst.add("6");
						lst.add("7");
						SpinnerListModel mod = new SpinnerListModel(lst);
						outboundLength = new JSpinner(mod);
						panel_1.add(outboundLength, "cell 1 3");
					}
					{
						JLabel lblInboundvariance = new JLabel("inbound.lengthVariance");
						panel_1.add(lblInboundvariance, "cell 0 4,alignx trailing");
					}
					{
						List<String> lst = new LinkedList<String>();
						lst.add("Default");
						lst.add("7");
						lst.add("6");
						lst.add("5");
						lst.add("4");
						lst.add("3");
						lst.add("2");
						lst.add("1");
						lst.add("0");
						lst.add("-1");
						lst.add("-2");
						lst.add("-3");
						lst.add("-4");
						lst.add("-5");
						lst.add("-6");
						lst.add("-7");
						SpinnerListModel mod = new SpinnerListModel(lst);
						inboundVariance = new JSpinner(mod);
						panel_1.add(inboundVariance, "cell 1 4");
					}
					{
						JLabel lblOutboundvariance = new JLabel("outbound.lengthVariance");
						panel_1.add(lblOutboundvariance, "cell 0 5,alignx trailing");
					}
					{
						List<String> lst = new LinkedList<String>();
						lst.add("Default");
						lst.add("7");
						lst.add("6");
						lst.add("5");
						lst.add("4");
						lst.add("3");
						lst.add("2");
						lst.add("1");
						lst.add("0");
						lst.add("-1");
						lst.add("-2");
						lst.add("-3");
						lst.add("-4");
						lst.add("-5");
						lst.add("-6");
						lst.add("-7");
						SpinnerListModel mod = new SpinnerListModel(lst);
						outboundVariance = new JSpinner(mod);
						panel_1.add(outboundVariance, "cell 1 5");
					}
					{
						JLabel lblInboundbackup = new JLabel("inbound.backupQuantity");
						panel_1.add(lblInboundbackup, "cell 0 6,alignx trailing");
					}
					{
						List<String> lst = new LinkedList<String>();
						lst.add("Default");
						lst.add("0");
						lst.add("1");
						lst.add("2");
						lst.add("3");
						lst.add("4");
						lst.add("5");
						lst.add("6");
						lst.add("7");
						SpinnerListModel mod = new SpinnerListModel(lst);
						inboundBackup = new JSpinner(mod);
						panel_1.add(inboundBackup, "cell 1 6");
					}
					{
						JLabel lblOutboundbackup = new JLabel("outbound.backupQuantity");
						panel_1.add(lblOutboundbackup, "cell 0 7,alignx trailing");
					}
					{
						List<String> lst = new LinkedList<String>();
						lst.add("Default");
						lst.add("0");
						lst.add("1");
						lst.add("2");
						lst.add("3");
						lst.add("4");
						lst.add("5");
						lst.add("6");
						lst.add("7");
						SpinnerListModel mod = new SpinnerListModel(lst);
						outboundBackupQuantity = new JSpinner(mod);
						panel_1.add(outboundBackupQuantity, "cell 1 7");
					}
					{
						JLabel lblInboundnickname = new JLabel("inbound.nickname");
						panel_1.add(lblInboundnickname, "cell 0 8,alignx trailing");
					}
					{
						inboundNickname = new JTextField();
						panel_1.add(inboundNickname, "cell 1 8,growx");
						inboundNickname.setColumns(10);
					}
					{
						JLabel lblOutboundnickname = new JLabel("outbound.nickname");
						panel_1.add(lblOutboundnickname, "cell 0 9,alignx trailing");
					}
					{
						outboundNickname = new JTextField();
						panel_1.add(outboundNickname, "cell 1 9,growx");
						outboundNickname.setColumns(10);
					}
					{
						inboundAllowZeroHop = new JCheckBox("inbound.allowZeroHop");
						panel_1.add(inboundAllowZeroHop, "cell 1 10,aligny baseline");
					}
					{
						outboundAllowZeroHop = new JCheckBox("outbound.allowZeroHop");
						panel_1.add(outboundAllowZeroHop, "cell 1 11");
					}
					{
						JLabel lblInboundiprestriction = new JLabel("inbound.IPRestriction");
						panel_1.add(lblInboundiprestriction, "cell 0 12,alignx trailing");
					}
					{
						List<String> lst = new LinkedList<String>();
						lst.add("Default");
						lst.add("0");
						lst.add("1");
						lst.add("2");
						lst.add("3");
						lst.add("4");
						SpinnerListModel mod = new SpinnerListModel(lst);
						inboundIPRestriction = new JSpinner(mod);
						panel_1.add(inboundIPRestriction, "cell 1 12");
					}
					{
						JLabel lblOutboundiprestriction = new JLabel("outbound.IPRestriction");
						panel_1.add(lblOutboundiprestriction, "cell 0 13,alignx trailing");
					}
					{
						List<String> lst = new LinkedList<String>();
						lst.add("Default");
						lst.add("0");
						lst.add("1");
						lst.add("2");
						lst.add("3");
						lst.add("4");
						SpinnerListModel mod = new SpinnerListModel(lst);
						outboundIPRestriction = new JSpinner(mod);
						panel_1.add(outboundIPRestriction, "cell 1 13");
					}
					{
						i2cpDontPublishLeaseSet = new JCheckBox("i2cp.dontPublishLeaseSet");
						panel_1.add(i2cpDontPublishLeaseSet, "cell 1 14,alignx center");
					}
					{
						JLabel lblIcpusername = new JLabel("i2cp.username");
						panel_1.add(lblIcpusername, "cell 0 15,alignx trailing");
					}
					{
						i2cpUsername = new JTextField();
						panel_1.add(i2cpUsername, "cell 1 15,growx");
						i2cpUsername.setColumns(10);
					}
					{
						JLabel lblIcppassword = new JLabel("i2cp.password");
						panel_1.add(lblIcppassword, "cell 0 16,alignx trailing");
					}
					{
						Password = new JTextField();
						panel_1.add(Password, "cell 1 16,growx");
						Password.setColumns(10);
					}
					{
						JLabel lblIcptcphost = new JLabel("i2cp.tcp.host");
						panel_1.add(lblIcptcphost, "cell 0 17,alignx trailing");
					}
					{
						i2cpHost = new JTextField();
						panel_1.add(i2cpHost, "cell 1 17,growx");
						i2cpHost.setColumns(10);
					}
					{
						JLabel lblIcptcpport = new JLabel("i2cp.tcp.port");
						panel_1.add(lblIcptcpport, "cell 0 18,alignx trailing");
					}
					{
						i2cpPort = new JTextField();
						panel_1.add(i2cpPort, "cell 1 18,growx");
						i2cpPort.setColumns(10);
					}
					{
						i2cpSSL = new JCheckBox("i2cp.SSL");
						panel_1.add(i2cpSSL, "cell 1 19");
					}
				}
				UseI2PBox.addChangeListener(new ChangeListener() {
					@Override
					public void stateChanged(ChangeEvent arg0) {
						setEditable();
					}
				});
			}
		}
		LoadI2PConfig();
		setEditable();
		{
			JPanel buttonPane = new JPanel();
			buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT));
			getContentPane().add(buttonPane, BorderLayout.SOUTH);
			{
				JButton okButton = new JButton("OK");
				okButton.setActionCommand("OK");
				okButton.addActionListener(new ActionListener() {
					@Override
					public void actionPerformed(ActionEvent a) {
						go();
					}
				});
				buttonPane.add(okButton);
				getRootPane().setDefaultButton(okButton);
			}
		}
		if (justgo) {
			setVisible(false);
			go(); 
		}
		else { setVisible(true); }
	}
	
	private void setEditable() {
		useproxy.setEnabled(!UseI2PBox.isSelected());
		textField.setEditable(!UseI2PBox.isSelected());
		textField_1.setEditable(!UseI2PBox.isSelected());
		peerPort.setEditable(!UseI2PBox.isSelected());
	}
	
	private Properties getProperties() {
		Properties props = new Properties();
		Pattern p = Pattern.compile("\\S+");
		Matcher m = p.matcher("");
		if (!getInboundQuantity().getValue().equals("Default")) {
			props.setProperty("inbound.quantity", getInboundQuantity().getValue().toString()); 		
		}
		if (!getOutboundQuantity().getValue().equals("Default")) {
			props.setProperty("outbound.quantity", getOutboundQuantity().getValue().toString()); 	
		}
		if (!getInboundLength().getValue().equals("Default")) {
			props.setProperty("inbound.length", getInboundLength().getValue().toString());    		
		}
		if (!getOutboundLength().getValue().equals("Default")) {
			props.setProperty("outbound.length", getOutboundLength().getValue().toString()); 		
		}
		if (!getInboundVariance().getValue().equals("Default")) {
			props.setProperty("inbound.lengthVariance", getInboundVariance().getValue().toString());
		}
		if (!getOutboundVariance().getValue().equals("Default")) {
			props.setProperty("outbound.lengthVariance", getOutboundVariance().getValue().toString()); 
		}
		if (!getInboundBackup().getValue().equals("Default")) {
			props.setProperty("inbound.backupQuantity", getInboundBackup().getValue().toString()); 	
		}
		if (!getOutboundBackupQuantity().getValue().equals("Default")) {
			props.setProperty("outbound.backupQuantity", getOutboundBackupQuantity().getValue().toString()); 
		}
		String s = getInboundNickname().getText();
		m.reset(s);
		if (m.find()) {
			props.setProperty("inbound.nickname", s);
		}
		s = getOutboundNickname().getText();
		m.reset(s);
		if (m.find()) {
			props.setProperty("outbound.nickname", s);
		}
		if (getInboundAllowZeroHop().isSelected()) {
			props.setProperty("inbound.allowZeroHop", "true");
		}
		else {
			props.setProperty("inbound.allowZeroHop", "false");
		}
		if (getOutboundAllowZeroHop().isSelected()) {
			props.setProperty("outbound.allowZeroHop", "true");
		}
		else {
			props.setProperty("outbound.allowZeroHop", "false"); 	
		}
		if (!getInboundIPRestriction().equals("Default")) {
			props.setProperty("inbound.IPRestriction", getInboundIPRestriction().getValue().toString());
		}
		if (!getOutboundIPRestriction().equals("Default")) {
			props.setProperty("outbound.IPRestriction", getOutboundIPRestriction().getValue().toString()); 	
		}
		if (getI2cpDontPublishLeaseSet().isSelected()) {
			props.setProperty("i2cp.dontPublishLeaseSet", "true");
		}
		else {
			props.setProperty("i2cp.dontPublishLeaseSet", "false");
		}
		s = getI2cpUsername().getText();
		m.reset(s);
		if (m.find()) {
			props.setProperty("i2cp.username", s);	
		}
		s = getPassword().getText();
		m.reset(s);
		if (m.find()) {
			props.setProperty("i2cp.password", s);
		}
		s = getI2cpHost().getText();
		m.reset(s);
		if (m.find()) {
			props.setProperty("i2cp.tcp.host", s);
		}
		s = getI2cpPort().getText();
		m.reset(s);
		if (m.find()) {
			props.setProperty("i2cp.tcp.port", s);
		}
		if (getI2cpSSL().isSelected()) {
			props.setProperty("i2cp.SSL", "true");
		}
		else {
			props.setProperty("i2cp.SSL", "false");
		}
		return props;
	}
	
	private void loadProperties(Properties props) {
		String s = props.getProperty("inbound.quantity");
		if (s != null) {
			getInboundQuantity().setValue(s);
		}
		s = props.getProperty("outbound.quantity");
		if (s != null) {
			getOutboundQuantity().setValue(s);
		}
		s = props.getProperty("inbound.length");
		if (s != null) {
			getInboundLength().setValue(s);
		}
		s = props.getProperty("outbound.length");
		if (s != null) {
			getOutboundLength().setValue(s);
		}
		s = props.getProperty("inbound.lengthVariance");
		if (s != null) {
			getInboundVariance().setValue(s);
		}
		s = props.getProperty("outbound.lengthVariance");
		if (s != null) {
			getOutboundVariance().setValue(s);
		}
		s = props.getProperty("inbound.backupQuantity");
		if (s != null) {
			getInboundBackup().setValue(s);
		}
		s = props.getProperty("outbound.backupQuantity");
		if (s != null) {
			getOutboundBackupQuantity().setValue(s);
		}
		s = props.getProperty("inbound.nickname");
		if (s != null) {
			getInboundNickname().setText(s);
		}
		s = props.getProperty("outbound.nickname");
		if (s != null) {
			getOutboundNickname().setText(s);
		}
		s = props.getProperty("inbound.allowZeroHop");
		if (s != null) {
			getInboundAllowZeroHop().setSelected(Boolean.valueOf(s));
		}
		s = props.getProperty("outbound.allowZeroHop");
		if (s != null) {
			getOutboundAllowZeroHop().setSelected(Boolean.valueOf(s));
		}
		s = props.getProperty("inbound.IPRestriction");
		if (s != null) {
			getInboundIPRestriction().setValue(s);
		}
		s = props.getProperty("outbound.IPRestriction");
		if (s != null) {
			getOutboundIPRestriction().setValue(s);
		}
		s = props.getProperty("i2cp.dontPublishLeaseSet");
		if (s != null) {
			getI2cpDontPublishLeaseSet().setSelected(Boolean.valueOf(s));
		}
		s = props.getProperty("i2cp.username");	
		if (s != null) {
			getI2cpUsername().setText(s);
		}
		s = props.getProperty("i2cp.password");
		if (s != null) {
			getPassword().setText(s);
		}
		s = props.getProperty("i2cp.tcp.host");
		if (s != null) {
			getI2cpHost().setText(s);
		}
		s = props.getProperty("i2cp.tcp.port");
		if (s != null) {
			getI2cpPort().setText(s);
		}
		s = props.getProperty("i2cp.SSL");
		if (s != null) {
			getI2cpSSL().setSelected(Boolean.valueOf(s));
		}
	}
	
	private void go() {
		if (UseI2PBox.isSelected()) {
			UseI2P = true;
			goI2P();
		}
		else {
			UseI2P = false;
			if (!useproxy.isSelected()) {
				UseProxy = false;
				goSimple();
			}
			else {
				String addr = textField.getText();
				if (!addr.matches("\\S+")) {
					JOptionPane.showMessageDialog(this, "Improper proxy address.");
				}
				else {
					String portstr = textField_1.getText();
					if (!portstr.matches("\\d+")) {
						JOptionPane.showMessageDialog(this, "Proxy port must be a number.");
					}
					else {
						try {
							ProxyPort = Integer.valueOf(portstr);
							ProxyAddr = addr;
							UseProxy = true;
							goSimple();
						}
						catch (Exception e) {
							JOptionPane.showMessageDialog(this, "The proxy port seems to be invalid.");
						}
					}
				}
			}
		}
	}
	
	public void goI2P() {
		SaveConfig();
		saveI2PConfig();
		if (!SimpleStarted) {
			if (I2PServer == null) {
				try {
					I2PServer = new OFSI2PServerSocket(BaseDir + File.separator + "i2pkey.dat", getProperties());
				} catch (Exception e) {
					e.printStackTrace();
					JOptionPane.showMessageDialog(this, "I2P Error.  Make sure it's running.  Check your i2p options.");
				}
				try {
					I2PConnector = (OFSI2PConnector) I2PServer.getOFSConnector();
				}
				catch (Exception e) {
				}
				GUI.InitPeer(I2PServer, I2PConnector, false);
				if (I2PServer != null) {
					GUI.setLocation(I2PServer.getMyLocation());
				}
				I2PStarted = true;
			}
			else {
				JOptionPane.showMessageDialog(this, "You will have to restart for your changes to take effect.");			
			}
		}
		else {
			JOptionPane.showMessageDialog(this, "You will have to restart for your changes to take effect.");			
		}
		setVisible(false);
	}
	
	public void goSimple() {
		SaveConfig();
		saveI2PConfig();
		if (!I2PStarted) {
			try {
				PeerPort = Integer.valueOf(peerPort.getText());
				if (SimpleServer == null) {
					SimpleServer = new SimpleServerSocket(new ServerSocket(PeerPort));
					SimpleConnector = new SimpleConnector(UseProxy, ProxyAddr, ProxyPort);
					GUI.InitPeer(SimpleServer, SimpleConnector, true);
				}
			}
			catch (Exception e) {
				JOptionPane.showMessageDialog(this, "The peer port seems to be invalid.");
				return;
			}
			SimpleConnector.setProxyAddr(ProxyAddr);
			SimpleConnector.setProxyPort(ProxyPort);
			SimpleConnector.setUseProxy(UseProxy);
			if (SimpleStarted) {
				JOptionPane.showMessageDialog(this, "If you have changed your peer port you will need to restart.");			
			}
			SimpleStarted = true;
		}
		else {
			JOptionPane.showMessageDialog(this, "You will have to restart for your changes to take effect.");			
		}
		setVisible(false);
	}

	public boolean isUseProxy() {
		return UseProxy;
	}

	public void setUseProxy(boolean useProxy) {
		UseProxy = useProxy;
	}

	public String getProxyAddr() {
		return ProxyAddr;
	}

	public void setProxyAddr(String proxyAddr) {
		ProxyAddr = proxyAddr;
	}

	public int getProxyPort() {
		return ProxyPort;
	}

	public void setProxyPort(int proxyPort) {
		ProxyPort = proxyPort;
	}

	public int getPeerPort() {
		return PeerPort;
	}
	
	public JCheckBox getUseI2PBox() {
		return UseI2PBox;
	}
	public JSpinner getInboundQuantity() {
		return inboundQuantity;
	}
	public JSpinner getOutboundQuantity() {
		return outboundQuantity;
	}
	public JSpinner getInboundLength() {
		return inboundLength;
	}
	public JSpinner getOutboundLength() {
		return outboundLength;
	}
	public JSpinner getInboundVariance() {
		return inboundVariance;
	}
	public JSpinner getOutboundVariance() {
		return outboundVariance;
	}
	public JSpinner getInboundBackup() {
		return inboundBackup;
	}
	public JSpinner getOutboundBackupQuantity() {
		return outboundBackupQuantity;
	}
	public JTextField getInboundNickname() {
		return inboundNickname;
	}
	public JTextField getOutboundNickname() {
		return outboundNickname;
	}
	public JCheckBox getInboundAllowZeroHop() {
		return inboundAllowZeroHop;
	}
	public JCheckBox getOutboundAllowZeroHop() {
		return outboundAllowZeroHop;
	}
	public JSpinner getInboundIPRestriction() {
		return inboundIPRestriction;
	}
	public JSpinner getOutboundIPRestriction() {
		return outboundIPRestriction;
	}
	public JCheckBox getI2cpDontPublishLeaseSet() {
		return i2cpDontPublishLeaseSet;
	}
	public JTextField getI2cpUsername() {
		return i2cpUsername;
	}
	public JTextField getI2cpHost() {
		return i2cpHost;
	}
	public JTextField getI2cpPort() {
		return i2cpPort;
	}
	public JCheckBox getI2cpSSL() {
		return i2cpSSL;
	}
	public JTextField getPassword() {
		return Password;
	}
}
