/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

package twomap;

import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 *
 * @author martin
 */
public class TwoMap<A,B> {
    private Map<A,Set<B>> first;
    private Map<B,Set<A>> second;

    public TwoMap() {
        first=new HashMap<>();
        second=new HashMap<>();
    }
    
    public void link(A a, B b){
        Set<B> aa;
        if (!first.containsKey(a)){
            aa = new HashSet<>();
            first.put(a,aa);
        }
        else
            aa = first.get(a);
        aa.add(b);
        
        Set<A> bb;
        if (!second.containsKey(b)){
            bb = new HashSet<>();
            second.put(b, bb);
        }
        else
            bb = second.get(b);
        bb.add(a);
    }
    
    public void unlink(A a,B b){
        if (first.containsKey(a)){
            for (B bb : first.get(a))
                second.get(bb).remove(a);
            first.remove(a);
        }
        if (second.containsKey(b)){
            for (A aa : second.get(b))
                first.get(aa).remove(b);
            second.remove(b);
        }
    }
    
    public Set<B> neighborA(A a){
        if (first.containsKey(a))
            return Collections.unmodifiableSet(first.get(a));
        return new HashSet<>();
    }
    
    public Set<A> neighborB(B b){
        if (second.containsKey(b))
            return Collections.unmodifiableSet(second.get(b));
        return new HashSet<>();
    }
    
    public void removeA(A a){
        if (first.containsKey(a)){
            for (B b:first.get(a))
                second.get(b).remove(a);
            first.remove(a);
        }
    }
    
    public void removeB(B b){
        if (second.containsKey(b)){
            for (A a:second.get(b))
                first.get(a).remove(b);
            second.remove(b);
        }
    }
}
