package network;

/**
 * Message Klasse
 * Stellt ein Antwort Packet in der Client/Server Kommunikation
 * dar und kann entweder ein Status od. ein Error sein
 */
public class Message {
	
	//Attribute
	private int iID;
	private int iParam;
	private float fParam1;
	private float fParam2;
	private float fParam3;
	
	// Nachrichtencodes
	public static final int POS = 1; // aktuelle Position
	public static final int IMGAVAIL = 2; // Cam-Bild zum Download bereit
	public static final int REFRESH_FTP = 3; 	  // FTP Tabelle neu laden
	
	// Fehlercodes
	public static final int POSIMP = 129;     // Position generell nicht anfahrbar
	public static final int POSOCC = 130;     // Hindernis im Weg
	public static final int WAYIMP = 131;     // Weg nicht möglich
	public static final int MOTIMP = 132;     // Bewegung nicht möglich
	public static final int FILEERR = 133;    // Datei öffnen nicht möglich
	public static final int LINEIMP = 134;    // Pkt. entlang Linie nicht anfahrbar
	public static final int NOTRANSOBJ = 135; // TransObj existiert nicht
	public static final int AUTHERR = 136; 	  // Falsches CMD Password


	
	/**
	 * Konstruktor der empafangenes Byte-Array(NetMessage)
	 * übernimmt und Message zusammenstellt
	 * @param i ID der Nachricht
	 */
	public Message(int i){
	 iID=i;
	}	
	
	/**
	 * Konstruktor der empafangenes Byte-Array(NetMessage)
	 * übernimmt und Message zusammenstellt
	 * @param nm NetMessage Objekt das in ein Message umgewandelt werden soll
	 */
	public Message(NetMessage nm){
	 this.mergeParams(nm.getRData());
	}

	/* ##########################################################################
	 * 						ÖFFENTLICHE METHODEN
	 * ##########################################################################*/		
	
	/** GET - Methoden */
	public int getID(){ return iID; }
	public int getiParam(){ return iParam; }
	public float getfParam1(){ return fParam1; }
	public float getfParam2(){ return fParam2; }
	public float getfParam3(){ return fParam3; }
	
	/** SET - Methoden */
	public void setiParam(int i){ iParam=i; }
	public void setfParam1(float f){ fParam1=f; }
	public void setfParam2(float f){ fParam2=f; }
	public void setfParam3(float f){ fParam3=f; }
	public void setID(int i){ iID=i; }	

	/* ##########################################################################
	 * 						HILFSMETHODEN
	 * ##########################################################################*/	
	
	/**
	 * verbindet die Bytes aus dem empfangenen Byte-Array zu
	 * den int/float Werten
	 * @param b byte - Array das empfangen wurde
	 */
	private void mergeParams(byte[] b){
		
		//ID zusweisen
		iID=byteValue(b[1]);

		//int-Wert filtern	
		iParam = mergeParam(b,2);

		//Message Params filtern
		if(iID<=127){
			fParam1 = Float.intBitsToFloat(mergeParam(b,6));
			fParam2 = Float.intBitsToFloat(mergeParam(b,10));
			fParam3 = Float.intBitsToFloat(mergeParam(b,14));
		}
		
	}
	
	/**
	 * verbindet 4 Bytes zu einem int-Wert
	 * @param b Bytes die vereint werden sollen
	 * @param n Position des ersten Byte im Array
	 * @return vereinigter Wert
	 */
	private int mergeParam(byte[] b,int n){
		int i=0;
		i += byteValue(b[n]);
		i += byteValue(b[n+1]) << 8;
		i += byteValue(b[n+2]) << 16;
		i += byteValue(b[n+3]) << 24;
		return i;
	}
	
	/**
	 * Da Byte signed ist, ist der Wert nicht immer
	 * eindeutig
	 * @param x Wert des Bytes
	 * @return den Bytewert
	 */
	private int byteValue(byte x){
		return (x<0)?x+256:x;
	}
	
}
