package org.mustbe.consulo.csharp.lang.psi.impl.source.resolve.sorter;

import java.util.Comparator;

import org.jetbrains.annotations.NotNull;
import org.mustbe.consulo.dotnet.psi.DotNetGenericParameterListOwner;
import org.mustbe.consulo.dotnet.psi.DotNetTypeWithTypeArguments;
import org.mustbe.consulo.dotnet.psi.DotNetUserType;
import org.mustbe.consulo.dotnet.resolve.DotNetNamespaceAsElement;
import com.intellij.psi.PsiElement;
import com.intellij.psi.ResolveResult;
import com.intellij.util.containers.ContainerUtil;

/**
 * @author VISTALL
 * @since 27.10.14
 */
public class TypeLikeSorter implements ResolveResultSorter
{
	public static class ResolveResultComparator implements Comparator<ResolveResult>
	{
		private final int myGenericCount;

		public ResolveResultComparator(int genericCount)
		{
			myGenericCount = genericCount;
		}

		@Override
		public int compare(ResolveResult o1, ResolveResult o2)
		{
			int compare = compare(o1);
			if(compare != 0)
			{
				return -compare;
			}
			compare = compare(o2);
			if(compare != 0)
			{
				return compare;
			}
			return 0;
		}

		private int compare(ResolveResult r)
		{
			PsiElement element = r.getElement();
			if(element instanceof DotNetNamespaceAsElement)
			{
				return -1;
			}

			if(element instanceof DotNetGenericParameterListOwner && ((DotNetGenericParameterListOwner) element).getGenericParametersCount() ==
					myGenericCount)
			{
				return 1;
			}
			return 0;
		}
	}

	@NotNull
	public static TypeLikeSorter createByReference(@NotNull PsiElement element)
	{
		int size = 0;
		PsiElement parent = element.getParent();
		if(parent instanceof DotNetUserType)
		{
			PsiElement userTypeParent = parent.getParent();
			if(userTypeParent instanceof DotNetTypeWithTypeArguments)
			{
				size = ((DotNetTypeWithTypeArguments) userTypeParent).getArguments().length;
			}
		}
		return new TypeLikeSorter(size);
	}

	private final Comparator<ResolveResult> myComparator;

	public TypeLikeSorter(int genericCount)
	{
		myComparator = new ResolveResultComparator(genericCount);
	}

	@Override
	public void sort(@NotNull ResolveResult[] resolveResults)
	{
	/*	System.out.println("before: ");
		for(ResolveResult resolveResult : resolveResults)
		{
			PsiElement element = resolveResult.getElement();
			System.out.println(" element: " + element.getClass().getSimpleName());
			if(element instanceof DotNetGenericParameterListOwner)
			{
				System.out.println(" generic count: " + ((DotNetGenericParameterListOwner) element).getGenericParametersCount());
			}
		}
		          */
		ContainerUtil.sort(resolveResults, myComparator);

	/*	System.out.println("after: ");
		for(ResolveResult resolveResult : resolveResults)
		{
			PsiElement element = resolveResult.getElement();
			System.out.println(" element: " + element.getClass().getSimpleName());
			if(element instanceof DotNetGenericParameterListOwner)
			{
				System.out.println(" generic count: " + ((DotNetGenericParameterListOwner) element).getGenericParametersCount());
			}
		}
               */
	}
}

@@ -207,16 +207,77 @@
 tOwner;%0A
+import org.mustbe.consulo.dotnet.psi.DotNetQualifiedElement;%0A
 import o
@@ -387,16 +387,69 @@
 erType;%0A
+import org.mustbe.consulo.dotnet.psi.DotNetVariable;%0A
 import o
@@ -1365,16 +1365,127 @@
 ;%0A%09%09%09%7D%0A%0A
+%09%09%09if(element instanceof DotNetVariable && element instanceof DotNetQualifiedElement)%0A%09%09%09%7B%0A%09%09%09%09return 2;%0A%09%09%09%7D%0A%0A
 %09%09%09if(el

update sorter