package org.opengroupware.jope.eocontrol;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import org.opengroupware.jope.foundation.NSObject;

/*
 * EOSortOrdering
 * 
 * TODO: document
 * 
 * Note: Be careful with using EOCompareCaseInsensitiveXYZ against SQL
 *       databases! Most databases can't use an index for a query if the
 *       WHERE contains UPPER(lastname) like stuff.
 *       Instead you might want to use an EOAttribute 'writeformat' to
 *       convert values to upper or lowercase on writes.
 */
public class EOSortOrdering extends NSObject {

  public static final Object EOCompareAscending  = "EOCompareAscending"; 
  public static final Object EOCompareDescending = "EOCompareDescending"; 
  public static final Object EOCompareCaseInsensitiveAscending  = 
    "EOCompareCaseInsensitiveAscending"; 
  public static final Object EOCompareCaseInsensitiveDescending = 
    "EOCompareCaseInsensitiveDescending"; 
  
  protected String key      = null;
  protected Object selector = null; /* maybe we want to use other objects */
  
  public EOSortOrdering(String _key, Object _sel) {
    this.key      = _key;
    this.selector = _sel;
  }
  
  /* accessors */
  
  public String key() {
    return this.key;
  }
  
  public Object selector() {
    return this.selector;
  }
  
  /* sorting */
  
  @SuppressWarnings("unchecked")
  public static void sort(List _list, EOSortOrdering[] _sos) {
    if (_list == null)
      return;
    if (_sos == null || _sos.length == 0) /* nothing to sort */
      return;
    
    Collections.sort(_list, new EOSortOrderingComparator(_sos));
  }
  
  public static List sortedList(List _list, EOSortOrdering[] _sos) {
    if (_list == null)
      return null;
    if (_sos == null || _sos.length == 0)
      return _list;
    
    ArrayList<Object> result = new ArrayList<Object>(_list.size());
    sort(result, _sos);
    return result;
  }
  
  /* description */
  
  public void appendAttributesToDescription(StringBuffer _d) {
    super.appendAttributesToDescription(_d);
    _d.append(" key=" + this.key);
    _d.append(" sel=" + this.selector);
  }
}
