/*
 * @(#)XObject.java    2.5.0   23 August 2006
 *
 * Copyright 2006
 * 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;

import edu.neu.ccs.util.*;
import java.beans.*;
import java.io.Serializable;
import java.text.ParseException;
import javax.swing.event.SwingPropertyChangeSupport;

/**
 * <P>Abstract superclass for 
 * <CODE>{@link Stringable Stringable}</CODE> objects.</P>
 * 
 * @author  Richard Rasala
 * @author  Jeff Raab
 * @version 2.5.0
 */
public abstract class XObject 
    implements Stringable, Cloneable, Serializable 
{
    /**
     * Bound property name for the value property
     * that indicates that a value has been set.
     */
    public static final String VALUE = "value";

    /** Helper object for property change API. */
    protected SwingPropertyChangeSupport changeAdapter =
        new SwingPropertyChangeSupport(this);

    ////////////////
    // Stringable //
    ////////////////
    
    public abstract void fromStringData(String data) 
        throws ParseException;

    public abstract String toStringData();
    
    ////////////////
    // Public API //
    ////////////////
    
    /**
     * Returns an array of <CODE>String</CODE>s 
     * containing the encapsulated states of the given array 
     * of <CODE>Stringable</CODE> objects.
     * 
     * @param obj an array of <CODE>Stringable</CODE> objects
     * @return the resulting array of <CODE>String</CODE>s
     * @since   1.0
     */
    public static String[] toStringArray(Stringable[] obj) {
        
        // return null array if appropriate
        if (obj == null)
            return null;
        
        // otherwise perform the type translation
        String[] temp = new String[obj.length];
        for (int i = 0; i < temp.length; i++)
            if (obj[i] != null)
                temp[i] = obj[i].toStringData();
        return temp;
    }

    /**
     * Registers the given object to listen for
     * property change events generated by this object.
     *
     * @param listener the listener to be registered
     * @since   1.0
     */
    public void addPropertyChangeListener(
        PropertyChangeListener listener) 
    {
        changeAdapter.addPropertyChangeListener(listener);
    }

    /**
     * Registers the given object to listen for
     * property change events with the provided name
     * generated by this object.
     *
     * @param propertyName the name of the desired property 
     * @param listener the listener to be registered
     * @since   1.0
     */
    public void addPropertyChangeListener(
        String propertyName,
        PropertyChangeListener listener) 
    {
        changeAdapter.addPropertyChangeListener(
            propertyName, 
            listener);
    }

    /**
     * Deregisters the given object from listening for
     * property change events generated by this object.
     *
     * @param listener the listener to be deregistered
     * @since   1.0
     */
    public void removePropertyChangeListener(
        PropertyChangeListener listener) 
    {
        changeAdapter.removePropertyChangeListener(listener);
    }

    /**
     * Deregisters the given object from listening for
     * property change events with the provided name
     * generated by this object.
     *
     * @param propertyName the name of the desired property 
     * @param listener the listener to be deregistered
     * @since   1.0
     */
    public void removePropertyChangeListener(
        String propertyName,
        PropertyChangeListener listener) 
    {
        changeAdapter.removePropertyChangeListener(
            propertyName, 
            listener);
    }

    ////////////////////
    // Static methods //
    ////////////////////

    /**
     * <p>Returns a neatly formatted String
     * representation of the given exception and the 
     * data that generated the exception,  for use
     * in user error messages.</p>
     * 
     * <p>As of 2.5.0, this method has been simplified
     * to return <code>ex.getMessage()</code> since
     * the formatting is now handled automatically via
     * code in the class <code>BaseParser</code>.  The
     * <code>data</code> parameter is now ignored.</p>
     * 
     * <p>This method was left in place rather than
     * edit numerous JPT classes that used the method.</p>
     * 
     * @param ex the <CODE>ParseException</CODE> to be reported
     * @param data the input String that generated the exception
     * @since   1.0
     */
    public static String formatErrorMessage(
        ParseException ex, 
        String data) 
    {
        // Formatting error messages is now built into BaseParser
        // The original code for this method is commented out
        
        /*
        String message = 
            ex.getMessage() +
            SystemUtilities.getLineSeparator();

        // show location of error if appropriate
        if (ex.getErrorOffset() > -1) {
            message += data + "\n";
            for (int i = 0; i < ex.getErrorOffset(); i++)
                message += " ";
            message += "^";
        }
        
        return message;
        */
        
        return ex.getMessage();
    }
}
