package org.eclipse.osbp.dsl.tests.carstore.dtos;

import java.beans.PropertyChangeListener;
import java.io.Serializable;
import java.util.Collections;
import java.util.List;
import javax.validation.Valid;
import org.eclipse.osbp.dsl.common.datatypes.IDto;
import org.eclipse.osbp.dsl.tests.carstore.dtos.BaseDto;
import org.eclipse.osbp.dsl.tests.carstore.dtos.CarDto;
import org.eclipse.osbp.dsl.tests.carstore.dtos.ToCycle2Dto;
import org.eclipse.osbp.runtime.common.annotations.Dispose;
import org.eclipse.osbp.runtime.common.annotations.DomainReference;
import org.eclipse.osbp.runtime.common.annotations.FilterDepth;

@SuppressWarnings("all")
public class ToCycle1Dto extends BaseDto implements IDto, Serializable, PropertyChangeListener {
  @DomainReference
  @FilterDepth(depth = 0)
  private CarDto car;
  
  @DomainReference
  @Valid
  @FilterDepth(depth = 0)
  private List<ToCycle2Dto> cycles2;
  
  public ToCycle1Dto() {
    installLazyCollections();
  }
  
  /**
   * Installs lazy collection resolving for entity {@link ToCycle1} to the dto {@link ToCycle1Dto}.
   * 
   */
  protected void installLazyCollections() {
    super.installLazyCollections();
    cycles2 = new org.eclipse.osbp.dsl.dto.lib.OppositeDtoList<>(
    				org.eclipse.osbp.dsl.dto.lib.MappingContext.getCurrent(),
    				ToCycle2Dto.class, "parent.uuid",
    				(java.util.function.Supplier<Object> & Serializable) () -> this.getUuid(), this);
  }
  
  /**
   * 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 car property or <code>null</code> if not present.
   */
  public CarDto getCar() {
    return this.car;
  }
  
  /**
   * Sets the <code>car</code> property to this instance.
   * Since the reference has an opposite reference, the opposite <code>CarDto#
   * cycles1</code> of the <code>car</code> will be handled automatically and no 
   * further coding is required to keep them in sync.<p>
   * See {@link CarDto#setCycles1(CarDto)
   * 
   * @param car - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setCar(final CarDto car) {
    checkDisposed();
    if (this.car != null) {
    	this.car.internalRemoveFromCycles1(this);
    }
    
    internalSetCar(car);
    
    if (this.car != null) {
    	this.car.internalAddToCycles1(this);
    }
  }
  
  /**
   * For internal use only!
   */
  public void internalSetCar(final CarDto car) {
    firePropertyChange("car", this.car, this.car = car);
  }
  
  /**
   * Returns an unmodifiable list of cycles2.
   */
  public List<ToCycle2Dto> getCycles2() {
    return Collections.unmodifiableList(internalGetCycles2());
  }
  
  /**
   * Returns the list of <code>ToCycle2Dto</code>s thereby lazy initializing it. For internal use only!
   * 
   * @return list - the resulting list
   * 
   */
  public List<ToCycle2Dto> internalGetCycles2() {
    if (this.cycles2 == null) {
      this.cycles2 = new java.util.ArrayList<ToCycle2Dto>();
    }
    return this.cycles2;
  }
  
  /**
   * Adds the given toCycle2Dto to this object. <p>
   * Since the reference is a composition reference, the opposite reference <code>ToCycle2Dto#parent</code> of the <code>toCycle2Dto</code> will be handled automatically and no further coding is required to keep them in sync.<p>
   * See {@link ToCycle2Dto#setParent(ToCycle2Dto)}.
   * 
   * @param toCycle2Dto - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void addToCycles2(final ToCycle2Dto toCycle2Dto) {
    checkDisposed();
    
    toCycle2Dto.setParent(this);
  }
  
  /**
   * Removes the given toCycle2Dto from this object. <p>
   * 
   * @param toCycle2Dto - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void removeFromCycles2(final ToCycle2Dto toCycle2Dto) {
    checkDisposed();
    
    toCycle2Dto.setParent(null);
  }
  
  /**
   * For internal use only!
   */
  public void internalAddToCycles2(final ToCycle2Dto toCycle2Dto) {
    
    if(!org.eclipse.osbp.dsl.dto.lib.MappingContext.isMappingMode()) {
    		List<ToCycle2Dto> oldList = null;
    		if(internalGetCycles2() instanceof org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) {
    			oldList = ((org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) internalGetCycles2()).copy();
    		} else {
    			oldList = new java.util.ArrayList<>(internalGetCycles2());
    		}
    		internalGetCycles2().add(toCycle2Dto);
    		firePropertyChange("cycles2", oldList, internalGetCycles2());
    }
  }
  
  /**
   * For internal use only!
   */
  public void internalRemoveFromCycles2(final ToCycle2Dto toCycle2Dto) {
    if(!org.eclipse.osbp.dsl.dto.lib.MappingContext.isMappingMode()) {
    	List<ToCycle2Dto> oldList = null;
    	if(internalGetCycles2() instanceof org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) {
    		oldList = ((org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) internalGetCycles2()).copy();
    	} else {
    		oldList = new java.util.ArrayList<>(internalGetCycles2());
    	}
    	internalGetCycles2().remove(toCycle2Dto);
    	firePropertyChange("cycles2", oldList, internalGetCycles2());	
    }else{
    	// in mapping mode, we do NOT resolve any collection
    	internalGetCycles2().remove(toCycle2Dto);
    }
  }
  
  /**
   * Sets the <code>cycles2</code> property to this instance.
   * Since the reference has an opposite reference, the opposite <code>ToCycle2Dto#
   * parent</code> of the <code>cycles2</code> will be handled automatically and no 
   * further coding is required to keep them in sync.<p>
   * See {@link ToCycle2Dto#setParent(ToCycle2Dto)
   * 
   * @param cycles2 - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setCycles2(final List<ToCycle2Dto> cycles2) {
    checkDisposed();
    for (ToCycle2Dto dto : internalGetCycles2().toArray(new ToCycle2Dto[this.cycles2.size()])) {
    	removeFromCycles2(dto);
    }
    
    if(cycles2 == null) {
    	return;
    }
    
    for (ToCycle2Dto dto : cycles2) {
    	addToCycles2(dto);
    }
  }
  
  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);
    }
  }
}
