package com.ramblingwood.minecraft.jsonapi.api;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;

public abstract class JSONAPIStream {
	protected List<JSONAPIStreamListener> listeners = Collections.synchronizedList(new ArrayList<JSONAPIStreamListener>());
	protected LinkedBlockingQueue<JSONAPIStreamMessage> messages = new LinkedBlockingQueue<JSONAPIStreamMessage>();
	protected List<JSONAPIStreamMessage> last50 = Collections.synchronizedList(new ArrayList<JSONAPIStreamMessage>(50));
	
	public void registerListener(JSONAPIStreamListener l, boolean feedOld) {
		if(feedOld) {
			for(JSONAPIStreamMessage m : last50) {
				l.onMessage(m, this);
			}
		}
		
		listeners.add(l);
	}
	
	public List<JSONAPIStreamMessage> getStack() {
		return last50;
	}
	
	public void deregisterListener(JSONAPIStreamListener l) {
		listeners.remove(l);
	}
	
	public void addMessage(JSONAPIStreamMessage m) {
		pushMessage(m);
	}
	
	public void pushMessage(JSONAPIStreamMessage m) {		
		try {
			messages.put(m);
		} catch (InterruptedException e) {
			
		}
		finally {
			last50.add(m);
			
			if(last50.size() > 50) {
				last50.remove(0);
			}			
		}
		
		ArrayList<JSONAPIStreamMessage> stack = new ArrayList<JSONAPIStreamMessage>();
		messages.drainTo(stack);
		
		synchronized (listeners) {
			for(JSONAPIStreamListener l : listeners) {
				for(JSONAPIStreamMessage mm : stack) {
					l.onMessage(mm, this);
				}			
			}
		}
	}
}

@@ -180,16 +180,70 @@
 eue;%0D%0A%0D%0A
+import com.ramblingwood.minecraft.jsonapi.JSONAPI;%0D%0A%0D%0A
 public a
@@ -1095,32 +1095,38 @@
 oid pushMessage(
+final 
 JSONAPIStreamMes
@@ -1138,103 +1138,213 @@
 m) %7B
-%09%09
 %0D%0A%09%09
-try %7B%0D%0A%09%09%09messages.put(m);%0D%0A%09%09%7D catch (InterruptedException e) %7B%0D%0A%09%09%09%0D%0A%09%09%7D%0D%0A%09%09finally %7B%0D%0A
+final JSONAPIStream that = this;%0D%0A%09%09JSONAPI.instance.getServer().getScheduler().scheduleSyncDelayedTask(JSONAPI.instance, new Runnable() %7B%0D%0A%09%09%09public void run () %7B%0D%0A%09%09%09%09try %7B%0D%0A%09%09%09%09%09messages.put(m);%0D%0A%09%09
 %09%09%09l
@@ -1361,18 +1361,22 @@
 m);%0D%0A%09%09%09
-%0D%0A
+%09%09%0D%0A%09%09
 %09%09%09if(la
@@ -1396,24 +1396,26 @@
  50) %7B%0D%0A%09%09%09%09
+%09
+%09
 last50.remov
@@ -1428,23 +1428,130 @@
 %0A%09%09%09
-%7D%09%09%09%0D%0A%09%09%7D%0D%0A%09%09%0D%0A
+%09%09%7D%0D%0A%09%09%09%09%7D catch (InterruptedException e) %7B%0D%0A%09%09%09%09%09// TODO Auto-generated catch block%0D%0A%09%09%09%09%09e.printStackTrace();%0D%0A%09%09%09%09%7D%0D%0A%09%09
 %09%09Ar
@@ -1628,16 +1628,18 @@
 ge%3E();%0D%0A
+%09%09
 %09%09messag
@@ -1660,18 +1660,22 @@
 ck);%0D%0A%09%09
-%0D%0A
+%09%09%0D%0A%09%09
 %09%09synchr
@@ -1691,32 +1691,34 @@
 isteners) %7B%0D%0A%09%09%09
+%09%09
 for(JSONAPIStrea
@@ -1745,24 +1745,26 @@
 ers) %7B%0D%0A%09%09%09%09
+%09%09
 for(JSONAPIS
@@ -1792,24 +1792,26 @@
 ck) %7B%0D%0A%09%09%09%09%09
+%09
+%09
 l.onMessage(
@@ -1820,18 +1820,18 @@
 , th
-is
+at
 );%0D%0A%09%09%09%09
 %7D%09%09%09
@@ -1830,23 +1830,42 @@
 %09%09%09%09
+%09
+%09
 %7D%09%09%09%0D%0A
+%09%09%09%09%09%7D%0D%0A%09%09%09%09%7D%0D%0A
 %09%09%09%7D%0D%0A
-
 %09%09%7D
+);
 %0D%0A%09%7D

move message queue to main thread via the scheduler to close #81. thanks Xon!