package org.osbp.mysmartshop.dtos;

import java.beans.PropertyChangeListener;
import java.io.Serializable;
import java.util.Collections;
import java.util.Date;
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.eclipse.osbp.runtime.common.annotations.Properties;
import org.eclipse.osbp.runtime.common.annotations.Property;
import org.osbp.mysmartshop.dtos.BaseUUIDDto;
import org.osbp.mysmartshop.dtos.CashPaymentDto;
import org.osbp.mysmartshop.dtos.CashPositionDto;
import org.osbp.mysmartshop.dtos.CashRegisterDto;
import org.osbp.mysmartshop.dtos.McustomerDto;

@SuppressWarnings("all")
public class CashSlipDto extends BaseUUIDDto implements IDto, Serializable, PropertyChangeListener {
  private String currentDay;
  
  @Valid
  private Date now;
  
  private String cashier;
  
  @Properties(properties = @Property(key = "decimalformat", value = "###,##0.00 &curren"))
  private Double total;
  
  private long serial;
  
  private boolean payed;
  
  @DomainReference
  @Valid
  @FilterDepth(depth = 0)
  private List<CashPositionDto> positions;
  
  @DomainReference
  @FilterDepth(depth = 0)
  private McustomerDto customer;
  
  @DomainReference
  @FilterDepth(depth = 0)
  private CashRegisterDto register;
  
  @DomainReference
  @Valid
  @FilterDepth(depth = 0)
  private List<CashPaymentDto> payments;
  
  public CashSlipDto() {
    installLazyCollections();
  }
  
  /**
   * Installs lazy collection resolving for entity {@link CashSlip} to the dto {@link CashSlipDto}.
   * 
   */
  protected void installLazyCollections() {
    super.installLazyCollections();
    positions = new org.eclipse.osbp.dsl.dto.lib.OppositeContainmentDtoList<>(
    				org.eclipse.osbp.dsl.dto.lib.MappingContext.getCurrent(),
    				CashPositionDto.class, this, "slip.id",
    				(java.util.function.Supplier<Object> & Serializable) () -> this.getId(), this);
    payments = new org.eclipse.osbp.dsl.dto.lib.OppositeContainmentDtoList<>(
    				org.eclipse.osbp.dsl.dto.lib.MappingContext.getCurrent(),
    				CashPaymentDto.class, this, "slip.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.positions != null) {
        for (CashPositionDto cashPositionDto : this.positions) {
          cashPositionDto.dispose();
        }
        this.positions = null;
      }
      if (this.payments != null) {
        for (CashPaymentDto cashPaymentDto : this.payments) {
          cashPaymentDto.dispose();
        }
        this.payments = null;
      }
      
    }
    finally {
      super.dispose();
    }
    
  }
  
  /**
   * Returns the currentDay property or <code>null</code> if not present.
   */
  public String getCurrentDay() {
    return this.currentDay;
  }
  
  /**
   * Sets the <code>currentDay</code> property to this instance.
   * 
   * @param currentDay - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setCurrentDay(final String currentDay) {
    firePropertyChange("currentDay", this.currentDay, this.currentDay = currentDay );
  }
  
  /**
   * 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 cashier property or <code>null</code> if not present.
   */
  public String getCashier() {
    return this.cashier;
  }
  
  /**
   * Sets the <code>cashier</code> property to this instance.
   * 
   * @param cashier - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setCashier(final String cashier) {
    firePropertyChange("cashier", this.cashier, this.cashier = cashier );
  }
  
  /**
   * Returns the total property or <code>null</code> if not present.
   */
  public Double getTotal() {
    return this.total;
  }
  
  /**
   * Sets the <code>total</code> property to this instance.
   * 
   * @param total - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setTotal(final Double total) {
    firePropertyChange("total", this.total, this.total = total );
  }
  
  /**
   * Returns the serial property or <code>null</code> if not present.
   */
  public long getSerial() {
    return this.serial;
  }
  
  /**
   * Sets the <code>serial</code> property to this instance.
   * 
   * @param serial - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setSerial(final long serial) {
    firePropertyChange("serial", this.serial, this.serial = serial );
  }
  
  /**
   * Returns the payed property or <code>null</code> if not present.
   */
  public boolean 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 boolean payed) {
    firePropertyChange("payed", this.payed, this.payed = payed );
  }
  
  /**
   * Returns an unmodifiable list of positions.
   */
  public List<CashPositionDto> getPositions() {
    return Collections.unmodifiableList(internalGetPositions());
  }
  
  /**
   * Returns the list of <code>CashPositionDto</code>s thereby lazy initializing it. For internal use only!
   * 
   * @return list - the resulting list
   * 
   */
  public List<CashPositionDto> internalGetPositions() {
    if (this.positions == null) {
      this.positions = new java.util.ArrayList<CashPositionDto>();
    }
    return this.positions;
  }
  
  /**
   * Adds the given cashPositionDto to this object. <p>
   * Since the reference is a composition reference, the opposite reference <code>CashPositionDto#slip</code> of the <code>cashPositionDto</code> will be handled automatically and no further coding is required to keep them in sync.<p>
   * See {@link CashPositionDto#setSlip(CashPositionDto)}.
   * 
   * @param cashPositionDto - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void addToPositions(final CashPositionDto cashPositionDto) {
    checkDisposed();
    
    cashPositionDto.setSlip(this);
  }
  
  /**
   * Removes the given cashPositionDto from this object. <p>
   * 
   * @param cashPositionDto - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void removeFromPositions(final CashPositionDto cashPositionDto) {
    checkDisposed();
    
    cashPositionDto.setSlip(null);
  }
  
  /**
   * For internal use only!
   */
  public void internalAddToPositions(final CashPositionDto cashPositionDto) {
    
    if(!internalGetPositions().contains(cashPositionDto)) {
    	if(!org.eclipse.osbp.dsl.dto.lib.MappingContext.isMappingMode()) {
    		List<CashPositionDto> oldList = null;
    		if(internalGetPositions() instanceof org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) {
    			oldList = ((org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) internalGetPositions()).copy();
    		} else {
    			oldList = new java.util.ArrayList<>(internalGetPositions());
    		}
    		internalGetPositions().add(cashPositionDto);
    		firePropertyChange("positions", oldList, internalGetPositions());
    	} else {
    		// in mapping mode, we do NOT resolve any collection
    		internalGetPositions().add(cashPositionDto);
    	}
    }
  }
  
  /**
   * For internal use only!
   */
  public void internalRemoveFromPositions(final CashPositionDto cashPositionDto) {
    if(!org.eclipse.osbp.dsl.dto.lib.MappingContext.isMappingMode()) {
    	List<CashPositionDto> oldList = null;
    	if(internalGetPositions() instanceof org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) {
    		oldList = ((org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) internalGetPositions()).copy();
    	} else {
    		oldList = new java.util.ArrayList<>(internalGetPositions());
    	}
    	internalGetPositions().remove(cashPositionDto);
    	firePropertyChange("positions", oldList, internalGetPositions());	
    }else{
    	// in mapping mode, we do NOT resolve any collection
    	internalGetPositions().remove(cashPositionDto);
    }
  }
  
  /**
   * Sets the <code>positions</code> property to this instance.
   * Since the reference has an opposite reference, the opposite <code>CashPositionDto#
   * slip</code> of the <code>positions</code> will be handled automatically and no 
   * further coding is required to keep them in sync.<p>
   * See {@link CashPositionDto#setSlip(CashPositionDto)
   * 
   * @param positions - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setPositions(final List<CashPositionDto> positions) {
    checkDisposed();
    for (CashPositionDto dto : internalGetPositions().toArray(new CashPositionDto[this.positions.size()])) {
    	removeFromPositions(dto);
    }
    
    if(positions == null) {
    	return;
    }
    
    for (CashPositionDto dto : positions) {
    	addToPositions(dto);
    }
  }
  
  /**
   * Returns the customer property or <code>null</code> if not present.
   */
  public McustomerDto getCustomer() {
    return this.customer;
  }
  
  /**
   * Sets the <code>customer</code> property to this instance.
   * Since the reference has an opposite reference, the opposite <code>McustomerDto#
   * slips</code> of the <code>customer</code> will be handled automatically and no 
   * further coding is required to keep them in sync.<p>
   * See {@link McustomerDto#setSlips(McustomerDto)
   * 
   * @param customer - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setCustomer(final McustomerDto customer) {
    checkDisposed();
    if (this.customer != null) {
    	this.customer.internalRemoveFromSlips(this);
    }
    
    internalSetCustomer(customer);
    
    if (this.customer != null) {
    	this.customer.internalAddToSlips(this);
    }
  }
  
  /**
   * For internal use only!
   */
  public void internalSetCustomer(final McustomerDto customer) {
    firePropertyChange("customer", this.customer, this.customer = customer);
  }
  
  /**
   * Returns the register property or <code>null</code> if not present.
   */
  public CashRegisterDto getRegister() {
    return this.register;
  }
  
  /**
   * Sets the <code>register</code> property to this instance.
   * Since the reference has an opposite reference, the opposite <code>CashRegisterDto#
   * slips</code> of the <code>register</code> will be handled automatically and no 
   * further coding is required to keep them in sync.<p>
   * See {@link CashRegisterDto#setSlips(CashRegisterDto)
   * 
   * @param register - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setRegister(final CashRegisterDto register) {
    checkDisposed();
    if (this.register != null) {
    	this.register.internalRemoveFromSlips(this);
    }
    
    internalSetRegister(register);
    
    if (this.register != null) {
    	this.register.internalAddToSlips(this);
    }
  }
  
  /**
   * For internal use only!
   */
  public void internalSetRegister(final CashRegisterDto register) {
    firePropertyChange("register", this.register, this.register = register);
  }
  
  /**
   * Returns an unmodifiable list of payments.
   */
  public List<CashPaymentDto> getPayments() {
    return Collections.unmodifiableList(internalGetPayments());
  }
  
  /**
   * Returns the list of <code>CashPaymentDto</code>s thereby lazy initializing it. For internal use only!
   * 
   * @return list - the resulting list
   * 
   */
  public List<CashPaymentDto> internalGetPayments() {
    if (this.payments == null) {
      this.payments = new java.util.ArrayList<CashPaymentDto>();
    }
    return this.payments;
  }
  
  /**
   * Adds the given cashPaymentDto to this object. <p>
   * Since the reference is a composition reference, the opposite reference <code>CashPaymentDto#slip</code> of the <code>cashPaymentDto</code> will be handled automatically and no further coding is required to keep them in sync.<p>
   * See {@link CashPaymentDto#setSlip(CashPaymentDto)}.
   * 
   * @param cashPaymentDto - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void addToPayments(final CashPaymentDto cashPaymentDto) {
    checkDisposed();
    
    cashPaymentDto.setSlip(this);
  }
  
  /**
   * Removes the given cashPaymentDto from this object. <p>
   * 
   * @param cashPaymentDto - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void removeFromPayments(final CashPaymentDto cashPaymentDto) {
    checkDisposed();
    
    cashPaymentDto.setSlip(null);
  }
  
  /**
   * For internal use only!
   */
  public void internalAddToPayments(final CashPaymentDto cashPaymentDto) {
    
    if(!internalGetPayments().contains(cashPaymentDto)) {
    	if(!org.eclipse.osbp.dsl.dto.lib.MappingContext.isMappingMode()) {
    		List<CashPaymentDto> oldList = null;
    		if(internalGetPayments() instanceof org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) {
    			oldList = ((org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) internalGetPayments()).copy();
    		} else {
    			oldList = new java.util.ArrayList<>(internalGetPayments());
    		}
    		internalGetPayments().add(cashPaymentDto);
    		firePropertyChange("payments", oldList, internalGetPayments());
    	} else {
    		// in mapping mode, we do NOT resolve any collection
    		internalGetPayments().add(cashPaymentDto);
    	}
    }
  }
  
  /**
   * For internal use only!
   */
  public void internalRemoveFromPayments(final CashPaymentDto cashPaymentDto) {
    if(!org.eclipse.osbp.dsl.dto.lib.MappingContext.isMappingMode()) {
    	List<CashPaymentDto> oldList = null;
    	if(internalGetPayments() instanceof org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) {
    		oldList = ((org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) internalGetPayments()).copy();
    	} else {
    		oldList = new java.util.ArrayList<>(internalGetPayments());
    	}
    	internalGetPayments().remove(cashPaymentDto);
    	firePropertyChange("payments", oldList, internalGetPayments());	
    }else{
    	// in mapping mode, we do NOT resolve any collection
    	internalGetPayments().remove(cashPaymentDto);
    }
  }
  
  /**
   * Sets the <code>payments</code> property to this instance.
   * Since the reference has an opposite reference, the opposite <code>CashPaymentDto#
   * slip</code> of the <code>payments</code> will be handled automatically and no 
   * further coding is required to keep them in sync.<p>
   * See {@link CashPaymentDto#setSlip(CashPaymentDto)
   * 
   * @param payments - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setPayments(final List<CashPaymentDto> payments) {
    checkDisposed();
    for (CashPaymentDto dto : internalGetPayments().toArray(new CashPaymentDto[this.payments.size()])) {
    	removeFromPayments(dto);
    }
    
    if(payments == null) {
    	return;
    }
    
    for (CashPaymentDto dto : payments) {
    	addToPayments(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);
    }
  }
}
