package edu.kufpg.armatus.data; import java.util.List; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; import android.os.Parcel; import android.os.Parcelable; import com.google.common.base.Objects; import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; import edu.kufpg.armatus.util.ParcelUtils; public class Glyph implements Parcelable { public static final String BLUE = "#0090D3"; public static final String RED = "#CC060B"; public static final String YELLOW = "#FDFD0D"; public static final String GREEN = "#1DDA1C"; public static final String CYAN = "#1BE0CC"; private static final String STYLE = "style", BINDING_SITE = "bindingSite", PATH = "path", TEXT = "text"; private final GlyphStyle mStyle; private final Optional<? extends List<Crumb>> mBindingSite; private final List<Crumb> mPath; private final String mText; public Glyph(GlyphStyle style, List<Crumb> path, String text) { this(style, Optional.<ImmutableList<Crumb>>absent(), ImmutableList.copyOf(path), text); } public Glyph(GlyphStyle style, List<Crumb> bindingSite, List<Crumb> path, String text) { this(style, Optional.fromNullable(ImmutableList.copyOf(bindingSite)), ImmutableList.copyOf(path), text); } public Glyph(JSONObject o) throws JSONException { this(jsonToStyle(o), jsonToBindingSite(o, BINDING_SITE), jsonToPath(o.getJSONArray(PATH)), o.getString(TEXT)); } private Glyph(GlyphStyle style, Optional<ImmutableList<Crumb>> bindingSite, ImmutableList<Crumb> path, String text) { mStyle = style; mBindingSite = bindingSite; mPath = path; mText = text; } public GlyphStyle getStyle() { return mStyle; } public List<Crumb> getBindingSite() throws IllegalStateException { return mBindingSite.get(); } public List<Crumb> getPath() { return mPath; } public String getText() { return mText; } public boolean hasBindingSite() { return mBindingSite.isPresent(); } public String getColor() { switch (mStyle) { case KEYWORD: return BLUE; case SYNTAX: return RED; case COERCION: return YELLOW; case TYPE: return GREEN; case LIT: return CYAN; default: return null; } } private static Optional<ImmutableList<Crumb>> jsonToBindingSite(JSONObject o, String name) throws JSONException { if (o.has(name)) { ImmutableList.Builder<Crumb> builder = ImmutableList.builder(); JSONArray a = o.getJSONArray(name); for (int i = 0; i < a.length(); i++) { builder.add(new Crumb(a.getJSONObject(i))); } return Optional.of(builder.build()); } else { return Optional.absent(); } } private static ImmutableList<Crumb> jsonToPath(JSONArray a) throws JSONException { ImmutableList.Builder<Crumb> builder = ImmutableList.builder(); for (int i = 0; i < a.length(); i++) { builder.add(new Crumb(a.getJSONObject(i))); } return builder.build(); } private static GlyphStyle jsonToStyle(JSONObject o) throws JSONException { if (o.has(STYLE)) { GlyphStyle glyphStyle = null; glyphStyle = GlyphStyle.valueOf(o.getString("style")); return glyphStyle; } else { return GlyphStyle.NORMAL; } } public static enum GlyphStyle { NORMAL, KEYWORD, SYNTAX, VAR, COERCION, TYPE, LIT, WARNING; } @Override public boolean equals(Object o) { if (o instanceof Glyph) { Glyph g = (Glyph) o; return mStyle.equals(g.getStyle()) && mBindingSite.equals(g.mBindingSite) && mPath.equals(g.getPath()) && mText.equals(g.getText()); } else { return false; } } @Override public int hashCode() { return Objects.hashCode(mStyle, mBindingSite, mPath, mText); } @Override public String toString() { return mText; } public static Parcelable.Creator<Glyph> CREATOR = new Parcelable.Creator<Glyph>() { @Override public Glyph createFromParcel(Parcel source) { GlyphStyle style = ParcelUtils.readEnum(source); Optional<ImmutableList<Crumb>> bindingSite = ParcelUtils.readOptional(source); ImmutableList<Crumb> path = ParcelUtils.readImmutableList(source); String text = source.readString(); return new Glyph(style, bindingSite, path, text); } @Override public Glyph[] newArray(int size) { return new Glyph[size]; } }; @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { ParcelUtils.writeEnum(dest, mStyle); ParcelUtils.writeOptional(dest, mBindingSite); ParcelUtils.writeCollection(dest, mPath); dest.writeString(mText); } }