package de.snailshell.consensus.demo;

import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import de.uka.ipd.consensus.foundation.ConsensusFoundation;
import de.uka.ipd.consensus.foundation.schema.Association;
import de.uka.ipd.consensus.foundation.schema.Topic;
import de.uka.ipd.consensus.foundation.schema.TypeInstance;
import de.uka.ipd.consensus.foundation.schema.User;

/**
 * @author Thomas Much
 * @version 2006-06-14
 */
public class ConsensusFoundationUtils {
	
	private static final int MAX_TOPIC_HISTORY = 10;
	

	public static ConsensusFoundation getConsensusFoundationManager(ServletContext context) {
		return (ConsensusFoundation)context.getAttribute( Constants.CONTEXT_ATTR_CONSENSUSFOUNDATION );
	}

	
	public static User getUser(HttpServletRequest request) {		
		HttpSession session = request.getSession(false);
		
		if (session != null) {
			return (User)session.getAttribute( Constants.SESSION_ATTR_USER );
		}
		else {
			return null;
		}
	}


	public static void addLastVisitedTopic(HttpServletRequest request, Topic t) {
		if (t != null) {
			HttpSession session = request.getSession(false);
			
			LinkedList list = null;
			
			if (session != null) {
				list = (LinkedList)session.getAttribute( Constants.SESSION_ATTR_LASTTOPICS );
			}
			
			if (list == null) {
				list = new LinkedList();
				session.setAttribute( Constants.SESSION_ATTR_LASTTOPICS, list );
			}
	
			list.remove( t );
			list.addFirst( t );
	
			if (list.size() > MAX_TOPIC_HISTORY) {
				list.removeLast();
			}
		}
	}


	public static List getLastVisitedTopics(HttpServletRequest request) {
		HttpSession session = request.getSession(false);
		
		List list = null;
		
		if (session != null) {
			list = (List)session.getAttribute( Constants.SESSION_ATTR_LASTTOPICS );
		}
		
		if (list == null) {
			return Collections.EMPTY_LIST;
		}
		else {
			return list;
		}
	}
	
	
	public static void setLastVisitedAssociation(HttpServletRequest request, Association a) {
		HttpSession session = request.getSession(false);
		
		if (session != null) {
			session.setAttribute( Constants.SESSION_ATTR_LASTASSOCIATION, a );
		}
	}
	
	
	public static Association getLastVisitedAssociation(HttpServletRequest request) {
		HttpSession session = request.getSession(false);
		
		if (session != null) {
			return (Association)session.getAttribute( Constants.SESSION_ATTR_LASTASSOCIATION );
		}
		else {
			return null;
		}
	}


	public static Set getParentTypes(User user, Topic t) {
		Set parentTypes = new HashSet();

		Iterator it = t.getTypes(user).iterator();

		if (it.hasNext()) {
			parentTypes.add( ((TypeInstance)it.next()).getType() );

			while (it.hasNext()) {
				parentTypes.add( ((TypeInstance)it.next()).getType() );
			}
			
			// now add *all* parent types
			// (don't do this recursively in case there are circular type hierarchies)
			
			boolean finished;
			
			do {
				finished = true;
				
				Iterator it2 = parentTypes.iterator();

				while (it2.hasNext()) {
					Iterator it3 = ((Topic)it2.next()).getTypes(user).iterator();
					
					while (it3.hasNext()) {
						Topic type = ((TypeInstance)it3.next()).getType();
						
						if (!parentTypes.contains( type )) {
							parentTypes.add( type );
							finished = false;
						}
					}
				}
				
			} while (!finished);
		}
		
		return parentTypes;
	}

}
