/**
 * AssetList.java
 * Created Apr 22, 2008
 * Copyright (c) TANDBERG Television 2007-2008
 */
package com.tandbergtv.watchpoint.pmm.entities;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;

import com.tandbergtv.watchpoint.pmm.entities.event.AssetListEvent;
import com.tandbergtv.watchpoint.pmm.entities.event.AssetListEventType;
import com.tandbergtv.workflow.core.event.DefaultMediator;

/**
 * Represents a collection of titles
 * 
 * @author Sahil Verma
 */
public abstract class AssetList implements IAssetList {
	
	protected Long id;
	
	protected String name;
	
	protected String description;
	
	protected Collection<Title> titles;
	
	protected Collection<ProgressItem> progressItems;
	
	protected Boolean isActive = true;

	/**
	 * Creates a AssetList
	 */
	protected AssetList() {
		titles = new ArrayList<Title>();
		progressItems = new ArrayList<ProgressItem>();
	}

	/* (non-Javadoc)
	 * @see com.tandbergtv.watchpoint.pmm.entities.IAssetList#getId()
	 */
	public Long getId() {
		return this.id;
	}

	/**
	 * @param id the id to set
	 */
	public void setId(Long id) {
		this.id = id;
	}

	/* (non-Javadoc)
	 * @see com.tandbergtv.watchpoint.pmm.entities.IAssetList#getName()
	 */
	public String getName() {
		return this.name;
	}

	/* (non-Javadoc)
	 * @see com.tandbergtv.watchpoint.pmm.entities.IAssetList#getDescription()
	 */
	public String getDescription() {
		return this.description;
	}

	/**
	 * @return the isActive
	 */
	public Boolean getIsActive() {
		return this.isActive;
	}

	/**
	 * @param isActive the isActive to set
	 */
	public void setIsActive(Boolean isActive) {
		this.isActive = isActive;
	}
	
	/**
	 * Adds the specified title to this list
	 * 
	 * @param title
	 */
	protected void addTitleInternal(Title title) {
		if (!titles.contains(title)) {
			this.titles.add(title);
		}
	}
	
	/**
	 * Adds the specified title to this list
	 * 
	 * @param title
	 */
	public void addTitle(Title title) {
		addTitleInternal(title);
		fireEvent(new AssetListEvent(this, this, AssetListEventType.TITLES_ADDED));
	}
	
	/**
	 * Adds the specified titles to this list
	 * @param titles
	 */
	public void addTitles(Title... titles) {
		for (Title title : titles)
			addTitleInternal(title);
		fireEvent(new AssetListEvent(this, this, AssetListEventType.TITLES_ADDED));
	}
	
	/**
	 * Adds the specified titles to this list
	 * @param titles
	 */
	public void addTitles(Collection<Title> titles) {
		for (Title title : titles)
			addTitleInternal(title);
		fireEvent(new AssetListEvent(this, this, AssetListEventType.TITLES_ADDED));
	}

	/**
	 * Removes the specified title
	 * 
	 * @param title
	 */
	protected void removeTitleInternal(Title title) {
		this.titles.remove(title);
	}
	
	/**
	 * Removes the specified title
	 * 
	 * @param title
	 */
	public void removeTitle(Title title) {
		removeTitleInternal(title);
		fireEvent(new AssetListEvent(this, this, AssetListEventType.TITLES_REMOVED));
	}
	
	/**
	 * Removes all titles from this list 
	 */
	public void removeTitles() {
		while(!titles.isEmpty())
			removeTitleInternal(titles.iterator().next());
		fireEvent(new AssetListEvent(this, this, AssetListEventType.TITLES_REMOVED));
	}
	
	/**
	 * Return the title with the specified id
	 * 
	 * @param titleId
	 */
	public Title getTitle(Long titleId) {
		for (Title t : this.titles) {
			if (t.getId().equals(titleId))
				return t;
		}
		
		return null;
	}

	/* (non-Javadoc)
	 * @see com.tandbergtv.watchpoint.pmm.entities.IAssetList#getTitles()
	 */
	public Collection<Title> getTitles() {
		return this.titles;
	}

	/**
	 * @param titles the titles to set
	 */
	public void setTitles(Collection<Title> titles) {
		removeTitles();
		addTitles(titles);
	}
	
	/**
	 * Returns the titles that are present in this list but not in the specified one
	 * 
	 * @param list
	 * @return
	 */
	public Collection<Title> getDelta(AssetList list) {
		Collection<Title> delta = new HashSet<Title>();
	
		for (Title title : this.titles) {
			if (!list.getTitles().contains(title))
				delta.add(title);
		}
		
		return delta;
	}
	
	/**
	 * @param event
	 */
	protected void fireEvent(AssetListEvent event) {
		DefaultMediator.getInstance().sendAsync(event);
	}

	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	public String toString() {
		String s = "[" + id + "]";
		
		if (this.titles != null)
			s += " " + this.titles.size() + " titles";
		
		return s;
	}

	/* (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 AssetList))
			return false;
		final AssetList other = (AssetList) obj;
		if (this.id == null) {
			if (other.id != null)
				return false;
		} else if (!this.id.equals(other.id))
			return false;
		return true;
	}
}
