package org.solovyev.android.calculator.variables; import android.os.Parcel; import android.os.Parcelable; import android.support.annotation.NonNull; import android.text.TextUtils; import jscl.math.function.IConstant; import org.json.JSONException; import org.json.JSONObject; import org.solovyev.android.Check; import org.solovyev.android.calculator.functions.CppFunction; import org.solovyev.android.calculator.json.Json; import org.solovyev.android.calculator.json.Jsonable; import javax.annotation.Nonnull; import static com.google.common.base.Strings.nullToEmpty; public class CppVariable implements Jsonable, Parcelable { public static final Json.Creator<CppVariable> JSON_CREATOR = new Json.Creator<CppVariable>() { @NonNull @Override public CppVariable create(@NonNull JSONObject json) throws JSONException { return new CppVariable(json); } }; public static final Creator<CppVariable> CREATOR = new Creator<CppVariable>() { @Override public CppVariable createFromParcel(Parcel in) { return new CppVariable(in); } @Override public CppVariable[] newArray(int size) { return new CppVariable[size]; } }; public static final int NO_ID = CppFunction.NO_ID; private static final String JSON_NAME = "n"; private static final String JSON_VALUE = "v"; private static final String JSON_DESCRIPTION = "d"; protected int id = NO_ID; @Nonnull protected String name; @Nonnull protected String value = ""; @Nonnull protected String description = ""; protected boolean system; private CppVariable(@Nonnull String name) { this.name = name; } protected CppVariable(@Nonnull CppVariable that) { this.id = that.id; this.name = that.name; this.value = that.value; this.description = that.description; this.system = that.system; } protected CppVariable(@NonNull IConstant that) { id = that.isIdDefined() ? that.getId() : NO_ID; name = that.getName(); value = nullToEmpty(that.getValue()); description = nullToEmpty(that.getDescription()); system = that.isSystem(); } private CppVariable(@NonNull JSONObject json) throws JSONException { this.name = json.getString(JSON_NAME); this.value = json.optString(JSON_VALUE); this.description = json.optString(JSON_DESCRIPTION); } protected CppVariable(Parcel in) { id = in.readInt(); name = in.readString(); value = in.readString(); description = in.readString(); system = in.readByte() != 0; } @NonNull public static CppVariable.Builder builder(@NonNull String name) { return new Builder(name); } @NonNull public static CppVariable.Builder builder(@NonNull String name, double value) { return new Builder(name).withValue(value); } @NonNull public static Builder builder(@NonNull IConstant constant) { return new Builder(constant); } @Nonnull @Override public JSONObject toJson() throws JSONException { final JSONObject json = new JSONObject(); json.put(JSON_NAME, name); if (!TextUtils.isEmpty(value)) { json.put(JSON_VALUE, value); } if (!TextUtils.isEmpty(description)) { json.put(JSON_DESCRIPTION, description); } return json; } @Nonnull public IConstant toJsclConstant() { return new JsclConstant(CppVariable.this); } @Override public boolean equals(Object o) { if (this == o) return true; if (!(o instanceof CppVariable)) return false; CppVariable that = (CppVariable) o; if (id != that.id) return false; return name.equals(that.name); } @Override public int hashCode() { int result = id; result = 31 * result + name.hashCode(); return result; } @Override public int describeContents() { return 0; } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeInt(id); dest.writeString(name); dest.writeString(value); dest.writeString(description); dest.writeByte((byte) (system ? 1 : 0)); } @Override public String toString() { if (id == NO_ID) { return name + "=" + value; } else { return name + "[#" + id + "]=" + value; } } public static class Builder { @NonNull private final CppVariable variable; private boolean built; private Builder(@NonNull String name) { variable = new CppVariable(name); } private Builder(@NonNull IConstant constant) { variable = new CppVariable(constant); } @Nonnull public Builder withDescription(@Nonnull String description) { Check.isTrue(!built); variable.description = description; return this; } @Nonnull public Builder withValue(@NonNull String value) { Check.isTrue(!built); variable.value = value; return this; } @Nonnull public Builder withValue(double value) { Check.isTrue(!built); return withValue(Double.toString(value)); } @Nonnull public Builder withSystem(boolean system) { Check.isTrue(!built); variable.system = system; return this; } @Nonnull public Builder withId(int id) { Check.isTrue(!built); variable.id = id; return this; } @Nonnull public CppVariable build() { built = true; return variable; } } }