package com.tandbergtv.watchpoint.pmm.title.conf;

import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * Utility class that relates the titleConfs based on the relationship to form a tree.
 * 
 * @author Raj Prakash
 */
class Relator {
	
	private Set<TitleConf> titleConfs = new HashSet<TitleConf>();
	
	/**
	 * Relates the given TitleConf with the existing ones, if they claim as related.
	 * 
	 * @param newTC	the new titleConf to be added to the family tree
	 */
	public void relate(TitleConf newTC) {
		//Section: parent of any (of top-level objects only)?
		for(Iterator<TitleConf> titleSetIter = titleConfs.iterator(); titleSetIter.hasNext(); ) {
			TitleConf tc = titleSetIter.next();
			if(tc.getParentName().equals(newTC.getName())) {
				titleSetIter.remove();
				newTC.addChild(tc);
			}
		}
		
		//Section: child of any?
		if(isNullOrEmpty(newTC.getParentName())) {
			titleConfs.add(newTC);
		} else {
			TitleConf parent = findByName(newTC.getParentName(), titleConfs);
			if(parent != null) {
				parent.addChild(newTC);
			} else {
				titleConfs.add(newTC);
			}
		}
	}
	
	/**
	 * Finds the TitleConf with the given name in the given collection and in their lineage.
	 * 
	 * @param name			the name of the titleConf to find
	 * @param titleConfs	the collection of titleConfs to be searched in
	 * @return				the titleConf that has the given name
	 */
	private TitleConf findByName(String name, Collection<TitleConf> titleConfs) {
		for(TitleConf tc : titleConfs) {
			if(tc.getName().equals(name)) {
				return tc;
			}
			else {
				for(TitleConf descendant : tc.getAllDescendants()) {
					if(descendant.getName().equals(name))
						return descendant;
				}
			}
		}
		return null;
	}
	
	/**
	 * Checks if the given string is null or empty (just spaces is also considered empty)
	 */
	private boolean isNullOrEmpty(String s) {
		return s == null || s.trim().length() == 0;
	}
	
	/**
	 * Gets the root(s) of the family tree.
	 */
	public Set<TitleConf> getFamilyTree() {
		return titleConfs;
	}
}
