/*
 * @(#)VisualColorList.java    2.3  8 September 2004
 *
 * Copyright 2004
 * College of Computer and Information Science
 * Northeastern University
 * Boston, MA  02115
 *
 * The Java Power Tools software may be used for educational
 * purposes as long as this copyright notice is retained intact
 * at the top of all source files.
 *
 * To discuss possible commercial use of this software, 
 * contact Richard Rasala at Northeastern University, 
 * College of Computer and Information Science,
 * 617-373-2462 or rasala@ccs.neu.edu.
 *
 * The Java Power Tools software has been designed and built
 * in collaboration with Viera Proulx and Jeff Raab.
 *
 * Should this software be modified, the words "Modified from 
 * Original" must be included as a comment below this notice.
 *
 * All publication rights are retained.  This software or its 
 * documentation may not be published in any media either
 * in whole or in part without explicit permission.
 *
 * This software was created with support from Northeastern 
 * University and from NSF grant DUE-9950829.
 */

package edu.neu.ccs.gui;

import edu.neu.ccs.*;
import edu.neu.ccs.gui.*;
import edu.neu.ccs.util.*;

import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.*;

/**
 * <p>Class <code>VisualColorList</code> displays the named colors as defined
 * in class <code>Colors</code> using a square color swatch and a label.  The
 * programmer has some control of the swatch size and pane height.  This
 * class is intended to provide color information not as a GUI control.</p>
 *
 * @author  Richard Rasala
 * @version 2.3.2
 * @since   2.3.2
 */
public class VisualColorList
    extends DisplayPanel implements JPTConstants
{
    /** The minimum swatch size. */
    private static final int MIN_SWATCH_SIZE     = PaintSwatch.DEFAULT_SWATCH_SIZE;
    
    /** The default swatch size. */
    private static final int DEFAULT_SWATCH_SIZE = PaintSwatch.DEFAULT_SWATCH_SIZE;
    
    /** The maximum swatch size. */
    private static final int MAX_SWATCH_SIZE     = 50;
    
    
    /** The standard border size. */
    private static final int BORDER_SIZE = PaintSwatch.BORDER_SIZE;
    
    /** The standard swatch border. */
    private static final Border BORDER = PaintSwatch.BLACK_BORDER;
    
    
    /** The internal table panel horizontal gap. */
    private static final int HGAP = 6;
    
    /** The internal table panel vertical gap. */
    private static final int VGAP = 6;
    
    
    /** The maximum width of the viewport of the list scroll pane. */
    private static final int MAX_WIDTH  = 720;  
    
    /** The minimum height of the viewport of the list scroll pane. */
    private static final int MIN_HEIGHT = 120;
    
    /** The maximum height of the viewport of the list scroll pane. */
    private static final int MAX_HEIGHT = 720;
    
    
    /** The swatch size that must be between MIN_SWATCH_SIZE and MAX_SWATCH_SIZE. */
    private int swatchSize = DEFAULT_SWATCH_SIZE;
    
    
    /**
     * The method to create a swatch based on the given color name and the
     * encapsulated swatch size.
     *
     * @param name a color name in the table in class Colors
     */
    private PaintSwatch makeSwatch(String name) {
        return new PaintSwatch
            (Colors.getColorFromName(name), swatchSize, swatchSize, BORDER);
    }
    
    
    /**
     * <p>The constructor that creates a <code>VisualColorList</code> using a
     * swatch size of 20 and a pane height of 720.</p>
     *
     * <p>Assuming the label font size is not too large, the vertical spacing
     * of the color swatch blocks will be 20 + 10 = 30.  This means that
     * 720 / 30 = 24 colors will be visible at one time.</p>
     */
    public VisualColorList() {
        this(DEFAULT_SWATCH_SIZE, MAX_HEIGHT);
    }
    
    
    /**
     * <p>The constructor that creates a <code>VisualColorList</code> using a
     * the given swatch size and a maximum pane height of 720.</p>
     *
     * <p>The swatch size will be forced to the range 20-50 before usage.</p>
     *
     * <p>Assuming the label font size is not too large, the vertical spacing
     * of the color swatch blocks will be (swatchSize + 10).  This means that
     * 720 / (swatchSize + 10) colors will be visible at one time.</p>
     *
     * <p>In particular, if the swatch size is set to its minimum of 20, then
     * 24 colors will be visible at one time.</P>
     *
     * @param swatchSize the desired swatch size
     */
    public VisualColorList(int swatchSize) {
        this(swatchSize, MAX_HEIGHT);
    }
    
    
    /**
     * <p>The constructor that creates a <code>VisualColorList</code> using a
     * the given swatch size and the given maximum pane height.</p>
     *
     * <p>The swatch size will be forced to the range 20-50 before usage.</p>
     *
     * <p>The pane height will be forced to the range 120-720 before usage.</p>
     *
     * <p>Assuming the label font size is not too large, the vertical spacing
     * of the color swatch blocks will be (swatchSize + 10).  This means that
     * paneHeight / (swatchSize + 10) colors will be visible at one time.</p>
     *
     * @param swatchSize the desired swatch size
     * @param paneHeight the desired pane height
     */
    public VisualColorList(int swatchSize, int paneHeight) {
        swatchSize = (swatchSize >= MIN_SWATCH_SIZE) ? swatchSize : MIN_SWATCH_SIZE;
        swatchSize = (swatchSize <= MAX_SWATCH_SIZE) ? swatchSize : MAX_SWATCH_SIZE;
        
        this.swatchSize = swatchSize;
        
        
        paneHeight = (paneHeight >= MIN_HEIGHT) ? paneHeight : MIN_HEIGHT;
        paneHeight = (paneHeight <= MAX_HEIGHT) ? paneHeight : MAX_HEIGHT;
        
        int itemHeight = swatchSize + (2 * BORDER_SIZE) + VGAP;
        
        paneHeight = itemHeight * (paneHeight / itemHeight);
        
        if (paneHeight < MIN_HEIGHT)
            paneHeight += itemHeight;
        
        
        final String[] nameArray = Colors.getColorNamesAsArray();
        
        final int length = nameArray.length;
        
        TableGenerator generator =
            new TableGenerator() {
                public Object makeContents(int row, int col) {
                    if ((row < 0) || (row >= length))
                        return null;
                    
                    if ((col < 0) || (col >= 2))
                        return null;
                    
                    if (col == 0)
                        return makeSwatch(nameArray[row]);
                    
                    return new JLabel(nameArray[row]);
                }
            };
        
        TablePanel nameColorPanel =
            new TablePanel(generator, length, 2, HGAP, VGAP, WEST);
        
        
        JPTScrollPane scrollPane =
            new JPTScrollPane(nameColorPanel);
        
        scrollPane.boundViewportPreferredSize(MAX_WIDTH, paneHeight);
        
        add(scrollPane);
    }
    
    
    /**
     * <p>This static convenience method makes a default <code>VisualColorList</code>
     * panel and displays the panel in a frame.</p>
     */
    public static void showVisualColorList() {
        JPTFrame.createQuickJPTFrame("Visual Color List", new VisualColorList());
    }
}
