package org.eclipse.osbp.authentication.account.dtos;

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import java.io.Serializable;
import java.util.Collections;
import java.util.List;
import javax.validation.Valid;
import javax.validation.constraints.Pattern;
import org.eclipse.osbp.authentication.account.dtos.UserAccountFilterDto;
import org.eclipse.osbp.dsl.common.datatypes.IDto;
import org.eclipse.osbp.runtime.common.annotations.Dirty;
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.Hidden;
import org.eclipse.osbp.runtime.common.annotations.Id;
import org.eclipse.osbp.runtime.common.annotations.Properties;
import org.eclipse.osbp.runtime.common.annotations.Property;
import org.eclipse.osbp.runtime.common.annotations.UniqueEntry;
import org.eclipse.osbp.runtime.common.validation.InfoSeverity;

@SuppressWarnings("all")
public class UserAccountDto implements IDto, Serializable, PropertyChangeListener {
  private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
  
  @Dispose
  private boolean disposed;
  
  @Dirty
  private transient boolean dirty;
  
  @Id
  private String id = java.util.UUID.randomUUID().toString();
  
  @UniqueEntry
  private String email;
  
  @UniqueEntry
  private String userName;
  
  @Hidden
  private String password;
  
  @Pattern(regexp = "[0-9]*", payload = InfoSeverity.class)
  private String extraPassword;
  
  private boolean passwordReset;
  
  @Properties(properties = @Property(key = "organization", value = ""))
  private String position;
  
  @Properties(properties = @Property(key = "perspective", value = ""))
  private String defaultPerspective;
  
  private boolean enabled;
  
  private boolean locked;
  
  private boolean superuser;
  
  private boolean forcePwdChange;
  
  private boolean notRegistered;
  
  private int failedAttempt;
  
  private int successfulAttempt;
  
  @Hidden
  private int cookieHashCode;
  
  @Properties(properties = @Property(key = "i18n", value = ""))
  private String localeTag;
  
  @Properties(properties = @Property(key = "Blob", value = "2"))
  private String profileimage;
  
  private String layoutingStrategy;
  
  private String focusingStrategy;
  
  @Properties(properties = @Property(key = "theme", value = ""))
  private String theme;
  
  @Properties(properties = @Property(key = "printservice", value = ""))
  private String printService;
  
  @Hidden
  @Valid
  private byte[] savedProperties;
  
  @DomainReference
  @FilterDepth(depth = 0)
  private List<UserAccountFilterDto> userAccountFilter;
  
  public UserAccountDto() {
    installLazyCollections();
  }
  
  /**
   * Installs lazy collection resolving for entity {@link UserAccount} to the dto {@link UserAccountDto}.
   * 
   */
  protected void installLazyCollections() {
    userAccountFilter = new org.eclipse.osbp.dsl.dto.lib.OppositeDtoList<>(
    				org.eclipse.osbp.dsl.dto.lib.MappingContext.getCurrent(),
    				UserAccountFilterDto.class, "userAccount.id",
    				(java.util.function.Supplier<Object> & Serializable) () -> this.getId(), this);
  }
  
  /**
   * @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);
  }
  
  /**
   * @return true, if the object is dirty. 
   * 
   */
  public boolean isDirty() {
    return dirty;
  }
  
  /**
   * Sets the dirty state of this object.
   * 
   */
  public void setDirty(final boolean dirty) {
    firePropertyChange("dirty", this.dirty, this.dirty = dirty );
  }
  
  /**
   * 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);
  }
  
  /**
   * Returns the id property or <code>null</code> if not present.
   */
  public String getId() {
    return this.id;
  }
  
  /**
   * Sets the <code>id</code> property to this instance.
   * 
   * @param id - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setId(final String id) {
    firePropertyChange("id", this.id, this.id = id );
    				installLazyCollections();
  }
  
  /**
   * Returns the <em>required</em> email property.
   */
  public String getEmail() {
    return this.email;
  }
  
  /**
   * Sets the <code>email</code> property to this instance.
   * 
   * @param email - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setEmail(final String email) {
    firePropertyChange("email", this.email, this.email = email );
  }
  
  /**
   * Returns the <em>required</em> userName property.
   */
  public String getUserName() {
    return this.userName;
  }
  
  /**
   * Sets the <code>userName</code> property to this instance.
   * 
   * @param userName - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setUserName(final String userName) {
    firePropertyChange("userName", this.userName, this.userName = userName );
  }
  
  /**
   * Returns the password property or <code>null</code> if not present.
   */
  public String getPassword() {
    return this.password;
  }
  
  /**
   * Sets the <code>password</code> property to this instance.
   * 
   * @param password - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setPassword(final String password) {
    firePropertyChange("password", this.password, this.password = password );
  }
  
  /**
   * Returns the extraPassword property or <code>null</code> if not present.
   */
  public String getExtraPassword() {
    return this.extraPassword;
  }
  
  /**
   * Sets the <code>extraPassword</code> property to this instance.
   * 
   * @param extraPassword - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setExtraPassword(final String extraPassword) {
    firePropertyChange("extraPassword", this.extraPassword, this.extraPassword = extraPassword );
  }
  
  /**
   * Returns the passwordReset property or <code>null</code> if not present.
   */
  public boolean getPasswordReset() {
    return this.passwordReset;
  }
  
  /**
   * Sets the <code>passwordReset</code> property to this instance.
   * 
   * @param passwordReset - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setPasswordReset(final boolean passwordReset) {
    firePropertyChange("passwordReset", this.passwordReset, this.passwordReset = passwordReset );
  }
  
  /**
   * Returns the position property or <code>null</code> if not present.
   */
  public String getPosition() {
    return this.position;
  }
  
  /**
   * Sets the <code>position</code> property to this instance.
   * 
   * @param position - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setPosition(final String position) {
    firePropertyChange("position", this.position, this.position = position );
  }
  
  /**
   * Returns the defaultPerspective property or <code>null</code> if not present.
   */
  public String getDefaultPerspective() {
    return this.defaultPerspective;
  }
  
  /**
   * Sets the <code>defaultPerspective</code> property to this instance.
   * 
   * @param defaultPerspective - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setDefaultPerspective(final String defaultPerspective) {
    firePropertyChange("defaultPerspective", this.defaultPerspective, this.defaultPerspective = defaultPerspective );
  }
  
  /**
   * Returns the enabled property or <code>null</code> if not present.
   */
  public boolean getEnabled() {
    return this.enabled;
  }
  
  /**
   * Sets the <code>enabled</code> property to this instance.
   * 
   * @param enabled - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setEnabled(final boolean enabled) {
    firePropertyChange("enabled", this.enabled, this.enabled = enabled );
  }
  
  /**
   * Returns the locked property or <code>null</code> if not present.
   */
  public boolean getLocked() {
    return this.locked;
  }
  
  /**
   * Sets the <code>locked</code> property to this instance.
   * 
   * @param locked - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setLocked(final boolean locked) {
    firePropertyChange("locked", this.locked, this.locked = locked );
  }
  
  /**
   * Returns the superuser property or <code>null</code> if not present.
   */
  public boolean getSuperuser() {
    return this.superuser;
  }
  
  /**
   * Sets the <code>superuser</code> property to this instance.
   * 
   * @param superuser - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setSuperuser(final boolean superuser) {
    firePropertyChange("superuser", this.superuser, this.superuser = superuser );
  }
  
  /**
   * Returns the forcePwdChange property or <code>null</code> if not present.
   */
  public boolean getForcePwdChange() {
    return this.forcePwdChange;
  }
  
  /**
   * Sets the <code>forcePwdChange</code> property to this instance.
   * 
   * @param forcePwdChange - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setForcePwdChange(final boolean forcePwdChange) {
    firePropertyChange("forcePwdChange", this.forcePwdChange, this.forcePwdChange = forcePwdChange );
  }
  
  /**
   * Returns the notRegistered property or <code>null</code> if not present.
   */
  public boolean getNotRegistered() {
    return this.notRegistered;
  }
  
  /**
   * Sets the <code>notRegistered</code> property to this instance.
   * 
   * @param notRegistered - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setNotRegistered(final boolean notRegistered) {
    firePropertyChange("notRegistered", this.notRegistered, this.notRegistered = notRegistered );
  }
  
  /**
   * Returns the failedAttempt property or <code>null</code> if not present.
   */
  public int getFailedAttempt() {
    return this.failedAttempt;
  }
  
  /**
   * Sets the <code>failedAttempt</code> property to this instance.
   * 
   * @param failedAttempt - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setFailedAttempt(final int failedAttempt) {
    firePropertyChange("failedAttempt", this.failedAttempt, this.failedAttempt = failedAttempt );
  }
  
  /**
   * Returns the successfulAttempt property or <code>null</code> if not present.
   */
  public int getSuccessfulAttempt() {
    return this.successfulAttempt;
  }
  
  /**
   * Sets the <code>successfulAttempt</code> property to this instance.
   * 
   * @param successfulAttempt - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setSuccessfulAttempt(final int successfulAttempt) {
    firePropertyChange("successfulAttempt", this.successfulAttempt, this.successfulAttempt = successfulAttempt );
  }
  
  /**
   * Returns the cookieHashCode property or <code>null</code> if not present.
   */
  public int getCookieHashCode() {
    return this.cookieHashCode;
  }
  
  /**
   * Sets the <code>cookieHashCode</code> property to this instance.
   * 
   * @param cookieHashCode - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setCookieHashCode(final int cookieHashCode) {
    firePropertyChange("cookieHashCode", this.cookieHashCode, this.cookieHashCode = cookieHashCode );
  }
  
  /**
   * Returns the localeTag property or <code>null</code> if not present.
   */
  public String getLocaleTag() {
    return this.localeTag;
  }
  
  /**
   * Sets the <code>localeTag</code> property to this instance.
   * 
   * @param localeTag - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setLocaleTag(final String localeTag) {
    firePropertyChange("localeTag", this.localeTag, this.localeTag = localeTag );
  }
  
  /**
   * Returns the profileimage property or <code>null</code> if not present.
   */
  public String getProfileimage() {
    return this.profileimage;
  }
  
  /**
   * Sets the <code>profileimage</code> property to this instance.
   * 
   * @param profileimage - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setProfileimage(final String profileimage) {
    firePropertyChange("profileimage", this.profileimage, this.profileimage = profileimage );
  }
  
  /**
   * Returns the layoutingStrategy property or <code>null</code> if not present.
   */
  public String getLayoutingStrategy() {
    return this.layoutingStrategy;
  }
  
  /**
   * Sets the <code>layoutingStrategy</code> property to this instance.
   * 
   * @param layoutingStrategy - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setLayoutingStrategy(final String layoutingStrategy) {
    firePropertyChange("layoutingStrategy", this.layoutingStrategy, this.layoutingStrategy = layoutingStrategy );
  }
  
  /**
   * Returns the focusingStrategy property or <code>null</code> if not present.
   */
  public String getFocusingStrategy() {
    return this.focusingStrategy;
  }
  
  /**
   * Sets the <code>focusingStrategy</code> property to this instance.
   * 
   * @param focusingStrategy - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setFocusingStrategy(final String focusingStrategy) {
    firePropertyChange("focusingStrategy", this.focusingStrategy, this.focusingStrategy = focusingStrategy );
  }
  
  /**
   * Returns the theme property or <code>null</code> if not present.
   */
  public String getTheme() {
    return this.theme;
  }
  
  /**
   * Sets the <code>theme</code> property to this instance.
   * 
   * @param theme - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setTheme(final String theme) {
    firePropertyChange("theme", this.theme, this.theme = theme );
  }
  
  /**
   * Returns the printService property or <code>null</code> if not present.
   */
  public String getPrintService() {
    return this.printService;
  }
  
  /**
   * Sets the <code>printService</code> property to this instance.
   * 
   * @param printService - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setPrintService(final String printService) {
    firePropertyChange("printService", this.printService, this.printService = printService );
  }
  
  /**
   * Returns the savedProperties property or <code>null</code> if not present.
   */
  public byte[] getSavedProperties() {
    return this.savedProperties;
  }
  
  /**
   * Sets the <code>savedProperties</code> property to this instance.
   * 
   * @param savedProperties - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setSavedProperties(final byte[] savedProperties) {
    firePropertyChange("savedProperties", this.savedProperties, this.savedProperties = savedProperties );
  }
  
  /**
   * Returns an unmodifiable list of userAccountFilter.
   */
  public List<UserAccountFilterDto> getUserAccountFilter() {
    return Collections.unmodifiableList(internalGetUserAccountFilter());
  }
  
  /**
   * Returns the list of <code>UserAccountFilterDto</code>s thereby lazy initializing it. For internal use only!
   * 
   * @return list - the resulting list
   * 
   */
  public List<UserAccountFilterDto> internalGetUserAccountFilter() {
    if (this.userAccountFilter == null) {
      this.userAccountFilter = new java.util.ArrayList<UserAccountFilterDto>();
    }
    return this.userAccountFilter;
  }
  
  /**
   * Adds the given userAccountFilterDto to this object. <p>
   * Since the reference is a composition reference, the opposite reference <code>UserAccountFilterDto#userAccount</code> of the <code>userAccountFilterDto</code> will be handled automatically and no further coding is required to keep them in sync.<p>
   * See {@link UserAccountFilterDto#setUserAccount(UserAccountFilterDto)}.
   * 
   * @param userAccountFilterDto - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void addToUserAccountFilter(final UserAccountFilterDto userAccountFilterDto) {
    checkDisposed();
    
    userAccountFilterDto.setUserAccount(this);
  }
  
  /**
   * Removes the given userAccountFilterDto from this object. <p>
   * 
   * @param userAccountFilterDto - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void removeFromUserAccountFilter(final UserAccountFilterDto userAccountFilterDto) {
    checkDisposed();
    
    userAccountFilterDto.setUserAccount(null);
  }
  
  /**
   * For internal use only!
   */
  public void internalAddToUserAccountFilter(final UserAccountFilterDto userAccountFilterDto) {
    
    if(!org.eclipse.osbp.dsl.dto.lib.MappingContext.isMappingMode()) {
    		List<UserAccountFilterDto> oldList = null;
    		if(internalGetUserAccountFilter() instanceof org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) {
    			oldList = ((org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) internalGetUserAccountFilter()).copy();
    		} else {
    			oldList = new java.util.ArrayList<>(internalGetUserAccountFilter());
    		}
    		internalGetUserAccountFilter().add(userAccountFilterDto);
    		firePropertyChange("userAccountFilter", oldList, internalGetUserAccountFilter());
    }
  }
  
  /**
   * For internal use only!
   */
  public void internalRemoveFromUserAccountFilter(final UserAccountFilterDto userAccountFilterDto) {
    if(!org.eclipse.osbp.dsl.dto.lib.MappingContext.isMappingMode()) {
    	List<UserAccountFilterDto> oldList = null;
    	if(internalGetUserAccountFilter() instanceof org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) {
    		oldList = ((org.eclipse.osbp.dsl.dto.lib.AbstractOppositeDtoList) internalGetUserAccountFilter()).copy();
    	} else {
    		oldList = new java.util.ArrayList<>(internalGetUserAccountFilter());
    	}
    	internalGetUserAccountFilter().remove(userAccountFilterDto);
    	firePropertyChange("userAccountFilter", oldList, internalGetUserAccountFilter());	
    }else{
    	// in mapping mode, we do NOT resolve any collection
    	internalGetUserAccountFilter().remove(userAccountFilterDto);
    }
  }
  
  /**
   * Sets the <code>userAccountFilter</code> property to this instance.
   * Since the reference has an opposite reference, the opposite <code>UserAccountFilterDto#
   * userAccount</code> of the <code>userAccountFilter</code> will be handled automatically and no 
   * further coding is required to keep them in sync.<p>
   * See {@link UserAccountFilterDto#setUserAccount(UserAccountFilterDto)
   * 
   * @param userAccountFilter - the property
   * @throws RuntimeException if instance is <code>disposed</code>
   * 
   */
  public void setUserAccountFilter(final List<UserAccountFilterDto> userAccountFilter) {
    checkDisposed();
    for (UserAccountFilterDto dto : internalGetUserAccountFilter().toArray(new UserAccountFilterDto[this.userAccountFilter.size()])) {
    	removeFromUserAccountFilter(dto);
    }
    
    if(userAccountFilter == null) {
    	return;
    }
    
    for (UserAccountFilterDto dto : userAccountFilter) {
    	addToUserAccountFilter(dto);
    }
  }
  
  public boolean equalVersions(final Object obj) {
    if (this == obj)
      return true;
    if (obj == null)
      return false;
    if (getClass() != obj.getClass())
      return false;
    UserAccountDto other = (UserAccountDto) obj;
    if (this.id == null) {
      if (other.id != null)
        return false;
    } else if (!this.id.equals(other.id))
      return false;
    return true;
  }
  
  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
    { 
    	// no super class available to forward event
    }
  }
}
