package org.osbp.mysmartshop.dtos;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.Serializable;

import org.eclipse.osbp.dsl.common.datatypes.IDto;
import org.eclipse.osbp.dsl.dto.lib.MappingContext;
import org.eclipse.osbp.runtime.common.annotations.Dispose;
import org.eclipse.osbp.runtime.common.annotations.Id;
import org.osbp.mysmartshop.entities.BaseID;

@SuppressWarnings("all")
public class BaseIDDto implements IDto, Serializable, PropertyChangeListener {
	private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(
			this);

	@Dispose
	private boolean disposed;

	@Id
	private int id;

	/**
	 * @return true, if the object is disposed. Disposed means, that it is
	 *         prepared for garbage collection and may not be used anymore.
	 *         Accessing objects that are already disposed will cause runtime
	 *         exceptions.
	 * 
	 */
	public boolean isDisposed() {
		return this.disposed;
	}

	/**
	 * @see PropertyChangeSupport#addPropertyChangeListener(PropertyChangeListener)
	 */
	public void addPropertyChangeListener(final PropertyChangeListener listener) {
		propertyChangeSupport.addPropertyChangeListener(listener);
	}

	/**
	 * @see PropertyChangeSupport#addPropertyChangeListener(String,
	 *      PropertyChangeListener)
	 */
	public void addPropertyChangeListener(final String propertyName,
			final PropertyChangeListener listener) {
		propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
	}

	/**
	 * @see PropertyChangeSupport#removePropertyChangeListener(PropertyChangeListener)
	 */
	public void removePropertyChangeListener(
			final PropertyChangeListener listener) {
		propertyChangeSupport.removePropertyChangeListener(listener);
	}

	/**
	 * @see PropertyChangeSupport#removePropertyChangeListener(String,
	 *      PropertyChangeListener)
	 */
	public void removePropertyChangeListener(final String propertyName,
			final PropertyChangeListener listener) {
		propertyChangeSupport.removePropertyChangeListener(propertyName,
				listener);
	}

	/**
	 * @see PropertyChangeSupport#firePropertyChange(String, Object, Object)
	 */
	public void firePropertyChange(final String propertyName,
			final Object oldValue, final Object newValue) {
		propertyChangeSupport.firePropertyChange(propertyName, oldValue,
				newValue);
	}

	/**
	 * Checks whether the object is disposed.
	 * 
	 * @throws RuntimeException
	 *             if the object is disposed.
	 */
	private void checkDisposed() {
		if (isDisposed()) {
			throw new RuntimeException("Object already disposed: " + this);
		}
	}

	/**
	 * Calling dispose will destroy that instance. The internal state will be
	 * set to 'disposed' and methods of that object must not be used anymore.
	 * Each call will result in runtime exceptions.<br/>
	 * If this object keeps composition containments, these will be disposed
	 * too. So the whole composition containment tree will be disposed on
	 * calling this method.
	 */
	@Dispose
	public void dispose() {
		if (isDisposed()) {
			return;
		}
		firePropertyChange("disposed", this.disposed, this.disposed = true);
	}

	/**
	 * Installs lazy collection resolving for entity {@link BaseID} to the dto
	 * {@link BaseIDDto}.
	 * 
	 */
	protected void installLazyCollections() {

	}

	/**
	 * Returns the id property or <code>null</code> if not present.
	 */
	public int getId() {
		return this.id;
	}

	/**
	 * Sets the <code>id</code> property to this instance.
	 * 
	 * @param id
	 *            - the property
	 * @throws RuntimeException
	 *             if instance is <code>disposed</code>
	 * 
	 */
	public void setId(final int id) {
		firePropertyChange("id", this.id, this.id = id);
	}

	@Override
	public boolean equals(final Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		BaseIDDto other = (BaseIDDto) obj;
		if (other.id != this.id)
			return false;
		return true;
	}

	@Override
	public int hashCode() {
		int prime = 31;
		int result = 1;
		result = prime * result + this.id;
		return result;
	}

	public BaseIDDto createDto() {
		return new BaseIDDto();
	}

	public BaseIDDto copy(final MappingContext context) {
		checkDisposed();

		if (context == null) {
			throw new IllegalArgumentException("Context must not be null!");
		}

		if (context.isMaxLevel()) {
			return null;
		}

		// if context contains a copied instance of this object
		// then return it
		BaseIDDto newDto = context.get(this);
		if (newDto != null) {
			return newDto;
		}

		try {
			context.increaseLevel();

			newDto = createDto();
			context.register(this, newDto);

			// first copy the containments and attributes
			copyContainments(this, newDto, context);

			// then copy cross references to ensure proper
			// opposite references are copied too.
			copyCrossReferences(this, newDto, context);
		} finally {
			context.decreaseLevel();
		}

		return newDto;
	}

	public void copyContainments(final BaseIDDto dto, final BaseIDDto newDto,
			final MappingContext context) {
		checkDisposed();

		if (context == null) {
			throw new IllegalArgumentException("Context must not be null!");
		}

		// copy attributes and beans (beans if derived from entity model)
		// copy id
		newDto.setId(getId());

		// copy containment references (cascading is true)
	}

	public void copyCrossReferences(final BaseIDDto dto,
			final BaseIDDto newDto,
			final org.eclipse.osbp.dsl.dto.lib.MappingContext context) {
		checkDisposed();

		if (context == null) {
			throw new IllegalArgumentException("Context must not be null!");
		}

		// copy cross references (cascading is false)
	}

	public void propertyChange(final java.beans.PropertyChangeEvent event) {
		Object source = event.getSource();

		// forward the event from embeddable beans to all listeners. So the
		// parent of the embeddable
		// bean will become notified and its dirty state can be handled properly
		{
			// no super class available to forward event
		}
	}
}
