package be.msyben.vinylManager.tools;

import java.lang.reflect.InvocationTargetException;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import org.apache.commons.beanutils.PropertyUtils;

/**
 * Classe permettant d'effectuer les différents tris.
 * @author Mathieu Syben
 */
public class Sort {

    public static void sort(List<? extends Comparable> l) {
        sort(l, false);
    }

    public static void sort(List<? extends Comparable> l, boolean inverse) {
        Collections.sort(l);
        if (inverse) {
            Collections.reverse(l);
        }
    }

    public static void sort(List l, final String... comparers) {
        
        sort(l, false, comparers);
    }
    
    

    public static void sort(List<? extends Comparable> l, boolean inverse, final boolean ignoreCase, final String... comparers) {
        Comparator c = new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {

                try {
                    for (int i = 0; i < comparers.length; i++) {
                        Comparable comp1 = (Comparable) PropertyUtils.getProperty(o1, comparers[i]);
                        Comparable comp2 = (Comparable) PropertyUtils.getProperty(o2, comparers[i]);
                        
                        if (ignoreCase &&comp1 instanceof String && comp2 instanceof String){
                            comp1 = ((String)comp1).toLowerCase();
                            comp2 = ((String)comp2).toLowerCase();
                        }
                        
                        int comp;
                        if (comp1 == null) {
                            if (comp2 == null) {
                                comp = 0;
                            } else {
                                comp = -1;
                            }
                        } else {
                            if (comp2 == null) {
                                comp = 1;
                            } else {
                                comp = comp1.compareTo(comp2);
                            }
                        }
                        if (comp != 0) {
                            return comp;
                        }
                    }
                } catch (IllegalAccessException ex) {
                    return 0;
                } catch (InvocationTargetException ex) {
                    return 0;
                } catch (NoSuchMethodException ex) {
                    return 0;
                } catch (ClassCastException ex) {
                    return 0;
                }
                return 0;
            }
        };

        Collections.sort(l, c);
        if (inverse) {
            Collections.reverse(l);
        }
    }

    public static void sort(List l, boolean inverse, final String... comparers) {
        Comparator c = new Comparator() {
            @Override
            public int compare(Object o1, Object o2) {

                try {
                    for (int i = 0; i < comparers.length; i++) {
                        Comparable comp1 = (Comparable) PropertyUtils.getProperty(o1, comparers[i]);
                        Comparable comp2 = (Comparable) PropertyUtils.getProperty(o2, comparers[i]);
                        int comp;
                        if (comp1 == null) {
                            if (comp2 == null) {
                                comp = 0;
                            } else {
                                comp = -1;
                            }
                        } else {
                            if (comp2 == null) {
                                comp = 1;
                            } else {
                                comp = comp1.compareTo(comp2);
                            }
                        }
                        if (comp != 0) {
                            return comp;
                        }
                    }
                } catch (IllegalAccessException ex) {
                    return 0;
                } catch (InvocationTargetException ex) {
                    return 0;
                } catch (NoSuchMethodException ex) {
                    return 0;
                } catch (ClassCastException ex) {
                    return 0;
                }
                return 0;
            }
        };

        Collections.sort(l, c);
        if (inverse) {
            Collections.reverse(l);
        }
    }
}
