/*******************************************************************************
 * Copyright (c) 2008 SAS Institute Inc.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     SAS Institute Inc. - initial API and implementation
 ******************************************************************************/
package org.eclipse.cosmos.me.provisional.deployment.sdd.tooling.btg.aggregator;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;

import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.Resource;
import org.eclipse.cosmos.me.provisional.deployment.sdd.common.spi.contentunit.Completion;

public class CompletionType
{
	static Collection <Completion> merge(Collection<Completion> completions1, Collection<Completion> completions2)
	{
		
		
		Collection <Completion> completionsToRemove = new ArrayList <Completion> ();
		Iterator <Completion> completionIter1 = completions1.iterator();		
		//iterate through the completions
		while (completionIter1.hasNext())
		{
			Completion completion1 = (Completion) completionIter1.next();
			Iterator <Completion> completionIter2 = completions2.iterator();
			while (completionIter2.hasNext())
			{
				Completion completion2 = (Completion) completionIter2.next();
				//if you find a match that hasn't been found, note it
				//one of the equals needs to be deleted with its children merged over
				if (completionsToRemove.contains(completion2)==false)
				{
					if (equals(completion1, completion2))
					{  //merge hosted completions, types and description groups
						completionsToRemove.add(completion2);						
						completion1 = merge(completion1,completion2);
						
					}
				}
					
			}
		}
		
		completions2.removeAll(completionsToRemove);
		//remove all of the matches that were found
		
		Collection <Completion> finalCompletions = new ArrayList <Completion> ();
		//create and return a new collection with all of the remaining items
		finalCompletions.addAll(completions1);
		finalCompletions.addAll(completions2);		
		
		return finalCompletions;
		
		
	}
	/*
	  <CompletionType>

		<xsd:complexType name="CompletionType">
		  <xsd:sequence>
		    <xsd:group ref="sdd-dd:DisplayElementGroup" minOccurs="0"/>
		    <xsd:element name="Condition" type="sdd-dd:ConditionType" minOccurs="0"/>
		    <xsd:any namespace="##other" processContents="lax" minOccurs="0" maxOccurs="unbounded"/>
		  </xsd:sequence>
		  <xsd:attribute name="type" type="sdd-dd:CompletionTypeNamesType" use="required"/>
		  <xsd:attribute name="resourceRef" type="xsd:IDREF" use="required"/>
		  <xsd:attribute name="operation" type="sdd-dd:OperationListType" use="required"/>
		  <xsd:anyAttribute namespace="##other" processContents="lax"/>
		</xsd:complexType>
		
		Type 	Element 	Attribute 	Data Type 	Compare?
		<CompletionType> 				
				type 	<CompletionTypeNamesType> 	Yes
				resourceRef 	xsd:IDREF 	Yes
				operation 	<OperationListType> 	Yes
				any 	namespace="##other" 	 ?
			DisplayElementGroup 		<DisplayElementGroup> 	Merge
			Condition 		<ConditionType> 	Merge
			any 		namespace="##other" 	 ?
		
		Notes:
		Compare the Resources pointed to by resourceRef, not the references themselves. */

	static boolean equals(Completion c1, Completion c2)
	{
		boolean equals = true;

		equals = equals && StringType.equals(c1.getCompletionType(), c2.getCompletionType());
		equals = equals && OperationsType.equals(c1.getCompletionOperations(), c2.getCompletionOperations());
		
		Resource rc1 = Util.resolveResourceRef(c1.getCompletionResourceReference());
		Resource rc2 = Util.resolveResourceRef(c2.getCompletionResourceReference());

		equals = equals && ResourceType.equals(rc1, rc2);		
				
		return equals;
	}
	
	static Completion merge(Completion c1, Completion c2)
	{
		c1.setDescription(TranslatableStringType.merge(c1.getDescription(), c2.getDescription()));
		c1.setDisplayName(TranslatableStringType.merge(c1.getDisplayName(), c2.getDisplayName()));
		c1.setShortDescription(TranslatableStringType.merge(c1.getShortDescription(), c2.getShortDescription()));
		return c1;
	}
	
}