/*
 * 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:
//     05/05/2009 Andrei Ilitchev
//       - JPA 2.0 - OrderedList support.
package org.eclipse.persistence.testing.models.orderedlist;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.io.StringWriter;
import java.math.BigDecimal;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import org.eclipse.persistence.indirection.ValueHolder;
import org.eclipse.persistence.indirection.ValueHolderInterface;
import org.eclipse.persistence.descriptors.changetracking.*;

public class Employee implements ChangeTracker {
    // implements ChangeTracker for testing

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

    /** Direct-to-field mapping, String -{@literal >} VARCHAR. */
    public String firstName;

    /** Direct-to-field mapping, String -{@literal >} VARCHAR. */
    public String lastName;

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

    /** One-to-many mapping (same class relationship), inverse relationship to manager, uses manager foreign key in the target. */
    public List<Employee> managedEmployees;

    /** One-to-many mapping, employee references its collection of phone numbers using a foreign key in the phone's table. */
    public List<PhoneNumber> phoneNumbers;

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

    /** One-to-many mapping, employee references projects they lead. */
    public List<Project> projectsLed;

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

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

    int salary;

    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));
        }
    }
    public Employee() {
        this.firstName = "";
        this.lastName = "";
        this.manager = new ValueHolder();
        this.managedEmployees = new ArrayList();
        this.projects = new ArrayList();
        this.projectsLed = new ArrayList();
        this.responsibilitiesList = new ArrayList();
        this.phoneNumbers = new ArrayList();
        this.children = new Vector();
    }

    public Employee(String firstName, String lastName) {
        this();
        this.firstName = firstName;
        this.lastName = lastName;
    }

    public Employee(String firstName) {
        this(firstName, "");
    }

    /**
     * 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;
    }

    /**
     * For bi-directional relationships, it is important to maintain both sides of the relationship when changing it.
     */
    public void addPhoneNumber(PhoneNumber phoneNumber) {
        getPhoneNumbers().add(phoneNumber);
    }

    public void addPhoneNumber(int index, PhoneNumber phoneNumber) {
        getPhoneNumbers().add(index, phoneNumber);
    }

    public PhoneNumber setPhoneNumber(int index, PhoneNumber phoneNumber) {
        return getPhoneNumbers().set(index, phoneNumber);
    }

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

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

    public Project setProject(int index, Project project) {
        Project removedProject = getProjects().set(index, project);
        removedProject.getEmployees().remove(this);
        project.getEmployees().add(this);
        return removedProject;
    }

    public void addProjectLed(Project project) {
        getProjectsLed().add(project);
        project.setTeamLeader(this);
    }

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

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

    public String setResponsibility(int index, String responsibility) {
        return getResponsibilitiesList().set(index, responsibility);
    }

    public BigDecimal getId() {
        return id;
    }

    public String getFirstName() {
        return firstName;
    }

    public Vector getChildren(){
        return children;
    }

    public String getLastName() {
        return lastName;
    }

    public int getSalary() {
        return salary;
    }

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

    /**
     * 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 Employee getManager() {
        return (Employee)manager.getValue();
    }

    public List<PhoneNumber> getPhoneNumbers() {
        return phoneNumbers;
    }

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

    public List<Project> getProjectsLed() {
        return projectsLed;
    }

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


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

    /**
     * For bi-directional relationships, it is important to maintain both sides of the relationship when changing it.
     */
    public Employee removeManagedEmployee(int i) {
        Employee emp = getManagedEmployees().remove(i);
        emp.setManager(null);
        return emp;
    }

    /**
     * Remove the phone number.
     * The phone number's owner must not be set to null as it is part of it primary key,
     * and you can never change the primary key of an existing object.
     * Only in independent relationships should you null out the back reference.
     */
    public void removePhoneNumber(PhoneNumber phoneNumber) {
        getPhoneNumbers().remove(phoneNumber);
    }

    public PhoneNumber removePhoneNumber(int i) {
        PhoneNumber phone = getPhoneNumbers().remove(i);
        return phone;
    }

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

    public Project removeProject(int i) {
        Project project = getProjects().remove(i);
        project.getEmployees().remove(this);
        return project;
    }

    public void removeProjectLed(Project project) {
        getProjectsLed().remove(project);
        project.setTeamLeader(null);
    }

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

    public String removeResponsibility(int i) {
      return getResponsibilitiesList().remove(i);
  }

    public void setChildren(Vector<Child> children){
        propertyChange("children", this.children, children);
        this.children = children;
    }

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

    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 getSalary(int  salary) {
        propertyChange("salary", this.salary, salary);
        this.salary = salary;
    }

    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 setPhoneNumbers(List<PhoneNumber> phoneNumbers) {
        propertyChange("phoneNumbers", this.phoneNumbers, phoneNumbers);
        this.phoneNumbers = phoneNumbers;
    }

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

    public void setProjectsLed(List<Project> projectsLed) {
        this.projectsLed = projectsLed;
    }

    public void setResponsibilitiesList(List<String> responsibilitiesList) {
        propertyChange("responsibilitiesList", this.responsibilitiesList, responsibilitiesList);
        this.responsibilitiesList = responsibilitiesList;
    }

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

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