package org.osbp.mysmartshop.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.runtime.common.annotations.Dispose;
import org.eclipse.osbp.runtime.common.annotations.DomainReference;
import org.eclipse.osbp.runtime.common.annotations.FilterDepth;
import org.osbp.mysmartshop.dtos.BaseUUIDDto;
import org.osbp.mysmartshop.dtos.CashDrawerSumDto;

@SuppressWarnings("all")
public class CashDrawerCurrencyDto extends BaseUUIDDto implements IDto, Serializable, PropertyChangeListener {
  @DomainReference
  @Valid
  @FilterDepth(depth = 0)
  private List<CashDrawerSumDto> sums;
  
  public CashDrawerCurrencyDto() {
    installLazyCollections();
  }
  
  /**
   * Installs lazy collection resolving for entity {@link CashDrawerCurrency} to the dto {@link CashDrawerCurrencyDto}.
   * 
   */
  protected void installLazyCollections() {
    super.installLazyCollections();
    sums = new org.eclipse.osbp.dsl.dto.lib.OppositeContainmentDtoList<>(
    				org.eclipse.osbp.dsl.dto.lib.MappingContext.getCurrent(),
    				CashDrawerSumDto.class, this, "drawer.id",
    				(java.util.function.Supplier<Object> & Serializable) () -> this.getId(), 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;
    }
    try {
      // Dispose all the composition references.
      if (this.sums != null) {
        for (CashDrawerSumDto cashDrawerSumDto : this.sums) {
          cashDrawerSumDto.dispose();
        }
        this.sums = null;
      }
      
    }
    finally {
      super.dispose();
    }
    
  }
  
  /**
   * Returns an unmodifiable list of sums.
   */
  public List<CashDrawerSumDto> getSums() {
    return Collections.unmodifiableList(internalGetSums());
  }
  
  /**
   * Returns the list of <code>CashDrawerSumDto</code>s thereby lazy initializing it. For internal use only!
   * 
   * @return list - the resulting list
   * 
   */
  public List<CashDrawerSumDto> internalGetSums() {
    if (this.sums == null) {
      this.sums = new java.util.ArrayList<CashDrawerSumDto>();
    }
    return this.sums;
  }
  
  /**
   * Adds the given cashDrawerSumDto to this object. <p>
   * Since the reference is a composition reference, the opposite reference <code>CashDrawerSumDto#drawer</code> of the <code>cashDrawerSumDto</code> will be handled automatically and no further coding is required to keep them in sync.<p>
   * See {@link CashDrawerSumDto#setDrawer(CashDrawerSumDto)}.
   * 
   * @param cashDrawerSumDto - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void addToSums(final CashDrawerSumDto cashDrawerSumDto) {
    checkDisposed();
    
    cashDrawerSumDto.setDrawer(this);
  }
  
  /**
   * Removes the given cashDrawerSumDto from this object. <p>
   * 
   * @param cashDrawerSumDto - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void removeFromSums(final CashDrawerSumDto cashDrawerSumDto) {
    checkDisposed();
    
    cashDrawerSumDto.setDrawer(null);
  }
  
  /**
   * For internal use only!
   */
  public void internalAddToSums(final CashDrawerSumDto cashDrawerSumDto) {
    
    if(!internalGetSums().contains(cashDrawerSumDto)) {
    	if(!org.eclipse.osbp.dsl.dto.lib.MappingContext.isMappingMode()) {
    		List<CashDrawerSumDto> oldList = null;
    		if(internalGetSums() instanceof org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) {
    			oldList = ((org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) internalGetSums()).copy();
    		} else {
    			oldList = new java.util.ArrayList<>(internalGetSums());
    		}
    		internalGetSums().add(cashDrawerSumDto);
    		firePropertyChange("sums", oldList, internalGetSums());
    	} else {
    		// in mapping mode, we do NOT resolve any collection
    		internalGetSums().add(cashDrawerSumDto);
    	}
    }
  }
  
  /**
   * For internal use only!
   */
  public void internalRemoveFromSums(final CashDrawerSumDto cashDrawerSumDto) {
    if(!org.eclipse.osbp.dsl.dto.lib.MappingContext.isMappingMode()) {
    	List<CashDrawerSumDto> oldList = null;
    	if(internalGetSums() instanceof org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) {
    		oldList = ((org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) internalGetSums()).copy();
    	} else {
    		oldList = new java.util.ArrayList<>(internalGetSums());
    	}
    	internalGetSums().remove(cashDrawerSumDto);
    	firePropertyChange("sums", oldList, internalGetSums());	
    }else{
    	// in mapping mode, we do NOT resolve any collection
    	internalGetSums().remove(cashDrawerSumDto);
    }
  }
  
  /**
   * Sets the <code>sums</code> property to this instance.
   * Since the reference has an opposite reference, the opposite <code>CashDrawerSumDto#
   * drawer</code> of the <code>sums</code> will be handled automatically and no 
   * further coding is required to keep them in sync.<p>
   * See {@link CashDrawerSumDto#setDrawer(CashDrawerSumDto)
   * 
   * @param sums - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setSums(final List<CashDrawerSumDto> sums) {
    checkDisposed();
    for (CashDrawerSumDto dto : internalGetSums().toArray(new CashDrawerSumDto[this.sums.size()])) {
    	removeFromSums(dto);
    }
    
    if(sums == null) {
    	return;
    }
    
    for (CashDrawerSumDto dto : sums) {
    	addToSums(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);
    }
  }
}
