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)
			{
				hide();
				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;
	}
}
