import java.io.*;
import java.net.*;
import java.util.*;
import java.text.*;

public class SocketManager extends Thread {
	static int count = 0;
	
	Socket s;
	BufferedReader incoming;
	PrintWriter sending;
	int nr = 0;
	
	public SocketManager(Socket s) {
		try {
			this.s = s;
			incoming = new BufferedReader(
					new InputStreamReader(
							s.getInputStream()));
			sending = new PrintWriter(s.getOutputStream(), true);
			
			for (int i = 0; i < 100; i++) {
				if (MultiUserServer.users[i] != null && MultiUserServer.users[i].inactive) {
					nr = i;
					MultiUserServer.users[nr].inactive = false;
				}
			}
			if (nr == 0) {
				nr = ++count;
				MultiUserServer.users[nr] = new Habbo();
			}
			
			System.out.println("Neue Verbindung akzeptiert!");
			System.out.println("Der neuen Verbindung wurde die Nummer " + nr + " zugewiesen.");
			sendData(sending, "@@");
		}
		catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	public void run() {
		try {
			while(true) {
				// ->
				// .. Hier kommen die Packets an
				char[] packetBuffer = new char[1024];
				int bufferSize = incoming.read(packetBuffer);
				String packet = "";
				for (int i = 0; i < bufferSize; i++)
					packet = packet + (char)(int)packetBuffer[i];
				System.out.println("<< " + packet);
				if (packet == null)
					break;
				if (packet.length() == 0)
					break;
				if (packet == ((char)10 + (char)13 + ""))
					break;

				// Laenge des Packets anhand des B64-Headers herausfinden
				int packetLength = MultiUserServer.encoding.b64_encode(packet.substring(1, 2));
				if (packetLength < 0 || packetLength > 1024) // Die Packetlaengenangabe ist ungueltig ..
					break;									 // .. also kann es sich nicht um eine original Clientnachricht handeln!
				
				// Nun  den Packetheader bestimmen, daran erkennen wir, was der Client ueberhaupt will
				int packetHeader = MultiUserServer.encoding.b64_encode(packet.substring(3, 5));
				packet = packet.substring(5); // Die bereits verarbeitete Information abtrennen

				// Neuen Thread zur Packetverarbeitung erstellen
				new ProcessPacket(this, packet, packetHeader).start();
				
				// <- Und oben gehts direkt wieder von vorne los
			}
			sendData(sending, (char)10 + (char)13);
			MultiUserServer.users[nr].inactive = true;
			s.close();
		}
		catch (IOException e) {
			System.out.println("IO-Error on Client #" + nr);
		}
		System.out.println("Protocol quit for Client #" + nr);
	}
	
	public void sendData(PrintWriter out, String data) {
		out.print(data + (char)1);
		out.flush();
		System.out.println("[" + this.nr + "] >> " + data + (char)1);
	}
	public void sendData(PrintWriter out, String data, boolean printConsole) {
		out.print(data + (char)1);
		out.flush();
		if (printConsole)
			System.out.println("[" + this.nr + "] >> " + data + (char)1);
	}
}
