/**
 * Schedule.java
 * Created Apr 22, 2008
 * Copyright (c) TANDBERG Television 2007-2008
 */
package com.tandbergtv.watchpoint.pmm.entities;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;

/**
 * Represents a collection of titles with an optional provider
 * 
 * @author Sahil Verma
 */
public abstract class Schedule extends AssetList {

	protected Date date;
	
	protected Long sourcePartnerID;
	
	/**
	 * This is the id of the downstream entity and could represent a partner, a service, 
	 * a site (headend), a content distribution network etc.
	 */
	protected Long contextID;
	
	protected ScheduleStatus status;
	
	/* This field is NOT persisted, it is used to lookup the source partner ID */
	protected String providerID;
	
	/**
	 * Creates a Schedule
	 */
	protected Schedule() {
		this.status = ScheduleStatus.NEW;
	}

	/**
	 * Creates a Schedule
	 * 
	 * @param sourcePartnerID
	 */
	protected Schedule(Long sourcePartnerID, Date date) {
		this.progressItems = new ArrayList<ProgressItem>();
		this.sourcePartnerID = sourcePartnerID;
		setDate(date);
		this.status = ScheduleStatus.NEW;
	}

	/**
	 * Sets the date rolling the given date back to the start of the day.
	 */
	protected void setDate(Date date) {
		Calendar c = Calendar.getInstance();
		c.setTime(date);
		
		c.set(Calendar.HOUR_OF_DAY, 0);
		c.set(Calendar.MINUTE, 0);
		c.set(Calendar.SECOND, 0);
		c.set(Calendar.MILLISECOND, 0);
		
		this.date = c.getTime();
	}
	
	/**
	 * @return the sourcePartnerID
	 */
	public Long getSourcePartnerID() {
		return this.sourcePartnerID;
	}

	/**
	 * @param sourcePartnerID the sourcePartnerID to set
	 */
	public void setSourcePartnerID(Long sourcePartnerID) {
		this.sourcePartnerID = sourcePartnerID;
	}

	/**
	 * @return the contextID
	 */
	public Long getContextID() {
		return this.contextID;
	}

	/**
	 * @param contextID the contextID to set
	 */
	public void setContextID(Long contextID) {
		this.contextID = contextID;
	}

	/**
	 * @return the progressItems
	 */
	public Collection<ProgressItem> getProgressItems() {
		return this.progressItems;
	}
	
	/**
	 * Returns all the progress items associated with the specified title
	 * 
	 * @param title
	 * @return
	 */
	public Collection<ProgressItem> getProgressItems(Title title) {
		Collection<ProgressItem> items = new ArrayList<ProgressItem>();
		
		for (ProgressItem progress : this.progressItems) {
			if (progress.getTitleId().equals(title.getId()))
				items.add(progress);
		}
		
		return items;
	}
	
	/**
	 * Returns the progress item of the specified title that matches the given name
	 * 
	 * @param title
	 * @param name
	 * @return
	 */
	public ProgressItem getProgressItem(Title title, String name) {
		Collection<ProgressItem> items = getProgressItems(title);
		
		/* Isn't it bloody obvious that we need an associative data structure here? */
		for (ProgressItem item : items) {
			if (name.equals(item.getName()))
				return item;
		}
		
		return null;
	}
	
	/**
	 * @return the status
	 */
	public ScheduleStatus getStatus() {
		return this.status;
	}

	/**
	 * @param status the status to set
	 */
	public void setStatus(ScheduleStatus status) {
		this.status = status;
	}

	/**
	 * Returns the date of this schedule. In general, it is preferable to call Planner.getArrivalDate()
	 * and DistributionSchedule.getPitchDate()
	 * 
	 * @return the date
	 */
	public Date getDate() {
		return this.date;
	}

	/**
	 * @return the providerID
	 */
	public String getProviderID() {
		return this.providerID;
	}

	/**
	 * @param providerID the providerID to set
	 */
	public void setProviderID(String providerID) {
		this.providerID = providerID;
	}
	
	/**
	 * Adds the specified progress item to this schedule
	 * 
	 * @param progressItem
	 */
	public void addProgressItem(ProgressItem progressItem) {
		this.progressItems.add(progressItem);
		progressItem.setAssetListId(this.id);
	}
	
	/**
	 * Removes the progress item from this schedule
	 * 
	 * @param progressItem
	 */
	public void removeProgressItem(ProgressItem progressItem) {
		this.progressItems.remove(progressItem);
		progressItem.setAssetListId(null);
	}

	/* (non-Javadoc)
	 * @see com.tandbergtv.watchpoint.pmm.entities.AssetList#removeTitleInternal(com.tandbergtv.watchpoint.pmm.entities.Title)
	 */
	@Override
	protected void removeTitleInternal(Title title) {
		super.removeTitleInternal(title);
		
		/* DESTROY THE PROGRESSIZZLES!!! */
		for (ProgressItem progress : getProgressItems(title))
			removeProgressItem(progress);
	}

}
