/* ScrollableGraphTableComponent.java
 * =========================================================================
 * This file is part of the GrInvIn project - http://www.grinvin.org
 * 
 * Copyright (C) 2005-2008 Universiteit Gent
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or (at
 * your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 * 
 * A copy of the GNU General Public License can be found in the file
 * LICENSE.txt provided with the source distribution of this program (see
 * the META-INF directory in the source jar). This license can also be
 * found on the GNU website at http://www.gnu.org/licenses/gpl.html.
 * 
 * If you did not receive a copy of the GNU General Public License along
 * with this program, contact the lead developer, or write to the Free
 * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */

package org.grinvin.gui.components;

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.util.ResourceBundle;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.ListCellRenderer;
import javax.swing.ListSelectionModel;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.grinvin.list.graphs.GraphList;
import org.grinvin.gui.components.render.GraphListElementRenderer;
import org.grinvin.list.graphs.GraphListModel;
import org.grinvin.list.invariants.InvariantListModel;

/**
 * A version of {@link GraphTableComponent} that is scrollable.
 */
public class ScrollableGraphTableComponent extends JScrollPane {
    
    //
    private static final String BUNDLE_NAME = "org.grinvin.worksheet.resources";
    
    //
    protected final GraphTableComponent graphtable;
    
    // shared instance
    private static final ListCellRenderer CELL_RENDERER
            = new TabelHeaderCellRenderer();
    
    //
    public ScrollableGraphTableComponent(GraphListModel graphListModel, InvariantListModel invariantListModel, ListSelectionModel selectionModel) {
        super();
        this.graphtable = new GraphTableComponent(graphListModel, invariantListModel, selectionModel);
        setViewportView(graphtable);

        // row header view is an almost standard graph list component
        GraphListComponent rowHeaderView =
                new GraphListComponent(graphListModel, selectionModel);
        rowHeaderView.setFixedCellHeight(graphtable.getRowHeight());
        rowHeaderView.setCellRenderer(CELL_RENDERER); // overrides cell renderer for graph list component
        rowHeaderView.setPaintWatermark(false);
        setRowHeaderView(rowHeaderView);
        //workaround from http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4202002
        getRowHeader().addChangeListener(new ChangeListener() {
              public void stateChanged(ChangeEvent e) {
                JViewport jvViewport = (JViewport) e.getSource();
                int iExtent = jvViewport.getExtentSize().height;
                int iMax = jvViewport.getViewSize().height;
                int iValue = Math.max(0, Math.min(jvViewport.getViewPosition().y, iMax - iExtent));
                getVerticalScrollBar().setValues(iValue, iExtent, 0, iMax);
              }
            });

        // top left corner
        JLabel corner = new JLabel (ResourceBundle.getBundle(BUNDLE_NAME).getString ("Corner.caption"));
        corner.setForeground(UIManager.getColor("TableHeader.foreground"));
        corner.setBackground(UIManager.getColor("TableHeader.background"));
        corner.setBorder (UIManager.getBorder("TableHeader.cellBorder"));
        corner.setOpaque(true);
        corner.setHorizontalAlignment(JLabel.CENTER);
        setCorner(UPPER_LEFT_CORNER, corner);
        
        // make watermark shine through
        getViewport().setOpaque(false);
        getRowHeader().setOpaque(false);
        graphtable.setOpaque(false);
        setOpaque(false); // we paint our own background
        setBackground(Color.WHITE);
        
    }
    
    //
    public GraphList getGraphList() {
        return graphtable.getGraphList();
    }

    
    /**
     * Overridden to also rescale the table columns whenever the layout needs a change
     */
    public void doLayout() {
        super.doLayout();
        graphtable.rescaleColumns();
    }
    
    /**
     * Adds a watermark to the list.
     */
    @Override
    protected void paintComponent(Graphics g) {
        g.setColor(getBackground());
        g.fillRect(0, 0, getWidth(), getHeight());
        GraphCellListComponent.WATERMARK_PAINTER.paint(this, g);
        super.paintComponent(g);
    }
    
    //
    private static class TabelHeaderCellRenderer extends GraphListElementRenderer {
        //
        private final Border noFocusBorder;
        
        public TabelHeaderCellRenderer() {
            this.noFocusBorder = UIManager.getBorder("TableHeader.cellBorder");
        }
        
        public Component getListCellRendererComponent
                (JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            
            super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            if (! cellHasFocus && ! isSelected)
                setBorder(BorderFactory.createCompoundBorder(noFocusBorder, BorderFactory.createEmptyBorder(0,0,0,5)));
            return this;
        }
        
    }
}
