#include "SDL_net.h"

#include "reply.h"
#include "misc.h"
#include "globals.h"

#include <string>
#include <sstream>

using namespace std;

void process_server_reply()
{
	istringstream recv_iss(getline());
	long robot_id;
	char c;
	while (recv_iss.peek() == '#')
	{
		recv_iss.get();
		
		recv_iss >> robot_id;
		bot *this_bot;
		if (robot_id == me.id)
			this_bot = &me;
		else
			this_bot = &bots[robot_id];
		
		c = '\0';
		recv_iss >> c;
		switch (c)
		{
		case 'N':
			this_bot->y++;
			d("reply", "n", robot_id);
			break;
		case 'E':
			this_bot->x++;
			d("reply", "e", robot_id);
			break;
		case 'S':
			this_bot->y--;
			d("reply", "s", robot_id);
			break;
		case 'W':
			this_bot->x--;
			d("reply", "w", robot_id);
			break;
		case 'P':
		{
			bool more_to_get = true;
			while (more_to_get)
			{
				package picked;
				recv_iss >> picked.id;
				if (available_packages.find(picked.id) != available_packages.end())
				{
					// move from available to this bot
					picked = available_packages[picked.id];
					this_bot->packages[picked.id] = picked;
					available_packages.erase(picked.id);
					d("reply-pick-known", robot_id, picked.id);
				}
				else
				{
					// insert into this bots list
					this_bot->packages[picked.id] = picked;
					d("reply-pick-new", robot_id, picked.id);
				}
				this_bot->burden += picked.weight;
				
				char c = recv_iss.get();
				if (recv_iss.peek() != 'P')
				{
					recv_iss.putback(c);
					more_to_get = false;
				}
				else
				{
					recv_iss >> c; // the 'P'
				}
			}
			
			break;
		}
		case 'D':
			package dropped;
			if (this_bot->packages.find(dropped.id) != this_bot->packages.end())
			{
				// delete from this bot, add to available
				dropped = this_bot->packages[dropped.id];
				this_bot->packages.erase(dropped.id);
				dropped.x = this_bot->x;
				dropped.y = this_bot->y;
				available_packages[dropped.id] = dropped;
				d("reply- dropped", robot_id, dropped.id);
			}
			else
			{
				dropped.x = this_bot->x;
				dropped.y = this_bot->y;
				available_packages[dropped.id] = dropped;
				d("reply- dropped one never ever known!", robot_id, dropped.id);
			}
			this_bot->burden -= dropped.weight;
			break;
		case 'X':
		{
			if (robot_id == me.id)
				this_bot = &me;
			else
				this_bot = new bot;
			
			// keep tokenizing to get the coordinates
			this_bot->id = robot_id;
			recv_iss >> this_bot->x;
			recv_iss >> c; // this is the 'Y', no need to do anything with it
			recv_iss >> this_bot->y;
			
			// add to list, unless ourself
			if (robot_id != me.id)
				bots[this_bot->id] = *this_bot;
			else
				d("it's me");
			
			// process the initial move direction
			d("reply-appear", this_bot->id, this_bot->x, this_bot->y);
			recv_iss >> c;
			switch (c)
			{
			case 'N':
				this_bot->y++;
				d("reply-appear-move", "n", robot_id);
				break;
			case 'E':
				this_bot->x++;
				d("reply-appear-move", "e", robot_id);
				break;
			case 'S':
				this_bot->y--;
				d("reply-appear-move", "s", robot_id);
				break;
			case 'W':
				this_bot->x--;
				d("reply-appear-move", "w", robot_id);
				break;
			}
			break;
		}
		case '\0':
			// nothing more
			break;
		default:
			d("reply-unprocessable", c);
			break;
		}
	}
	
	// any other messages
	/*
	string s = recv_iss.str();
	cout << "<<" << s << endl;
	if ((s.find("died") != s.npos) && (s.find(me.id)  != s.npos))
		while((s = getline()).size())
			cout << "^^" << s << endl;
	*/
}