/*
 * Licensed Materials - Property of Perforce Software, Inc. 
 * © Copyright Perforce Software, Inc. 2014, 2021 
 * © Copyright IBM Corp. 2009, 2014
 * © Copyright ILOG 1996, 2009
 * All Rights Reserved.
 *
 * Note to U.S. Government Users Restricted Rights:
 * The Software and Documentation were developed at private expense and
 * are "Commercial Items" as that term is defined at 48 CFR 2.101,
 * consisting of "Commercial Computer Software" and
 * "Commercial Computer Software Documentation", as such terms are
 * used in 48 CFR 12.212 or 48 CFR 227.7202-1 through 227.7202-4,
 * as applicable.
 */
package treemap.table;

import java.util.ArrayList;
import java.util.List;

import javax.faces.model.DataModel;
import javax.faces.model.DataModelEvent;
import javax.faces.model.DataModelListener;

import ilog.views.chart.datax.flat.table.IlvFlatTableModel;
import ilog.views.util.IlvResourceUtil;

/**
 * This class defines a JSF table model that wraps a
 * <code>IlvFlatTableModel</code>.
 */
public class FlatTableModel extends DataModel {

  private IlvFlatTableModel model;
  private int index = 0;

  /**
   * Creates an new <code>TableMode</code> instance
   * 
   * @param model
   *          The model to wrap.
   */
  public FlatTableModel(IlvFlatTableModel model) {
    setWrappedData(model);
  }

  Override
  public int getRowCount() {
    return model != null ? model.getRowCount() : -1;
  }

  Override
  public int getRowIndex() {
    return model == null ? -1 : index;
  }

  Override
  public boolean isRowAvailable() {
    return model == null ? false : index >= 0 && index < getRowCount();
  }

  Override
  public void setRowIndex(int index) {
    this.index = index;
    if (model != null) {
      DataModelListener[] listeners = getDataModelListeners();
      for (int i = 0; i < listeners.length; i++) {
        DataModelListener listener = listeners[i];
        listener.rowSelected(new DataModelEvent(this, index, getRowData()));
      }
    }
  }

  Override
  public Object getRowData() {
    return model == null ? null : buildRow(index);
  }

  /**
   * Creates the row data from the wrapped model. The model mustn't be null.
   * 
   * @param index
   *          The row index.
   * @return The row data.
   */
  private Object buildRow(int index) {
    List<Object> l = new ArrayList<Object>(model.getColumnCount());
    for (int col = 0; col < model.getColumnCount(); col++) {
      l.add(model.getValueAt(index, col));
    }
    return new TableRow(l);
  }

  Override
  public Object getWrappedData() {
    return model;
  }

  Override
  public void setWrappedData(Object model) {
    if (model instanceof IlvFlatTableModel)
      this.model = (IlvFlatTableModel) model;
    else {
      String msg = IlvResourceUtil.getCurrentLocaleString(FlatTableModel.class, "IlvFlatTableModelInstancesOnly");
      throw new IllegalArgumentException(msg);
    }
  }

  /**
   * Returns the wrapped <code>IlvFlatTableModel</code> instance.
   * 
   * @return The wrapped model.w
   */
  public IlvFlatTableModel getModel() {
    return model;
  }

  /**
   * This class defines a table row.
   */
  public static class TableRow {

    private List<Object> data;

    /**
     * Creates a new <code>TableRow</code> instance.
     * 
     * @param data
     *          The row data.
     */
    public TableRow(List<Object> data) {
      this.data = data;
    }

    /**
     * Returns the row data.
     * 
     * @return The row data.
     */
    public List<Object> getData() {
      return data;
    }

  }

}