package com.ircclouds.irc.api;

import java.io.*;
import java.util.*;

import org.slf4j.*;

import com.ircclouds.irc.api.comms.*;
import com.ircclouds.irc.api.domain.*;
import com.ircclouds.irc.api.domain.messages.interfaces.*;
import com.ircclouds.irc.api.om.*;

/**
 * 
 * @author miguel
 * 
 */

public abstract class AbstractMessageReader implements IMessageReader, INeedsConnection
{
	private static final Logger LOG = LoggerFactory.getLogger(AbstractMessageReader.class);
	private static final String CRLF = "\r\n";

	private AbstractMessageFactory msgFactory;
	private StringBuilder ircData = new StringBuilder();
	private Queue<String> ircMessages = new LinkedList<String>();
	private boolean canRead = true;
	
	public AbstractMessageReader()
	{
		msgFactory = new AbstractMessageFactory()
		{
			@Override
			protected IRCServerOptions getIRCServerOptions()
			{
				return AbstractMessageReader.this.getIRCServerOptions();
			}
		};
	}

	public boolean available() throws IOException
	{
		if (canRead)
		{
			ircData.append(getConnection().read());				
			canRead = false;
			fetchNextBatch();
		}

		return true;
	}

	public IMessage readMessage()
	{
		IMessage _msg = IMessage.NULL_MESSAGE;
		
		if (ircMessages.peek() != null)
		{
			try 
			{
				_msg =  msgFactory.build(ircMessages.poll());
			}
			catch (IRCOMException aExc)
			{
				LOG.error("Error from the OM layer", aExc);
			}
		}
		
		canRead = ircMessages.isEmpty();
		
		return _msg;
	}

	@Override
	public void reset()
	{
		ircMessages.clear();
		ircData.setLength(0);
		canRead = true;
	}
	
	protected abstract IRCServerOptions getIRCServerOptions();
	
	private void fetchNextBatch()
	{
		if (ircData.indexOf(CRLF) != -1)
		{
			String _tempMsg = ircData.toString();
			if (ircData.lastIndexOf(CRLF) != ircData.length() - CRLF.length() - 1)
			{
				int _i = ircData.lastIndexOf(CRLF);
				_tempMsg = ircData.substring(0, _i);
				ircData = new StringBuilder(ircData.substring(_i + CRLF.length()));
			}
			else
			{
				ircData.setLength(0);
			}

			ircMessages.addAll(Arrays.asList(_tempMsg.split(CRLF)));
		}
	}
}
@@ -508,22 +508,16 @@
  static 
-final 
 String C
@@ -526,14 +526,12 @@
 F = 
-%22%5Cr%5Cn%22
+null
 ;%0D%0A%0D
@@ -1114,16 +1114,42 @@
 false;%0D%0A
+%09%09%09%0D%0A%09%09%09trySetNewLine();%0D%0A
 %09%09%09fetch
@@ -1662,16 +1662,16 @@
 %0A%09%7D%0D%0A%09%0D%0A
-
 %09protect
@@ -1722,16 +1722,241 @@
 ions();%0D
+%0A%0D%0A%09private void trySetNewLine()%0D%0A%09%7B%0D%0A%09%09if (CRLF != null)%0D%0A%09%09%7B%0D%0A%09%09%09return;%0D%0A%09%09%7D%0D%0A%09%09else if (ircData.indexOf(%22%5Cr%5Cn%22) != -1)%0D%0A%09%09%7B%0D%0A%09%09%09CRLF = %22%5Cr%5Cn%22;%0D%0A%09%09%7D%0D%0A%09%09else if (ircData.indexOf(%22%5Cn%22) != -1)%0D%0A%09%09%7B%0D%0A%09%09%09CRLF = %22%5Cn%22;%0D%0A%09%09%7D%0D%0A%09%7D%09%0D
 %0A%09%0D%0A%09pri

Fix for issue 14