package gov.nih.nci.cabig.caaers.domain;

import java.util.Date;
import java.util.List;
import java.util.ArrayList;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.OneToMany;

import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;

import gov.nih.nci.cabig.ctms.domain.AbstractMutableDomainObject;
import gov.nih.nci.cabig.caaers.domain.StudySite;


/**
 * @author Krikor Krumlian
 */

@Entity
@Table (name = "participant_assignments")
@GenericGenerator(name="id-generator", strategy = "native",
    parameters = {
        @Parameter(name="sequence", value="seq_participant_assignments_id")
    }
)
public class StudyParticipantAssignment extends AbstractMutableDomainObject {
    private Participant participant;
    private StudySite studySite;
    private Date dateOfEnrollment;
    private List<ExpeditedAdverseEventReport> aeReports;
    private List<RoutineAdverseEventReport> aeRoutineReports;

    public StudyParticipantAssignment(Participant participant, StudySite studySite) {
        this.participant = participant;
        this.studySite = studySite;
        this.dateOfEnrollment = new Date();
    }
    
    public StudyParticipantAssignment() { }

    ////// LOGIC

    public void addReport(ExpeditedAdverseEventReport report) {
        report.setAssignment(this);
        getAeReports().add(report);
    }
    
    public void addRoutineReport(RoutineAdverseEventReport routineReport) {
        routineReport.setAssignment(this);
        getAeRoutineReports().add(routineReport);
    }

    ////// BEAN PROPERTIES

    public void setStudySite(StudySite studySite) {
        this.studySite = studySite;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "study_site_id")
    @Cascade({ CascadeType.LOCK, CascadeType.SAVE_UPDATE })
    public StudySite getStudySite() {
        return studySite;
    }
    
    public void setParticipant(Participant participant) {
        this.participant = participant;
    }

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "participant_id")
    @Cascade({ CascadeType.LOCK, CascadeType.SAVE_UPDATE })
    public Participant getParticipant() {
        return participant;
    }

    public void setDateOfEnrollment(Date dateOfEnrollment) {
        this.dateOfEnrollment = dateOfEnrollment;
    }

    @Column(name = "date_of_enrollment")
    public Date getDateOfEnrollment() {
        return dateOfEnrollment;
    }

    @OneToMany(mappedBy = "assignment")
    public List<ExpeditedAdverseEventReport> getAeReports() {
        if (aeReports == null) aeReports = new ArrayList<ExpeditedAdverseEventReport>();
        return aeReports;
    }

    public void setAeReports(List<ExpeditedAdverseEventReport> aeReports) {
        this.aeReports = aeReports;
    }
    
    @OneToMany(mappedBy = "assignment")
    public List<RoutineAdverseEventReport> getAeRoutineReports() {
        if (aeRoutineReports == null) aeRoutineReports = new ArrayList<RoutineAdverseEventReport>();
        return aeRoutineReports;
    }

    public void setAeRoutineReports(List<RoutineAdverseEventReport> aeRoutineReports) {
        this.aeRoutineReports = aeRoutineReports;
    }
    
    ////// OBJECT METHODS

	public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        final StudyParticipantAssignment that = (StudyParticipantAssignment) o;

        if (dateOfEnrollment != null ? !dateOfEnrollment.equals(that.dateOfEnrollment) : that.dateOfEnrollment != null)
            return false;
        if (studySite != null ? !studySite.equals(that.studySite) : that.studySite != null)
            return false;
        // Participant#equals calls this method, so we can't use it here
        if (!AbstractMutableDomainObject.equalById(participant, that.participant)) return false;

        return true;
    }

    public int hashCode() {
        int result;
        result = (studySite != null ? studySite.hashCode() : 0);
        result = 29 * result + (participant != null ? participant.hashCode() : 0);
        result = 29 * result + (dateOfEnrollment != null ? dateOfEnrollment.hashCode() : 0);
        return result;
    }
}

@@ -642,36 +642,34 @@
 .nih.nci.cabig.c
-aaer
+tm
 s.domain.StudySi
@@ -661,25 +661,33 @@
 .domain.
-StudySite
+DomainObjectTools
 ;%0D%0A%0D%0A%0D%0A/
@@ -3606,9 +3606,27 @@
 %0D%0A%0D%0A
-%09
+    @Override%0D%0A    
 publ
@@ -4201,31 +4201,16 @@
    if (!
-AbstractMutable
 DomainOb
@@ -4213,16 +4213,21 @@
 inObject
+Tools
 .equalBy
@@ -4301,32 +4301,47 @@
 true;%0D%0A    %7D%0D%0A%0D%0A
+    @Override%0D%0A
     public int h

Update for changes in ctms-commons-core