import javax.swing.*;
import javax.swing.table.*;
import java.awt.*;

    // Implement the methods of AbstractTableModel that make it
    // possible to edit some of the data, and have headers displayed.
class LeagueTableModel extends AbstractTableModel {
    public LeagueTableModel(League l){
        league = l;
    }

        // Implementations of the abstract methods.

    public int getRowCount(){
        return getTeams().length;
    }

    public int getColumnCount(){
        return numColumns;
    }

    public Object getValueAt(int row, int col){
        final TeamDetails[] teams = getTeams();
        final int numTeams = teams.length;
        if((row >= 0) && (row < numTeams) && (col >= 0) && (col < numColumns)){
            final TeamDetails team = teams[row];
            switch(col){
                case TEAM:
                    return team.getName();
                case COACH:
                    return team.getCoach();
                case VENUE:
                    return team.getVenue();
                case POINTS:
                    return new Integer(team.getPoints());
                default:
                    return null;
            }
        }
        else{
            return null;
        }
    }

        // Only a team's points may be changed.
    public boolean isCellEditable(int row, int col){
        return col == POINTS;
    }

        // Implement the required change, if the cell is editable.
    public void setValueAt(Object value,int row, int col){
        if(isCellEditable(row,col)){
            try{
                final TeamDetails[] teams = getTeams();
                final TeamDetails team = teams[row];
                switch(col){
                    case POINTS:
                        int points = Integer.parseInt((String) value);
                        team.setPoints(points);
                        fireTableCellUpdated(row,col);
                        break;
                }
            }
            catch(Exception e){
                JOptionPane.showMessageDialog(null,e,
                            "Value Setting Error",JOptionPane.ERROR_MESSAGE);
            }
        }
    }

    public String getColumnName(int col){
        final String[] headers = getHeaders();
        if(col < headers.length){
            return headers[col];
        }
        else{
            return "???";
        }
    }

    public Class getColumnClass(int col){
        if(col < numColumns){
            // Pick up the class from an arbitrary cell
            // in this column.
            return getValueAt(0,col).getClass();
        }
        else{
            Object o = new Object();
            return o.getClass();
        }
    }

    protected TeamDetails[] getTeams(){
        return getLeague().getTeams();
    }

    protected League getLeague(){
        return league;
    }

    protected String[] getHeaders(){
        return headers;
    }

    // This information is closely tied to the implementation of
    // TeamDetails.
    private static final int numColumns = 4;
    private static final int TEAM = 0, COACH = 1, VENUE = 2, POINTS = 3;
    private static final String[] headers = new String[numColumns];
    static {   
        headers[TEAM] = "Team";
        headers[COACH] = "Coach";
        headers[VENUE] = "Venue";
        headers[POINTS] = "Points";
    };

    // The team details.
    private final League league;
}
