package org.osbp.tests.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.DomainKey;
import org.eclipse.osbp.runtime.common.annotations.DomainReference;
import org.osbp.tests.dtos.AddressDto;
import org.osbp.tests.dtos.BaseUUIDDto;
import org.osbp.tests.dtos.CompanyDto;

@SuppressWarnings("all")
public class DepartmentDto extends BaseUUIDDto implements IDto, Serializable, PropertyChangeListener {
  @DomainReference
  private CompanyDto company;
  
  @DomainKey
  private String name;
  
  private String description;
  
  @DomainReference
  @Valid
  private List<AddressDto> address;
  
  private double default_yearly_income;
  
  public DepartmentDto() {
    installLazyCollections();
  }
  
  /**
   * Installs lazy collection resolving for entity {@link Department} to the dto {@link DepartmentDto}.
   * 
   */
  protected void installLazyCollections() {
    super.installLazyCollections();
    address = new org.eclipse.osbp.dsl.dto.lib.OppositeContainmentDtoList<>(
    				org.eclipse.osbp.dsl.dto.lib.MappingContext.getCurrent(),
    				AddressDto.class, "department.id",
    				(java.util.function.Supplier<Object> & Serializable) () -> this.getId());
  }
  
  /**
   * 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.address != null) {
        for (AddressDto addressDto : this.address) {
          addressDto.dispose();
        }
        this.address = null;
      }
      
    }
    finally {
      super.dispose();
    }
    
  }
  
  /**
   * Returns the company property or <code>null</code> if not present.
   */
  public CompanyDto getCompany() {
    return this.company;
  }
  
  /**
   * Sets the <code>company</code> property to this instance.
   * Since the reference has an opposite reference, the opposite <code>CompanyDto#
   * departments</code> of the <code>company</code> will be handled automatically and no 
   * further coding is required to keep them in sync.<p>
   * See {@link CompanyDto#setDepartments(CompanyDto)
   * 
   * @param company - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setCompany(final CompanyDto company) {
    checkDisposed();
    if (this.company != null) {
    	this.company.internalRemoveFromDepartments(this);
    }
    
    internalSetCompany(company);
    
    if (this.company != null) {
    	this.company.internalAddToDepartments(this);
    }
  }
  
  /**
   * For internal use only!
   */
  public void internalSetCompany(final CompanyDto company) {
    firePropertyChange("company", this.company, this.company = company);
  }
  
  /**
   * Returns the name property or <code>null</code> if not present.
   */
  public String getName() {
    return this.name;
  }
  
  /**
   * Sets the <code>name</code> property to this instance.
   * 
   * @param name - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setName(final String name) {
    firePropertyChange("name", this.name, this.name = name );
  }
  
  /**
   * Returns the description property or <code>null</code> if not present.
   */
  public String getDescription() {
    return this.description;
  }
  
  /**
   * Sets the <code>description</code> property to this instance.
   * 
   * @param description - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setDescription(final String description) {
    firePropertyChange("description", this.description, this.description = description );
  }
  
  /**
   * Returns an unmodifiable list of address.
   */
  public List<AddressDto> getAddress() {
    return Collections.unmodifiableList(internalGetAddress());
  }
  
  /**
   * Returns the list of <code>AddressDto</code>s thereby lazy initializing it. For internal use only!
   * 
   * @return list - the resulting list
   * 
   */
  public List<AddressDto> internalGetAddress() {
    if (this.address == null) {
      this.address = new java.util.ArrayList<AddressDto>();
    }
    return this.address;
  }
  
  /**
   * Adds the given addressDto to this object. <p>
   * Since the reference is a composition reference, the opposite reference <code>AddressDto#department</code> of the <code>addressDto</code> will be handled automatically and no further coding is required to keep them in sync.<p>
   * See {@link AddressDto#setDepartment(AddressDto)}.
   * 
   * @param addressDto - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void addToAddress(final AddressDto addressDto) {
    checkDisposed();
    
    addressDto.setDepartment(this);
  }
  
  /**
   * Removes the given addressDto from this object. <p>
   * 
   * @param addressDto - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void removeFromAddress(final AddressDto addressDto) {
    checkDisposed();
    
    addressDto.setDepartment(null);
  }
  
  /**
   * For internal use only!
   */
  public void internalAddToAddress(final AddressDto addressDto) {
    
    if(!internalGetAddress().contains(addressDto)) {
    	if(!org.eclipse.osbp.dsl.dto.lib.MappingContext.isMappingMode()) {
    		// collections will become resolved! We need to send a delta notification.
    		List<AddressDto> oldList = new java.util.ArrayList<>(internalGetAddress());
    		internalGetAddress().add(addressDto);
    		firePropertyChange("address", oldList, internalGetAddress());
    	} else {
    		// in mapping mode, we do NOT resolve any collection
    		internalGetAddress().add(addressDto);
    	}
    }
  }
  
  /**
   * For internal use only!
   */
  public void internalRemoveFromAddress(final AddressDto addressDto) {
    if(!org.eclipse.osbp.dsl.dto.lib.MappingContext.isMappingMode()) {
    	// collections will become resolved! We need to send a delta notification.
    	List<AddressDto> oldList = new java.util.ArrayList<>(internalGetAddress());
    	internalGetAddress().remove(addressDto);
    	firePropertyChange("address", oldList, internalGetAddress());	
    }else{
    	// in mapping mode, we do NOT resolve any collection
    	internalGetAddress().remove(addressDto);
    }
  }
  
  /**
   * Sets the <code>address</code> property to this instance.
   * Since the reference has an opposite reference, the opposite <code>AddressDto#
   * department</code> of the <code>address</code> will be handled automatically and no 
   * further coding is required to keep them in sync.<p>
   * See {@link AddressDto#setDepartment(AddressDto)
   * 
   * @param address - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setAddress(final List<AddressDto> address) {
    checkDisposed();
    for (AddressDto dto : internalGetAddress().toArray(new AddressDto[this.address.size()])) {
    	removeFromAddress(dto);
    }
    
    if(address == null) {
    	return;
    }
    
    for (AddressDto dto : address) {
    	addToAddress(dto);
    }
  }
  
  /**
   * Returns the default_yearly_income property or <code>null</code> if not present.
   */
  public double getDefault_yearly_income() {
    return this.default_yearly_income;
  }
  
  /**
   * Sets the <code>default_yearly_income</code> property to this instance.
   * 
   * @param default_yearly_income - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setDefault_yearly_income(final double default_yearly_income) {
    firePropertyChange("default_yearly_income", this.default_yearly_income, this.default_yearly_income = default_yearly_income );
  }
  
  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);
    }
  }
}
