package nxm.sys.inc;

import java.io.IOException;
import java.io.NotSerializableException;
import java.io.ObjectOutputStream;
import java.util.EventObject;

/** A "PropertyViewEvent" event is generated when a Java Bean property is viewed. You can register
    a {@link PropertyViewedListener} so as to be notified when the property is viewed. <br>
    <br>
    This class is intentionally similar to {@link java.beans.PropertyChangeListener}.

    @author  J. Czechowski IV
    @since   NeXtMidas 2.1.0
 */
public interface PropertyViewedListener {
  /** This method gets called just before a property is viewed.
      @param evt The event object describing which property is viewed.
   */
  void propertyView (PropertyViewEvent evt);


  //////////////////////////////////////////////////////////////////////////////////////////////////
  // DEFINE A VIEW EVENT
  //////////////////////////////////////////////////////////////////////////////////////////////////

  /** Event sent when a property is viewed. <br>
      <br>
      If a {@link PropertyViewedListener} wishes to verify the value of the property, is should
      use {@link #getOldValue()}, is should not attempt to get the property from the source as
      dosing so will cause an infinite loop. <br>
      <br>
      This class is intentionally similar to {@link java.beans.PropertyChangeEvent}.
   */
  public static class PropertyViewEvent extends EventObject {
    /** NOTE: this should be changed if the structure/fields of this class changes. */
    private static final long serialVersionUID = 2010080300290L; // for Serializable interface
    /** The property name.  */
    private final String name;
    /** The property value. */
    @SuppressWarnings("serial")
    private final Object value;
    /** Message given when user tries to serialize a PropertyViewEvent that contains unserializble Objects */
    @InternalUseOnly
    public static final String UNSERIALIZABLE_PROPERTYVIEWEVENT_OBJECT_MESSAGE =
        "nxm.sys.inc.PropertyViewedListener.PropertyViewEvent only Serializable if the property value is Serializable";

    /** Creates a new instance.
        @param source       The source of the event.
        @param propertyName The property name.
        @param oldValue     The property value.
     */
    public PropertyViewEvent (Object source, String propertyName, Object oldValue) {
      super(source);
      name  = propertyName;
      value = oldValue;
    }

    /** Gets the name of the property viewed.
        @return The name of the property viewed.
     */
    public String getPropertyName () {
      return name;
    }

    /** Gets the current value of the property.
        @return The current value of the property.
     */
    public Object getOldValue () {
      return value;
    }

    /** Overwrite default serialization only to give more descriptive error
     *
     *  @param oos          Object Output Stream
     *  @throws IOException Exception thrown by writeObject
     */
   private void writeObject (ObjectOutputStream oos) throws IOException {
     try {
       // default serialization
       oos.defaultWriteObject();
     }
     catch (NotSerializableException nse) {
       throw new UnsupportedOperationException(UNSERIALIZABLE_PROPERTYVIEWEVENT_OBJECT_MESSAGE, nse);
     }
   }
  } // end inner class PropertyViewEvent

} // end interface PropertyViewedListener
