/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software 
 * distributed under the License is distributed on an "AS IS" BASIS, 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 * See the License for the specific language governing permissions and 
 * limitations under the License.
 */
 
package org.apache.jdo.tck.pc.companyAnnotatedJPA;

import javax.persistence.*;

import java.io.Serializable;
import java.io.ObjectInputStream;
import java.io.IOException;

import java.util.Collections;
import java.util.Comparator;
import java.util.Set;
import java.util.HashSet;
import java.math.BigDecimal;

import org.apache.jdo.tck.pc.company.IProject;
import org.apache.jdo.tck.util.DeepEquality;
import org.apache.jdo.tck.util.EqualityHelper;

/**
 * This class represents a project, a budgeted task with one or more
 * employees working on it.
 */

@Entity
@Table(name="projects")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(discriminatorType=DiscriminatorType.STRING,
        name="DISCRIMINATOR")
    public class JPAAppProject 
    implements IProject, Serializable, Comparable, Comparator, DeepEquality  {

    @Id
    @Column(name="PROJID")
    private long projid;
    @Column(name="NAME")
    private String     name;
    @Column(name="BUDGET", length=11, scale=2)
    private BigDecimal budget;
    @ManyToMany(targetEntity=org.apache.jdo.tck.pc.companyAnnotatedJPA.JPAAppEmployee.class)
    @JoinTable(name="project_reviewer", joinColumns=@JoinColumn(name="PROJID"),
            inverseJoinColumns=@JoinColumn(name="REVIEWER"))
    private Set reviewers = new HashSet();
    @ManyToMany(targetEntity=org.apache.jdo.tck.pc.companyAnnotatedJPA.JPAAppEmployee.class)
    @JoinTable(name="project_member", joinColumns=@JoinColumn(name="PROJID"),
            inverseJoinColumns=@JoinColumn(name="MEMBER"))
    private Set members = new HashSet();
    
    /** This is the JDO-required no-args constructor. The TCK relies on
     * this constructor for testing PersistenceManager.newInstance(PCClass).
     */
    public JPAAppProject() {}

    /**
     * Initialize a project.
     * @param projid The project identifier.
     * @param name The name of the project.
     * @param budget The budget for the project.
     */
    public JPAAppProject(long projid, String name, BigDecimal budget) {
        this.projid = projid;
        this.name = name;
        this.budget = budget;
    }

    /**
     * Set the id associated with this object.
     * @param id the id.
     */
    public void setProjid(long id) {
        if (this.projid != 0)
            throw new IllegalStateException("Id is already set.");
        this.projid = id;
    }

    /**
     * Get the project ID.
     * @return The project ID.
     */
    public long getProjid() {
        return projid;
    }

    /**
     * Get the name of the project.
     * @return The name of the project.
     */
    public String getName() {
        return name;
    }

    /**
     * Set the name of the project.
     * @param name The name of the project.
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * Get the project's budget.
     * @return The project's budget.
     */
    public BigDecimal getBudget() {
        return budget;
    }

    /**
     * Set the project's budget.
     * @param budget The project's budget.
     */
    public void setBudget(BigDecimal budget) {
        this.budget = budget;
    }

    /**
     * Get the reviewers associated with this project.
     */
    public Set getReviewers() {
        return Collections.unmodifiableSet(reviewers);
    }

    /**
     * Add a reviewer to the project.
     * @param emp The employee to add as a reviewer.
     */
    public void addReviewer(JPAAppEmployee emp) {
        reviewers.add(emp);
    }

    /**
     * Remove a reviewer from the project.
     * @param emp The employee to remove as a reviewer of this project.
     */
    public void removeReviewer(JPAAppEmployee emp) {
        reviewers.remove(emp);
    }

    /**
     * Set the reviewers associated with this project.
     * @param reviewers The set of reviewers to associate with this project.
     */
    public void setReviewers(Set reviewers) {
        // workaround: create a new HashSet, because fostore does not
        // support LinkedHashSet
        this.reviewers = (reviewers != null) ? new HashSet(reviewers) : null;
    }

    /**
     * Get the project members.
     * 
     * 
     * @return The members of the project is returned as an unmodifiable
     * set of <code>JPAAppEmployee</code>s.
     */
    public Set getMembers() {
        return Collections.unmodifiableSet(members);
    }

    /**
     * Add a new member to the project.
     * @param emp The employee to add to the project.
     */
    public void addMember(JPAAppEmployee emp) {
        members.add(emp);
    }

    /**
     * Remove a member from the project.
     * @param emp The employee to remove from the project.
     */
    public void removeMember(JPAAppEmployee emp) {
        members.remove(emp);
    }

    /**
     * Set the members of the project.
     * @param employees The set of employees to be the members of this
     * project. 
     */
    public void setMembers(Set employees) {
        // workaround: create a new HashSet, because fostore does not
        // support LinkedHashSet
        this.members = (employees != null) ? new HashSet(employees) : null;
    }

    /**
     * Serialization support: initialize transient fields.
     * @param in stream
     * @throws IOException error during reading
     * @throws ClassNotFoundException class could not be found
     */
    private void readObject(ObjectInputStream in)
        throws IOException, ClassNotFoundException {
        in.defaultReadObject();
        reviewers = new HashSet();
        members = new HashSet();
    }

    /**
     * Returns a String representation of a <code>JPAAppProject</code> object.
     * 
     * 
     * @return a String representation of a <code>JPAAppProject</code> object.
     */
    public String toString() {
        return "JPAProject(" + getFieldRepr() + ")";
    }
    
    /**
     * Returns a String representation of the non-relationship fields.
     * @return a String representation of the non-relationship fields.
     */
    protected String getFieldRepr() {
        StringBuffer rc = new StringBuffer();
        rc.append(projid);
        rc.append(", name ").append(name);
        rc.append(", budget ").append(budget);
        return rc.toString();
    }

    /** 
     * Returns <code>true</code> if all the fields of this instance are
     * deep equal to the coresponding fields of the specified Person.
     * @param other the object with which to compare.
     * @param helper EqualityHelper to keep track of instances that have
     * already been processed. 
     * @return <code>true</code> if all the fields are deep equal;
     * <code>false</code> otherwise.  
     * @throws ClassCastException if the specified instances' type prevents
     * it from being compared to this instance. 
     */
    public boolean deepCompareFields(Object other, 
                                     EqualityHelper helper) {
        JPAAppProject otherProject = (JPAAppProject)other;
        String where = "JPAProject<" + projid + ">";
        return 
            helper.equals(projid, otherProject.getProjid(), where + ".projid") &
            helper.equals(name, otherProject.getName(), where + ".name") &
            helper.equals(budget, otherProject.getBudget(), where + ".budget") &
            helper.deepEquals(reviewers, otherProject.getReviewers(), where + ".reviewers") &
            helper.deepEquals(members, otherProject.getMembers(), where + ".members");
    }
    
    /** 
     * Compares this object with the specified object for order. Returns a
     * negative integer, zero, or a positive integer as this object is less
     * than, equal to, or greater than the specified object. 
     * @param o The Object to be compared. 
     * @return a negative integer, zero, or a positive integer as this 
     * object is less than, equal to, or greater than the specified object. 
     * @throws ClassCastException - if the specified object's type prevents
     * it from being compared to this Object. 
     */
    public int compareTo(Object o) {
        return compareTo((JPAAppProject)o);
    }

    /** 
     * Compare two instances. This is a method in Comparator.
     */
    public int compare(Object o1, Object o2) {
        return compare((JPAAppProject)o1, (JPAAppProject)o2);
    }

    /**
     * 
     * Compares this object with the specified JPAAppProject object for
     * order. Returns a negative integer, zero, or a positive integer as
     * this object is less than, equal to, or greater than the specified
     * object.  
     * 
     * 
     * @param other The JPAAppProject object to be compared.
     * @return a negative integer, zero, or a positive integer as this
     * object is less than, equal to, or greater than the specified JPAAppProject object.
     */
    public int compareTo(JPAAppProject other) {
        return compare(this, other);
    }

    /**
     * Compares its two IProject arguments for order. Returns a negative
     * integer, zero, or a positive integer as the first argument is less
     * than, equal to, or greater than the second. 
     * @param o1 the first IProject object to be compared. 
     * @param o2 the second IProject object to be compared. 
     * @return a negative integer, zero, or a positive integer as the first
     * object is less than, equal to, or greater than the second object. 
     */
    public static int compare(JPAAppProject o1, JPAAppProject o2) {
        return EqualityHelper.compare(o1.getProjid(), o2.getProjid());
    }

    /** 
     * Indicates whether some other object is "equal to" this one.
     * @param obj the object with which to compare.
     * @return <code>true</code> if this object is the same as the obj
     * argument; <code>false</code> otherwise. 
     */
    public boolean equals(Object obj) {
        if (obj instanceof JPAAppProject) {
            return compareTo((JPAAppProject)obj) == 0;
        }
        return false;
    }
        
    /**
     * Returns a hash code value for the object. 
     * @return a hash code value for this object.
     */
    public int hashCode() {
        return (int)projid;
    }

    /**
     * This class is used to represent the application identity
     * for the <code>JPAAppProject</code> class.
     */
    public static class Oid implements Serializable, Comparable {

        /**
         * This field represents the identifier for the
         * <code>JPAAppProject</code> class. It must match a field in the
         * <code>JPAAppProject</code> class in both name and type.
         */
        public long projid;

        /**
         * The required public no-arg constructor.
         */
        public Oid() { }

        /**
         * Initialize the application identifier with a project ID.
         * @param projid The id of the project.
         */
        public Oid(long projid) {
            this.projid = projid;
        }
        
        public Oid(String s) { projid = Long.parseLong(justTheId(s)); }

        public String toString() { return this.getClass().getName() + ": "  + projid;}

        /** */
        public boolean equals(java.lang.Object obj) {
            if( obj==null || !this.getClass().equals(obj.getClass()) )
                return( false );
            Oid o = (Oid) obj;
            if( this.projid != o.projid ) return( false );
            return( true );
        }

        /** */
        public int hashCode() {
            return( (int) projid );
        }
        
        protected static String justTheId(String str) {
            return str.substring(str.indexOf(':') + 1);
        }

        /** */
        public int compareTo(Object obj) {
            // may throw ClassCastException which the user must handle
            Oid other = (Oid) obj;
            if( projid < other.projid ) return -1;
            if( projid > other.projid ) return 1;
            return 0;
        }

    }

}

