package org.kne.cloud.network.minecraft;
import static org.kne.cloud.network.minecraft.MinecraftPacket.*;

import java.io.BufferedInputStream;
import java.io.ByteArrayInputStream;
import java.io.FilterInputStream;
import java.io.IOException;
import java.io.InputStream;

import org.kne.cloud.network.klalb.PINGPacket;
import org.kne.io.VarDataInputStream;

public class MinecraftInputStream extends VarDataInputStream {
	private MinecraftProtocolContext context;
	public MinecraftInputStream(InputStream in,MinecraftProtocolContext context) {
		super(grin(in));
		this.context=context;
	}
	private static InputStream grin(InputStream in) {
		InputStream rin;
		if(in.markSupported()) {
			rin=in;
		}else {
			rin=new BufferedInputStream(in,8192);
		}
		return rin;
	}
	public MinecraftProtocolContext getContext() {
		return context;
	}
	public MinecraftPacket readPacket() throws IOException {
		mark(1);
		read();
		reset();
		if(context.getState()==2) {
			MinecraftUnsolvedPacket mup=new MinecraftUnsolvedPacket();
			mup.readFromStream(this);
			if(mup.getLenth()==-1) {
				return null;
			}else {
			return mup;
			}
		}
		byte[]b=readPacketVarBytes();
		if(b==null)
			return null;
		VarDataInputStream vdi=new VarDataInputStream(new ByteArrayInputStream(b));
		int type=vdi.readVarInt();
		MinecraftPacket mp;
		if(context.isServer()) {
			switch(context.getState()){
			case 0:
				switch(type) {
				case HANDSHAKE_MOTD:
							mp=new MinecraftHandShakePacket();
							mp.readFromStream(vdi);
							context.setState(((MinecraftHandShakePacket) mp).getNextstate());
							break;
				
					default :
						mp=new MinecraftDefaultPacket(type);
						mp.readFromStream(vdi);
						break;
				}
				break;
			case 1:
				switch(type) {
				case HANDSHAKE_MOTD:
					mp=new MinecraftMotdRequest();
					mp.readFromStream(vdi);
							break;
				case PING_PONG:
					mp=new MinecraftPingPacket();
					mp.readFromStream(vdi);
					break;
					default :
						mp=new MinecraftDefaultPacket(type);
						mp.readFromStream(vdi);
						break;
				}
			break;
			default:
			mp=new MinecraftDefaultPacket(type);
			mp.readFromStream(vdi);
			break;
			}
			
		}else {
			switch(context.getState()) {
					case 1:
			switch(type) {
			case HANDSHAKE_MOTD:
					
					mp=new MinecraftMotdResponse();
					mp.readFromStream(vdi);
					break;
					case PING_PONG:
						mp=new MinecraftPongPacket();
						mp.readFromStream(vdi);
						break;
					default:
						mp=new MinecraftDefaultPacket(type);
						mp.readFromStream(vdi);
						break;
					}
				break;
					
				default :
					mp=new MinecraftDefaultPacket(type);
					mp.readFromStream(vdi);
			}
		}
		//System.out.println(mp);
				return mp;
	}
}
