package org.osbp.mysmartshop.dtos;

import java.beans.PropertyChangeListener;
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.DomainReference;
import org.osbp.mysmartshop.dtos.BaseUUIDDto;
import org.osbp.mysmartshop.dtos.DtoTestParentDto;

@SuppressWarnings("all")
public class DtoTestChildCrossRefDto extends BaseUUIDDto implements IDto, Serializable, PropertyChangeListener {
  @DomainReference
  private DtoTestParentDto container;
  
  public DtoTestChildCrossRefDto() {
    installLazyCollections();
  }
  
  /**
   * Installs lazy collection resolving for entity {@link DtoTestChildCrossRef} to the dto {@link DtoTestChildCrossRefDto}.
   * 
   */
  protected void installLazyCollections() {
    super.installLazyCollections();
  }
  
  /**
   * 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;
    }
    super.dispose();
  }
  
  /**
   * Returns the container property or <code>null</code> if not present.
   */
  public DtoTestParentDto getContainer() {
    return this.container;
  }
  
  /**
   * Sets the <code>container</code> property to this instance.
   * Since the reference has an opposite reference, the opposite <code>DtoTestParentDto#
   * crossRefChilds</code> of the <code>container</code> will be handled automatically and no 
   * further coding is required to keep them in sync.<p>
   * See {@link DtoTestParentDto#setCrossRefChilds(DtoTestParentDto)
   * 
   * @param container - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setContainer(final DtoTestParentDto container) {
    checkDisposed();
    if (this.container != null) {
    	this.container.internalRemoveFromCrossRefChilds(this);
    }
    
    internalSetContainer(container);
    
    if (this.container != null) {
    	this.container.internalAddToCrossRefChilds(this);
    }
  }
  
  /**
   * For internal use only!
   */
  public void internalSetContainer(final DtoTestParentDto container) {
    firePropertyChange("container", this.container, this.container = container);
  }
  
  public DtoTestChildCrossRefDto createDto() {
    return new DtoTestChildCrossRefDto();
  }
  
  public DtoTestChildCrossRefDto 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
    DtoTestChildCrossRefDto 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 DtoTestChildCrossRefDto dto, final DtoTestChildCrossRefDto newDto, final MappingContext context) {
    checkDisposed();
    
    if (context == null) {
    	throw new IllegalArgumentException("Context must not be null!");
    }
    
    super.copyContainments(dto, newDto, context);
    
    // copy attributes and beans (beans if derived from entity model)
    
    // copy containment references (cascading is true)
  }
  
  public void copyCrossReferences(final DtoTestChildCrossRefDto dto, final DtoTestChildCrossRefDto newDto, final org.eclipse.osbp.dsl.dto.lib.MappingContext context) {
    checkDisposed();
    
    if (context == null) {
    	throw new IllegalArgumentException("Context must not be null!");
    }
    
    super.copyCrossReferences(dto, newDto, context);
    
    // copy cross references (cascading is false)
    // copy dto container
    if(getContainer() != null) {
    	newDto.setContainer(getContainer().copy(context));
    }
  }
  
  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
    { 
    	super.propertyChange(event);
    }
  }
}
