/*
 * Copyright (c) 1998, 2021 Oracle and/or its affiliates. All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v. 2.0 which is available at
 * http://www.eclipse.org/legal/epl-2.0,
 * or the Eclipse Distribution License v. 1.0 which is available at
 * http://www.eclipse.org/org/documents/edl-v10.php.
 *
 * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
 */

// Contributors:
//     07/16/2009 Andrei Ilitchev
//       - Bug 282553: JPA 2.0 JoinTable support for OneToOne and ManyToOne
package org.eclipse.persistence.testing.models.onetoonejointable;

import java.util.*;
import java.io.*;
import java.math.BigDecimal;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import org.eclipse.persistence.indirection.*;
import org.eclipse.persistence.descriptors.changetracking.*;

/**
 * <p><b>Purpose</b>: Represent a employee of an organization.
 * <p><b>Description</b>: An Employee is a root object in the Employee Demo.
 * It maintains relationships to all of the other objects in the system.
 * The employee shows usage of 1-1, 1-m, m-m, aggregate and transformation mappings.
 * The employee also shows usage of value holder to implement indirection for its relationships
 * (note, it is strongly suggested to always use value holders for relationships).
 */
public class Employee implements Serializable, ChangeTracker {
    // implements ChangeTracker for testing

    /** Primary key, mapped as a direct-to-field, BigDecimal -> NUMBER, that makes use of sequence numbers to generate the id. */
    public BigDecimal id;

    /** Direct-to-field mapping, String -> VARCHAR. */
    public String firstName;

    /** Direct-to-field mapping, String -> VARCHAR. */
    public String lastName;

    /** Object-type mapping, maps "Male" -> "M", "Female" -> "F". */
    public String gender;

    /** One-to-one mapping, employee references its address through a foreign key. */
    public ValueHolderInterface address;

    /** One-to-one mapping (same class relationship), employee references its manager through a foreign key. */
    public ValueHolderInterface manager;

    public List<Employee> managedEmployees;

    /** Many-to-many mapping, employee references its projects through an intermediate join table. */
    public List<Project> projects;

    /** Direct-collection mapping, employee stores its collection of plain Strings in an intermediate table. */
    public List<String> responsibilitiesList;

    /** Direct-to-field mapping, int -> NUMBER, salary of the employee in dollars. */
    public int salary;

    /** One-to-many mapping, employee references its collection of children arranged by age.
     * This relationship uses transparent indirection */
    public List<Child> children;

    /** One-to-one mapping , inverse relationship to Project.teamLeader */
    public ValueHolderInterface projectLed;

    /** For performance testing, how many times primary key extracted. */
    public static int getIdCallCount = 0;
    public PropertyChangeListener listener;

    @Override
    public PropertyChangeListener _persistence_getPropertyChangeListener() {
        return listener;
    }

    @Override
    public void _persistence_setPropertyChangeListener(PropertyChangeListener listener) {
        this.listener = listener;
    }

    public void propertyChange(String propertyName, Object oldValue, Object newValue) {
        if (listener != null) {
            if (oldValue != newValue) {
                listener.propertyChange(new PropertyChangeEvent(this, propertyName, oldValue, newValue));
            }
        }
    }

    public void collectionChange(String propertyName, Object oldValue, Object newValue, int changeType, boolean isChangeApplied) {
        if (listener != null) {
            listener.propertyChange(new CollectionChangeEvent(this, propertyName, oldValue, newValue, changeType, isChangeApplied));
        }
    }

    /**
     * For fields that make use of indirection the constructor should build the value holders.
     */
    public Employee() {
        this.firstName = "";
        this.lastName = "";
        this.address = new ValueHolder();
        this.manager = new ValueHolder();
        this.managedEmployees = new ArrayList();
        this.projects = new ArrayList();
        this.responsibilitiesList = new ArrayList();
        this.children = new ArrayList();
        this.projectLed = new ValueHolder();
    }

    /**
     * For bi-directional relationships, it is important to maintain both sides of the relationship when changing it.
     */
    public void addManagedEmployee(Employee employee) {
        getManagedEmployees().add(employee);
        employee.setManager(this);
    }

    public void addManagedEmployee(int index, Employee employee) {
        getManagedEmployees().add(index, employee);
        employee.setManager(this);
    }

    public Employee setManagedEmployee(int index, Employee employee) {
        Employee removedEmp = getManagedEmployees().set(index, employee);
        removedEmp.setManager(null);
        employee.setManager(this);
        return removedEmp;
    }

    public void addChild(Child child) {
        getChildren().add(child);
        child.setParent(this);
    }

    public void addProject(Project project) {
        getProjects().add(project);
        project.getEmployees().add(this);
    }

    public void addResponsibility(String responsibility) {
        getResponsibilitiesList().add(responsibility);
    }

    public Address getAddress() {
        return (Address)address.getValue();
    }

    public String getFirstName() {
        return firstName;
    }

    public String getGender() {
        return gender;
    }

    /**
     * Used for performance testing.
     */
    public static int getGetIdCallCount() {
        return getIdCallCount;
    }

    /**
     * Return the persistent identifier of the receiver.
     */
    public BigDecimal getId() {
        getIdCallCount++;
        return id;
    }

    public List<Child> getChildren(){
        return children;
    }

    public String getLastName() {
        return lastName;
    }

    public List<Employee> getManagedEmployees() {
        return managedEmployees;
    }

    public Employee getManager() {
        return (Employee)manager.getValue();
    }

    public Project getProjectLed() {
        return (Project)projectLed.getValue();
    }

    public List<Project> getProjects() {
        return projects;
    }

    public List<String> getResponsibilitiesList() {
        return responsibilitiesList;
    }

    public int getSalary() {
        return salary;
    }

    public void removeManagedEmployee(Employee employee) {
        getManagedEmployees().remove(employee);
        employee.setManager(null);
    }

    public void removeProject(Project project) {
        getProjects().remove(project);
        project.getEmployees().remove(this);
    }

    public void removeResponsibility(String responsibility) {
        getResponsibilitiesList().remove(responsibility);
    }

    public void setAddress(Address address) {
        propertyChange("address", this.address.getValue(), address);
        this.address.setValue(address);
    }

    public void setChildren(Vector children){
        this.children = children;
    }

    public void setFemale() {
        propertyChange("gender", this.gender, "Female");
        setGender("Female");
    }

    public void setFirstName(String firstName) {
        propertyChange("firstName", getFirstName(), firstName);
        this.firstName = firstName;
    }

    public void setGender(String gender) {
        propertyChange("gender", this.gender, gender);
        this.gender = gender;
    }

    /**
     * For performance testing.
     */
    public static void setGetIdCallCount(int value) {
        Employee.getIdCallCount = value;
    }

    /**
     * Set the persistent identifier of the receiver.
     * Note this should never be changed.
     * Consider making the primary key set methods protected or not having them.
     * In this demo the setId is required for testing purposes.
     */
    public void setId(BigDecimal id) {
        propertyChange("id", this.id, id);
        this.id = id;
    }

    public void setLastName(String lastName) {
        propertyChange("lastName", this.lastName, lastName);
        this.lastName = lastName;
    }

    public void setMale() {
        propertyChange("gender", this.gender, "Male");
        setGender("Male");
    }

    /**
     * Notice that the usage of value holders does not effect the public interface or usage of the class.
     * The get/set methods must however be changed to wrap/unwrap the value holder.
     */
    public void setManagedEmployees(List<Employee> managedEmployees) {
        propertyChange("managedEmployees", this.managedEmployees, managedEmployees);
        this.managedEmployees = managedEmployees;
    }

    /**
     * For bi-directional relationships, it is important to maintain both sides of the relationship when changing it.
     * Notice that the usage of value holders does not effect the public interface or usage of the class.
     * The get/set methods must however be changed to wrap/unwrap the value holder.
     */
    public void setManager(Employee manager) {
        propertyChange("manager", this.manager.getValue(), manager);
        this.manager.setValue(manager);
    }

    public void setProjectLed(Project projectLed) {
        propertyChange("projectLed", this.projectLed.getValue(), projectLed);
        this.projectLed.setValue(projectLed);
    }

    public void setProjects(List<Project> projects) {
        propertyChange("projects", this.projects, projects);
        this.projects = projects;
    }

    /**
     * Notice that the usage of value holders does not effect the public interface or usage of the class.
     * The get/set methods must however be changed to wrap/unwrap the value holder.
     */
    public void setResponsibilitiesList(Vector responsibilitiesList) {
        propertyChange("responsibilitiesList", this.responsibilitiesList, responsibilitiesList);
        this.responsibilitiesList = responsibilitiesList;
    }

    public void setSalary(int salary) {
        propertyChange("salary", this.salary, salary);
        this.salary = salary;
    }

    /**
     * Print the first & last name
     */
    public String toString() {
        StringWriter writer = new StringWriter();

        writer.write("Employee: ");
        writer.write(getFirstName());
        writer.write(" ");
        writer.write(getLastName());
        return writer.toString();
    }
}
