/* $Id: DaySummaryTableModel.java 124 2008-03-06 07:19:25Z bananeweizen $
* GNU GPL Version 2, Copyright (C) 2005 Paul C. Kunysch */
package de.kunysch.tvbrowser.localimdb;
import java.util.*;
import javax.swing.ListSelectionModel;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.TableModel;
import util.ui.Localizer;
import de.kunysch.localimdb.Movie;
import de.kunysch.tvbrowser.WrappedProgram;
import devplugin.Marker;
import devplugin.Program;
import devplugin.ProgramFieldType;
/**
* This TableModel manages a list of Program/Movie pairs. It knows how to
* display relevant information and how to sort specific columns.
*/
public class DaySummaryTableModel extends AbstractTableModel {
private static Localizer mLocalizer = util.ui.Localizer.getLocalizerFor(DaySummaryTableModel.class);
private static final long serialVersionUID = 1L;
private List<RatedProgram> rows = new ArrayList<RatedProgram>();
private String[] columns = new String[] { mLocalizer.msg("time", "Time"),
Localizer.getLocalization(Localizer.I18N_CHANNEL), mLocalizer.msg("title", "Title"),
mLocalizer.msg("original", "Orig. Title"), mLocalizer.msg("year", "Year"), mLocalizer.msg("rank", "Rank"),
mLocalizer.msg("votes", "Votes"), mLocalizer.msg("imdbYear", "IMDb Year") };
private int sortColumn = 5;
private boolean sortReverse = false;
/** This is the default constructor. */
public DaySummaryTableModel() {
}
/** This tries to keep the sort settings from another DaySummaryTableModel. */
public DaySummaryTableModel(TableModel other) {
if (other instanceof DaySummaryTableModel) {
final DaySummaryTableModel dstModel = (DaySummaryTableModel) other;
this.sortColumn = dstModel.sortColumn;
this.sortReverse = dstModel.sortReverse;
}
}
/**
* This Comparator sorts the table entries based on a column index and an
* invert flag.
*/
private class EntryComparator implements Comparator<RatedProgram> {
private final int column;
private final boolean invert;
private final boolean[] columnOrder = new boolean[] { false, false, false, false, false, true, true, false };
/**
* This creates a Comparator for Entry objects.
*
* @param column
* is the table row that should be sorted.
* @param reverse
* is false for the primary and true for the reversed sorting
* order.
*/
public EntryComparator(int column, boolean reverse) {
this.column = column;
this.invert = reverse;
}
/**
* This compares two <code>Entry</code>s.
*
* @return a negative integer, zero, or a positive integer as the first
* Entry is less than, equal to, or greater than the second.
* @see Comparator#compare(java.lang.Object, java.lang.Object)
*/
public int compare(RatedProgram lhsEntry, RatedProgram rhsEntry) {
Comparable lhs = getColumn(lhsEntry, column);
Comparable rhs = getColumn(rhsEntry, column);
if (!lhs.getClass().equals(rhs.getClass())) {
return Integer.class.equals(lhs.getClass()) == invert ? -1 : 1;
}
if (0 == column) {
int dayCompare = lhsEntry.getDate().compareTo(rhsEntry.getDate());
if (0 != dayCompare) {
return invert ? -1 * dayCompare : dayCompare;
}
final int lhsTime = lhsEntry.getTimeField(ProgramFieldType.START_TIME_TYPE);
final int rhsTime = rhsEntry.getTimeField(ProgramFieldType.START_TIME_TYPE);
if (lhsTime == rhsTime) {
return 0;
}
return ((lhsTime < rhsTime) != invert) ? -1 : 1;
}
if (invert == columnOrder[column]) {
if (lhs.getClass().equals(String.class)) {
return ((String) lhs).compareToIgnoreCase((String) rhs);
}
return lhs.compareTo(rhs);
}
if (lhs.getClass().equals(String.class)) {
return ((String) rhs).compareToIgnoreCase((String) lhs);
}
return rhs.compareTo(lhs);
}
}
/**
* This returns the number of columns.
*
* @return the number of columns.
*/
public int getColumnCount() {
return columns.length;
}
/**
* This returns the number of rows.
*
* @return the number of rows.
*/
public int getRowCount() {
return rows.size();
}
/**
* This returns the value for the specified cell.
*
* @param row
* the row whose value is to be queried.
* @param column
* the column whose value is to be queried.
* @return the value for the specified cell.
*/
public Object getValueAt(int row, int column) {
final RatedProgram entry = rows.get(row);
return getColumn(entry, column);
}
/**
* This returns the value for the column of an Entry.
*
* @param entry
* the entry whose value is to be queried.
* @param column
* the column whose value is to be queried.
* @return the the value for the column of an Entry.
*/
private Comparable getColumn(RatedProgram entry, int column) {
switch (column) {
case 0:
return entry.getTimeString();
case 1:
return entry.getChannel().getName();
case 2:
String title = entry.getTitle();
Marker[] markers = entry.getMarkerArr();
if (!entry.isTitleFound()) {
title = "(" + title + ")"; //$NON-NLS-1$ //$NON-NLS-2$
}
if (null != markers && 0 < markers.length) {
title = "<html><strong>" + title + "</strong></html>"; //$NON-NLS-1$ //$NON-NLS-2$
}
return title;
case 3:
final String otitle = entry.getTextField(ProgramFieldType.ORIGINAL_TITLE_TYPE);
if (null == otitle) {
return "--"; //$NON-NLS-1$
}
final String ltitle = entry.getTitle();
return (entry.isOrigTitleFound() || ltitle.equals(otitle)) ? otitle : "(" + otitle + ")"; //$NON-NLS-1$ //$NON-NLS-2$
case 4:
final int year = Plugin.getProductionYear(entry);
if (-1 != year) {
return new Integer(year);
}
return "--"; //$NON-NLS-1$
case 5:
return new Double(entry.getMovie().getRank() / 10.0);
case 6:
return new Integer(entry.getMovie().getVotes());
case 7:
return new Integer(entry.getMovie().getYear());
}
return null;
}
/**
* Returns the name for the column.
*
* @param column
* the column being queried.
* @return a string containing the name of the <code>column</code>.
*/
@Override
public String getColumnName(int column) {
return columns[column];
}
/**
* This adds table entries for the given <code>Movie</code> search result.
*
* @param prog
* is the program that was used in a search.
* @param movies
* contains <code>Movie</code> s found with the regular title, this
* must not be null.
* @param omovies
* contains <code>Movie</code> s found with the original title,
* this may be null.
*/
public void addSearchResult(Program prog, Set<Movie> movies, Set<Movie> omovies) {
Set<Movie> allMovies = new TreeSet<Movie>(movies);
if (null != omovies) {
allMovies.addAll(omovies);
}
final Iterator<Movie> iter = allMovies.iterator();
while (iter.hasNext()) {
final Movie movie = iter.next();
final boolean fromTitle = movies.contains(movie);
final boolean fromOrigTitle = null != omovies && omovies.contains(movie);
rows.add(RatedProgram.Handler.create(prog, movie, null, fromTitle, fromOrigTitle));
}
}
/**
* This sorts a clicked column. If the column was already sorted in the
* regular order it will be sorted in the reverse order.
*
* @param column
* must be a valid column.
*/
public void onColumnClicked(int column) {
sortReverse = !sortReverse && (sortColumn == column);
sortColumn = column;
sort();
}
/** This sorts the table. */
public void sort() {
Collections.sort(rows, new EntryComparator(sortColumn, sortReverse));
fireTableDataChanged();
}
/**
* This returns the Program object for the specified row.
*
* @param row
* the row to be queried.
*/
public Program getProgramFromRow(int row) {
return (rows.get(row));
}
public Program[] getRows() {
return rows.toArray(new Program[rows.size()]);
}
public int select(Program prog, ListSelectionModel selection) {
int firstRow = -1;
selection.removeSelectionInterval(0, rows.size() - 1);
for (int i = 0; i < rows.size(); ++i) {
Program entry = (rows.get(i)).getWrappedProgram(null);
if (prog instanceof WrappedProgram) {
prog = ((WrappedProgram) prog).getWrappedProgram(null);
}
if (entry == prog) {
selection.addSelectionInterval(i, i);
if (-1 == firstRow) {
firstRow = i;
}
}
}
return firstRow;
}
}