package cz.cuni.amis.utils.collections;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

/**
 * Translates one observable collection into another
 * @author ik
 */
public abstract class TranslatedObservableCollection<T, U> extends ObservableList<T> {

    /**
     * Holds mapping between original objects and the translated one.
     */
    Map<Object, T> map = new HashMap<Object, T>();

    public TranslatedObservableCollection(ObservableCollection<U> col) {
        super(new ArrayList<T>());

        // listen for changes
        col.addCollectionListener(new ElementListener<U>() {

            @Override
            public void elementChanged(U elem, boolean added) {
                if (added) {
                    T val = translate(elem);
                    if (val != null) {
                        add(val);
                    }
                } else {
                    // remove element
                    T val = map.remove(elem);
                    remove(val);
                }
            }
        });

        // import existing items
        for (U val : col) {
            T v = translate(val);
            if (v != null) {
                add(v);
            }
        }

    }

    /**
     * Translates object from wrapped collection into this collection.
     * @param obj object to be translated
     * @return the translated object, null if the object shouldn't be added to the collection
     */
    protected abstract T translate(U obj);
}
