/**
 * Title.java
 * Created Apr 17, 2008
 * Copyright (c) TANDBERG Television 2007-2008
 */
package com.tandbergtv.watchpoint.pmm.entities;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import com.tandbergtv.metadatamanager.model.Asset;

/**
 * Represents a title in a VOD system. A title is a composite structure that can be used to represent 
 * a video, audio or image asset and associated metadata in a heirarchy. The rationale for a 
 * heirarchy is that titles are usually grouped together. e.g. a CableLabs VOD 1.1 package may consist of a
 * movie, poster and preview assets.
 * 
 * Each title corresponds to at most one physical asset.
 * 
 * The title object model is intended to be capable of storing information independent of the 
 * metadata specification and can be used in domains other than VOD.
 * 
 * @author Sahil Verma
 */
public class Title {
	
	private Long id;
	
	private TitleStatus status;
	
	private String externalLocation;
	
	private String metadataContent;
	
	private Asset asset;
	
	private Collection<IAssetList> titlelists;
	
	private Collection<ProgressItem> progressItems;
	
	private Map<String, TitleStatus> assetVersionStatusMap;

	/**
	 * Creates a Title
	 */
	public Title() {
		progressItems = new ArrayList<ProgressItem>();
		titlelists = new ArrayList<IAssetList>();
		status = TitleStatus.DRAFT;
		assetVersionStatusMap = new HashMap<String, TitleStatus>();
	}

	/**
	 * Creates a Title.
	 */
	public Title(Long id) {
		this();
		this.id = id;
	}
	
	/**
	 * Creates a Title
	 * 
	 * @param status
	 */
	public Title(TitleStatus status) {
		this();
		this.status = status;
	}
	
	/**
	 * Returns the id
	 * 
	 * @return the id
	 */
	public Long getId() {
		return this.id;
	}

	/**
	 * Sets the id. This method should not get called ordinarily.
	 * 
	 * @param id the id to set
	 */
	public void setId(Long id) {
		this.id = id;
	}

	/**
	 * Determines if the title is active or deleted
	 * 
	 * @return true if active, false if deleted
	 */
	public Boolean getIsActive() {
		return getAsset().isActive();
	}

	/**
	 * Sets the active flag. This method should not get called ordinarily.
	 * 
	 * @param isActive the isActive to set
	 */
	public void setIsActive(Boolean isActive) {
		this.getAsset().setState(isActive);
	}

	/**
	 * @return the asset
	 */
	public Asset getAsset() {
		return asset;
	}

	/**
	 * @param asset the asset to set
	 */
	public void setAsset(Asset asset) {
		this.asset = asset;
	}

	/**
	 * Returns the id of an external title repository from which this title has been imported. The
	 * format is systemId-instanceid, where systemId is the two character identifier of an external
	 * repository and instanceid represents a character string that uniquely identifies an instance
	 * of the title repository. Note that only WatchPoint is the sole systemId naming authority.
	 * 
	 * @return the externalLocation
	 */
	public String getExternalLocation() {
		return this.externalLocation;
	}
	
	/**
	 * Sets the id of an external title repository from which this title has been imported
	 * 
	 * @param externalLocation
	 */
	public void setExternalLocation(String externalLocation) {
		this.externalLocation = externalLocation;
	}	

	/**
	 * @return the metadataContent
	 */
	public String getMetadataContent() {
		return metadataContent;
	}

	/**
	 * @param metadataContent the metadataContent to set
	 */
	public void setMetadataContent(String metadataContent) {
		this.metadataContent = metadataContent;
	}

	/**
	 * Returns the status
	 * 
	 * @return the status
	 */
	public TitleStatus getStatus() {
		return this.status;
	}

	/**
	 * Sets the status
	 * 
	 * @param status the status to set
	 */
	public void setStatus(TitleStatus status) {
		this.status = status;
	}

	/**
	 * Returns all the lists that this title belongs to
	 * 
	 * @return the titlelists
	 */
	public Collection<IAssetList> getTitlelists() {
		return this.titlelists;
	}

	/**
	 * Returns all active progress status associated with this title
	 * 
	 * @return the progressItems
	 */
	public Collection<ProgressItem> getProgressItems() {
		Collection<ProgressItem> progressItems = new ArrayList<ProgressItem>();
		for(ProgressItem progress : this.progressItems) {
			if(progress.getIsActive()) {
				progressItems.add(progress);
			}
		}
		return progressItems;
	}

	/**
	 * Returns back all the progress items (active and inactive) associated with this title.
	 * 
	 * @return
	 */
	public Collection<ProgressItem> getAllProgressItems() {
		return this.progressItems;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		return "[" + id + " | " + asset + "] " + status;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#hashCode()
	 */
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((this.id == null) ? 0 : this.id.hashCode());
		return result;
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#equals(java.lang.Object)
	 */
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (!(obj instanceof Title))
			return false;
		final Title other = (Title) obj;
		if (this.id == null) {
			if (other.id != null)
				return false;
		} else if (!this.id.equals(other.id))
			return false;
		return true;
	}

	/**
	 * @return the assetStatusMap
	 */
	public Map<String, TitleStatus> getAssetStatusMap() {
		return assetVersionStatusMap;
	}

	/**
	 * @param assetStatusMap the assetStatusMap to set
	 */
	public void setAssetStatusMap(Map<String, TitleStatus> assetStatusMap) {
		this.assetVersionStatusMap = assetStatusMap;
	}
	
	/**
	 * Returns the status for the title whose asset had the matching version.
	 * 
	 * @param version
	 * @return
	 */
	public TitleStatus getStatus(String version) {
		return assetVersionStatusMap.get(version);
	}
}
