/*
 * $Id: ArrayUtils.java,v 1.5 2007/08/08 12:14:50 marbobo Exp $
 *
 * Copyright (c) Siemens AG 2008 
 *           (c) Universität Paderborn 2008 
 * Licensed under EUPL 1.1. 
 *
 * $Log: ArrayUtils.java,v $
 * Revision 1.5  2007/08/08 12:14:50  marbobo
 * + License-Funktionalität komplett umgeschrieben
 * + Bugfix bzgl. Beschreibungsfelder von Entitäten
 * + Bugfix mailing
 *
 * Revision 1.4  2006/03/23 11:44:30  marbobo
 * + Mögliche NPE abgefangen
 *
 * Revision 1.3  2004/08/20 12:56:06  koppy
 * toIntegerSet
 *
 * Revision 1.2  2004/07/20 08:46:27  jonyp
 * added copyright info + cvs log
 *
 *
 */

package vkc.util;

import java.lang.reflect.Array;
import java.util.HashSet;
import java.util.Set;

public class ArrayUtils {
    private ArrayUtils() {
    }

	public static Integer[] removeElement(Integer[] array, Integer element) {
		return (Integer[])removeElem(array, element);
	}

	public static Integer[] removeElement(Integer[] array, int element) {
		return (Integer[])removeElem(array, new Integer(element));
	}

	public static Integer[] addElement(Integer[] array, Integer element) {
		return (Integer[])addElem(array, element);
	}

	public static Integer[] addElement(Integer[] array, int element) {
		return (Integer[])addElem(array, new Integer(element));
	}

	public static Integer[] addElementUnique(Integer[] array, Integer element) {
		return (Integer[])addElemUnique(array, element);
	}
	
	public static Integer[] addElementUnique(Integer[] array, int element) {
		return (Integer[])addElemUnique(array, new Integer(element));
	}

    public static Long[] removeElement(Long[] array, Long element) {
        return (Long[])removeElem(array, element);
    }

    public static Long[] removeElement(Long[] array, long element) {
        return (Long[])removeElem(array, new Long(element));
    }

    public static Long[] addElement(Long[] array, Long element) {
        return (Long[])addElem(array, element);
    }

    public static Long[] addElement(Long[] array, long element) {
        return (Long[])addElem(array, new Long(element));
    }

    public static Long[] addElementUnique(Long[] array, Long element) {
        return (Long[])addElemUnique(array, element);
    }
    
    public static Long[] addElementUnique(Long[] array, long element) {
        return (Long[])addElemUnique(array, new Long(element));
    }

	/**
	 * Adds an element to the end of an array.
	 * Although the return type is an Object,
	 * you can cast it to an array of the same type as ar.
	 *
	 * @param ar The array to add an element to.
	 * @param elem The element to add to the end of the array.
	 * @return A new array with the same elements as ar, with elem at the end.
	 */
	private static Object addElem(Object ar, Object elem) {
		int arl = Array.getLength(ar);
		Object newar = Array.newInstance(ar.getClass().getComponentType(), arl+1);
		System.arraycopy(ar, 0, newar, 0, arl);
		Array.set(newar, arl, elem);
		
		return newar;
	}

	/**
	 * Adds an element to the end of an array, if and only if
	 * the element is not already in the array. Comparison is done
	 * using the == operator, NOT the Object.equals method.
	 * Although the return type is an Object,
	 * you can cast it to an array of the same type as ar.
	 *
	 * @param ar The array to add an element to.
	 * @param elem The element to add to the end of the array.
	 * @return A new array with the same elements as ar, with elem at the end.
	 */
	private static Object addElemUnique(Object ar, Object elem) {
		if (findElement(ar, elem) == -1) {
			return addElem(ar, elem);
		}
		
		return ar;
	}	

    /**
     * Removes the element at given position, and moves all elements above that 1 position down.
     * Although the return type is an Object[],
     * you can cast it to an array of the same type as ar.
     *
     * @param ar The array to remove the element from.
     * @param pos The position of the element to remove.
     * @return A new array containing all elements of ar, except the element at position pos.
     */
    private static Object removeElem(Object ar, int pos) {
        int    arl = Array.getLength(ar);
        Object newar = Array.newInstance(ar.getClass().getComponentType(), arl - 1);
        System.arraycopy(ar, 0, newar, 0, pos);

        if (pos != arl - 1) {
            System.arraycopy(ar, pos + 1, newar, pos, arl - pos - 1);
        }

        return newar;
    }

    /**
     * Removes an element from an array. Not an equals method is used,
     * but a direct == comparison. This method will thus only remove the exact same
     * element from the array.
     * Although the return type is an Object[],
     * you can cast it to an array of the same type as ar.
     *
     * @param ar The array to remove the element from.
     * @param elem The element to remove.
     * @return A new array containing all elements of ar, except elem.
     */
    public static Object removeElem(Object ar, Object elem) {
        int index = findElement(ar, elem);

        if (index == -1) {
            return ar;
        }

        return removeElem(ar, index);
    }

    /**
     * Checks if an element is part of an array, using the == operator.
     *
     * @param ar The array to search.
     * @param elem The element to search for.
     * @return The index of the element in the array. If the element is not in the array, returns -1.
     */
    public static int findElement(Object ar, Object elem) {
        int arl = Array.getLength(ar);

        for (int i = 0; i < arl; i++) {
        	Object obj = Array.get(ar, i);
        	
        	if (obj == null) {
        		if (obj == elem) {
        			return i;
        		}
        	} else {
				if (obj.equals(elem)) {
					return i;
				}
        	}
        }

        return -1;
    }
    
	/**
	 * Converts an array of number Strings into a Set of Integer objects
	 * <p>
	 * @param ids - array of number strings
	 * @return Set of Integer objects
	 * @throws NumberFormatException if any of the number strings is not 
	 * parsable as a Integer
	 */
	public static final Set toIntegerSet(String[] ids) throws NumberFormatException {
		if (ids == null) {
			return new HashSet();
		}

		Set idsSet = new HashSet();
		int length = ids.length;
	
		for (int i = 0; i < length; i++) {
			idsSet.add(new Integer(ids[i]));
		}
		
		return idsSet;
	}
	
	/**
	 * Converts an array of number Strings into a Set of Integer objects
	 * <p>
	 * @param ids - array of number strings
	 * @return Set of Integer objects
	 * @throws NumberFormatException if any of the number strings is not 
	 * parsable as a Integer
	 */
	public static final Set toIntegerSet(Integer[] ids) throws NumberFormatException {
		if (ids == null) {
			return new HashSet();
		}
		
		Set idsSet = new HashSet();
		int length = ids.length;
		
		for (int i = 0; i < length; i++) {
			idsSet.add(ids[i]);
		}
		
		return idsSet;
	}
}