package jp.sourceforge.glad.collection;

import java.util.Collection;
import java.util.Collections;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;

import jp.sourceforge.glad.collection.closure.Closure;
import jp.sourceforge.glad.collection.iteration.MapIterationHandler;
import jp.sourceforge.glad.collection.predicate.Predicate;

public class MapAdapter<K, V> implements Iterable<Map.Entry<K, V>> {

    final Map<K, V> map;

    public MapAdapter() {
        this(new LinkedHashMap<K, V>());
    }

    public MapAdapter(Map<K, V> map) {
        this.map = map;
    }

    public Map<K, V> map() {
        return map;
    }

    public int size() {
        return map().size();
    }

    public boolean isEmpty() {
        return map().isEmpty();
    }

    public boolean containsKey(Object key) {
        return map().containsKey(key);
    }

    public boolean containsValue(Object value) {
        return map().containsValue(value);
    }

    public V get(Object key) {
        return map().get(key);
    }

    public MapAdapter<K, V> put(K key, V value) {
        map().put(key, value);
        return this;
    }

    public MapAdapter<K, V> putAll(Map<? extends K, ? extends V> t) {
        map().putAll(t);
        return this;
    }

    public MapAdapter<K, V> remove(Object key) {
        map().remove(key);
        return this;
    }

    public MapAdapter<K, V> clear() {
        map().clear();
        return this;
    }

    public Map<K, V> unmodifiableMap() {
        return Collections.unmodifiableMap(map());
    }

    public Map<K, V> synchronizedMap() {
        return Collections.synchronizedMap(map());
    }

    public Map<K, V> checkedMap(Class<K> keyType, Class<V> valueType) {
        return Collections.checkedMap(map(), keyType, valueType);
    }

    public Set<K> keySet() {
        return map().keySet();
    }

    public Collection<V> values() {
        return map().values();
    }

    public Set<Map.Entry<K, V>> entrySet() {
        return map().entrySet();
    }

    public Iterator<Entry<K, V>> iterator() {
        return entrySet().iterator();
    }

    public Enumeration<Entry<K, V>> enumeration() {
        return Collections.enumeration(entrySet());
    }

    public void iterate(Closure<Entry<K, V>> callback) {
        new MapIterationHandler<K, V>(map()).iterate(callback);
    }

    public void iterate(Predicate<Entry<K, V>> callback) {
        new MapIterationHandler<K, V>(map()).iterate(callback);
    }

    public String toString() {
        return map().toString();
    }

}
