/*
 * AirPort Port Inspector
 *
 * Copyright (C) 2003, 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
 *
 */

package airportinspector; 
 
import java.awt.*;
import java.awt.event.*;
import java.util.*;
import java.io.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;

/**
*	Handles display and updating of port mapping information.
*/

public class PortMapTable extends JPanel
{
	private Vector portInfoVector, portCountVector;
	private JTable table;
	private AbstractTableModel tableModel;
	private JScrollPane scrollPane;
	
	private int displayType;
	
	public static final int DETAILED = 0;
	public static final int SIMPLE = 1;
	
	
	/**
	*	Table model which maintains detailed list of port mappings.
	*/
	private class DetailedPortMapTableModel extends AbstractTableModel
	{
		public int getColumnCount() 
		{ 
			return 8; 
		}
		
		public int getRowCount() 
		{ 
			return portInfoVector.size();
		}
		
		public boolean isCellEditable(int row, int col) 
		{ 
			return false;
		}
		
		public String getColumnName(int col) 
		{ 
			switch (col)
			{
				case 0:
					return "      Local MAC       ";
					
				case 1:
					return "      Local IP      ";
					
				case 2:
					return "Local port";
					
				case 3:
					return "     Remote IP      ";
					
				case 4:
					return "Remote port";
					
				case 5:
					return "Router port";
					
				case 6:
					return "Port type";
					
				case 7:
					return "Life (sec)";
					
				default:
					return "";
			}
			
		}
		
		public Object getValueAt(int row, int col)
		{
			
			if (row < portInfoVector.size())
			{
				PortInfo portInfo = (PortInfo)portInfoVector.elementAt(row);
				
				switch (col)
    			{
    				case 0:
    					return portInfo.localMAC;
    					
    				case 1:
    					return portInfo.localIP;
    					
    				case 2:
    					return new Integer(portInfo.localPort);
    					
    				case 3:
    					return portInfo.remoteIP;
    					
    				case 4:
    					return new Integer(portInfo.remotePort);
    					
    				case 5:
    					return new Integer(portInfo.gatewayPort);
    					
    				case 6:
    				{
    					if (portInfo.portType == 1)
    					    return "TCP";
    					else
    					    return "UDP";
    				}
    				case 7:
    					return new Integer(portInfo.lifetime);
    					
    				default:
    					return "";
    			}
		    }
			else
				return "";
		}
		
		
		
	}
	
	
	
	
	
	/**
	*	Table model which maintains simplified list of port mappings.
	*/
	private class SimplePortMapTableModel extends AbstractTableModel
	{
		public int getColumnCount() 
		{ 
			return 3; 
		}
		
		public int getRowCount() 
		{ 
			return portCountVector.size();
		}
		
		public boolean isCellEditable(int row, int col) 
		{ 
			return false;
		}
		
		public String getColumnName(int col) 
		{ 
			switch (col)
			{
				case 0:
					return "Local MAC address";
					
				case 1:
					return "Local IP address";
					
				case 2:
					return "Open ports";
				default:
					return "";
			}
			
		}
		
		public Object getValueAt(int row, int col)
		{
			
			if (row < portCountVector.size())
			{
				PortCount portCount = (PortCount)portCountVector.elementAt(row);
				
				switch (col)
    			{
    				case 0:
    					return portCount.localMAC;
    					
    				case 1:
    					return portCount.localIP;
    					
    				case 2:
    					return new Integer(portCount.portCount);
    					
    				default:
    					return "";
    			}
		    }
			else
				return "";
		}
		
		public void setValueAt(Object newValue, int row, int col) 
		{
			
		}
		
	}
	
	
	
	
	
	
	/**
	*	Create new table based on data in airportInfo.
	*/
	
	public PortMapTable(PortInfoTreeMap portInfoHashtable, int displayType)
	{
		this.portInfoVector = new Vector(portInfoHashtable.values());
		setPortCount();
		table = new JTable();
		setDisplayType(displayType);
		scrollPane = new JScrollPane(table);
		setUpDisplay();
	}
	
	
	
	
	private void setUpDisplay()
	{
		
		GridBagLayout  theLayout = new GridBagLayout();
		this.setLayout(theLayout);
		
		GridBagConstraints c = new GridBagConstraints();
		
		c.gridwidth = 1;
		c.gridheight = 1;
		c.fill = GridBagConstraints.BOTH;
		c.ipadx = 0;
		c.ipady = 0;
		Insets theMargin = new Insets(2,2,2,2);
		c.insets = theMargin;
		c.anchor = GridBagConstraints.CENTER;
		c.weightx = .5;
		c.weighty = .5;
		
		c.gridx = 1;
		c.gridy = 1;
		theLayout.setConstraints(scrollPane, c);
		this.add(scrollPane);
	}
	
	
	
	public synchronized void setInfo(PortInfoTreeMap portInfoHashtable)
	{
	    this.portInfoVector = new Vector(portInfoHashtable.values());
	    setPortCount();
	    tableModel.fireTableDataChanged();
	    //table.doLayout();
	    //table.repaint();
	    //this.revalidate();
	}
		
		
		
	public synchronized void setDisplayType(int displayType)
	{
	    this.displayType = displayType;
	    if (displayType == DETAILED)
		{
		    tableModel = new DetailedPortMapTableModel();
		    table.setModel(tableModel);
		    table.setPreferredScrollableViewportSize(new Dimension(680,300));
		}
		else    // (displayType == SIMPLE)
		{
		    tableModel = new SimplePortMapTableModel();
		    table.setModel(tableModel);
    	    table.setPreferredScrollableViewportSize(new Dimension(300,300));
		}
		
		setColumnPreferredWidths(table);
    	table.setCellSelectionEnabled(false);
    	
	}
	
	
		
	
	/**
	*	Refresh the display based on the current data in the underlying byte block.
	*/
	
	/*
	public synchronized void refreshDisplay()
	{
		
		
		
	}
	*/
	
	
	private void setPortCount()
	{
	    portCountVector = new Vector();
	    String currentIP = "";
	    PortCount portCount = new PortCount(currentIP, "");
	    
	    for (int i = 0; i < portInfoVector.size(); i++)
	    {
	        PortInfo portInfo = (PortInfo)portInfoVector.elementAt(i);
	        
	        if (currentIP.equals(portInfo.localIP))
	        {
	            // same local host as previous; just increment count
	            portCount.portCount++;
	        }
	        else
	        {
	            // new local host; add new entry
	            portCount = new PortCount(portInfo.localIP, portInfo.localMAC);
	            portCount.portCount++;
	            portCountVector.add(portCount);
	            currentIP = portInfo.localIP;
	        }
	    }
	}
	
	
	
	public void setColumnPreferredWidths(JTable table) 
	{
		TableModel tableModel = table.getModel();
		TableColumnModel tableColumnModel = table.getColumnModel();
		
		for (int i = 0; i < tableModel.getColumnCount(); i++)
		{
		    int stringSize = tableModel.getColumnName(i).length();
		    tableColumnModel.getColumn(i).setPreferredWidth(stringSize*20);
		}
	}
		
		
	
	
	/*
	public void doLayout()
	{
	    super.doLayout();
	    System.out.println("doLayout called");
	}
	
	
	public void validate()
	{
	    super.validate();
	    System.out.println("validate called");
	}
	
	
	public void invalidate()
	{
	    super.invalidate();
	    System.out.println("invalidate called");
	}
	
	
	public void repaint()
	{
	    super.repaint();
	    System.out.println("repaint called");
	}
	
	
	public void update(Graphics g)
	{
	    super.update(g);
	    System.out.println("update called, clipRect = " + g.getClipBounds());
	}
	
	
	public void paintAll(Graphics g)
	{
	    super.paintAll(g);
	    System.out.println("paintall called");
	}
	
	
	public void paint(Graphics g)
	{
	    super.paint(g);
	    //System.out.println("paint called");
	    System.out.println("paint called, mapcount = " + portInfoVector.size() + ", table = " + table);
	}
	*/
	

}