import java.io.*;
import java.net.*;
import java.text.*;
import java.util.*;

public class ProcessPacket extends Thread {
	String packet = null;
	int length = 0;
	int header = 0;
	SocketManager u;
	Habbo user;
	
	// Konstruktor fuer einen neuen ProcessPacket-Thread
	public ProcessPacket (SocketManager u, String packet, int header) {
		this.packet = packet;
		this.u = u;
		this.header = header;
		user = MultiUserServer.users[u.nr];
	}
	
	// Verarbeitung des Packets
	// --> Dieses Programm laeuft parallel zum Rest in einem eigenen Thread
	//     Das macht z.B. dann sinn, wenn laengere operationen stattfinden sollen
	//     wie beispielsweise die Wartezeit beim Wuerfeln
	public void run() {
		switch (header) {
		case 42: // Benutzernamen pruefen (@j)
		{
			// Zuerst dekodieren wir die Laenge des namens:
			int nameLength = MultiUserServer.encoding.b64_encode(packet.substring(0, 2));
			
			// Pruefen, ob der Name die richtige Laenge hat
			if (nameLength < 3 || nameLength > 20) {
				sendData("@dK");
				break;
			}
			
			// Die Laenge ist ok, also wird der Name nun eingelesen
			String name = packet.substring(2, (2 + nameLength));
			
			// Pruefen, ob der Name bereits existiert
			// Wichtig, dass man bei so einer Abfrage das LIMIT auf 1 setzt,
			// sonst muss MySQL jedesmal die gesamte Tabelle abfahren.
			if (MultiUserServer.database.dbExists(
					"SELECT id " +
					"FROM users " +
					"WHERE username = '" + name.toLowerCase() + "' " +
					"LIMIT 1")) {
				sendData("@dPA");
				break;
			}
			
			// Der Name ist okay, also geben wir gruenes Licht
			sendData("@dH");
			break;
		}
		
		case 43: // Neuen Habbo erstellen (@k)
		{
			String temp = packet;
			
			int userNameLength = MultiUserServer.encoding.b64_encode(temp.substring(2, 4));
			String userName = temp.substring(4, 4 + userNameLength);
			temp = temp.substring(4 + userNameLength);

			int figureLength = MultiUserServer.encoding.b64_encode(temp.substring(2, 4));
			String figureCode = temp.substring(4, 4 + figureLength);
			temp = temp.substring(4 + figureLength);

			char gender = temp.charAt(4);
			temp = temp.substring(9);

			int emailLength = MultiUserServer.encoding.b64_encode(temp.substring(2, 4));
			String emailAdress = temp.substring(4, 4 + emailLength);
			temp = temp.substring(4 + emailLength);

			int dateOfBirthLength = MultiUserServer.encoding.b64_encode(temp.substring(2, 4));
			String dateOfBirth = temp.substring(10, 14) + temp.substring(7, 9) + temp.substring(4, 6);
			temp = temp.substring(4 + dateOfBirthLength);

			boolean receiveAdminMails =
				(temp.charAt(8) == 'A');
			temp = temp.substring(9);
			
			int passwordLength = MultiUserServer.encoding.b64_encode(temp.substring(2, 4));
			String password = temp.substring(4, 4 + passwordLength);
			
			// Hier entsteht der neue User wirklich, das heisst
			// HIER wird er in der Datenbank festgehalten!
			MultiUserServer.database.dbRunQuery("INSERT INTO users (" +
					"username, " +
					"figureCode, " +
					"gender, " +
					"emailAdress, " +
					"dateOfBirth, " +
					"receiveAdminMails, " +
					"password) VALUES (" +
					"'" + userName + "', " + 
					"'" + figureCode + "', " + 
					"'" + gender + "', " + 
					"'" + emailAdress + "', " + 
					"'" + dateOfBirth + "', " + 
					"" + receiveAdminMails + ", " + 
					"'" + password + "')");
			
			// < hier gehts noch weiter ... >
			
			break;
		}
		
		case 46: // Unbekannt (@n)
		{
			sendData("DO");
			break;
		}
			
		case 49: // Der Client moechte das aktuelle Datum im Format dd-MM-yyyy (@q)
		{
			SimpleDateFormat date = new SimpleDateFormat("dd-MM-yyyy");
			Date now = new Date();
			sendData("Bc" + date.format(now));
			break;
		}
			
		case 131: // Der Benutzer ist unter 10 Jahre Alt
		{
			sendData("BK" + "Hier darf sich jeder Registrieren, also klick einfach auf den anderen Button ;)");
			break;
		}
		
		case 146: // Unbekannt (BR)
		{
			sendData("CY1");
			break;
		}
		
		case 197: // E-Mail Adresse pruefen (CE)
		{
			// Ich zaehle hier einfach die @'s im String, dieses Verfahren ist
			// nicht besonders gut aber ich denke es ist vorerst ausreichend.
			int mailLength = MultiUserServer.encoding.b64_encode(packet.substring(0, 2));
			int atCount = 0;
			for (int i = 0; i < mailLength; i++) {
				if (packet.charAt(i + 2) == '@')
					atCount++;
			}
			if (atCount != 1) {
				sendData("DZJ");
				break;
			}
			
			sendData("DO");
			break;
		}
			
		case 202: // Registrierungsformular starten (CJ)
		{
			sendData("DARAHIIIKHJIPAIQAdd-MM-yyyy" + (char)2);
			sendData("@H[100,105,110,115,120,125,130,135,140,145,150,155,160,165,170,175,176,177,178,180,185,190,195,200,205,206,207,210,215,220,225,230,235,240,245,250,255,260,265,266,267,270,275,280,281,285,290,295,300,305,500,505,510,515,520,525,530,535,540,545,550,555,565,570,575,580,585,590,595,596,600,605,610,615,620,625,626,627,630,635,640,645,650,655,660,665,667,669,670,675,680,685,690,695,696,700,705,710,715,720,725,730,735,740]");
			break;
		}
		
		case 203: // Neues Passwort pruefen (CK)
		{
			int nameLength = MultiUserServer.encoding.b64_encode(packet.substring(0, 2));
			// Das Dekodieren der Passwortlaenge ist unnoetig, da das Passwort
			// am Ende des Packets steht!
			String password = packet.substring(4 + nameLength);
			
			// Zuerst pruefen wir die laenge, das Passwort sollte zwischen 6 und 10 Zeichen lang sein
			if (password.length() < 6 || password.length() > 10) {
				sendData("DZI");
				break;
			}
			
			// Jedes Passwort sollte eine Zahl enthalten ..
			boolean containsNumber = false;
			for (int i = 0; i < password.length(); i++)
				if (Character.isDigit(password.charAt(i)))
					containsNumber = true;
			if (!containsNumber) {
				sendData("DZI");
				break;
			}
			
			// Ist das Programm hier angekommen, muss das Passwort gueltig sein
			sendData("DZH");
		}
			
		}
	}
	
	// Interne Methode zum senden von Packets
	// Sie dient nur dazu, dass man beim Senden von packets nicht immer soviel
	// schreiben muss ;)
	public void sendData(String data) {
		u.sendData(u.sending, data);
	}
}
