/*
 * Created on Sep 14, 2004
 *
 * To change the template for this generated file go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */

/**
 * @author tamer
 *
 * To change the template for this generated type comment go to
 * Window&gt;Preferences&gt;Java&gt;Code Generation&gt;Code and Comments
 */



package communication;
import gameObjects.Player;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

import knowledgeAndTechnics.BaseFunctions;
import knowledgeAndTechnics.Intelligence;
import messages.PassMessage;


public class MessageParser {
	private BaseFunctions baseFunctions;
	private int time;
	private Intelligence infoPool;
	private int lastBallPossessionTime = -100;
	
	boolean repeatBroadCast = false;
	//Spieler, der zuletzt erfolgreich gebroadcasted hat
	private int lastBroadcastingPlayer = 0;
	//größter Zeitstempel der bisher erhaltenen Broadcast-Nachrichten 
	private int lastBroadcastingTime = -1;
	
//Pattern see, sense_body, hear
	final private Pattern SEE = Pattern.compile("\\(see ([^ ]*) (.*)\\)");
	final private Pattern SENSE_BODY = Pattern.compile("\\(sense_body ([^ ]*) (.*)\\)");
	final private Pattern HEAR = Pattern.compile("\\(hear ([^ ]*) (.*)\\)");
	final private Pattern SERVER_PARAM = Pattern.compile("\\(server_param (.*)\\)");
	final private Pattern PLAYER_PARAM = Pattern.compile("\\(player_param (.*)\\)");
//Pattern sense_body
//	(sense_body 19 (view_mode high normal) (stamina 4000 1) (speed 0 0) (head_angle 0) (kick 0) (dash 0) (turn 0) (say 0) (turn_neck 0) (catch 0) (move 0) (change_view 0) (arm (movable 0) (expires 0) (target 0 0) (count 0)) (focus (target none) (count 0)) (tackle (expires 0) (count 0)))	
	final private Pattern VIEW_MODE = Pattern.compile("\\(view_mode ([^ ]*) ([^ ]*)\\)");
	final private Pattern STAMINA = Pattern.compile("\\(stamina ([^ ]*) ([^ ]*)\\)");
	final private Pattern SPEED = Pattern.compile("\\(speed ([^ ]*) ([^ ]*)\\)");
	final private Pattern HEAD_ANGLE = Pattern.compile("\\(head_angle ([^ ]*)\\)");
	final private Pattern KICK = Pattern.compile("\\(kick ([^ ]*)\\)");
	final private Pattern DASH = Pattern.compile("\\(dash ([^ ]*)\\)");
	final private Pattern TURN = Pattern.compile("\\(turn ([^ ]*)\\)");
	final private Pattern SAY = Pattern.compile("\\(say ([^ ]*)\\)");
	final private Pattern TURN_NECK = Pattern.compile("\\(turn_neck ([^ ]*)\\)");
	final private Pattern CATCH = Pattern.compile("\\(catch ([^ ]*)\\)");
	final private Pattern MOVE = Pattern.compile("\\(move ([^ ]*)\\)");
	final private Pattern CHANGE_VIEW = Pattern.compile("\\(change_view ([^ ]*)\\)");
	final private Pattern ARM = Pattern.compile( "\\(arm \\(movable ([^ ]*)\\) \\(expires ([^ ]*)\\) \\(target ([^ ]*) ([^ ]*)\\) \\(count ([^ ]*)\\)\\)");
	final private Pattern FOCUS = Pattern.compile("\\(focus \\(target ([^ ]*)\\) \\(count ([^ ]*)\\)\\)");
	final private Pattern TACKLE = Pattern.compile("\\(tackle \\(expires ([^ ]*)\\) \\(count ([^ ]*)\\)\\)");
// Pattern see
//	((f c t) 15.3 11 0 0) ((f r t) 67.4 3)
	final private Pattern FLAG_VISIBLE = Pattern.compile("\\(\\(f ([^)]*)\\) ([^ )]*) ([^ )]*) ([^ )]*) ([^ )]*)\\)");
	final private Pattern FLAG_INVISIBLE = Pattern.compile("\\(\\(f ([^)]*)\\) ([^ )]*) ([^ )]*)\\)");
	final private Pattern GOAL_VISIBLE = Pattern.compile("\\(\\((g [^)]*)\\) ([^ )]*) ([^ )]*) ([^ )]*) ([^ )]*)\\)");
	final private Pattern GOAL_INVISIBLE = Pattern.compile("\\(\\((g [^)]*)\\) ([^ ]*) ([^ ]*)\\)");
//  ((p "verlierer" 1) 20.1 0 0 0 0 0);((p "verlierer") 49.4 0);((p) 66.7 0)
	final private Pattern PLAYER_UNUM = Pattern.compile("\\(\\(p \"([^\"]*)\" ([^ ]*)\\) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*) ([^ ]*)\\)");
	final private Pattern PLAYER_TEAM = Pattern.compile("\\(\\(p \"([^\"]*)\"\\) ([^ ]*) ([^ ]*)\\)");
	final private Pattern PLAYER_INVISIBLE = Pattern.compile("\\(\\(p\\) ([^ ]*) ([^ ]*)\\)");
	final private Pattern PLAYER_TOUCHED = Pattern.compile("\\(\\(P\\) ([^ ]*) ([^ ]*)\\)");
//  ((b) 10 0 0 0); ((b) 60.3 0)
    final private Pattern BALL_VISIBLE = Pattern.compile("\\(\\(b\\) ([^ )]*) ([^ )]*) ([^ )]*) ([^ )]*)\\)");
    final private Pattern BALL_INVISIBLE = Pattern.compile("\\(\\(b\\) ([^ ]*) ([^ ]*)\\)");
    final private Pattern BALL_TOUCHED = Pattern.compile("\\(\\(B\\) ([^ ]*) ([^ ]*)\\)");
//	((l r) 62.8 90)
	final private Pattern LINE = Pattern.compile("\\(\\(l ([^)])\\) ([^ ]*) ([^ ]*)\\)");
// Pattern hear
// (hear 0 referee kick_off_l)
/*
 * TODO: play modes testen. sind aber komplett
 * 
 */
   final private Pattern BEFORE_KICK_OFF = Pattern.compile("referee before_kick_off"); //OK
	final private Pattern PLAY_ON = Pattern.compile("referee play_on");//OK
	final private Pattern TIME_OVER = Pattern.compile("referee time_over");
	final private Pattern KICK_OFF = Pattern.compile("referee kick_off_([^ ]*)"); //OK
	final private Pattern KICK_IN = Pattern.compile("referee kick_in_([^ ]*)");
	final private Pattern FREE_KICK = Pattern.compile("referee free_kick_([^ ]*)"); //OK
	final private Pattern CORNER_KICK = Pattern.compile("referee corner_kick_([^ ]*)");
	final private Pattern GOAL_KICK = Pattern.compile("referee goal_kick_([^ ]*)");
	final private Pattern GOAL = Pattern.compile("referee goal_([^ ])");
	final private Pattern DROP_BALL = Pattern.compile("referee drop_ball"); //OK
	final private Pattern OFFSIDE = Pattern.compile("referee offside_([^ ]*)");
	final private Pattern GOAL_SIDE_N = Pattern.compile("referee goal_([^ ])_([^ ]*)");
	final private Pattern FOUL = Pattern.compile("referee foul_([^ ]*)"); //OK
	final private Pattern GOALIE_CATCH_BALL = Pattern.compile("referee goalie_catch_ball_([^ ]*)");
	final private Pattern TIME_UP_WITHOUT_A_TEAM = Pattern.compile("referee time_up_without_a_team"); //OK
	final private Pattern TIME_UP = Pattern.compile("referee time_up");
	final private Pattern HALF_TIME = Pattern.compile("referee half_time");
	final private Pattern TIME_EXTENDED = Pattern.compile("referee time_extended");

	final private Pattern MESSAGE_SELF = Pattern.compile("self \"(.*)\"");
	final private Pattern MESSAGE_OTHER = Pattern.compile("(-?\\d{1,3}) our (\\d{1,2}) \"(\\d{2})(.*)\"");
//Pattern server_param
// (goal_width 14.02)
	final private Pattern GOAL_WIDTH = Pattern.compile("\\(goal_width ([^)]*)\\)");

	
//Pattern player_param
	//TODO: die beiden müssen noch getestet werden
	final private Pattern KICKABLE_MARGIN_DELTA_MAX = Pattern.compile("\\(kickable_margin_delta_max ([^ ]*)\\)");
	final private Pattern KICKABLE_MARGIN_DELTA_MIN = Pattern.compile("\\(kickable_margin_delta_min ([^ ]*)\\)");
	final private Pattern CATCHABLE_AREA_L = Pattern.compile("\\(catchable_area_l ([^ ]*)\\)");
	final private Pattern CATCHABLE_AREA_W = Pattern.compile("\\(catchable_area_w ([^ ]*)\\)");
//Pattern init	
	final private Pattern INIT = Pattern.compile("\\(init ([^ ]*) ([^ ]*) ([^)]*)\\)");
	final private Pattern ERROR_NO_MORE_TEAM_OR_PLAYER_OR_GOALIE = Pattern.compile("\\(error no_more_team_or_player_or_goalie\\)");
	final private Pattern RECONNECT = Pattern.compile("\\(init ([^ ]*) ([^)]*)\\)");
	final private Pattern ERROR_NO_MORE_TEAM_OR_PLAYER = Pattern.compile("\\(error no_more_team_or_player_or_goalie\\)");
	final private Pattern ERROR_RECONNECT = Pattern.compile("\\(error reconnect\\)");
	

	

//******************************
//* Constructors
//******************************

	public MessageParser(Intelligence infoPool, BaseFunctions sender){
		this.infoPool = infoPool;
		this.baseFunctions = sender;
	}

//************************
//* Methoden zum Parsen
//************************
	
	//Methode zum Erkennen der richtigen Nachricht	
	public void parse(String message){

			Matcher m = SEE.matcher(message);
			if (m.lookingAt()) {
				infoPool.newSee();
				parseSee(Integer.parseInt(m.group(1)), m.group(2));
				return;				
			}
		    m =SENSE_BODY.matcher(message);
			if (m.lookingAt()) {
				parseSenseBody(Integer.parseInt(m.group(1)), m.group(2));
				return;				
			}
			m = HEAR.matcher(message);
			if (m.lookingAt()) {
				infoPool.newHear();
				parseHear(Integer.parseInt(m.group(1)), m.group(2));
				return;				
			}
			m = SERVER_PARAM.matcher(message);
			if (m.lookingAt()) {
				parseServerParam(m.group(1));
				return;
			}
			m = PLAYER_PARAM.matcher(message);
			if (m.lookingAt()) {
				parsePlayerParam(m.group(1));
				return;
			}
			m = INIT.matcher(message);
				if (m.lookingAt()) {
					parseInit(m.group(1),m.group(2),m.group(3));
				return;
			}
			
	//		throw new MessageUnknownException("Die Nachricht \"" + message + "\" konnte nicht erkannt werden");
	}
	
	//Methode zum Parsen von See
	private synchronized void parseSee(int time, String data){ 
		//Kommentar entfernen zum debuggen von parseSee:
		//System.out.println(time + ", " + data);
		
		Matcher m = FLAG_VISIBLE.matcher(data);
		while (m.find())	{
			infoPool.insertSeenFlag(m.group(1), Float.parseFloat(m.group(2)), Float.parseFloat(m.group(3)), Float.parseFloat(m.group(4)), Float.parseFloat(m.group(5)), time);
		}
		m = FLAG_INVISIBLE.matcher(data);
		while (m.find())	{
			infoPool.insertSeenFlag(m.group(1), Float.parseFloat(m.group(2)), Float.parseFloat(m.group(3)), time);
		}	
		
		m = GOAL_VISIBLE.matcher(data);
		while (m.find())	{
			infoPool.insertSeenFlag(m.group(1), Float.parseFloat(m.group(2)), Float.parseFloat(m.group(3)), Float.parseFloat(m.group(4)), Float.parseFloat(m.group(5)), time);
		}
		m = GOAL_INVISIBLE.matcher(data);
		while (m.find())	{
			infoPool.insertSeenFlag(m.group(1), Float.parseFloat(m.group(2)), Float.parseFloat(m.group(3)), time);
		}	
		
		m = BALL_VISIBLE.matcher(data);
		if (m.find())	{
			infoPool.insertSeenBall(Float.parseFloat(m.group(1)), Float.parseFloat(m.group(2)), Float.parseFloat(m.group(3)), Float.parseFloat(m.group(4)), time);
			//System.out.println("Ball gesehen");
		} else {	
			m = BALL_INVISIBLE.matcher(data);
			if (m.find())	{
				infoPool.insertSeenBall(Float.parseFloat(m.group(1)), Float.parseFloat(m.group(2)), time);
				//System.out.println("Ball fast gesehen");
			}else {
			    m = BALL_TOUCHED.matcher(data);
			    if (m.find())	{
			        infoPool.insertSeenBall(Float.parseFloat(m.group(1)), Float.parseFloat(m.group(2)), time);
			    //System.out.println("Ball gefühlt");
			    }
			}
		}
		
		//Informationen aus 3 unterschiedlichgen Distanzen UNUM, TEAM, INVISIBLE	
		m = PLAYER_UNUM.matcher(data);
			while (m.find())	{
				int teamNumber = m.group(1).equals(infoPool.getTeamName())?
												Player.TEAM_WE: Player.TEAM_OPPONENT;
				infoPool.insertUnumPlayer(teamNumber, Integer.parseInt(m.group(2)), Float.parseFloat(m.group(3)), Float.parseFloat(m.group(4)), Float.parseFloat(m.group(5)), Float.parseFloat(m.group(6)), Float.parseFloat(m.group(7)), Float.parseFloat(m.group(8)), time);
			}
		m = PLAYER_TEAM.matcher(data);
			while (m.find())	{
				int teamNumber = m.group(1).equals(infoPool.getTeamName())?
												Player.TEAM_WE: Player.TEAM_OPPONENT;
				infoPool.insertTeamPlayer(teamNumber, Float.parseFloat(m.group(2)), Float.parseFloat(m.group(3)), time);
			}
		m = PLAYER_INVISIBLE.matcher(data);
			while (m.find())	{
				infoPool.insertInvisiblePlayer(Float.parseFloat(m.group(1)), Float.parseFloat(m.group(2)), time);
			}
		m = PLAYER_TOUCHED.matcher(data);
			while (m.find())	{
				infoPool.insertTouchedPlayer(Float.parseFloat(m.group(1)), Float.parseFloat(m.group(2)), time);
			}
			
		m = LINE.matcher(data);
			while (m.find())	{
				infoPool.insertSeenLine(m.group(1), Float.parseFloat(m.group(2)), Float.parseFloat(m.group(3)));
			}
		infoPool.setSeeTime(time);
		if (infoPool.getSeeTime() == infoPool.getSenseBodyTime()) infoPool.calculatePositions();
	}
	
	//Methode zum Parsen von SenseBody
	private synchronized void parseSenseBody(int time, String data){
		infoPool.setSenseBodyTime(time);
		if(
		        (time - lastBallPossessionTime >= 3)
		        && (infoPool.getBallPossession() == Intelligence.BALL_POSSESSION_WE))
		    infoPool.setBallPossession(Intelligence.BALL_POSSESSION_OPPONENT);
		else if ((time - lastBallPossessionTime < 3) 
		        && (infoPool.getBallPossession() == Intelligence.BALL_POSSESSION_OPPONENT))
		    infoPool.setBallPossession(Intelligence.BALL_POSSESSION_WE);
		else if(
		        infoPool.getBallPossession() == Intelligence.BALL_POSSESSION_ME
		        && (time % 2 == 0)){
		    baseFunctions.broadcastBallPosessionWe();
		}
		String viewWidth = null, viewQuality = null;
		double stamina = 0, effort = 0;
		double amountOfSpeed = 0, directionOfSpeed = 0;
		double headDirection = 0;
		int kickCount = 0, dashCount = 0, turnCount = 0, sayCount = 0, 
			turnNeckCount = 0, catchCount = 0, moveCount = 0, changeViewCount = 0,
			armCount = 0, focusCount = 0, tackleCount = 0;
		String armMovable = null, armExpires = null;
		double armTarget_Zahl1 = 0, armTarget_Zahl2 = 0;
		String focusTarget = null;
		String tackleExpires = null;	
	
		Matcher m = VIEW_MODE.matcher(data);
					if (m.find()) {
						viewQuality = m.group(1);
						viewWidth = m.group(2);	
					}
		m = STAMINA.matcher(data);
					if (m.find()) {
						stamina = Double.parseDouble(m.group(1));
						effort = Double.parseDouble(m.group(2));
					}
		m = SPEED.matcher(data);
					if (m.find()) {
						amountOfSpeed = Double.parseDouble(m.group(1));						
						directionOfSpeed = Double.parseDouble(m.group(2));
					}
		m = HEAD_ANGLE.matcher(data);
					if (m.find()) {
						headDirection = Double.parseDouble(m.group(1));
					}
		m = KICK.matcher(data);
					if (m.find()) {
						kickCount = Integer.parseInt(m.group(1));
					}					
		m = DASH.matcher(data);
					if (m.find()) {
						dashCount = Integer.parseInt(m.group(1));
					}
		m = TURN.matcher(data);
					if (m.find()) {
						turnCount = Integer.parseInt(m.group(1));
					}
		m = SAY.matcher(data);
					if (m.find()) {
						sayCount = Integer.parseInt(m.group(1));
					}
		m = TURN_NECK.matcher(data);
					if (m.find()) {
						turnNeckCount = Integer.parseInt(m.group(1));
					}
		m = CATCH.matcher(data);
					if (m.find()) {
						catchCount = Integer.parseInt(m.group(1));
					}
		m = MOVE.matcher(data);
					if (m.find()) {
						moveCount = Integer.parseInt(m.group(1));
					}
		m = CHANGE_VIEW.matcher(data);
					if (m.find()) {
						changeViewCount = Integer.parseInt(m.group(1));
					}
		m = ARM.matcher(data);
					if (m.find()) {
						armMovable = m.group(1);
						armExpires = m.group(2);
						armTarget_Zahl1 = Double.parseDouble(m.group(3));
						armTarget_Zahl2 = Double.parseDouble(m.group(4));
						armCount = Integer.parseInt(m.group(5));	
					}
		m = FOCUS.matcher(data);
					if (m.find()) {
						focusTarget = m.group(1);
						focusCount = Integer.parseInt(m.group(2));
					}
		m = TACKLE.matcher(data);
					if (m.find()) {
						tackleExpires = m.group(1);
						tackleCount = Integer.parseInt(m.group(2));
					}
		infoPool.setSenseBodyData(viewWidth, viewQuality, stamina, effort, 
			amountOfSpeed, directionOfSpeed, headDirection,
			kickCount, dashCount, turnCount, sayCount, turnNeckCount, 
			catchCount, moveCount, changeViewCount, armCount, focusCount, tackleCount,
			armMovable, armExpires, armTarget_Zahl1, armTarget_Zahl2, focusTarget,
			tackleExpires);		
		if (infoPool.getSeeTime() == infoPool.getSenseBodyTime()) infoPool.calculatePositions();
//		System.out.println(time + ", " + data);
	}
	
	//Methode zum Parsen von Hear
	private synchronized void parseHear(int time, String data){
		infoPool.setHearTime(time);
		//zum Debuggen von parseHear Kommentar entfernen:
		//System.out.println(time + ", " + data);

		
		Matcher m = BEFORE_KICK_OFF.matcher(data);
		if (m.find()) {infoPool.setPlayMode(Intelligence.BEFORE_KICK_OFF);}
		
		m = PLAY_ON.matcher(data);
		if (m.find()) {infoPool.setPlayMode(Intelligence.PLAY_ON);}
		
		m = TIME_OVER.matcher(data);
		if (m.find()) {infoPool.setPlayMode(Intelligence.TIME_OVER);}
			
		m = KICK_OFF.matcher(data);
	   	if (m.find()) {
	   		if (((infoPool.getPlayDirection() == Intelligence.PLAY_DIRECTION_RIGHT) && (m.group(1).equals("l"))) || ((infoPool.getPlayDirection() == Intelligence.PLAY_DIRECTION_LEFT) && (m.group(1).equals("r")))){
				infoPool.setPlayMode(Intelligence.KICK_OFF_WE);	
			} else {
				infoPool.setPlayMode(Intelligence.KICK_OFF_OPPONENT);			
			}   
	  	}
					
		m = FREE_KICK.matcher(data);
		if (m.find()) {
			if (((infoPool.getPlayDirection() == Intelligence.PLAY_DIRECTION_RIGHT) && (m.group(1).equals("l"))) || ((infoPool.getPlayDirection() == Intelligence.PLAY_DIRECTION_LEFT) && (m.group(1).equals("r")))){
				infoPool.setPlayMode(Intelligence.FREE_KICK_WE);			
			}else{
				infoPool.setPlayMode(Intelligence.FREE_KICK_OPPONENT);
			}
		}
		
		
		m = KICK_IN.matcher(data);
		if (m.find()) {
			if (((infoPool.getPlayDirection() == Intelligence.PLAY_DIRECTION_RIGHT) && (m.group(1).equals("l"))) || ((infoPool.getPlayDirection() == Intelligence.PLAY_DIRECTION_LEFT) && (m.group(1).equals("r")))){
				infoPool.setPlayMode(Intelligence.KICK_IN_WE);
			} else {
				infoPool.setPlayMode(Intelligence.KICK_IN_OPPONENT);
			}
		}
		
		m = CORNER_KICK.matcher(data);
		if (m.find()) {
			if (((infoPool.getPlayDirection() == Intelligence.PLAY_DIRECTION_RIGHT) && (m.group(1).equals("l"))) || ((infoPool.getPlayDirection() == Intelligence.PLAY_DIRECTION_LEFT) && (m.group(1).equals("r")))){
				infoPool.setPlayMode(Intelligence.CORNER_KICK_WE);			
			}else{
				infoPool.setPlayMode(Intelligence.CORNER_KICK_OPPONENT);
			}
		}
		
		m = GOAL_KICK.matcher(data);
		if (m.find()) {
			if (((infoPool.getPlayDirection() == Intelligence.PLAY_DIRECTION_RIGHT) && (m.group(1).equals("l"))) || ((infoPool.getPlayDirection() == Intelligence.PLAY_DIRECTION_LEFT) && (m.group(1).equals("r")))){
				infoPool.setPlayMode(Intelligence.GOAL_KICK_WE);			
			}else{
				infoPool.setPlayMode(Intelligence.GOAL_KICK_OPPONENT);			
			}			
		}
		
		/*m = GOAL.matcher(data);
		if (m.matches()) {
			if (((infoPool.getPlayDirection() == InformationPool.PLAY_DIRECTION_RIGHT) && (m.group(1).equals("l"))) || ((infoPool.getPlayDirection() == InformationPool.PLAY_DIRECTION_LEFT) && (m.group(1).equals("r")))){
				infoPool.setPlayMode(InformationPool.GOAL_WE);			
			}else{
				infoPool.setPlayMode(InformationPool.GOAL_OPPONENT);			
			}
		}*/
		
		m = DROP_BALL.matcher(data);
		if (m.find()) {
			infoPool.setPlayMode(Intelligence.DROP_BALL);
		}
		
		m = OFFSIDE.matcher(data);
		if (m.find()) {
			if (((infoPool.getPlayDirection() == Intelligence.PLAY_DIRECTION_RIGHT) && (m.group(1).equals("l"))) || ((infoPool.getPlayDirection() == Intelligence.PLAY_DIRECTION_LEFT) && (m.group(1).equals("r")))){
				infoPool.setPlayMode(Intelligence.OFFSIDE_WE);			
			}else{
				infoPool.setPlayMode(Intelligence.OFFSIDE_OPPONENT);			
			}
		}
		
		m = GOAL_SIDE_N.matcher(data);
		if (m.find()) {
			if (((infoPool.getPlayDirection() == Intelligence.PLAY_DIRECTION_RIGHT) && (m.group(1).equals("l"))) || ((infoPool.getPlayDirection() == Intelligence.PLAY_DIRECTION_LEFT) && (m.group(1).equals("r")))){
				infoPool.setBallPossession(Intelligence.BALL_POSSESSION_OPPONENT);
				infoPool.setPlayMode(Intelligence.GOAL_WE_N);
			}else{
				infoPool.setBallPossession(Intelligence.BALL_POSSESSION_OPPONENT);
				infoPool.setPlayMode(Intelligence.GOAL_OPPONENT_N);
			}

		}
		m = FOUL.matcher(data);
		if (m.find()) {
			if (((infoPool.getPlayDirection() == Intelligence.PLAY_DIRECTION_RIGHT) && (m.group(1).equals("l"))) || ((infoPool.getPlayDirection() == Intelligence.PLAY_DIRECTION_LEFT) && (m.group(1).equals("r")))){
				infoPool.setPlayMode(Intelligence.FOUL_WE);			
			}else{
				infoPool.setPlayMode(Intelligence.FOUL_OPPONENT);			
			}
		}
				
		m = GOALIE_CATCH_BALL.matcher(data);
		if (m.find()) {
			if (((infoPool.getPlayDirection() == Intelligence.PLAY_DIRECTION_RIGHT) && (m.group(1).equals("l"))) || ((infoPool.getPlayDirection() == Intelligence.PLAY_DIRECTION_LEFT) && (m.group(1).equals("r")))){
				infoPool.setPlayMode(Intelligence.GOALIE_CATCH_BALL_WE);
			}else{
				infoPool.setPlayMode(Intelligence.GOALIE_CATCH_BALL_OPPONENT);
			}
		}
				
		m = GOALIE_CATCH_BALL.matcher(data);
		if (m.find()) {
			if (((infoPool.getPlayDirection() == Intelligence.PLAY_DIRECTION_RIGHT) && (m.group(1).equals("l"))) || ((infoPool.getPlayDirection() == Intelligence.PLAY_DIRECTION_LEFT) && (m.group(1).equals("r")))){
				infoPool.setPlayMode(Intelligence.GOALIE_CATCH_BALL_WE);			
			}else{
				infoPool.setPlayMode(Intelligence.GOALIE_CATCH_BALL_OPPONENT);
			}
		}
		
		m = TIME_UP_WITHOUT_A_TEAM.matcher(data);
		if (m.find()) {infoPool.setPlayMode(Intelligence.TIME_UP_WITHOUT_A_TEAM);}
		
		m = TIME_UP.matcher(data);
		if (m.find()) {infoPool.setPlayMode(Intelligence.TIME_UP);}
		
		m = HALF_TIME.matcher(data);
		if (m.find()) {infoPool.setPlayMode(Intelligence.HALF_TIME);}
		
		m = TIME_EXTENDED.matcher(data);
		if (m.find()) {infoPool.setPlayMode(Intelligence.TIME_EXTENDED);}
		
		// gesagte Nachrichten**************************************
		
		m= MESSAGE_SELF.matcher(data);
		if (m.find()) {
		    /*doNothing*/
		}
		
		//"(-?\\d{1,3}) our \\(d{1,2}) \"(\\d{2})(.*)\"")
		m= MESSAGE_OTHER.matcher(data);
		if (m.find()) {					
			try{
			    int receiverUnum = Integer.parseInt(m.group(3));
				if((receiverUnum == infoPool.getUnum()) || (receiverUnum == BaseFunctions.MSG_BROADCAST)){
					String messageData = m.group(4);
					int senderUnum = Integer.parseInt(m.group(2));
					char subject = messageData.charAt(0);
					int directionOfSender = Integer.parseInt(m.group(1));
					int AbsoluteDirectionOfSender = (int) (directionOfSender + infoPool.getHeadDirection());				
					switch (subject){
						case 'c':							
						    infoPool.setPersonToCover(-1);
						    for (int i = 0; i<2; i++){
							    int friend = Integer.parseInt(messageData.substring(1 + i,2 + i), 16);
							    int enemy = Integer.parseInt(messageData.substring(2 + i,3 + i), 16);
							    if (friend == infoPool.getUnum()) {
							        infoPool.setPersonToCover(enemy);
							    }
							}						    
							break;							
						case 'p': 					
							int x = Integer.parseInt(messageData.substring(1, 4));
							int y = Integer.parseInt(messageData.substring(4, 7));
							int passSegment = Integer.parseInt(messageData.substring(7));
							int passDirection = (passSegment - 4)* 45;  
							infoPool.setPassMessage(new PassMessage(infoPool.getHearTime(), senderUnum, receiverUnum, directionOfSender, AbsoluteDirectionOfSender, x, y, passDirection));
							infoPool.setBallPossession(Intelligence.BALL_POSSESSION_ME);
							//infoPool.addMessage(new PassMessage(infoPool.getHearTime(), senderUnum, receiverUnum, directionOfSender, AbsoluteDirectionOfSender, x, y, passDirection)); 						
							break;
									
						case 'w':
							lastBallPossessionTime = time;
							if (
							        (infoPool.getBallPossession() == Intelligence.BALL_POSSESSION_ME)
							        &&(senderUnum > infoPool.getUnum()))
							    infoPool.setBallPossession(Intelligence.BALL_POSSESSION_WE);							   
						    break;						
						default:
						    System.err.println("Nachricht unverstaendlich: " + data);
							
							
					}					
					    
				}
				
			} catch (NumberFormatException e){
				e.printStackTrace();
				System.err.println("MP:Diese Nachricht hat die Exception verursacht: "+ data);
			}
		}
		
		//Zum debuggen der Playmodes
		//System.out.println(" Playmode: "+infoPool.getPlayMode() + "PlayEvent: "+infoPool.getPlayMode());
	}
	
	/**
	 * Aktualisiert die Felder, falls man selber gerade Broadcasted
	 * Muss nicht gecheckt werde, da die eigene Nachricht auf jeden
	 * Fall eine Runde spaeter erstellt wird, als in dieser Runde
	 * erhaltene Nachrichten
	 * @param lastBroadcastingPlayer neuer Wert fuer das Feld lastBroadcastingPlayer
	 * @param lastBroadcastingTime neuer Wert fuer das Feld lastBroadcastingTime
	 */
	void setOwnBroadcastValues(int lastBroadcastingPlayer, int lastBroadcastingTime){
		this.lastBroadcastingTime = lastBroadcastingTime;
		this.lastBroadcastingPlayer = lastBroadcastingPlayer;
	}
	
	//Methode zum Parsen von ServerParam
	private void parseServerParam(String data){
		Matcher m = GOAL_WIDTH.matcher(data);
		if (m.find()) {
			infoPool.setGoalWidth(Float.parseFloat(m.group(1)));
		}
		//System.out.println("Server Parameter: " + data);
		
		m = CATCHABLE_AREA_L.matcher(data);
		if (m.find()){
			infoPool.setCatchableAreaL(Float.parseFloat(m.group(1)));
		}
		m = CATCHABLE_AREA_W.matcher(data);
		if (m.find()){
			infoPool.setCatchableAreaW(Float.parseFloat(m.group(1)));
		}
	}
	
	//Methode zum Parsen von ServerParam
	private void parsePlayerParam(String data){
		
		//System.out.println(data);
		
		/*Matcher m = KICKABLE_MARGIN_DELTA_MAX.matcher(data);
		if (m.find()){
			infoPool.setKickableMarginDeltaMax(Float.parseFloat(m.group(1)));	
		}
		m = KICKABLE_MARGIN_DELTA_MIN.matcher(data);
		if (m.find()){
			infoPool.setKickableMarginDeltaMin(Float.parseFloat(m.group(1)));
		}*/
	}
	
	/**
	 * ?bermittelt die Komponenten der Init-Nachricht an den Information-Pool
	 * */
	private void parseInit(String side, String unum, String playMode){
		if (side.equals("l")) infoPool.setPlayDirection(Intelligence.PLAY_DIRECTION_RIGHT);
		else {
			infoPool.setPlayDirection(Intelligence.PLAY_DIRECTION_LEFT);
			//assert side;//.equals("r");
		} 
		infoPool.insertFlags();
		infoPool.insertLines();
		infoPool.setUnum(Integer.parseInt(unum));
		infoPool.setPlayMode(Intelligence.BEFORE_KICK_OFF);
	}
	
	

    /**
     * @param repeatBroadCast The repeatBroadCast to set.
     */
    public void setRepeatBroadCast(boolean repeatBroadCast) {
        this.repeatBroadCast = repeatBroadCast;
    }
}
