/*
 * AirportBaseStationHangup Utility
 *
 * Copyright (C) 2000, Jonathan Sevy <jsevy@mcs.drexel.edu>
 *
 * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 */



import java.util.*;
import java.net.*;
import java.awt.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.plaf.*;
import java.awt.event.*;
//import snmp.*;




public class AirportBaseTester extends JFrame
							implements ActionListener, Runnable, WindowListener
{
	
	JButton sendPayloadButton, newHostButton, setPasswordButton;
	JTextArea messagesArea;
	JScrollPane messagesScroll;
	JTextField hostIDField, payloadField;
	JLabel authorLabel, hostIDLabel, payloadLabel;
	
	MenuBar theMenubar;
	Menu fileMenu;
	MenuItem quitItem;
	
	//SNMPv1CommunicationInterface comInterface;
	String community;
	InetAddress hostAddress;
	int version;
	
	boolean minimized;
	
	long startTime;		// used to hold approximate modem connection start time
	Thread statusThread;
			
	
	
			
	
	public AirportBaseTester() 
	{
		setUpDisplay();
		
		
		try
		{
			community = "public";
			version = 0;	// SNMPv1
			hostAddress = InetAddress.getByName(hostIDField.getText());
			
			//comInterface = new SNMPv1CommunicationInterface(version, hostAddress, community);
			// set socket timeout to 5 seconds
			//comInterface.setSocketTimeout(5000);
			
			/*
			statusThread = new Thread(this);
			statusThread.start();
			*/
		}
		catch(Exception e)
		{
			messagesArea.setText("Exception during startup:  " + e + "\n");
		}
		
		
		
	}
	
	
	
	private void setUpDisplay()
	{
		
		
		try
		{
			// set look-and-feel to native platform l&f, if possible
			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
		}
		catch(Exception e)
		{
			// or not...
		}

		
		this.getRootPane().setBorder(new BevelBorder(BevelBorder.RAISED));
		
		// set fonts to smaller-than-normal size, for compaction!
		FontUIResource appFont = new FontUIResource("SansSerif", Font.PLAIN, 10);
		UIDefaults defaults = UIManager.getLookAndFeelDefaults();
		Enumeration keys = defaults.keys();
		
		while (keys.hasMoreElements())
		{
			String nextKey = (String)(keys.nextElement());
			if ((nextKey.indexOf("font") > -1) || (nextKey.indexOf("Font") > -1))
			{
			    UIManager.put(nextKey, appFont);
			}
		}
		
		// register self as WindowListener, to catch minimization events
		addWindowListener(this);
		
		/*
		theMenubar = new MenuBar();
		this.setMenuBar(theMenubar);
		fileMenu = new Menu("File");
		
		quitItem = new MenuItem("Quit");
		quitItem.setActionCommand("quit");
		quitItem.addActionListener(this);
		fileMenu.add(quitItem);
		
		theMenubar.add(fileMenu);
		*/
		
		hostIDLabel = new JLabel("Address:");
		hostIDField = new JTextField(10);
		hostIDField.setText("10.0.1.1");
		hostIDField.setEditable(false);
		
		payloadLabel = new JLabel("Payload:");
		payloadField = new JTextField(10);
		payloadField.setEditable(true);
		
		authorLabel = new JLabel(" Version 1.0        J. Sevy, March 2002");
		authorLabel.setFont(new Font("SansSerif", Font.ITALIC, 8));
			
		
		sendPayloadButton = new JButton("Send payload");
		sendPayloadButton.setActionCommand("send payload");
		sendPayloadButton.addActionListener(this);
		
		newHostButton = new JButton("Set address");
		newHostButton.setActionCommand("new host");
		newHostButton.addActionListener(this);
		
		setPasswordButton = new JButton("Set password");
		setPasswordButton.setActionCommand("set password");
		setPasswordButton.addActionListener(this);
		
		messagesArea = new JTextArea(20,30);
		messagesScroll = new JScrollPane(messagesArea);
		 
		/*
        URL url = AirportBaseStationHangup.class.getResource("iconImage.gif");
		this.setIconImage(Toolkit.getDefaultToolkit().getImage(url));
		*/
		
		
		
		// now set up display
		// set params for layout manager
		GridBagLayout  theLayout = new GridBagLayout();
		GridBagConstraints c = new GridBagConstraints();
		
		c.gridwidth = 1;
		c.gridheight = 1;
		c.fill = GridBagConstraints.NONE;
		c.ipadx = 0;
		c.ipady = 0;
		c.insets = new Insets(2,2,2,2);
		c.anchor = GridBagConstraints.CENTER;
		c.weightx = 0;
		c.weighty = 0;
		
		
		this.setTitle("OSU-NMS Tester");
		
		Panel buttonPanel = new Panel();
		buttonPanel.setLayout(theLayout);
		
		c.gridx = 1;
		c.gridy = 1;
		theLayout.setConstraints(sendPayloadButton, c);
		buttonPanel.add(sendPayloadButton);
		
		c.gridx = 2;
		c.gridy = 1;
		theLayout.setConstraints(payloadField, c);
		buttonPanel.add(payloadField);
		
		
		
		
		Panel hostPanel = new Panel();
		hostPanel.setLayout(theLayout);
		
		c.gridx = 1;
		c.gridy = 1;
		theLayout.setConstraints(hostIDLabel, c);
		hostPanel.add(hostIDLabel);
		
		c.gridx = 2;
		c.gridy = 1;
		theLayout.setConstraints(hostIDField, c);
		hostPanel.add(hostIDField);
		
		
		c.gridx = 1;
		c.gridy = 2;
		theLayout.setConstraints(newHostButton, c);
		hostPanel.add(newHostButton);
		
		c.gridx = 2;
		c.gridy = 2;
		theLayout.setConstraints(setPasswordButton, c);
		hostPanel.add(setPasswordButton);
		
		
		
		c.gridwidth = 1;
		c.anchor = GridBagConstraints.CENTER;
		
		
		
		
		this.getContentPane().setLayout(theLayout);
		
		
		c.gridx = 1;
		c.gridy = 1;
		theLayout.setConstraints(hostPanel, c);
		this.getContentPane().add(hostPanel);
		
		
		c.gridx = 1;
		c.gridy = 2;
		theLayout.setConstraints(buttonPanel, c);
		this.getContentPane().add(buttonPanel);
		
		
		c.gridx = 1;
		c.gridy = 3;
		JLabel messagesLabel = new JLabel("Messages:");
		theLayout.setConstraints(messagesLabel, c);
		this.getContentPane().add(messagesLabel);
		
		
		c.weightx = .5;
		c.weighty = .5;
		
		c.gridx = 1;
		c.gridy = 4;
		c.fill = GridBagConstraints.BOTH;
		theLayout.setConstraints(messagesScroll, c);
		this.getContentPane().add(messagesScroll);				
		
		c.weightx = 0;
		c.weighty = 0;
		c.fill = GridBagConstraints.NONE;
		
		c.gridx = 1;
		c.gridy = 5;
		theLayout.setConstraints(authorLabel, c);
		this.getContentPane().add(authorLabel);
		
		
		
		
	}
	
	
	
	// WindowListener methods
	
	public void windowActivated(WindowEvent e)
	{
		// do nothing
	}
	
	
	public void windowClosing(WindowEvent e)
	{
	    // exit
	    System.exit(0);
	}
	
	
	public void windowClosed(WindowEvent e)
	{
		// do nothing
	}
	
	
	public void windowDeactivated(WindowEvent e)
	{
		// do nothing
	}
	
	
	public void windowOpened(WindowEvent e)
	{
		// do nothing
	}
	
	
	public void windowIconified(WindowEvent e)
	{
	    // display minimized stuff; will print just connect time (or "Unconnected") as title text
	    minimized = true;
	    
	}
	
	
	public void windowDeiconified(WindowEvent e)
	{
	    // display full title; connect time will be placed in
	    minimized = false;
	    
	}
	
	
	
	
	
	public void actionPerformed(ActionEvent theEvent)
	// respond to button pushes, menu selections
	{
		String command = theEvent.getActionCommand();
		
	
		if (command == "quit")
		{
			System.exit(0);
		}
		
		
		
		if (command == "new host")
		{
			
			String newHost = JOptionPane.showInputDialog("Input new host:");
			if (newHost != null)
			{
				
				try
				{
					hostAddress = InetAddress.getByName(newHost);
					//comInterface = new SNMPv1CommunicationInterface(version, hostAddress, community);
					hostIDField.setText(newHost);
					
					startTime = -1;		// -1 indicates start time not yet set
					
				
				}
				catch(UnknownHostException e)
				{
					JOptionPane.showMessageDialog(this, "Unknown host name supplied.");
				}
				catch(Exception e)
				{
					JOptionPane.showMessageDialog(this, "Error setting new host.");
				}
			}
			
		}
		
		
		
		if (command == "set password")
		{
			
			String newPassword = JOptionPane.showInputDialog("Base station password:");
			
			if (newPassword != null)
			{
				
				try
				{
					community = newPassword;
					//comInterface = new SNMPv1CommunicationInterface(version, hostAddress, community);
					
					startTime = -1;		// -1 indicates start time not yet set
					
				
				}
				catch(Exception e)
				{
					JOptionPane.showMessageDialog(this, "Error entering new password.");
				}
			}
			
		}
		
		
		
		if (command == "send payload")
		{
			sendPayload();
		}	
		
		
		
	
		
	}
	
	
	
	private void sendPayload() 
	{
		try
		{
			
			DatagramSocket dSocket = new DatagramSocket();
			dSocket.setSoTimeout(1000);	// 1 second
			int OSU_NMS_PORT = 192;
			InetAddress hostAddress = InetAddress.getByName(hostIDField.getText());
	
			
			try
			{
				
				messagesArea.append("Sending payload " + payloadField.getText() + "\n");
				
				// get the payload field, convert to bytes
				byte[] payloadBytes = new byte[116];
				byte[] textBytes = convertFromHexString(payloadField.getText());
				int length = payloadBytes.length < textBytes.length? payloadBytes.length : textBytes.length;
				
				for(int i = 0; i < length; i++)
					payloadBytes[i] = textBytes[i];
				
				DatagramPacket outPacket = new DatagramPacket(payloadBytes, payloadBytes.length, hostAddress, OSU_NMS_PORT);
						
				dSocket.send(outPacket);
				
				
				// wait for a reply
				byte[] bytes = new byte[116];	// from sniffs
				
				DatagramPacket inPacket = new DatagramPacket(bytes, bytes.length);
				dSocket.receive(inPacket);
				bytes = inPacket.getData();
				
				
				messagesArea.append("Returned Message bytes:\n");
				for (int i = 0; i < bytes.length; ++i)
				{
					messagesArea.append(hexByte(bytes[i]) + " ");
					
					if ((i+1)%16 == 0)
						messagesArea.append("\n");
				}
				messagesArea.append("\n");
				
				for (int i = 0; i < bytes.length; ++i)
				{
					messagesArea.append((char)bytes[i] + "");
					
					if ((i+1)%16 == 0)
						messagesArea.append("\n");
				}
				messagesArea.append("\n");
					
							
			}
			catch(Exception e)
			{
				System.out.println("Exception during payload send:  " + e.toString() + "\n");
			}
		
		
		}
		
		catch(Exception e)
		{
			//messagesArea.append("Exception during payload send:  " + e.toString() + "\n");
		}
		
	}
	
	
	
	
	private byte[] convertFromHexString(String hexString)
		throws NumberFormatException
	{
		
		// eliminate spaces in string
		hexString.trim();
		int index;
		while((index = hexString.indexOf(' ')) != -1)
		{
			hexString = hexString.substring(0,index) + hexString.substring(index+1);
		}
		
		// make sure have even number of hex digits
		if (2 * (hexString.length()/2) != hexString.length())
			throw new NumberFormatException("Must have an even number of hexadecimal digits.");
		
		byte[] bytes = new byte[hexString.length()/2];
		
		for (int i = 0; i < bytes.length; i++)
		{
			// get next pair of digits
			String digitString = hexString.substring(2*i,2*i+2);
			
			try
			{
				int value = Integer.parseInt(digitString, 16);	
				bytes[i] = (byte)value;
			}
			catch (NumberFormatException e)
			{
				throw new NumberFormatException("Entries must be hexadecimal digits (0 through 9 and a through f or A through F) or spaces.");
			}
			
		}
		
		return bytes;
	}
	
	
	
	
	
	
	private String hexByte(byte b)
	{
		int pos = b;
		if (pos < 0)
			pos += 256;
		String returnString = new String();
		returnString += Integer.toHexString(pos/16);
		returnString += Integer.toHexString(pos%16);
		return returnString;
	}
	
	
	
	
	public void run()
	{
		statusPollingThreadRoutine();
		
	}
	
	
	
	
	
	private void statusPollingThreadRoutine()
	{
		
		
		
	}
	
	
	
	
	
	
	public static void main(String args[]) 
	{
		try
		{
			AirportBaseTester theApp = new AirportBaseTester();
			theApp.pack();
			theApp.show();
		}
		catch (Exception e)
		{}
	}
	

}