/**
 * Copyright (c) 2015 - 2016 - Loetz GmbH&Co.KG, 69115 Heidelberg, Germany
 * 
 *  All rights reserved. This program and the accompanying materials
 *  are made available under the terms of the Eclipse Public License v1.0
 *  which accompanies this distribution, and is available at
 *  http://www.eclipse.org/legal/epl-v10.html
 * 
 *  Contributors:
 * 	   Loetz GmbH&Co.KG - Initial implementation
 */
package org.eclipse.osbp.utils.functionnormalizer.dtos;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.Serializable;
import java.util.Collections;
import java.util.List;
import org.eclipse.osbp.dsl.common.datatypes.IDto;
import org.eclipse.osbp.dsl.dto.lib.MappingContext;
import org.eclipse.osbp.runtime.common.annotations.Dispose;
import org.eclipse.osbp.runtime.common.annotations.DomainReference;
import org.eclipse.osbp.utils.functionnormalizer.dtos.FunctionNormalizerDto;
import org.eclipse.osbp.utils.functionnormalizer.dtos.FunctionTypeDto;

@SuppressWarnings("all")
public class FunctionTypingDto implements IDto, Serializable, PropertyChangeListener {
  private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
  
  @Dispose
  private boolean disposed;
  
  @DomainReference
  private List<FunctionTypeDto> types;
  
  @DomainReference
  private List<FunctionNormalizerDto> normalizer;
  
  /**
   * @return true, if the object is disposed. 
   * Disposed means, that it is prepared for garbage collection and may not be used anymore. 
   * Accessing objects that are already disposed will cause runtime exceptions.
   * 
   */
  public boolean isDisposed() {
    return this.disposed;
  }
  
  /**
   * @see PropertyChangeSupport#addPropertyChangeListener(PropertyChangeListener)
   */
  public void addPropertyChangeListener(final PropertyChangeListener listener) {
    propertyChangeSupport.addPropertyChangeListener(listener);
  }
  
  /**
   * @see PropertyChangeSupport#addPropertyChangeListener(String, PropertyChangeListener)
   */
  public void addPropertyChangeListener(final String propertyName, final PropertyChangeListener listener) {
    propertyChangeSupport.addPropertyChangeListener(propertyName, listener);
  }
  
  /**
   * @see PropertyChangeSupport#removePropertyChangeListener(PropertyChangeListener)
   */
  public void removePropertyChangeListener(final PropertyChangeListener listener) {
    propertyChangeSupport.removePropertyChangeListener(listener);
  }
  
  /**
   * @see PropertyChangeSupport#removePropertyChangeListener(String, PropertyChangeListener)
   */
  public void removePropertyChangeListener(final String propertyName, final PropertyChangeListener listener) {
    propertyChangeSupport.removePropertyChangeListener(propertyName, listener);
  }
  
  /**
   * @see PropertyChangeSupport#firePropertyChange(String, Object, Object)
   */
  public void firePropertyChange(final String propertyName, final Object oldValue, final Object newValue) {
    propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
  }
  
  /**
   * 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;
    }
    firePropertyChange("disposed", this.disposed, this.disposed = true);
  }
  
  /**
   * Installs lazy collection resolving for entity {@link FunctionTyping} to the dto {@link FunctionTypingDto}.
   * 
   */
  protected void installLazyCollections() {
    
  }
  
  /**
   * Returns an unmodifiable list of types.
   */
  public List<FunctionTypeDto> getTypes() {
    return Collections.unmodifiableList(internalGetTypes());
  }
  
  /**
   * Returns the list of <code>FunctionTypeDto</code>s thereby lazy initializing it. For internal use only!
   * 
   * @return list - the resulting list
   * 
   */
  private List<FunctionTypeDto> internalGetTypes() {
    if (this.types == null) {
      this.types = new java.util.ArrayList<FunctionTypeDto>();
    }
    return this.types;
  }
  
  /**
   * Adds the given functionTypeDto to this object. <p>
   * 
   * @param functionTypeDto - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void addToTypes(final FunctionTypeDto functionTypeDto) {
    checkDisposed();
    
    if(!internalGetTypes().contains(functionTypeDto)){
    	internalAddToTypes(functionTypeDto);
    }
  }
  
  public void removeFromTypes(final FunctionTypeDto functionTypeDto) {
    checkDisposed();
    
    internalRemoveFromTypes(functionTypeDto);
  }
  
  /**
   * For internal use only!
   */
  public void internalAddToTypes(final FunctionTypeDto functionTypeDto) {
    // add this as property change listener for embeddable beans
    functionTypeDto.addPropertyChangeListener(this);
    internalGetTypes().add(functionTypeDto);
  }
  
  /**
   * For internal use only!
   */
  public void internalRemoveFromTypes(final FunctionTypeDto functionTypeDto) {
    // remove this as property change listener from the embeddable bean
    functionTypeDto.removePropertyChangeListener(this);
    internalGetTypes().remove(functionTypeDto);
  }
  
  /**
   * Sets the <code>types</code> property to this instance.
   * 
   * @param types - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setTypes(final List<FunctionTypeDto> types) {
    checkDisposed();
    for (FunctionTypeDto dto : internalGetTypes().toArray(new FunctionTypeDto[this.types.size()])) {
    	removeFromTypes(dto);
    }
    
    if(types == null) {
    	return;
    }
    
    for (FunctionTypeDto dto : types) {
    	addToTypes(dto);
    }
  }
  
  /**
   * Returns an unmodifiable list of normalizer.
   */
  public List<FunctionNormalizerDto> getNormalizer() {
    return Collections.unmodifiableList(internalGetNormalizer());
  }
  
  /**
   * Returns the list of <code>FunctionNormalizerDto</code>s thereby lazy initializing it. For internal use only!
   * 
   * @return list - the resulting list
   * 
   */
  private List<FunctionNormalizerDto> internalGetNormalizer() {
    if (this.normalizer == null) {
      this.normalizer = new java.util.ArrayList<FunctionNormalizerDto>();
    }
    return this.normalizer;
  }
  
  /**
   * Adds the given functionNormalizerDto to this object. <p>
   * 
   * @param functionNormalizerDto - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void addToNormalizer(final FunctionNormalizerDto functionNormalizerDto) {
    checkDisposed();
    
    if(!internalGetNormalizer().contains(functionNormalizerDto)){
    	internalAddToNormalizer(functionNormalizerDto);
    }
  }
  
  public void removeFromNormalizer(final FunctionNormalizerDto functionNormalizerDto) {
    checkDisposed();
    
    internalRemoveFromNormalizer(functionNormalizerDto);
  }
  
  /**
   * For internal use only!
   */
  public void internalAddToNormalizer(final FunctionNormalizerDto functionNormalizerDto) {
    // add this as property change listener for embeddable beans
    functionNormalizerDto.addPropertyChangeListener(this);
    internalGetNormalizer().add(functionNormalizerDto);
  }
  
  /**
   * For internal use only!
   */
  public void internalRemoveFromNormalizer(final FunctionNormalizerDto functionNormalizerDto) {
    // remove this as property change listener from the embeddable bean
    functionNormalizerDto.removePropertyChangeListener(this);
    internalGetNormalizer().remove(functionNormalizerDto);
  }
  
  /**
   * Sets the <code>normalizer</code> property to this instance.
   * 
   * @param normalizer - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setNormalizer(final List<FunctionNormalizerDto> normalizer) {
    checkDisposed();
    for (FunctionNormalizerDto dto : internalGetNormalizer().toArray(new FunctionNormalizerDto[this.normalizer.size()])) {
    	removeFromNormalizer(dto);
    }
    
    if(normalizer == null) {
    	return;
    }
    
    for (FunctionNormalizerDto dto : normalizer) {
    	addToNormalizer(dto);
    }
  }
  
  public FunctionTypingDto createDto() {
    return new FunctionTypingDto();
  }
  
  public FunctionTypingDto copy(final MappingContext context) {
    checkDisposed();
    
    if (context == null) {
    	throw new IllegalArgumentException("Context must not be null!");
    }
    
    if(context.isMaxLevel()){
    	return null;
    }
    
    // if context contains a copied instance of this object
    // then return it
    FunctionTypingDto newDto = context.get(this);
    if(newDto != null){
    	return newDto;
    }
    
    try{
    	context.increaseLevel();
    	
    	newDto = createDto();
    	context.register(this, newDto);
    	
    	// first copy the containments and attributes
    	copyContainments(this, newDto, context);
    	
    	// then copy cross references to ensure proper
    	// opposite references are copied too.
    	copyCrossReferences(this, newDto, context);
    } finally {
    	context.decreaseLevel();
    }
    
    return newDto;
  }
  
  public void copyContainments(final FunctionTypingDto dto, final FunctionTypingDto newDto, final MappingContext context) {
    checkDisposed();
    
    if (context == null) {
    	throw new IllegalArgumentException("Context must not be null!");
    }
    
    
    // copy attributes and beans (beans if derived from entity model)
    
    // copy containment references (cascading is true)
  }
  
  public void copyCrossReferences(final FunctionTypingDto dto, final FunctionTypingDto newDto, final org.eclipse.osbp.dsl.dto.lib.MappingContext context) {
    checkDisposed();
    
    if (context == null) {
    	throw new IllegalArgumentException("Context must not be null!");
    }
    
    
    // copy cross references (cascading is false)
    // copy list of types dtos
    for(org.eclipse.osbp.utils.functionnormalizer.dtos.FunctionTypeDto _dto : getTypes()) {
    	newDto.addToTypes(_dto.copy(context));
    }
    // copy list of normalizer dtos
    for(org.eclipse.osbp.utils.functionnormalizer.dtos.FunctionNormalizerDto _dto : getNormalizer()) {
    	newDto.addToNormalizer(_dto.copy(context));
    }
  }
  
  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
    if(source == types){
    	firePropertyChange("types" + "_" + event.getPropertyName(), event.getOldValue(), event.getNewValue());
    } else 
    if(source == normalizer){
    	firePropertyChange("normalizer" + "_" + event.getPropertyName(), event.getOldValue(), event.getNewValue());
    } else 
    { 
    	// no super class available to forward event
    }
  }
}
