/*
 * Wireless Host Monitor
 *
 * 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
 *
 */

 
 
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 KnownHostTable extends JPanel
{
	private Vector displayVector;
	private JTable table;
	private AbstractTableModel tableModel;
	private JScrollPane scrollPane;
	
	
	
	/**
	*	Table model which maintains list of name - mac address pairs.
	*/
	private class KnownHostTableModel extends AbstractTableModel
	{
		public int getColumnCount() 
		{ 
			return 2; 
		}
		
		public int getRowCount() 
		{ 
			return displayVector.size() + 1;
		}
		
		public boolean isCellEditable(int row, int col) 
		{ 
			// allow first empty row to be editted
			if (row <= displayVector.size())
			    return true;
			else
			    return false;
		}
		
		public String getColumnName(int col) 
		{ 
			switch (col)
			{
				case 0:
					return "Name";
					
				case 1:
					return "MAC address";
					
				default:
					return "";
			}
			
		}
		
		public Object getValueAt(int row, int col)
		{
			
			if (row < displayVector.size())
			{
				String[] hostInfo = (String[])displayVector.elementAt(row);
				
				switch (col)
    			{
    				case 0:
    					return hostInfo[0];     // name
    					
    				case 1:
    					return hostInfo[1];     // MAC address
    					
    				default:
    					return "";
    			}
		    }
			else
				return "";
		}
		
		public void setValueAt(Object newValue, int row, int col) 
		{
			// do nothing if row is bigger than vector size
			if (row > displayVector.size())
			    return;
			
			if (newValue instanceof String)
			{
				if (row < displayVector.size())
				{
					String[] hostInfo = (String[])displayVector.elementAt(row);
					hostInfo[col] = (String)newValue;
				}
				else
				{
					String[] hostInfo = {"",""};
					hostInfo[col] = (String)newValue;
					displayVector.insertElementAt(hostInfo, displayVector.size());
				}
			}

		}
		
	}
	
	
	
	
	
	
	/**
	*	Create new empty table
	*/
	
	public KnownHostTable()
	{
		
		displayVector = new Vector();
		table = new JTable();
		tableModel = new KnownHostTableModel();
		table.setModel(tableModel);
        table.setPreferredScrollableViewportSize(new Dimension(300,300));
		scrollPane = new JScrollPane(table);
		setUpDisplay();
	}
	
	
	
	/**
	*	Create new table based on data in config file.
	*/
	
	public KnownHostTable(TreeMap knownHostTreeMap)
	{
		displayVector = new Vector();
		Collection knownHostCollection = knownHostTreeMap.values();
		Iterator iterator = knownHostCollection.iterator();
		
		while (iterator.hasNext())
		{
		    KnownHostInfo knownHostInfo = (KnownHostInfo)iterator.next();
		    String[] hostInfo = {knownHostInfo.name, knownHostInfo.macAddress.toString()};
		    displayVector.add(hostInfo);
		}
		table = new JTable();
		tableModel = new KnownHostTableModel();
		table.setModel(tableModel);
        table.setPreferredScrollableViewportSize(new Dimension(300,300));
		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(Vector knownHostVector)
	{
		displayVector = new Vector();
		for (int i = 0; i < knownHostVector.size(); i++)
		{
		    KnownHostInfo knownHostInfo = (KnownHostInfo)knownHostVector.elementAt(i);
		    String[] hostInfo = {knownHostInfo.name, knownHostInfo.macAddress.toString()};
		    displayVector.add(hostInfo);
		}
		
		tableModel.fireTableDataChanged();
	}
	
	
	
	public synchronized void addHost(KnownHostInfo knownHostInfo)
	{
		String newMacAddressString = knownHostInfo.macAddress.toString().trim();
		String newName = knownHostInfo.name;
		
		// see if MAC address already in list
		for (int i = 0; i < displayVector.size(); i++)
    	{
    	    String[] hostInfo = (String[])displayVector.elementAt(i);
    	    String name = hostInfo[0];
    	    String macAddressString = hostInfo[1].trim();
    	    
    	    // if MAC address equals that we're adding, return
    	    if (macAddressString.equals(newMacAddressString))
    	        return;
    	        
    	}
    	
    	// didn't find it; add new info to table
    	String[] newHostInfo = {newName, newMacAddressString};
		displayVector.add(newHostInfo);
		
	    tableModel.fireTableDataChanged();
	}
	
	
	
	
	public synchronized TreeMap getKnownHostTreeMap()
	    throws ValueFormatException
	{
	    // stop any in-progress editing operations
	    // first, record changes if cell currently being edited
		TableCellEditor editor = table.getCellEditor(); 
		if(editor != null)
			editor.stopCellEditing();
		
		// try to create a Vector of KnownHostInfo objects; this could throw
		// a ValueFormatException if there's an invalid MAC address
		TreeMap knownHostTreeMap = new TreeMap();
		int i = 0;
		try
		{
    		for (i = 0; i < displayVector.size(); i++)
    		{
    		    String[] hostInfo = (String[])displayVector.elementAt(i);
    		    String name = hostInfo[0];
    		    String macAddressString = hostInfo[1].trim();
    		    
    		    // if MAC address string is empty after trimming, just continue
    		    if (macAddressString.equals(""))
    		        continue;
    		        
    		    MacAddress macAddress = new MacAddress(macAddressString);
    		    
    		    // throw exception if duplicate entry
    		    if (knownHostTreeMap.containsKey(macAddress))
    		        throw new ValueFormatException("Duplicate entry for MAC address " + hostInfo[1]);
    		        
    		    knownHostTreeMap.put(macAddress, new KnownHostInfo(name, macAddress)); 
    		}
		}
		catch(ValueFormatException e)
		{
		    // set the editing to the mac address in the row that caused the problem
		    table.editCellAt(i,1);
			
			// rethrow the exception so can report it
			throw e;
		}
			
	    return knownHostTreeMap;
	}
		
	
	
	
	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);
		}
	}
		
	


}