// IMPORT FROM PICCOLOX

package netmatch.piccolox;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.*;

public class PNotificationCenter {
  protected static class CompoundValue extends WeakReference {
    protected int hashCode;
    protected Method method;

    public Method getMethod() {
      return method;
    }

    public int hashCode() {
      return hashCode;
    }

    public boolean equals(Object obj) {
      if(this == obj)
        return true;
      CompoundValue compoundvalue = (CompoundValue) obj;
      if(method == compoundvalue.method || method != null && method.equals(compoundvalue.method)) {
        Object obj1 = get();
        if(obj1 != null && obj1 == compoundvalue.get())
          return true;
      }
      return false;
    }

    public String toString() {
      return "[CompoundValue:" + get() + ":" + getMethod().getName() + "]";
    }

    public CompoundValue(Object obj, Method method1) {
      super(obj);
      hashCode = obj.hashCode();
      method = method1;
    }
  }

  protected static class CompoundKey extends WeakReference {

    private Object name;
    private int hashCode;

    public Object name() {
      return name;
    }

    public int hashCode() {
      return hashCode;
    }

    public boolean equals(Object obj) {
      if(this == obj)
        return true;
      CompoundKey compoundkey = (CompoundKey) obj;
      if(name == compoundkey.name || name != null && name.equals(compoundkey.name)) {
        Object obj1 = get();
        if(obj1 != null && obj1 == compoundkey.get())
          return true;
      }
      return false;
    }

    public String toString() {
      return "[CompoundKey:" + name() + ":" + get() + "]";
    }

    public CompoundKey(Object obj, Object obj1) {
      super(obj1);
      name = obj;
      hashCode = obj.hashCode() + obj1.hashCode();
    }

    public CompoundKey(Object obj, Object obj1, ReferenceQueue referencequeue) {
      super(obj1, referencequeue);
      name = obj;
      hashCode = obj.hashCode() + obj1.hashCode();
    }
  }


  public static final Object NULL_MARKER = new Object();
  protected static PNotificationCenter DEFAULT_CENTER;
  protected HashMap listenersMap;
  protected ReferenceQueue keyQueue;

  public static PNotificationCenter defaultCenter() {
    if(DEFAULT_CENTER == null)
      DEFAULT_CENTER = new PNotificationCenter();
    return DEFAULT_CENTER;
  }

  private PNotificationCenter() {
    listenersMap = new HashMap();
    keyQueue = new ReferenceQueue();
  }

  public void addListener(Object obj, String s, String s1, Object obj1) {
    processKeyQueue();
    Object obj2 = s1;
    Method method;
    try {
      method = obj.getClass().getMethod(s, new Class[]{
          PNotification.class
      });
    }
    catch(NoSuchMethodException nosuchmethodexception) {
      nosuchmethodexception.printStackTrace();
      return;
    }
    if(obj2 == null)
      obj2 = NULL_MARKER;
    if(obj1 == null)
      obj1 = NULL_MARKER;
    CompoundKey compoundkey = new CompoundKey(obj2, obj1);
    CompoundValue compoundvalue = new CompoundValue(obj, method);
    Object obj3 = listenersMap.get(compoundkey);
    if(obj3 == null) {
      obj3 = new ArrayList();
      listenersMap.put(new CompoundKey(obj2, obj1, keyQueue), obj3);
    }
    if(!((List) (obj3)).contains(compoundvalue))
      ((List) (obj3)).add(compoundvalue);
  }

  public void removeListener(Object obj) {
    processKeyQueue();
    for(Iterator iterator = (new LinkedList(listenersMap.keySet())).iterator();iterator.hasNext();removeListener(obj, iterator.next()))
      ;
  }

  public void removeListener(Object obj, String s, Object obj1) {
    processKeyQueue();
    List list = matchingKeys(s, obj1);
    for(Iterator iterator = list.iterator();iterator.hasNext();removeListener(obj, iterator.next()))
      ;
  }

  public void postNotification(String s, Object obj) {
    postNotification(s, obj, null);
  }

  public void postNotification(String s, Object obj, Map map) {
    postNotification(new PNotification(s, obj, map));
  }

  public void postNotification(PNotification pnotification) {
    LinkedList linkedlist = new LinkedList();
    String s = pnotification.getName();
    Object obj = pnotification.getObject();
    if(s != null) {
      if(obj != null) {
        List list = (List) listenersMap.get(new CompoundKey(s, obj));
        if(list != null)
          linkedlist.addAll(list);
        list = (List) listenersMap.get(new CompoundKey(s, NULL_MARKER));
        if(list != null)
          linkedlist.addAll(list);
        list = (List) listenersMap.get(new CompoundKey(NULL_MARKER, obj));
        if(list != null)
          linkedlist.addAll(list);
      }
      else {
        List list1 = (List) listenersMap.get(new CompoundKey(s, NULL_MARKER));
        if(list1 != null)
          linkedlist.addAll(list1);
      }
    }
    else if(obj != null) {
      List list2 = (List) listenersMap.get(new CompoundKey(NULL_MARKER, obj));
      if(list2 != null)
        linkedlist.addAll(list2);
    }
    CompoundKey compoundkey = new CompoundKey(NULL_MARKER, NULL_MARKER);
    List list3 = (List) listenersMap.get(compoundkey);
    if(list3 != null)
      linkedlist.addAll(list3);
    for(Iterator iterator = linkedlist.iterator();iterator.hasNext();) {
      CompoundValue compoundvalue = (CompoundValue) iterator.next();
      if(compoundvalue.get() == null)
        iterator.remove();
      else
        try {
          compoundvalue.getMethod().invoke(compoundvalue.get(), new Object[]{
              pnotification
          });
        }
        catch(IllegalAccessException illegalaccessexception) {
          illegalaccessexception.printStackTrace();
        }
        catch(InvocationTargetException invocationtargetexception) {
          invocationtargetexception.printStackTrace();
        }
    }

  }

  protected List matchingKeys(String s, Object obj) {
    LinkedList linkedlist = new LinkedList();
    Iterator iterator = listenersMap.keySet().iterator();
    do {
      if(!iterator.hasNext())
        break;
      CompoundKey compoundkey = (CompoundKey) iterator.next();
      if((s == null || s == compoundkey.name()) && (obj == null || obj == compoundkey.get()))
        linkedlist.add(compoundkey);
    }
    while(true);
    return linkedlist;
  }

  protected void removeListener(Object obj, Object obj1) {
    if(obj == null) {
      listenersMap.remove(obj1);
      return;
    }
    List list = (List) listenersMap.get(obj1);
    if(list == null)
      return;
    Iterator iterator = list.iterator();
    do {
      if(!iterator.hasNext())
        break;
      Object obj2 = ((CompoundValue) iterator.next()).get();
      if(obj2 == null || obj == obj2)
        iterator.remove();
    }
    while(true);
    if(list.size() == 0)
      listenersMap.remove(obj1);
  }

  protected void processKeyQueue() {
    CompoundKey compoundkey;
    while((compoundkey = (CompoundKey) keyQueue.poll()) != null)
      listenersMap.remove(compoundkey);
  }

}