package sim.util;

import java.awt.*;
import java.awt.event.*;
import java.net.*;
import java.io.*;

import sim.MainWindow;
import sim.SimException;

import sim.util.DialogButton;

public class DownloadDialog extends Dialog implements ActionListener, FocusListener
{
	private static final String CATALOG = "catalog.tbl";
	private static final char SEPARATOR = '|';
	private TextField url = new TextField(15);
	private Choice files = new Choice();
	private String sourceURL;
	private String fileName;

	public DownloadDialog(String codeBase)
	{
		super(MainWindow.MAIN_WINDOW, "Download");

		this.setLayout(new GridBagLayout());
		this.setModal(true);

		this.url.setText(codeBase);
		this.url.addFocusListener(this);
		this.url.addActionListener(this);
		this.downloadFileNames();

		Panel p = new Panel(new FlowLayout(FlowLayout.RIGHT, 10, 10));
		DialogButton b = new DialogButton("OK");
		b.addActionListener(this);
		p.add(b);
		b = new DialogButton("Cancel");
		b.addActionListener(this);
		p.add(b);

		GridBagConstraints c = new GridBagConstraints();
		c.gridx = 0;
		c.gridy = 2;
		c.gridwidth = 1;
		c.weightx = 1;
		c.weighty = 0;
		c.gridheight = 1;
		c.anchor = GridBagConstraints.EAST;
		c.fill = GridBagConstraints.NONE;

		this.add(p, c);

		p = new Panel(new BorderLayout(10, 10));
		p.add(new Label("URL"), BorderLayout.WEST);
		p.add(this.url, BorderLayout.CENTER);

		c.gridy = 0;
		c.insets = new Insets(10, 10, 10, 10);
		c.fill = GridBagConstraints.HORIZONTAL;

		this.add(p, c);

		p = new Panel(new BorderLayout(10, 10));
		p.add(new Label("File name"), BorderLayout.WEST);
		p.add(this.files, BorderLayout.CENTER);

		c.gridy = 1;

		this.add(p, c);

		this.addWindowListener(new WindowAdapter()
		{
			public void windowClosing(WindowEvent e)
			{
				setVisible(false);
				fileName = null;
			}
		});
	}

	public void addNotify()
	{
		super.addNotify();

		this.setSize(300, 126 + this.getInsets().top + this.getInsets().bottom);
		this.setResizable(false);
		this.setLocation(MainWindow.getMiddleOfScreen(this));
	}

	public void setVisible(boolean b)
	{
		if(b)
			this.setLocation(MainWindow.getMiddleOfScreen(this));

		super.setVisible(b);
	}

	public void actionPerformed(ActionEvent e)
	{
		this.getURL();

		if(e.getSource() instanceof DialogButton)
		{
			if(((DialogButton)e.getSource()).getLabel().equals("OK") && this.files.isEnabled())
				this.fileName = this.files.getSelectedItem();
			else
				this.fileName = null;

			this.dispose();
		}
	}

	public void focusGained(FocusEvent e)
	{
	}

	public void focusLost(FocusEvent e)
	{
		this.getURL();
	}

	public String getURL()
	{
		if(!this.sourceURL.equals(this.url.getText()))
			this.downloadFileNames();

		return this.sourceURL;
	}

	public String getFile()
	{
		return this.fileName;
	}

	private void downloadFileNames()
	{
		this.sourceURL = this.url.getText();

		if(this.sourceURL.charAt(this.sourceURL.length() - 1) != '/')
		{
			this.sourceURL = this.sourceURL + '/';
			this.url.setText(this.sourceURL);
		}

		try
		{
			InputStream in = new URL(this.sourceURL + DownloadDialog.CATALOG).openStream();

			String read = new String();
			byte[] buffer = new byte[1];
			buffer[0] = (byte)in.read();

			while(buffer[0] != -1)
			{
				read = read + new String(buffer);
				buffer[0] = (byte)in.read();
			}
			in.close();

			String parameter = this.extractParameter(read, 0);

			int size = Integer.valueOf(parameter).intValue();

			if(size > 0)
			{
				String[] circuits = this.extractParameters(parameter.length() + 1, size, read);
				this.files.removeAll();

				for(size = 0; size < circuits.length; size++)
					this.files.addItem(circuits[size]);

				this.files.setEnabled(true);
				this.files.invalidate();
			}
			else
				throw (new SimException("incorrect file format"));
		}
		catch(MalformedURLException mue)
		{
			this.files.removeAll();
			this.files.setEnabled(false);
		}
		catch(IOException ie)
		{
			this.files.removeAll();
			this.files.setEnabled(false);
		}
		catch(NumberFormatException nfe)
		{
			this.files.removeAll();
			this.files.setEnabled(false);
		}
		catch(SimException se)
		{
			this.files.removeAll();
			this.files.setEnabled(false);
		}
	}

	private String[] extractParameters(int position, int size, String in) throws SimException
	{
		String[] result = new String[size];

		for(int index = 0; index < size; index++)
		{
			result[index] = this.extractParameter(in, position);
			position = position + result[index].length() + 1;
		}

		return result;
	}

	private String extractParameter(String in, int position) throws SimException
	{
		String result = new String();

		if(position >= in.length())
			throw (new SimException("incorrect file format"));
		else if(in.charAt(position) == DownloadDialog.SEPARATOR)
			throw (new SimException("incorrect file format"));

		boolean finished = false;

		while(!finished)
		{
			if(in.charAt(position) != DownloadDialog.SEPARATOR)
				result = result + in.charAt(position);
			else
				finished = true;

			position = position + 1;

			if((!finished) && (position >= in.length()))
				throw (new SimException("incorrect file format"));
		}

		return result;
	}
}
