package net.sf.nebulacards.comm;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.StreamCorruptedException;
import java.net.Socket;
import net.sf.nebulacards.comm.netpkt.AcceptPkt;
import net.sf.nebulacards.comm.netpkt.BidPkt;
import net.sf.nebulacards.comm.netpkt.BootPkt;
import net.sf.nebulacards.comm.netpkt.ChatPkt;
import net.sf.nebulacards.comm.netpkt.DealPkt;
import net.sf.nebulacards.comm.netpkt.EndHandPkt;
import net.sf.nebulacards.comm.netpkt.GameNamePkt;
import net.sf.nebulacards.comm.netpkt.LeavePkt;
import net.sf.nebulacards.comm.netpkt.PassNotifyPkt;
import net.sf.nebulacards.comm.netpkt.PassPkt;
import net.sf.nebulacards.comm.netpkt.PlayPkt;
import net.sf.nebulacards.comm.netpkt.PositionPkt;
import net.sf.nebulacards.comm.netpkt.QueryPkt;
import net.sf.nebulacards.comm.netpkt.RejectPkt;
import net.sf.nebulacards.comm.netpkt.ResponsePkt;
import net.sf.nebulacards.comm.netpkt.SofarPkt;
import net.sf.nebulacards.comm.netpkt.TrickPkt;
import net.sf.nebulacards.comm.netpkt.TrumpPkt;
import net.sf.nebulacards.comm.netpkt.YourTurnPkt;
import net.sf.nebulacards.main.GameResult;
import net.sf.nebulacards.main.NebulaUI;
import net.sf.nebulacards.main.PileOfCards;
import net.sf.nebulacards.main.Player;
import net.sf.nebulacards.main.PlayingCard;
import net.sf.nebulacards.main.UIListener;
/**
* An abstraction of a remote player. Communication uses the Java Serialization
* API.
* @author James Ranson
* @version 0.7
*/
public class SerializationUI
implements NebulaUI, PacketListener
{
private CommThread m_comm;
private UIListener m_callbacks;
/**
* Constructor.
* @param socket The socket on which the remote player is connected.
* @param ois The object input stream for the socket.
* @param oos The object output stream for the socket.
* @param id An integer to distinguish this instance (for debugging).
*/
public SerializationUI( Socket socket, ObjectInputStream ois,
ObjectOutputStream oos, int id )
throws IOException, StreamCorruptedException
{
m_comm = new CommThread( socket, ois, oos, id );
m_comm.addPacketListener( this );
m_comm.start();
}
/**
* Get the listener for incoming events. Unlike a Communicator, this
* class handles only one callback listener.
*/
public void setCallbacks( UIListener cb )
{
m_callbacks = cb;
}
/**
* Send the packet according to our resend policy.
*/
private void send(Object o)
{
m_comm.send(o);
}
public void setPosition( int where )
{
send( new PositionPkt(where) );
}
public void setTrump( int t, String n )
{
send(new TrumpPkt(t,n));
}
public void respond( String query )
{
send( new QueryPkt(query) );
}
public void setGameName( String n )
{
send( new GameNamePkt(n) );
}
public void setBid( int who, int bid )
{
send( new BidPkt(bid,who) );
}
public void setPlayers( Player[] p )
{
send(p);
}
public void cardToTableau( int pos, PlayingCard c )
{
send(new PlayPkt(c,pos));
}
public void clearTableau( int whoWonTrick )
{
send(new TrickPkt(whoWonTrick));
}
public void dealHand( PileOfCards h )
{
send(new DealPkt(h));
}
public void yourTurn()
{
send(new YourTurnPkt(YourTurnPkt.PLAY));
}
public void yourTurnToBid()
{
send(new YourTurnPkt(YourTurnPkt.BID));
}
public void yourTurnToPass( int howmany, int who )
{
send(new PassNotifyPkt(howmany,who));
}
public void accepted()
{
send(new AcceptPkt());
}
public void rejected()
{
send(new RejectPkt());
}
public void chat( String s )
{
send(new ChatPkt(s));
}
public void endGame( GameResult gr )
{
send(gr);
}
public void endHand()
{
send( new EndHandPkt() );
}
public void booted( String why )
{
send( new BootPkt(why) );
}
public void playedSoFar( PileOfCards bp )
{
send( new SofarPkt(bp) );
}
public void miscInfo( Object o )
{
send( o );
}
/**
* Interpret incoming packets and call the respective callback method.
* Satisfies the PacketListener interface.
*/
public void packetReceived(int who, Object o)
{
if (o == null)
return;
//System.out.println( "SerializationUi received: " + o );
if (o instanceof ChatPkt)
{
m_callbacks.submitChat( ((ChatPkt)o).getMessage() );
} else if (o instanceof LeavePkt) {
m_callbacks.wantToQuit();
} else if (o instanceof PlayPkt) {
m_callbacks.submitPlay( ((PlayPkt)o).getCard() );
} else if (o instanceof PassPkt) {
m_callbacks.submitPass( ((PassPkt)o).getCards() );
} else if (o instanceof BidPkt) {
m_callbacks.submitBid( ((BidPkt)o).getBid() );
} else if (o instanceof ResponsePkt) {
m_callbacks.submitResponse( ((ResponsePkt)o).toString() );
}
}
/**
* Call wantToQuit() when the player disconnects.
* @param who The player who disconnected.
*/
public void packetStreamClosed(int who)
{
m_comm.removePacketListener(this);
m_comm.end();
m_callbacks.wantToQuit();
}
}