/*
 * Copyright (c) 2011, Patrik Dufresne. All rights reserved.
 * Patrik Dufresne PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.planimod.core;

import javax.persistence.Entity;
import javax.persistence.ManyToOne;

import org.hibernate.annotations.NamedQueries;
import org.hibernate.annotations.NamedQuery;

/**
 * A task represent a period in time where a position is filled by an employee.
 * This task is directly related to a production event.
 * 
 * @author Patrik Dufresne
 * 
 */
@Entity
@NamedQueries({
		@NamedQuery(name = "listQualificationAndAvaibilityTable", query = "SELECT E, Ta, Po, Se, PE, Pr, S, Te "
				+ "FROM Employee E, Task Ta JOIN Ta.position as Po JOIN Po.section as Se JOIN Ta.productionEvent as PE JOIN PE.product as Pr JOIN PE.shift as S JOIN S.team as Te, Qualification Q "
				+ "WHERE E.id = Q.employee "
				+ "AND Q.position=Ta.position "
				+ "AND Ta.startDate >= :start "
				+ "AND Ta.endDate <= :end "
				+ "AND not exists ( "
				+ "FROM NonAvailability as NA "
				+ "WHERE NA.employee=E "
				+ "AND NA.startDate <= Ta.startDate "
				+ "AND NA.endDate >= Ta.endDate " + ")"),
		@NamedQuery(name = "listQualifiedAndAvailableEmployees", query = "SELECT DISTINCT E "
				+ "FROM Employee E, Qualification Q, ProductPosition PP, ProductionEvent PE "
				+ "JOIN PE.shift as S "
				+ "WHERE E.id=Q.employee "
				+ "AND Q.position=PP.position "
				+ "AND PP.product=PE.product "
				+ "AND S.startDate >= :start "
				+ "AND S.endDate <= :end "
				+ "AND not exists ( "
				+ "FROM NonAvailability as NA "
				+ "WHERE NA.employee=E "
				+ "AND NA.startDate <= S.startDate "
				+ "AND NA.endDate >= S.endDate " + ")") })
public class Task extends AbstractCalendarEvent {

	/**
	 * Employee property.
	 */
	public static final String EMPLOYEE = "employee"; //$NON-NLS-1$

	/**
	 * Locked property.
	 */
	public static final String LOCKED = "locked"; //$NON-NLS-1$

	/**
	 * Position property
	 */
	public static final String POSITION = "position"; //$NON-NLS-1$

	/**
	 * Production event property
	 */
	public static final String PRODUCTION_EVENT = "productionEvent"; //$NON-NLS-1$

	private static final long serialVersionUID = 6154178076000554135L;

	/**
	 * The employee that will fill the position for this period of time.
	 */
	private Employee employee;

	private boolean locked;

	/**
	 * the position to be filled by an employee.
	 */
	private Position position;

	/**
	 * The related production event.
	 */
	private ProductionEvent productionEvent;

	/**
	 * Return the value of property <code>employee</code>.
	 * 
	 * @return
	 */
	@ManyToOne(optional = true)
	public Employee getEmployee() {
		return this.employee;
	}

	public boolean getLocked() {
		return this.locked;
	}

	/**
	 * Return the position to be filled.
	 * 
	 * @return
	 */
	@ManyToOne(optional = false)
	public Position getPosition() {
		return this.position;
	}

	/**
	 * Return the production event.
	 * 
	 * @return
	 */
	@ManyToOne(optional = false)
	public ProductionEvent getProductionEvent() {
		return this.productionEvent;
	}

	public void setEmployee(Employee employee) {
		this.changeSupport.firePropertyChange(EMPLOYEE, this.employee,
				this.employee = employee);
	}

	public void setLocked(boolean locked) {
		this.changeSupport.firePropertyChange(LOCKED, this.locked,
				this.locked = locked);
	}

	public void setPosition(Position position) {
		this.changeSupport.firePropertyChange(POSITION, this.position,
				this.position = position);
	}

	public void setProductionEvent(ProductionEvent event) {
		this.changeSupport.firePropertyChange(PRODUCTION_EVENT,
				this.productionEvent, this.productionEvent = event);
	}

	@Override
	public String toString() {
		return "Task [id=" + this.id + "]"; //$NON-NLS-1$ //$NON-NLS-2$
	}

}
