package edu.kufpg.armatus.data;
import java.util.List;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.graphics.Color;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.SpannableStringBuilder;
import android.text.style.BackgroundColorSpan;
import android.text.style.ForegroundColorSpan;
import com.google.common.base.Objects;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import edu.kufpg.armatus.data.Glyph.GlyphStyle;
import edu.kufpg.armatus.util.ParcelUtils;
import edu.kufpg.armatus.util.StringUtils;
public class CommandResponse implements Parcelable {
private static final String AST = "ast", GLYPHS = "glyphs", MSG = "msg";
private final int mAst;
private final Optional<? extends List<Glyph>> mGlyphs;
private final Optional<? extends Spannable> mGlyphText;
private final Optional<String> mMessage;
public CommandResponse(int ast) {
this(ast, Optional.<ImmutableList<Glyph>>absent(), Optional.<String>absent());
}
public CommandResponse(int ast, List<Glyph> glyphs) {
this(ast, Optional.fromNullable(ImmutableList.copyOf(glyphs)), Optional.<String>absent());
}
public CommandResponse(int ast, String message) {
this(ast, Optional.<ImmutableList<Glyph>>absent(), Optional.fromNullable(message));
}
public CommandResponse(int ast, List<Glyph> glyphs, String message) {
this(ast, Optional.fromNullable(ImmutableList.copyOf(glyphs)), Optional.fromNullable(message));
}
public CommandResponse(JSONObject o) throws JSONException {
this(o.getInt(AST), jsonToGlyphs(o), jsonToMessage(o));
}
private CommandResponse(int ast, Optional<ImmutableList<Glyph>> maybeGlyphs, Optional<String> maybeMessage) {
this(ast, maybeGlyphs, createPrettyText(maybeGlyphs), maybeMessage);
}
private CommandResponse(int ast, Optional<ImmutableList<Glyph>> glyphs,
Optional<SpannableStringBuilder> glyphText, Optional<String> message) {
mAst = ast;
mGlyphs = glyphs;
mGlyphText = glyphText;
mMessage = message;
}
public int getAst() {
return mAst;
}
public List<Glyph> getGlyphs() throws IllegalStateException {
return mGlyphs.get();
}
public Spannable getGlyphText() throws IllegalStateException {
return mGlyphText.get();
}
public String getMessage() throws IllegalStateException {
return mMessage.get();
}
public boolean hasGlyphs() {
return mGlyphs.isPresent();
}
public boolean hasMessage() {
return mMessage.isPresent();
}
private static Optional<ImmutableList<Glyph>> jsonToGlyphs(JSONObject o) throws JSONException {
if (o.has(GLYPHS)) {
ImmutableList.Builder<Glyph> builder = ImmutableList.builder();
JSONArray a = o.getJSONArray(GLYPHS);
for (int i = 0; i < a.length(); i++) {
builder.add(new Glyph(a.getJSONObject(i)));
}
return Optional.of(builder.build());
} else {
return Optional.absent();
}
}
private static Optional<SpannableStringBuilder> createPrettyText(Optional<? extends List<Glyph>> glyphs) {
if (glyphs.isPresent()) {
SpannableStringBuilder builder = new SpannableStringBuilder();
for (Glyph glyph : glyphs.get()) {
SpannableString spanWord = new SpannableString(glyph.getText());
if (glyph.getStyle().equals(GlyphStyle.WARNING)) {
spanWord.setSpan(new BackgroundColorSpan(Color.YELLOW),
0, glyph.getText().length(), 0);
spanWord.setSpan(new ForegroundColorSpan(Color.BLACK),
0, glyph.getText().length(), 0);
} else {
String glyphColor = glyph.getColor();
if (glyphColor != null) {
spanWord.setSpan(new ForegroundColorSpan(Color.parseColor(glyphColor)),
0, glyph.getText().length(), 0);
}
}
builder.append(spanWord);
}
return Optional.of(builder);
} else {
return Optional.absent();
}
}
private static Optional<String> jsonToMessage(JSONObject o) throws JSONException {
if (o.has(MSG)) {
return Optional.of(StringUtils.tightenSpacing(o.getString("msg")));
} else {
return Optional.absent();
}
}
@Override
public boolean equals(Object o) {
if (o instanceof CommandResponse) {
CommandResponse cr = (CommandResponse) o;
return mAst == cr.getAst()
&& mGlyphs.equals(cr.mGlyphs)
&& mMessage.equals(cr.mMessage);
} else {
return false;
}
}
@Override
public int hashCode() {
return Objects.hashCode(mAst, mGlyphs, mMessage);
}
public static Parcelable.Creator<CommandResponse> CREATOR =
new Parcelable.Creator<CommandResponse>() {
@Override
public CommandResponse createFromParcel(Parcel source) {
int ast = source.readInt();
Optional<ImmutableList<Glyph>> glyphs = ParcelUtils.readOptional(source);
Optional<SpannableStringBuilder> glyphText = ParcelUtils.readOptional(source);
Optional<String> message = ParcelUtils.readOptional(source);
return new CommandResponse(ast, glyphs, glyphText, message);
}
@Override
public CommandResponse[] newArray(int size) {
return new CommandResponse[size];
}
};
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(mAst);
ParcelUtils.writeOptional(dest, mGlyphs);
ParcelUtils.writeOptional(dest, mGlyphText);
ParcelUtils.writeOptional(dest, mMessage);
}
}