/*
 * 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:
//     Oracle - initial API and implementation from Oracle TopLink
package org.eclipse.persistence.testing.models.employee.domain;

import java.sql.Date;
import java.io.*;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;
import org.eclipse.persistence.descriptors.changetracking.*;

/**
 * <p><b>Purpose</b>: Defines the period an Employee worked for the organization
 * <p><b>Description</b>: The period holds the start date and optionally the end date if the employee has left (null otherwise).
 * Maintained in an aggregate relationship of Employee
 * @see Employee
 */
public class EmploymentPeriod implements Serializable, ChangeTracker, Cloneable {
    // implements ChangeTracker for testing
    public Date startDate;
    public Date endDate;
    public PropertyChangeListener listener;

    public EmploymentPeriod() {
    }

    /**
     * Return a new employment period instance.
     * The constructor's purpose is to allow only valid instances of a class to be created.
     * Valid means that the get/set and clone/toString methods should work on the instance.
     * Arguments to constructors should be avoided unless those arguments are required to put
     * the instance into a valid state, or represent the entire instance definition.
     */
    public EmploymentPeriod(Date startDate, Date endDate) {
        this.startDate = startDate;
        this.endDate = endDate;

    }

    @Override
    public Object clone()
    {
        try {
            return super.clone();
        } catch (Exception ignore) {}
        return null;
    }

    @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 Date getEndDate() {
        return endDate;
    }

    public Date getStartDate() {
        return startDate;
    }

    public void setEndDate(Date endDate) {
        Date oldDate = this.endDate;
        this.endDate = endDate;
        propertyChange("endDate", oldDate, endDate);
    }

    public void setStartDate(Date startDate) {
        Date oldDate = this.startDate;
        this.startDate = startDate;
        propertyChange("startDate", oldDate, startDate);
    }

    /**
     * Print the start &amp; end date
     */
    public String toString() {
        StringWriter writer = new StringWriter();

        writer.write("EmploymentPeriod: ");
        if (getStartDate() != null) {
            writer.write(getStartDate().toString());
        }
        writer.write("-");
        if (getEndDate() != null) {
            writer.write(getEndDate().toString());
        }
        return writer.toString();
    }

    public boolean equals(Object period){
        if (this == period){
            return true;
        }
        if (period == null || !(period instanceof EmploymentPeriod)){
            return false;
        }
        EmploymentPeriod empPeriod = (EmploymentPeriod)period;
        if ((getStartDate() == null && empPeriod.getStartDate() != null) || (getStartDate() != null && empPeriod.getStartDate() == null)){
            return false;
        }
        if ((getEndDate() == null && empPeriod.getEndDate() != null) || (getEndDate() != null && empPeriod.getEndDate() == null)){
            return false;
        }
        boolean match = (getStartDate() == null && empPeriod.getStartDate() == null) || (getStartDate().equals(empPeriod.getStartDate()));
        match = match && ((getEndDate() == null && empPeriod.getEndDate() == null) || getEndDate().equals(empPeriod.getEndDate()));
        return  match;
    }

    public int hashCode() {
        int hash = 0;
        hash += (this.getStartDate() != null ? this.getStartDate().hashCode() : 0);
        hash += (this.getEndDate() != null ? this.getEndDate().hashCode() : 0);
        return hash;
    }

}
