/*
 * Copyright (C) 2001-2004 Red Hat Inc. All Rights Reserved.
 *
 * The contents of this file are subject to the CCM Public
 * License (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the
 * License at http://www.redhat.com/licenses/ccmpl.html.
 *
 * Software distributed under the License is distributed on an
 * "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express
 * or implied. See the License for the specific language
 * governing rights and limitations under the License.
 *
 */
package com.arsdigita.bebop;

import com.arsdigita.bebop.table.TableModel;
import com.arsdigita.bebop.list.ListModel;

import java.util.ArrayList;

/**
 * Converts a linear ListModel to a grid of items.
 * For example, <code>A B C D E F G</code> becomes:
 *
 * <code><pre>
 * A D G
 * B E .
 * C F .
 * </pre></code>
 *
 * The extraneous cells in the table are filled
 * with <code>GridTableModel.PLACEHOLDER</code>.
 */

public class GridTableModel implements TableModel {

    public static final String versionId = "$Id: //core-platform/dev/src/com/arsdigita/bebop/GridTableModel.java#6 $ by $Author: dennis $, $DateTime: 2004/04/07 16:07:11 $";

    private ListModel m_items;
    private int m_colHeight, m_cols, m_size, m_index;
    private Object[] m_elements;
    private Object[] m_keys;

    /**
     * Constructs a new <code>GridTableModel</code>.
     * @param items a {@link ListModel} that represents the
     *   items
     * @param cols the number of columns in the grid
     */
    public GridTableModel(ListModel items, int cols) {
        m_items = items;
        m_cols = cols;

        // Load the items into memory
        ArrayList elements = new ArrayList(), keys = new ArrayList();
        for(m_size=0; m_items.next(); m_size++) {
            elements.add(m_items.getElement());
            keys.add(m_items.getKey());
        }

        m_elements = elements.toArray();
        m_keys = keys.toArray();

        // Round up
        m_colHeight = m_size / m_cols;
        if(m_colHeight * m_cols < m_size) ++m_colHeight;

        m_index = -1;
    }

    public int getColumnCount() {
        return m_cols;
    }

    public boolean nextRow() {
        if(m_index >= m_colHeight - 1)
            return false;

        ++m_index;
        return true;
    }

    private Object safeGet(Object[] a, int columnIndex) {
        int i = m_index + m_colHeight*columnIndex;

        if(i >= a.length)
            return null;
        else
            return a[i];
    }

    public Object getElementAt(int columnIndex) {
        return safeGet(m_elements, columnIndex);
    }

    public Object getKeyAt(int columnIndex) {
        return safeGet(m_keys, columnIndex);
    }
}
