/*
 * @(#)ScrollableDisplay.java    1.0  13 June 2003
 *
 * 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 java.awt.*;
import java.beans.*;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.SwingPropertyChangeSupport;

/**
 * <P>A <CODE>JPTScrollPane</CODE> that contains 
 * a single <CODE>Displayable</CODE> object, 
 * and delegates <CODE>Displayable</CODE> method calls
 * to its viewport view.</P>
 *
 * <P>The functionality of this class assumes that the viewport view
 * for this scroll pane is a <CODE>Displayable</CODE> object
 * set through the 
 * <CODE>{@link #setDisplay(Displayable) setDisplay}</CODE> method,
 * and effects are undefined if the viewport view 
 * is set through other means.</P>
 *
 * <P>To allow access to the methods in <CODE>JPTScrollPane</CODE>,
 * this class was revise to extend <CODE>JPTScrollPane</CODE>.</P>
 *
 * @author  Jeff Raab
 * @version 2.3
 * @since   1.0
 */
public class ScrollableDisplay 
    extends JPTScrollPane 
    implements Displayable 
{
    /** Bound property name for the display property. */
    public static final String DISPLAY = "display";
    
    
    /**
     * Constructs a scrollable display containing 
     * a blank <CODE>DisplayPanel</CODE>.
     *
     * @see #ScrollableDisplay(Displayable)
     */
    public ScrollableDisplay() {
        this(new DisplayPanel());
    }
    
    
    /**
     * Constructs a scrollable display 
     * containing the given <CODE>Displayable</CODE> object.
     *
     * @param d the displayable to become the viewport view
     * @see #ScrollableDisplay()
     */
    public ScrollableDisplay(Displayable d) {
        super();
        setDisplay(d);
    }
    
    
    /////////////////
    // Displayable //
    /////////////////

    /**
     * Sets the view state of the displayed object
     * to the given <CODE>String</CODE> data.
     *
     * @param data the given <CODE>String</CODE> data
     * @see #getViewState()
     * @see Displayable
     */
    public void setViewState(String data) {
        getDisplay().setViewState(data);
        
        // notify listeners of property change
        firePropertyChange(
            VIEW_STATE, 
            null, 
            data);
    }
    
    
    /**
     * Returns the view state of the object on display.
     *
     * @return the view state of the object on display
     * @see #setViewState(String)
     * @see Displayable
     */
    public String getViewState() {
        return getDisplay().getViewState();
    }
    
    
    /**
     * Sets the default view state of the displayed object
     * to the given <CODE>String</CODE> data.
     *
     * @param data the given <CODE>String</CODE> data
     * @see #reset()
     * @see Displayable
     */
    public void setDefaultViewState(String data) {
        getDisplay().setDefaultViewState(data);
        
        firePropertyChange(
            DEFAULT_VIEW_STATE, 
            null, 
            data);
    }
    
    
    /**
     * Returns the default view state for the displayed object.
     *
     * @return the default view state for the displayed object
     * @see #setDefaultViewState(String)
     * @see #reset()
     */
    public String getDefaultViewState() {
        return getDisplay().getDefaultViewState();
    }
    
    
    /**
     * Enables or disables the scrollable display 
     * and its contents, based on the given value.
     *
     * @param isEnabled whether or not the component is to be enabled
     * @see Displayable
     */
    public void setEnabled(boolean isEnabled) {
        getDisplay().setEnabled(isEnabled);

        super.setEnabled(isEnabled);
    }
    
    
    /**
     * Resets the view state of the displayed object
     * to its default view state.
     *
     * @see #setDefaultViewState(String)
     * @see Displayable
     */
    public void reset() {
        getDisplay().reset();
    }
    
    
    ////////////////
    // Public API //
    ////////////////
    
    /**
     * <P>Sets the displayed object 
     * to the given <CODE>Displayable</CODE> object.</P>
     *
     * <P>If the given object is <CODE>null</CODE>,
     * the displayed object is not changed.</P>
     *
     * @param d the object to be displayed
     * @see #getDisplay()
     */
    public void setDisplay(Displayable d) {
        if (d == null)
            return;
    
        Displayable oldDisplay = getDisplay();
    
        setViewportView((Component)d);

        // update ui
        validateTree();
        
        // if the display has changed
        if (d != oldDisplay) {

            // notify listeners of property change
            firePropertyChange(
                DISPLAY,
                oldDisplay,
                getDisplay());
        }
    }
    
    
    /**
     * Returns the displayed object.
     *
     * @return the displayed object
     * @see #setDisplay(Displayable)
     */
    public Displayable getDisplay() {
        return (Displayable)(getViewport().getView());
    }
}
