/*
ESUP-portail is a french academic project developed under the GPL (General Public License) augmented according to the following :
A binary or source file developped by ESUP-portail can be used or compiled with products under Apache license.
The official english text of the GPL can be found here : http://www.gnu.org/licenses/gpl.html .
A non official french translation can be found here : http://www.linux-France.org/article/these/gpl.html .
The different kinds of licenses governing the products developed by the Apache foundation can be found here : http://www.apache.org/licenses .
It follows that you can as well as use download contents as well modify and redistribute them provided you respect the GPL terms.
Downloading and using such contents do not provide any guaranty.
Be sure that you have well understood the terms of the license before using the contents it covers.
The ESUP-portail distribution includes the following distributions :
    * UPortal :
      software developed by JA-SIG (Java Architecture - Special Interest Group)
      You can find the license page here : http://mis105.udel.edu/ja-sig/uportal/license.html
    * CAS :
      SSO solution developed by Yale University
      You can find the project page here : http://www.yale.edu/tp/auth
    * Cocoon :
      XML framework distributed by the Apache foundation under Apache license;
      Please find the full text here : http://cocoon.apache.org/2.1/license.html
    * Mod_dav:
      A DAV module for Apache web server
      You can find the project page here : http://www.webdav.org/mod_dav
    * IMP :
      webmail from Horde application framework
      You can find the project page here : http://www.horde.org
    * …. To be completed
*/
package org.esupportail.portal.channels.CStockage.provider;

import java.util.TreeSet;

import org.esupportail.portal.channels.CStockage.provider.ChannelResource;

/**
 * Id: SortedChannelResource.java,v 1.0 13 avr. 2005
 * Copyright (c) 2005 Esup Portail (www.esup-portail.org)
 * Classes: SortedChannelResource
 * Original Author: Yohan Colmant
 * This is a channel resource used to sort
 */
public class SortedChannelResource extends ChannelResource implements Comparable {


	public static final String SORT_TYPE = "sort_type";
	public static final String SORT_TYPE_REVERSE = "sort_type_reverse";
	public static final String SORT_NAME = "sort_name";
	public static final String SORT_NAME_REVERSE = "sort_name_reverse";
	public static final String SORT_WEIGHT = "sort_weight";
	public static final String SORT_WEIGHT_REVERSE = "sort_weight_reverse";
	public static final String SORT_DATE = "sort_date";
	public static final String SORT_DATE_REVERSE = "sort_date_reverse";
	
	
	
	/**
	 * The osrt type of the resource
	 */
	private String sortType;
	
	
	
	/**
	 * 
	 * @param resource
	 * @param sortType
	 */
	public SortedChannelResource(ChannelResource resource, String sortType) {
		super(resource.getName(), resource.getDisplayName(), resource.getPath(), resource.getContentLength(), resource.getContentType(), resource.getLastModified(), resource.isCollection(), resource.getUportalRealUri());
		this.setState(resource.getState());
		this.sortType = sortType;
	}
	
	
	
	/**
	 * Compare this to an other object
	 * @param arg0 the object we want to compare to
	 * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
	 */	
	public int compareTo(Object arg0) {
		
		if (this.sortType.equals(SORT_TYPE)) {
			return compareSortType(arg0);
		}
		else {
			if (this.sortType.equals(SORT_TYPE_REVERSE)) {
				return compareSortTypeReverse(arg0);
			}
			else {
				if (this.sortType.equals(SORT_NAME)) {
					return compareSortName(arg0);
				}
				else {
					if (this.sortType.equals(SORT_NAME_REVERSE)) {
						return compareSortNameReverse(arg0);
					}
					else {
						if (this.sortType.equals(SORT_WEIGHT)) {
							return compareSortWeight(arg0);
						}
						else {
							if (this.sortType.equals(SORT_WEIGHT_REVERSE)) {
								return compareSortWeightReverse(arg0);
							}
							else {
								if (this.sortType.equals(SORT_DATE)) {
									return compareSortDate(arg0);
								}
								else {
									if (sortType.equals(SORT_DATE_REVERSE)) {
										return compareSortDateReverse(arg0);
									}
									else {
										return -1;
									}
								}
							}
						}
					}
				}
			}
		}
	}

	
	
	/**
	 * Compare this to an other object, for the SORT_TYPE sort
	 * @param arg0 the object we want to compare to
	 * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
	 */	
	public int compareSortType(Object arg0) {
		
		SortedChannelResource res = (SortedChannelResource)arg0;
		
		// if this is directory
		if (this.isCollection()) {
			
			// if other is collection
			if (res.isCollection()) {
				
				if (this.getState()==null || res.getState()==null) {
					return this.getName().compareToIgnoreCase(res.getName());
				}
				else {
					
					// compare the states
					int comp = this.getState().compareToIgnoreCase(res.getState());
					if (comp == 0) {
						return this.getName().compareToIgnoreCase(res.getName());
					}
					else return comp;
					
				}
			}
			
			else {
				return -1;
			}
			
		}
		
		// this is a file
		else {

			// if other is collection
			if (res.isCollection()) {
				return 1;
			}
			
			else {
				return this.getName().compareToIgnoreCase(res.getName());
			}
			
		}
		
	}
	
	/**
	 * Compare this to an other object, for the SORT_TYPE_REVERSE sort
	 * @param arg0 the object we want to compare to
	 * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
	 */	
	public int compareSortTypeReverse(Object arg0) {
		
		SortedChannelResource res = (SortedChannelResource)arg0;

		// if this is directory
		if (this.isCollection()) {
			
			// if other is collection
			if (res.isCollection()) {

				if (this.getState()==null || res.getState()==null) {
					return -this.getName().compareToIgnoreCase(res.getName());
				}
				else {
					
					// compare the states
					int comp = this.getState().compareToIgnoreCase(res.getState());
					if (comp == 0) {
						return this.getName().compareToIgnoreCase(res.getName());
					}
					else return -comp;
					
				}
			}
			
			else {
				return 1;
			}
			
		}
		
		// this is a file
		else {

			// if other is collection
			if (res.isCollection()) {
				return -1;
			}
			
			else {
				return this.getName().compareToIgnoreCase(res.getName());
			}
			
		}
		
	}
	
	/**
	 * Compare this to an other object, for the SORT_NAME sort
	 * @param arg0 the object we want to compare to
	 * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
	 */	
	public int compareSortName(Object arg0) {
		
		SortedChannelResource res = (SortedChannelResource)arg0;
		return this.getName().compareToIgnoreCase(res.getName());
		
	}
	
	/**
	 * Compare this to an other object, for the SORT_NAME_REVERSE sort
	 * @param arg0 the object we want to compare to
	 * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
	 */	
	public int compareSortNameReverse(Object arg0) {
		
		SortedChannelResource res = (SortedChannelResource)arg0;
		return -this.getName().compareToIgnoreCase(res.getName());
		
	}
	
	/**
	 * Compare this to an other object, for the SORT_WEIGHT sort
	 * @param arg0 the object we want to compare to
	 * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
	 */	
	public int compareSortWeight(Object arg0) {
		
		SortedChannelResource res = (SortedChannelResource)arg0;

		// if this is directory
		if (this.isCollection()) {
			
			// if other is collection
			if (res.isCollection()) {
				return this.getName().compareToIgnoreCase(res.getName());
			}
			
			else {
				return -1;
			}
			
		}
		
		// this is a file
		else {

			// if other is collection
			if (res.isCollection()) {
				return 1;
			}
			
			else {
				
				if (this.getContentLength() > res.getContentLength()) {
					return 1;
				}
				else {
					return -1;
				}
				
			}
			
		}
	}
	
	/**
	 * Compare this to an other object, for the SORT_WEIGHT_REVERSE sort
	 * @param arg0 the object we want to compare to
	 * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
	 */	
	public int compareSortWeightReverse(Object arg0) {

		SortedChannelResource res = (SortedChannelResource)arg0;

		// if this is directory
		if (this.isCollection()) {
			
			// if other is collection
			if (res.isCollection()) {
				return this.getName().compareToIgnoreCase(res.getName());
			}
			
			else {
				return 1;
			}
			
		}
		
		// this is a file
		else {

			// if other is collection
			if (res.isCollection()) {
				return -1;
			}
			
			else {
				
				if (this.getContentLength() <= res.getContentLength()) {
					return 1;
				}
				else {
					return -1;
				}
				
			}
			
		}
	}
	
	/**
	 * Compare this to an other object, for the SORT_DATE sort
	 * @param arg0 the object we want to compare to
	 * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
	 */	
	public int compareSortDate(Object arg0) {

		SortedChannelResource res = (SortedChannelResource)arg0;
		if (this.getLastModified() > res.getLastModified()) {
			return 1;
		}
		else {
			return -1;
		}
		
	}
	
	/**
	 * Compare this to an other object, for the SORT_DATE_REVERSE sort
	 * @param arg0 the object we want to compare to
	 * @return a negative integer, zero, or a positive integer as this object is less than, equal to, or greater than the specified object.
	 */	
	public int compareSortDateReverse(Object arg0) {
		
		SortedChannelResource res = (SortedChannelResource)arg0;
		if (this.getLastModified() <= res.getLastModified()) {
			return 1;
		}
		else {
			return -1;
		}
		
	}
	
	
	
	
	/**
	 * Sort the resources to a tree set
	 * @param resources the resources list in an array
	 * @param sortType the type of sort
	 * @return the tree set containing all the resources
	 */
	public static TreeSet sortResources(ChannelResource[] resources, String sortType) {
		
		// we transform ChannelResource to SortedChannelResource
		SortedChannelResource[] res = new SortedChannelResource[resources.length];
		for (int i=0; i<resources.length; i++) {
			ChannelResource r = resources[i];
			if (r!=null)
				res[i] = new SortedChannelResource(r, sortType);
			else res[i] = null;
		}
		
		// the object used to sort
		TreeSet sortedResources = new TreeSet();
		
		// we add each element into the treeset
		for (int i=0; i<res.length; i++) {
			SortedChannelResource r = res[i];
			if (r!=null)
				sortedResources.add(r);
		}
		
		// return the result
		return sortedResources;
	}
	
	
}
