/*
 * @author Ranides Atterwim <ranides@gmail.com>
 * @copyright Ranides Atterwim
 * @license WTFPL
 * @url http://ranides.net/projects/assira
 */
package net.ranides.assira.collection.maps;

import java.util.Objects;
import java.util.function.Function;
import net.ranides.assira.generic.HashUtils;
import net.ranides.assira.reflection.IClass;

/**
 *
 * @author msieron
 */
public class GenericKey<K,V> implements Function<GenericHashMap<K>, V> {
    
    private final IClass<V> type;
    private final K key;

    @SuppressWarnings("unchecked")
    public GenericKey(K key) {
        this.type = (IClass<V>)IClass.typeinfo(getClass()).params().get(0);
        this.key = key;
    }
    
    public GenericKey(IClass<V> type, K key) {
        this.type = type;
        this.key = key;
    }
    
    public GenericKey(Class<V> type, K key) {
        this(IClass.typeinfo(type), key);
    }
    
    public IClass<V> type() {
        return type;
    }
    
    public K key() {
        return key;
    }

    @Override
    public V apply(GenericHashMap<K> map) {
        return map.get(this);
    }
    
    public V apply(GenericHashMap<K> map, V ddefault) {
        return map.getOrDefault(this, ddefault);
    }

    @Override
    public int hashCode() {
        return HashUtils.hashPair(type, key);
    }

    @Override
    public boolean equals(Object object) {
        if (this == object) {
            return true;
        }
        if (object == null) {
            return false;
        }
        if (getClass() != object.getClass()) {
            return false;
        }
        final GenericKey<?, ?> that = (GenericKey<?, ?>) object;
        return Objects.equals(this.type, that.type) && Objects.equals(this.key, that.key);
    }
    
    
    
}
