package org.osbp.tests.dtos;

import java.beans.PropertyChangeListener;
import java.io.Serializable;
import java.util.Date;
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.Properties;
import org.eclipse.osbp.runtime.common.annotations.Property;
import org.osbp.tests.dtos.BaseUUIDDto;
import org.osbp.tests.dtos.CashPaymentMethodDto;
import org.osbp.tests.dtos.CashSlipDto;

@SuppressWarnings("all")
public class CashPaymentDto extends BaseUUIDDto implements IDto, Serializable, PropertyChangeListener {
  @Valid
  private Date now;
  
  @Properties(properties = @Property(key = "decimalformat", value = "###,##0.00 &curren;"))
  private Double payed;
  
  @DomainReference
  private CashSlipDto slip;
  
  @DomainReference
  private CashPaymentMethodDto methodOfPayment;
  
  public CashPaymentDto() {
    installLazyCollections();
  }
  
  /**
   * Installs lazy collection resolving for entity {@link CashPayment} to the dto {@link CashPaymentDto}.
   * 
   */
  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 now property or <code>null</code> if not present.
   */
  public Date getNow() {
    return this.now;
  }
  
  /**
   * Sets the <code>now</code> property to this instance.
   * 
   * @param now - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setNow(final Date now) {
    firePropertyChange("now", this.now, this.now = now );
  }
  
  /**
   * Returns the payed property or <code>null</code> if not present.
   */
  public Double getPayed() {
    return this.payed;
  }
  
  /**
   * Sets the <code>payed</code> property to this instance.
   * 
   * @param payed - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setPayed(final Double payed) {
    firePropertyChange("payed", this.payed, this.payed = payed );
  }
  
  /**
   * Returns the slip property or <code>null</code> if not present.
   */
  public CashSlipDto getSlip() {
    return this.slip;
  }
  
  /**
   * Sets the <code>slip</code> property to this instance.
   * Since the reference has an opposite reference, the opposite <code>CashSlipDto#
   * payments</code> of the <code>slip</code> will be handled automatically and no 
   * further coding is required to keep them in sync.<p>
   * See {@link CashSlipDto#setPayments(CashSlipDto)
   * 
   * @param slip - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setSlip(final CashSlipDto slip) {
    checkDisposed();
    if (this.slip != null) {
    	this.slip.internalRemoveFromPayments(this);
    }
    
    internalSetSlip(slip);
    
    if (this.slip != null) {
    	this.slip.internalAddToPayments(this);
    }
  }
  
  /**
   * For internal use only!
   */
  public void internalSetSlip(final CashSlipDto slip) {
    firePropertyChange("slip", this.slip, this.slip = slip);
  }
  
  /**
   * Returns the methodOfPayment property or <code>null</code> if not present.
   */
  public CashPaymentMethodDto getMethodOfPayment() {
    return this.methodOfPayment;
  }
  
  /**
   * Sets the <code>methodOfPayment</code> property to this instance.
   * Since the reference has an opposite reference, the opposite <code>CashPaymentMethodDto#
   * payments</code> of the <code>methodOfPayment</code> will be handled automatically and no 
   * further coding is required to keep them in sync.<p>
   * See {@link CashPaymentMethodDto#setPayments(CashPaymentMethodDto)
   * 
   * @param methodOfPayment - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setMethodOfPayment(final CashPaymentMethodDto methodOfPayment) {
    checkDisposed();
    if (this.methodOfPayment != null) {
    	this.methodOfPayment.internalRemoveFromPayments(this);
    }
    
    internalSetMethodOfPayment(methodOfPayment);
    
    if (this.methodOfPayment != null) {
    	this.methodOfPayment.internalAddToPayments(this);
    }
  }
  
  /**
   * For internal use only!
   */
  public void internalSetMethodOfPayment(final CashPaymentMethodDto methodOfPayment) {
    firePropertyChange("methodOfPayment", this.methodOfPayment, this.methodOfPayment = methodOfPayment);
  }
  
  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);
    }
  }
}
