/*******************************************************************************
 * Copyright (c) 2005, 2007 IBM Corporation and others.
 * 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:
 *     IBM Corporation - Initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.server.ui.internal.viewers;

import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.wst.server.core.IRuntimeType;
import org.eclipse.wst.server.core.IServerType;
/**
 * Class used to sort categories, runtime types, and server types in the
 * New wizards.
 */
public class DefaultViewerSorter extends ViewerSorter {
	public static class Version implements Comparable {
		private static final String SEPARATORS = ".,";

		private final String[] segments;

		private Version(String[] segments) {
			this.segments = segments;
		}

		public static Version parseVersion(String version) {
			List<String> list = new ArrayList<String>();
			StringTokenizer st = new StringTokenizer(version, SEPARATORS, false);
			while (st.hasMoreTokens())
				list.add(st.nextToken());
			
			String[] s = new String[list.size()];
			list.toArray(s);
			return new Version(s);
		}

		private int compareTo(String s1, String s2) {
			try {
				int i1 = Integer.parseInt(s1);
				int i2 = Integer.parseInt(s2);
				if (i1 == i2)
					return 0;
				if (i1 > i2)
					return 1;
				return -1;
			} catch (Exception e) {
				// ignore
			}
			return s1.compareTo(s2);
		}

		public int compareTo(Object object) {
			if (object == this)
				return 0;
			
			Version other = (Version) object;
			int i = 0;
			while (i < segments.length && i < other.segments.length) {
				String s1 = segments[i];
				String s2 = other.segments[i];
				int c = compareTo(s1, s2);
				if (c != 0)
					return c;
				i++;
			}
			
			if (i == segments.length && i == other.segments.length)
				return 0;
			
			if (i == segments.length)
				return -1;
			return 1;
		}
	}

	/**
	 * @see ViewerSorter#compare(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
	 */
	public int compare(Viewer viewer, Object o1, Object o2) {
		if (o1 instanceof AbstractTreeContentProvider.TreeElement)
			o1 = ((AbstractTreeContentProvider.TreeElement) o1).text;
		
		if (o2 instanceof AbstractTreeContentProvider.TreeElement)
			o2 = ((AbstractTreeContentProvider.TreeElement) o2).text;
		
		// filter out strings
		if (o1 instanceof String && o2 instanceof String)
			return compareCategories((String) o1, (String) o2);
		if (o1 instanceof String)
			return -1;
		if (o2 instanceof String)
			return 1;
		
		if (o1 instanceof IRuntimeType && o2 instanceof IRuntimeType)
			return compareRuntimeTypes((IRuntimeType) o1, (IRuntimeType) o2);
		
		if (o1 instanceof IServerType && o2 instanceof IServerType)
			return compareServerTypes((IServerType) o1, (IServerType) o2);
		
		return 0;
	}

	/**
	 * Sort two category names.
	 * 
	 * @param s1 the first category
	 * @param s2 the second category
	 * @return a negative number if the first element is less  than the 
	 *    second element; the value <code>0</code> if the first element is
	 *    equal to the second element; and a positive number if the first
	 *    element is greater than the second element
	 */
	protected static int compareCategories(String s1, String s2) {
		try {
			Version v1 = Version.parseVersion(s1);
			Version v2 = Version.parseVersion(s2);
			
			return v1.compareTo(v2);
		} catch (NumberFormatException nfe) {
			// ignore
		}
		
		return s1.compareTo(s2);
	}

	/**
	 * Returns <code>true</code> if the two items are in the same 'family', and
	 * <code>false</code> otherwise.
	 * 
	 * @param s1 - first name
	 * @param v1 - first version
	 * @param s2 - second name
	 * @param v2 - second version
	 * @return <code>true</code> if the two items are in the same 'family', and
	 *    <code>false</code> otherwise
	 */
	protected static boolean isSameFamily(String s1, String v1, String s2, String v2) {
		if (s1 == null || s2 == null)
			return false;
		
		if (v1 != null) {
			int ind = s1.indexOf(v1);
			if (ind >= 0)
				s1 = s1.substring(0, ind) + s1.substring(ind+v1.length());
		}
		
		if (v2 != null) {
			int ind = s2.indexOf(v2);
			if (ind >= 0)
				s2 = s2.substring(0, ind) + s2.substring(ind+v2.length());
		}
		return (s1.equals(s2));
	}

	protected static int compareVersions(String s1, String s2) {
		Version v1 = Version.parseVersion(s1);
		Version v2 = Version.parseVersion(s2);
		
		return v1.compareTo(v2);
	}

	/**
	 * Sort two runtime types.
	 * 
	 * @param r1 the first runtime type
	 * @param r2 the second runtime type
	 * @return a negative number if the first element is less  than the 
	 *    second element; the value <code>0</code> if the first element is
	 *    equal to the second element; and a positive number if the first
	 *    element is greater than the second element
	 */
	protected static int compareRuntimeTypes(IRuntimeType r1, IRuntimeType r2) {
		if (isSameFamily(r1.getName(), r1.getVersion(), r2.getName(), r2.getVersion()))
			return compareVersions(r1.getVersion(), r2.getVersion());
		
		return r1.getName().compareToIgnoreCase(r2.getName());
	}

	/**
	 * Sort two server types.
	 * 
	 * @param s1 the first server type
	 * @param s2 the second server type
	 * @return a negative number if the first element is less  than the 
	 *    second element; the value <code>0</code> if the first element is
	 *    equal to the second element; and a positive number if the first
	 *    element is greater than the second element
	 */
	protected static int compareServerTypes(IServerType s1, IServerType s2) {
		IRuntimeType r1 = s1.getRuntimeType();
		IRuntimeType r2 = s2.getRuntimeType();
		if (r1 != null && r2 != null) {
			if (isSameFamily(s1.getName(), r1.getVersion(), s2.getName(), r2.getVersion()))
				return compareVersions(r1.getVersion(), r2.getVersion());
		}
		
		return s1.getName().compareToIgnoreCase(s2.getName());
	}
}