package server;
import org.json.JSONObject;
import card.Card;
import org.json.JSONException;
public class Message {
public static final byte[] MAGIC = { 1, 3, 3, 7 };
public static final byte MSG_FIRST_MSG = Move.DRY << 1;
public static final byte MSG_YOURTURN = MSG_FIRST_MSG + 0;
public static final byte MAG_READY = MSG_FIRST_MSG + 1;
public static final byte MSG_UNREADY = MSG_FIRST_MSG + 2;
public static final byte MSG_INVALID = MSG_FIRST_MSG + 3; //FIXME first, fix all other errors (META_MOVE_INVALID)
public static final byte MSG_VALID = MSG_FIRST_MSG + 4; //FIXME first, fix all other errors (META_MOVE_VALID)
public static final byte MSG_WON = MSG_FIRST_MSG + 5;
public static final byte MSG_LOST = MSG_FIRST_MSG + 6;
public static final byte MSG_LEAVE = MSG_FIRST_MSG + 7;
public static final byte MSG_CONNECTION_VALID = MSG_FIRST_MSG + 8;
public static final byte MSG_CONNECTION_INVALID = MSG_FIRST_MSG + 9;
public static final byte MSG_LAST_MSG = MSG_CONNECTION_INVALID;
public static final byte HINT_COLOR = 0;
public static final byte HINT_VALUE = 1;
public enum MsgByteCat { MSG, MOVE, INVALID };
private static MsgByteCat msgByteCat(byte b) {
if(b > 0 && b < MSG_FIRST_MSG) return MsgByteCat.MOVE;
if(b >= MSG_FIRST_MSG && b <= MSG_LAST_MSG) return MsgByteCat.MSG;
return MsgByteCat.INVALID;
}
private static void throwOnWrongMsgByte(byte b, MsgByteCat shouldBe) {
MsgByteCat is = msgByteCat(b);
if(is != shouldBe) {
throw new InternalHanabiError("Message type is " + is + ", but it should be " + shouldBe + ".");
}
}
private int origin;
private byte msgType;
private Move move;
//private JSONObject jo;
public Message(byte mT) { this(-1, mT); }
public Message(byte mT, Move m) { this(-1, mT, m); }
public Message(int o, byte mT) {
throwOnWrongMsgByte(mT, MsgByteCat.MSG);
origin = o;
setMsgType(mT);
}
public Message(int o, byte moveType, Move m) {
throwOnWrongMsgByte(moveType, MsgByteCat.MOVE);
origin = o;
setMsgType(moveType);
move = m;
}
//public Message(JSONObject jo) throws JSONException {
//this.jo = (JSONObject)jo.clone();
//this.jo = jo; // TODO: clone?
// moveType = (byte)jo.getInt("msgType");
//}
// public static Message newMove(Card c) {
// try {
// return new Message(c.toJson());
// } catch(JSONException ex) {
// throw new InternalHanabiError(ex);
// }
// }
public Message(byte[] bytes) {
throw new RuntimeException("Not implemented. This is a bug.");
}
public byte[] toBytes() {
return toBytes(ServerGame.PROTO_VIBE_DUMB);
}
public byte[] toBytes(byte proto) {
switch(proto) {
case ServerGame.PROTO_VIBE_DUMB:
throw new RuntimeException("Not implemented. This is a bug.");
default:
throw new InternalHanabiError("Message.toBytes(byte) called with invalid protocol code " + proto + ".");
}
}
// public JSONObject getJson() {
// return jo;
// }
// public String toJsonString() {
// if(jo == null) return "";
// return jo.toString();
// }
public byte getMsgType() {
return msgType;
}
public int getOrigin() {
return origin;
// try {
// return jo.getInt("origin");
// } catch(JSONException ex) {
// throw new InternalHanabiError(ex);
// }
}
public void setOrigin(int orig) { origin = orig; }
public int getHintType() {
if(msgType != Move.HINT) {
throw new RuntimeException("Internal Error: Hint type of non-hint move requested.");
}
try {
return jo.getInt("type");
} catch(JSONException ex) {
throw new InternalHanabiError(ex);
}
}
public int getValue() {
if(msgType != Move.HINT) {
throw new RuntimeException("Internal Error: Hint value of non-hint message requested.");
}
try {
return jo.getInt("value");
} catch(JSONException ex) {
throw new InternalHanabiError(ex);
}
}
public int getHintRecipient() {
if(msgType != Move.HINT) {
throw new RuntimeException("Internal Error: Target player ID of non-hint message requested.");
}
try {
return jo.getInt("playerId");
} catch(JSONException ex) {
throw new InternalHanabiError(ex);
}
}
public int getOwnId() {
if(msgType != MSG_CONNECTION_VALID) {
throw new RuntimeException("Internal Error: ownId of non-connection valid message requested.");
}
try {
return jo.getInt("id");
} catch(JSONException ex) {
throw new InternalHanabiError(ex);
}
}
public static Message makeInvalidMoveAnswer(Message m) {
return new Message(MSG_INVALID);
}
public static Message makeItsYourTurnMessage() {
return new Message(MSG_YOURTURN);
}
public boolean isNonMove() {
return msgByteCat(msgType) == MsgByteCat.MSG;
//return msgType >= MSG_FIRST_MSG;
}
public void setMsgType(byte msgType) {
this.msgType = msgType;
try {
jo.put("msgType", msgType);
} catch (JSONException ex) {
throw new InternalHanabiError(ex);
}
}
public Move getMove() {
return move;
}
}