/*
 * @(#)XObjectView.java    1.0  18 February 2001
 *
 * 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.console.*;
import java.beans.*;
import javax.swing.*;

/**
 * <P>View for output of the <CODE>String</CODE> representation
 * of the state of an <CODE>{@link XObject XObject}</CODE>.
 *
 * @author  Jeff Raab
 * @version 2.2
 * @since   1.0
 */
public class XObjectView 
    extends JLabel 
    implements Displayable, PropertyChangeListener, ConsoleAware 
{
    /** Bound property name for the model property. */
    public static final String MODEL = "model";

    /** The data model for this view. */
    protected XObject model = null;
    
    //////////////////
    // Constructors //
    //////////////////
    
    /**
     * Constructs a view with no data model.
     */
    public XObjectView() {
        this(null);
    }
    
    /**
     * Constructs a view with the given data model.
     *
     * If the given model object is <CODE>null</CODE>,
     * no data model is initially associated with this view.
     *
     * @param obj the desired data model for the view
     */
    public XObjectView(XObject obj) {
        setModel(obj);
    }
    
    ////////////////////////////
    // PropertyChangeListener //
    ////////////////////////////

    /**
     * Handles a property change event issued by the data model.
     *
     * @param evt the property change event issued by the model
     */
    public void propertyChange(PropertyChangeEvent evt) {

        // ensure event was generated by the model
        if (evt.getSource() != model)
            return;
        
        // extract the "new value" for testing
        Object obj = evt.getNewValue();

        // if the new value is null, 
        // display the String representation of the model object
        // or the empty string if there is no model object
        if (obj == null) {
            if (model == null)
                setText("");
            else
                setText(model.toStringData());
        }

        // if the new value is a String, display it
        else if (obj instanceof String)
            setText((String)obj);    

        // if the new value is Stringable, 
        // display its String representation
        else if (obj instanceof Stringable) {
            Stringable s = (Stringable)obj;
            setText(s.toStringData());    
        }
        
        // if the new value is an Object, 
        // display the toString() representation
        else
            setText(obj.toString());    
    }

    /////////////////
    // Displayable //
    /////////////////
    
    /** Not used by this class. */
    public void setViewState(String value) {}
    
    /** 
     * Not used by this class. 
     *
     * @return <CODE>null</CODE>
     */
    public String getViewState() {
        return null;
    }
    
    /** Not used by this class. */
    public void setDefaultViewState(String value) {}
    
    /** 
     * Not used by this class. 
     *
     * @return <CODE>null</CODE>
     */
    public String getDefaultViewState() {
        return null;
    }

    /** Not used by this class. */
    public void reset() {}
    
    ////////////////
    // Public API //
    ////////////////
    
    /**
     * Sets the data model for this view to the given object.
     *
     * If the given model object is <CODE>null</CODE>,
     * the view will display the empty string.
     *
     * @param obj the desired data model for this view
     */
    public void setModel(XObject obj) {
        XObject oldModel = getModel();

        // remove listener from model to be replaced
        if (model != null)
            model.removePropertyChangeListener(this);

        // store new model
        model = obj;
 
        // listen to new model if appropriate
        if (model != null) {
            model.addPropertyChangeListener(this);
            setText(model.toStringData());
        }
       
        // otherwise empty the label
        else setText("");
            
        // if the model has changed
        if (obj != oldModel) {

            // notify listeners of property change
            firePropertyChange(
                MODEL, 
                oldModel, 
                getModel());
        }            
    }
    
    /**
     * Returns the data model for this view,
     * or <CODE>null</CODE> if there is no data model for this view.
     */
    public XObject getModel() {
        return model;
    }
}
