package ANTARCTICA.downloadTest;

import java.util.*;
import java.net.*;
import java.security.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import com.objectspace.voyager.*;

public class DownloadTest extends JApplet {

	private static final String TITLE = "Download GUI";

	public static void main(String[] args) throws Exception {
		Voyager.startup();
		new DownloadTest(new JFrame(TITLE));
	}

	private IPick pick;
	private Method method;
	private String node = "sid.cps.unizar.es";
	private String port = "9000";
	private JFrame jframe;
	private JLabel piecesInfo;
	private JTextField piecesField, downloadTextfield;
	private JComboBox retrieveMethod;
	private JButton retrieveJButton, downloadJButton;

	DownloadTest(JFrame jframe) {
		this.jframe = jframe;
		initialize();
	}

	public DownloadTest() throws Exception {
		
		this.jframe = new JFrame(TITLE);
		SecurityManager sm = System.getSecurityManager();

		if (sm != null) {
			Permission[] permissions = {
				new SerializablePermission("enableSubstitution"),
				new RuntimePermission("createClassLoader"),
				new RuntimePermission("accessDeclaredMembers"),
				new SocketPermission("*", "accept, connect, listen, resolve"),
				};
			Vector errors = new Vector();
			for (int i = 0; i < permissions.length; i++) {
				try {
					sm.checkPermission(permissions[i]);
				} catch (Exception e) {
					errors.add(permissions[i].toString());
				}
			}
			if (!errors.isEmpty()) {
				String message = "Java permissions needed to execute this applet:\n";
				for (int i = 0; i < errors.size(); i++) {
					message = message + errors.elementAt(i) + "\n";
				}
				JOptionPane.showMessageDialog(jframe, message, "SECURITY",
					JOptionPane.ERROR_MESSAGE);
				return;
			}
		}


		Voyager.startup(this, null);
		initialize();
	}

	private void initialize() {
		jframe.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		jframe.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent e) {
				System.exit(0);
			}
		});
		jframe.setResizable(false);
		JMenuBar menuBar = new JMenuBar();
		jframe.setJMenuBar(menuBar);
		JMenu fileMenu = menuBar.add(new JMenu("File"));
		JMenuItem contactFileMenu = fileMenu.add(
			new JMenuItem("Contact Server"));
		contactFileMenu.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String url = "//" + node + ":" + port + "/Pick";
				try {
					Object o = Namespace.lookup(url);
					pick = (IPick) o;
				} catch (Exception exc) {
					pick = null;
					JOptionPane.showMessageDialog(jframe, exc, "EXCEPTION",
						JOptionPane.ERROR_MESSAGE);
				}
				method = null;
				adjust();
			}
		});
		fileMenu.addSeparator();
		JMenuItem exitMenuItem = fileMenu.add(new JMenuItem("Exit"));
		exitMenuItem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				System.exit(0);
			}
		});
		JMenu optionsMenu = menuBar.add(new JMenu("Options"));
		JMenuItem GSNMenuItem = optionsMenu.add(new JMenuItem("GSN"));
		GSNMenuItem.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				String result;
				result = JOptionPane.showInputDialog(jframe,
					"Location of GSN (currently " + node + "):");
				if (result != null && !result.equals("")) {
					node = result;
					pick = null;
				}
				result = JOptionPane.showInputDialog(jframe,
					"Port of GSN (currently " + port + "):");
				if (result != null && !result.equals("")) {
					port = result;
					pick = null;
				}
				adjust();
			}
		});

		GridBagLayout gridbag = new GridBagLayout();
		GridBagConstraints c = new GridBagConstraints();
		JPanel mainJPanel = new JPanel(gridbag);
		jframe.setContentPane(mainJPanel);

		piecesInfo = new JLabel();
		//c.gridwidth = 13;
		c.gridwidth = GridBagConstraints.RELATIVE;
		c.fill = GridBagConstraints.HORIZONTAL;
		gridbag.setConstraints(piecesInfo, c);
		mainJPanel.add(piecesInfo);

		piecesField = new JTextField();
		piecesField.setPreferredSize(new Dimension(30, (int) piecesField.getPreferredSize().getHeight()));
		piecesField.addInputMethodListener(new InputMethodListener() {
			public void caretPositionChanged(InputMethodEvent e) {
			}
			public void inputMethodTextChanged(InputMethodEvent e) {
				method = null;
				adjust();
			}
		});
		c.gridwidth = 1;
		gridbag.setConstraints(piecesField, c);
		mainJPanel.add(piecesField);

		retrieveJButton = new JButton("Retrieve");
		retrieveJButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				try {
					int numPiece = Integer.parseInt(piecesField.getText());
					method.retrieve(numPiece);
					JOptionPane.showMessageDialog(jframe, "Piece successfully retrieved", "OK",
						JOptionPane.INFORMATION_MESSAGE);
				} catch (Exception exc) {
					JOptionPane.showMessageDialog(jframe, exc, "EXCEPTION",
						JOptionPane.ERROR_MESSAGE);
				}
				adjust();
			}
		});
		c.gridwidth = 4;
		c.gridx = 2;
		c.gridy = 1;
		c.fill = GridBagConstraints.NONE;
		gridbag.setConstraints(retrieveJButton, c);
		mainJPanel.add(retrieveJButton);

		retrieveMethod = new JComboBox();
		retrieveMethod.addItem("HTTP method");
		retrieveMethod.addItem("CORBA method");
		retrieveMethod.addItem("REMOTE method");
		retrieveMethod.addItem("MOBILE method");
		retrieveMethod.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				Object item = retrieveMethod.getSelectedItem();
				if (item.equals("HTTP method")) {
					method = new HTTPMethod(pick);
				} else if (item.equals("CORBA method")) {
					method = new CORBAMethod(pick);
				} else if (item.equals("REMOTE method")) {
					method = new REMOTEMethod(pick);
				} else if (item.equals("MOBILE method")) {
					method = new MOBILEMethod(pick);
				}
				adjust();
			}
		});
		c.gridwidth = 4;
		c.gridx = 8;
		gridbag.setConstraints(retrieveMethod, c);
		mainJPanel.add(retrieveMethod);

		downloadJButton = new JButton("Download");
		downloadJButton.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {
				SecurityManager sm = System.getSecurityManager();
				if (sm != null) {
					boolean error = false;
					Permission[] permissions = {
						new FilePermission(downloadTextfield.getText(), "write"),
						new FilePermission(downloadTextfield.getText() + File.separator + "*", "write"),
					};
					for (int i = 0; i < permissions.length; i++) {
						try {
							sm.checkPermission(permissions[i]);
						} catch (Exception exc) {
							JOptionPane.showMessageDialog(jframe, exc, "SEGURIDAD",
								JOptionPane.ERROR_MESSAGE);
							error = true;
						}
					}
					if (error) {
						return;
					}
					try {
						method.download(downloadTextfield.getText());
						JOptionPane.showMessageDialog(jframe, "Piece successfully downloaded", "OK",
							JOptionPane.INFORMATION_MESSAGE);
					} catch (Exception exc) {
						JOptionPane.showMessageDialog(jframe, exc, "EXCEPTION",
							JOptionPane.ERROR_MESSAGE);
					}
					adjust();
				}
			}
		});
		c.gridwidth = 4;
		c.gridx = 0;
		c.gridy = 2;
		c.fill = GridBagConstraints.HORIZONTAL;
		gridbag.setConstraints(downloadJButton, c);
		mainJPanel.add(downloadJButton);

		File downloadFiledir=new File(".");
		downloadTextfield=new JTextField();
		try {
			downloadTextfield.setText(downloadFiledir.getCanonicalPath());
		} catch (Exception e) {
			downloadTextfield.setText("Unknown download dir");
		}
		downloadTextfield.setPreferredSize(new Dimension(30, (int) downloadTextfield.getPreferredSize().getHeight()));
		c.gridwidth = GridBagConstraints.REMAINDER;
		c.gridx = GridBagConstraints.RELATIVE;
		gridbag.setConstraints(downloadTextfield, c);
		mainJPanel.add(downloadTextfield);

		adjust();
		jframe.pack();
		Dimension screen=jframe.getToolkit().getScreenSize();
		jframe.setLocation((screen.width-jframe.getSize().width)/2,
			(screen.height-jframe.getSize().height)/2);
		jframe.show();

	}

	private void adjust() {
		retrieveMethod.setEnabled(pick != null);
		if (pick != null) {
			if (method == null) {
				Object item = retrieveMethod.getSelectedItem();
				if (item.equals("HTTP method")) {
					method = new HTTPMethod(pick);
				} else if (item.equals("CORBA method")) {
					method = new CORBAMethod(pick);
				} else if (item.equals("REMOTE method")) {
					method = new REMOTEMethod(pick);
				} else if (item.equals("MOBILE method")) {
					method = new MOBILEMethod(pick);
				}
			}
			try {
				int numPieces = pick.getNumPieces();
				piecesInfo.setText(numPieces +
					" pieces available. Select one (0-" +
					(numPieces - 1) + "):");
			} catch (Exception e) {
				JOptionPane.showMessageDialog(jframe, e, "EXCEPTION",
					JOptionPane.ERROR_MESSAGE);
				pick = null;
				adjust();
				return;
			}
		} else {
			method = null;
			piecesInfo.setText("No information about pieces available yet");
		}
		retrieveJButton.setEnabled(method != null);
		downloadJButton.setEnabled((method != null) &&
			(method.canDownload()));
		jframe.pack();
	}

}
