package de.fitsample.timerecording.ui;

import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.event.EventListenerList;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;

import de.fitsample.timerecording.TimeRecord;
import de.fitsample.timerecording.TimeRecording;

/**
 * A TableModel for the {@link TimeRecording TimeRecording}.
 * 
 * @author Ralf
 */
public class TimeRecordingTableModel implements TableModel,
        PropertyChangeListener {

    public static final int DAY_COLUMN = 0;

    public static final int FROM_COLUMN = 1;

    public static final int TO_COLUMN = 2;

    public static final int WORKING_TIME_COLUMN = 3;

    public static final int SUM_COLUMN = 4;

    private static final String[] COLUMN_NAMES = new String[] { "day", "from",
            "to", "working time", "sum" };

    private TimeRecording timeRecording;

    private EventListenerList listenerList;

    /**
     * Creates a TimeRecordingTableModel from the given timeRecording.
     * 
     * @param timeRecording
     *            the TimeRecording this TableModel is based on.
     */
    public TimeRecordingTableModel(TimeRecording timeRecording) {
        this.timeRecording = timeRecording;
        timeRecording.addPropertyChangeListener(this);
        listenerList = new EventListenerList();
    }

    /**
     * @see java.beans.PropertyChangeListener#propertyChange(java.beans.PropertyChangeEvent)
     */
    public void propertyChange(PropertyChangeEvent evt) {
        if (TimeRecording.RECORDS_PROPERTY.equals(evt.getPropertyName())) {
            fireTableModelChanged();
        }
    }

    /**
     * @see javax.swing.table.TableModel#addTableModelListener(javax.swing.event.TableModelListener)
     */
    public void addTableModelListener(TableModelListener l) {
        listenerList.add(TableModelListener.class, l);
    }

    /**
     * @see javax.swing.table.TableModel#removeTableModelListener(javax.swing.event.TableModelListener)
     */
    public void removeTableModelListener(TableModelListener l) {
        listenerList.remove(TableModelListener.class, l);
    }

    protected void fireTableModelChanged() {
        TableModelListener[] listeners = (TableModelListener[]) listenerList
                .getListeners(TableModelListener.class);
        for (int i = 0; i < listeners.length; i++) {
            listeners[i].tableChanged(new TableModelEvent(this));
        }
    }

    /**
     * @see javax.swing.table.TableModel#getColumnClass(int)
     */
    public Class getColumnClass(int columnIndex) {
        return String.class;
    }

    /**
     * @see javax.swing.table.TableModel#getColumnCount()
     */
    public int getColumnCount() {
        return COLUMN_NAMES.length;
    }

    /**
     * @see javax.swing.table.TableModel#getColumnName(int)
     */
    public String getColumnName(int columnIndex) {
        return COLUMN_NAMES[columnIndex];
    }

    /**
     * @see javax.swing.table.TableModel#getRowCount()
     */
    public int getRowCount() {
        return timeRecording.size();
    }

    /**
     * @see javax.swing.table.TableModel#getValueAt(int, int)
     */
    public Object getValueAt(int rowIndex, int columnIndex) {
        TimeRecord timeRecord = timeRecording.getRecord(rowIndex);
        boolean isLastDay = false;
        if (rowIndex == timeRecording.size()-1) {
            isLastDay = true;
        } else {
            isLastDay = timeRecord.getDay() != timeRecording.getRecord(
                    rowIndex + 1).getDay();

        }
        boolean isFirstDay = false;
        if (rowIndex == 0) {
            isFirstDay = true;
        } else {
            isFirstDay = timeRecord.getDay() != timeRecording.getRecord(
                    rowIndex - 1).getDay();

        }
        switch (columnIndex) {
        case DAY_COLUMN:
            if (isFirstDay) {
                return new Integer(timeRecord.getDay());
            }
            return null;
        case FROM_COLUMN:
            return timeRecord.getTimeFrame().getStartTime();
        case TO_COLUMN:
            return timeRecord.getTimeFrame().getEndTime();
        case WORKING_TIME_COLUMN:
            if (isLastDay) {
                return new Double(timeRecording.getWorkingTimeForDay(timeRecord
                        .getDay()));
            }
            return null;
        case SUM_COLUMN:
            if (isLastDay) {
                return new Double(timeRecording
                        .getWorkingTimeUpToDay(timeRecord.getDay()));
            }
            return null;
        }
        return null;
    }

    /**
     * @see javax.swing.table.TableModel#isCellEditable(int, int)
     */
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return false;
    }

    /**
     * @see javax.swing.table.TableModel#setValueAt(java.lang.Object, int, int)
     */
    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
        // nothing editable
    }
}
