package org.osbp.mysmartshop.dtos;

import java.beans.PropertyChangeListener;
import java.io.Serializable;
import java.util.Collections;
import java.util.List;
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.eclipse.osbp.runtime.common.annotations.FilterDepth;
import org.osbp.mysmartshop.dtos.BaseUUIDDto;
import org.osbp.mysmartshop.dtos.CashSlipDto;

@SuppressWarnings("all")
public class CashRegisterDto extends BaseUUIDDto implements IDto, Serializable, PropertyChangeListener {
  @DomainKey
  private String num;
  
  private String ip;
  
  private String location;
  
  private String currentDay;
  
  @DomainReference
  @FilterDepth(depth = 0)
  private List<CashSlipDto> slips;
  
  public CashRegisterDto() {
    installLazyCollections();
  }
  
  /**
   * Installs lazy collection resolving for entity {@link CashRegister} to the dto {@link CashRegisterDto}.
   * 
   */
  protected void installLazyCollections() {
    super.installLazyCollections();
    slips = new org.eclipse.osbp.dsl.dto.lib.OppositeDtoList<>(
    				org.eclipse.osbp.dsl.dto.lib.MappingContext.getCurrent(),
    				CashSlipDto.class, "register.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;
    }
    super.dispose();
  }
  
  /**
   * Returns the num property or <code>null</code> if not present.
   */
  public String getNum() {
    return this.num;
  }
  
  /**
   * Sets the <code>num</code> property to this instance.
   * 
   * @param num - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setNum(final String num) {
    firePropertyChange("num", this.num, this.num = num );
  }
  
  /**
   * Returns the ip property or <code>null</code> if not present.
   */
  public String getIp() {
    return this.ip;
  }
  
  /**
   * Sets the <code>ip</code> property to this instance.
   * 
   * @param ip - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setIp(final String ip) {
    firePropertyChange("ip", this.ip, this.ip = ip );
  }
  
  /**
   * Returns the location property or <code>null</code> if not present.
   */
  public String getLocation() {
    return this.location;
  }
  
  /**
   * Sets the <code>location</code> property to this instance.
   * 
   * @param location - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setLocation(final String location) {
    firePropertyChange("location", this.location, this.location = location );
  }
  
  /**
   * 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 an unmodifiable list of slips.
   */
  public List<CashSlipDto> getSlips() {
    return Collections.unmodifiableList(internalGetSlips());
  }
  
  /**
   * Returns the list of <code>CashSlipDto</code>s thereby lazy initializing it. For internal use only!
   * 
   * @return list - the resulting list
   * 
   */
  public List<CashSlipDto> internalGetSlips() {
    if (this.slips == null) {
      this.slips = new java.util.ArrayList<CashSlipDto>();
    }
    return this.slips;
  }
  
  /**
   * Adds the given cashSlipDto to this object. <p>
   * Since the reference is a composition reference, the opposite reference <code>CashSlipDto#register</code> of the <code>cashSlipDto</code> will be handled automatically and no further coding is required to keep them in sync.<p>
   * See {@link CashSlipDto#setRegister(CashSlipDto)}.
   * 
   * @param cashSlipDto - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void addToSlips(final CashSlipDto cashSlipDto) {
    checkDisposed();
    
    cashSlipDto.setRegister(this);
  }
  
  /**
   * Removes the given cashSlipDto from this object. <p>
   * 
   * @param cashSlipDto - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void removeFromSlips(final CashSlipDto cashSlipDto) {
    checkDisposed();
    
    cashSlipDto.setRegister(null);
  }
  
  /**
   * For internal use only!
   */
  public void internalAddToSlips(final CashSlipDto cashSlipDto) {
    
    if(!internalGetSlips().contains(cashSlipDto)) {
    	if(!org.eclipse.osbp.dsl.dto.lib.MappingContext.isMappingMode()) {
    		List<CashSlipDto> oldList = null;
    		if(internalGetSlips() instanceof org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) {
    			oldList = ((org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) internalGetSlips()).copy();
    		} else {
    			oldList = new java.util.ArrayList<>(internalGetSlips());
    		}
    		internalGetSlips().add(cashSlipDto);
    		firePropertyChange("slips", oldList, internalGetSlips());
    	} else {
    		// in mapping mode, we do NOT resolve any collection
    		internalGetSlips().add(cashSlipDto);
    	}
    }
  }
  
  /**
   * For internal use only!
   */
  public void internalRemoveFromSlips(final CashSlipDto cashSlipDto) {
    if(!org.eclipse.osbp.dsl.dto.lib.MappingContext.isMappingMode()) {
    	List<CashSlipDto> oldList = null;
    	if(internalGetSlips() instanceof org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) {
    		oldList = ((org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) internalGetSlips()).copy();
    	} else {
    		oldList = new java.util.ArrayList<>(internalGetSlips());
    	}
    	internalGetSlips().remove(cashSlipDto);
    	firePropertyChange("slips", oldList, internalGetSlips());	
    }else{
    	// in mapping mode, we do NOT resolve any collection
    	internalGetSlips().remove(cashSlipDto);
    }
  }
  
  /**
   * Sets the <code>slips</code> property to this instance.
   * Since the reference has an opposite reference, the opposite <code>CashSlipDto#
   * register</code> of the <code>slips</code> will be handled automatically and no 
   * further coding is required to keep them in sync.<p>
   * See {@link CashSlipDto#setRegister(CashSlipDto)
   * 
   * @param slips - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setSlips(final List<CashSlipDto> slips) {
    checkDisposed();
    for (CashSlipDto dto : internalGetSlips().toArray(new CashSlipDto[this.slips.size()])) {
    	removeFromSlips(dto);
    }
    
    if(slips == null) {
    	return;
    }
    
    for (CashSlipDto dto : slips) {
    	addToSlips(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);
    }
  }
}
