/*
 * 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 HostInfoTable extends JPanel
{
	private Vector hostInfoVector;
	private JTable table;
	private AbstractTableModel tableModel;
	private JScrollPane scrollPane;
	
	private JDataButton addButton;
	
	
	/**
	*	Table model which maintains simplified list of port mappings.
	*/
	private class HostTableModel extends AbstractTableModel
	{
		public int getColumnCount() 
		{ 
			return 5; 
		}
		
		public int getRowCount() 
		{ 
			return hostInfoVector.size();
		}
		
		public boolean isCellEditable(int row, int col) 
		{ 
			if (col == 4)
			    return true;
			else
			    return false;
		}
		
		public String getColumnName(int col) 
		{ 
			switch (col)
			{
				case 0:
					return "Host name";
					
				case 1:
					return "MAC address";
					
				case 2:
					return "IP address";
					
			    case 3:
					return "Time associated";
					
				case 4:
				    return "Add";
					
				default:
					return "";
			}
			
		}
		
		public Object getValueAt(int row, int col)
		{
			
			if (row < hostInfoVector.size())
			{
				
				HostInfo hostInfo = (HostInfo)hostInfoVector.elementAt(row);
				
				switch (col)
    			{
    				case 0:
    				    return hostInfo.name;
    				
    				case 1:
    					return hostInfo.macAddress.toString();
    					
    				case 2:
    					return hostInfo.ipAddress;
    					
    				case 3:
    					return timeString(hostInfo.timeAssociated);
    					
    				case 4:
    				{
    					//return addButton;
    					return "";
    				}
    					
    				default:
    					return "";
    			}
		    }
			else
				return "";
		}
		
		public void setValueAt(Object newValue, int row, int col) 
		{
			//System.out.println("setValueAt row = " + row + ", col = " + col);
		}
		
	}
	
	
	
	
	
	
	/**
	*	Create new table based on data in hostInfoTreeMap.
	*/
	
	public HostInfoTable(HostInfoTreeMap hostInfoTreeMap, ActionListener hostEditorListener)
	{
		addButton = new JDataButton("Add");
		addButton.setActionCommand("edit known hosts");
		addButton.addActionListener(hostEditorListener); 
		
		this.hostInfoVector = new Vector(hostInfoTreeMap.values());
		table = new JTable();
		tableModel = new HostTableModel();
		table.setModel(tableModel);
        setColumnPreferredWidths(table);
        setAddHostRendererAndEditor(table);
		table.setPreferredScrollableViewportSize(new Dimension(600,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(HostInfoTreeMap hostInfoTreeMap)
	{
	    this.hostInfoVector = new Vector(hostInfoTreeMap.values());
	    tableModel.fireTableDataChanged();
	}
		
		
	
	
	private void setColumnPreferredWidths(JTable table) 
	{
		TableModel tableModel = table.getModel();
		TableColumnModel tableColumnModel = table.getColumnModel();
		
		tableColumnModel.getColumn(0).setPreferredWidth(150);
		tableColumnModel.getColumn(1).setPreferredWidth(120);
		tableColumnModel.getColumn(2).setPreferredWidth(120);
		tableColumnModel.getColumn(3).setPreferredWidth(150);
		tableColumnModel.getColumn(4).setPreferredWidth(60);
	}
	
	
	
	private void oldSetColumnPreferredWidths(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);
		}
	}
	
	
	
	private void setAddHostRendererAndEditor(JTable table) 
	{
		TableModel tableModel = table.getModel();
		TableColumnModel tableColumnModel = table.getColumnModel();
		
		for (int i = 0; i < 4; i ++)
		{
		    TableColumn tableColumn =  tableColumnModel.getColumn(i);
		    tableColumn.setCellRenderer(new CenteredRenderer());
		}
		
		TableColumn tableColumn =  tableColumnModel.getColumn(4);
		tableColumn.setCellEditor(new ButtonEditor(addButton));
		tableColumn.setCellRenderer(new ButtonRenderer(addButton));
		
	}
	
	
	
	private class CenteredRenderer extends JLabel
        implements TableCellRenderer 
    {
        
        public CenteredRenderer() 
        {
            super("", CENTER);
            this.setForeground(Color.black);
        }

        public Component getTableCellRendererComponent(JTable table, Object color, boolean isSelected, boolean hasFocus, int row, int column)
        {
            setText((String)table.getModel().getValueAt(row, column));
            return this;
        }
    }
	
	
	
	private class ButtonRenderer
        implements TableCellRenderer 
    {
        private JButton button;
        private JLabel label;
        
        public ButtonRenderer(JButton b) 
        {
            super();
            
            // create a new button based on that passed in; use different button so clicks passed??
            this.button = new JButton(b.getText());
            this.label = new JLabel("");
        }

        public Component getTableCellRendererComponent(JTable table, Object color, boolean isSelected, boolean hasFocus, int row, int column)
        {
            //System.out.println("ButtonEditor.getTableCellRendererComponent");
            HostInfo hostInfo = (HostInfo)hostInfoVector.elementAt(row);
				
			if (hostInfo.known)
			{
			    return this.label;
			}
			else
			{
			    return this.button;
			}
        }
    }
    
    
	
	private class ButtonEditor 
	    extends DefaultCellEditor 
	{

        private JButton button;
        private JLabel label;
        
        public ButtonEditor(JButton b)
        {
            // constructor expects a check box, combo box, or text field
            super(new JCheckBox()); 
            
            //System.out.println("ButtonEditor constructor");
            
            // assign button as editor component
            button = b;
            label = new JLabel("");
            setClickCountToStart(1);

            // do this so that editing stops when button clicked...
            b.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    //System.out.println("ButtonEditor: button clicked");
                    fireEditingStopped();
                }
            }); 
            
            
        }

        protected void fireEditingStopped() 
        {
            //System.out.println("ButtonEditor.fireEditingStopped");
            super.fireEditingStopped();
        }
        
        public boolean shouldSelectCell(EventObject anEvent)
        {
            // return false so row not selected when button clicked...
            return false;
        }

        public Object getCellEditorValue() 
        {
            //System.out.println("ButtonEditor.getCellEditorValue");
            return null;
        }

        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) 
        {
            //System.out.println("ButtonEditor.getTableCellEditorComponent");
            HostInfo hostInfo = (HostInfo)hostInfoVector.elementAt(row);
				
			if (hostInfo.known)
			{
			    return this.label;
			}
			else
			{
			    if (button instanceof JDataButton)
                {
                    // set data in JDataButton so we know which entry to add
                    JDataButton dataButton = (JDataButton)button;
    				dataButton.setData(hostInfo.macAddress);
                }
                return this.button;
			}
			
        }
    }
	
	
	
	private String timeString(int time)
	{
	    
	    if (time < 0)
	        return "unknown";
	        
	    int seconds = time % 60;
	    int minutes = (time /60) % 60;
	    int hours = (time / 3600) % 24;
	    int days = (time / 86400);
	    
	    String returnString = new String();
	    
	    if (seconds == 1)
	        returnString = seconds + " second";
	    else
	        returnString = seconds + " seconds";
	    
	    if (minutes > 0)
	    {
	        if (minutes == 1)
	            returnString = minutes + " minute, " + returnString;
	        else
	            returnString = minutes + " minutes, " + returnString;
	    }
	    
	    if (hours > 0)
	    {
	        if (hours == 1)
	            returnString = hours + " hour, " + returnString;
	        else
	            returnString = hours + " hours, " + returnString;
	    }
	    
	    if (days > 0)
	    {
	        if (days == 1)
	            returnString = days + " day, " + returnString;
	        else
	            returnString = days + " days, " + returnString;
	    }
	    
	    return returnString;
	}


}