package com.kickstarter.models;
import android.net.Uri;
import android.os.Parcelable;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.StringDef;
import com.kickstarter.libs.qualifiers.AutoGson;
import com.kickstarter.libs.utils.DateTimeUtils;
import com.kickstarter.libs.utils.IntegerUtils;
import org.joda.time.DateTime;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.Collections;
import java.util.List;
import auto.parcel.AutoParcel;
@AutoGson
@AutoParcel
public abstract class Project implements Parcelable {
public abstract int backersCount();
public abstract String blurb();
public abstract @Nullable Backing backing();
public abstract @Nullable Category category();
public abstract @Nullable Integer commentsCount();
public abstract String country(); // e.g.: US
public abstract DateTime createdAt();
public abstract User creator();
public abstract String currency(); // e.g.: USD
public abstract String currencySymbol(); // e.g.: $
public abstract boolean currencyTrailingCode();
public abstract @Nullable DateTime featuredAt();
public abstract @Nullable List<User> friends();
public abstract @Nullable DateTime deadline();
public abstract float goal();
public abstract long id(); // in the Kickstarter app, this is project.pid not project.id
public abstract boolean isBacking();
public abstract boolean isStarred();
public abstract @Nullable DateTime launchedAt();
public abstract @Nullable Location location();
public abstract String name();
public abstract float pledged();
public abstract @Nullable Photo photo();
public abstract @Nullable DateTime potdAt();
public abstract @Nullable String slug();
public abstract @State String state();
public abstract @Nullable DateTime stateChangedAt();
public abstract @Nullable Float staticUsdRate();
public abstract @Nullable Integer updatesCount();
public abstract @Nullable List<Reward> rewards();
public abstract @Nullable DateTime updatedAt();
public abstract Urls urls();
public abstract @Nullable Video video();
@AutoParcel.Builder
public abstract static class Builder {
public abstract Builder backersCount(int __);
public abstract Builder blurb(String __);
public abstract Builder backing(Backing __);
public abstract Builder category(Category __);
public abstract Builder commentsCount(Integer __);
public abstract Builder country(String __);
public abstract Builder createdAt(DateTime __);
public abstract Builder creator(User __);
public abstract Builder currency(String __);
public abstract Builder currencySymbol(String __);
public abstract Builder currencyTrailingCode(boolean __);
public abstract Builder deadline(DateTime __);
public abstract Builder featuredAt(DateTime __);
public abstract Builder friends(List<User> __);
public abstract Builder goal(float __);
public abstract Builder id(long __);
public abstract Builder isBacking(boolean __);
public abstract Builder isStarred(boolean __);
public abstract Builder launchedAt(DateTime __);
public abstract Builder location(Location __);
public abstract Builder name(String __);
public abstract Builder pledged(float __);
public abstract Builder photo(Photo __);
public abstract Builder potdAt(DateTime __);
public abstract Builder rewards(List<Reward> __);
public abstract Builder slug(String __);
public abstract Builder staticUsdRate(Float __);
public abstract Builder state(@State String __);
public abstract Builder stateChangedAt(DateTime __);
public abstract Builder updatedAt(DateTime __);
public abstract Builder updatesCount(Integer __);
public abstract Builder urls(Urls __);
public abstract Builder video(Video __);
public abstract Project build();
}
public static Builder builder() {
return new AutoParcel_Project.Builder()
.isBacking(false)
.isStarred(false)
.rewards(Collections.emptyList());
}
public abstract Builder toBuilder();
public static final String STATE_STARTED = "started";
public static final String STATE_SUBMITTED = "submitted";
public static final String STATE_LIVE = "live";
public static final String STATE_SUCCESSFUL = "successful";
public static final String STATE_FAILED = "failed";
public static final String STATE_CANCELED = "canceled";
public static final String STATE_SUSPENDED = "suspended";
public static final String STATE_PURGED = "purged";
@Retention(RetentionPolicy.SOURCE)
@StringDef({STATE_STARTED, STATE_SUBMITTED, STATE_LIVE, STATE_SUCCESSFUL, STATE_FAILED, STATE_CANCELED, STATE_SUSPENDED, STATE_PURGED})
public @interface State {}
public @NonNull String creatorBioUrl() {
return urls().web().creatorBio();
}
public boolean isBackingRewardId(final long rewardId) {
return this.backing() != null && this.backing().rewardId() != null && this.backing().rewardId() == rewardId;
}
public @NonNull String descriptionUrl() {
return urls().web().description();
}
public @NonNull String updatesUrl() {
return urls().web().updates();
}
public @NonNull String webProjectUrl() {
return urls().web().project();
}
@AutoParcel
@AutoGson
public abstract static class Urls implements Parcelable {
public abstract Web web();
public abstract @Nullable Api api();
@AutoParcel.Builder
public abstract static class Builder {
public abstract Builder web(Web __);
public abstract Builder api(Api __);
public abstract Urls build();
}
public static Builder builder() {
return new AutoParcel_Project_Urls.Builder();
}
public abstract Builder toBuilder();
@AutoParcel
@AutoGson
public abstract static class Web implements Parcelable {
public abstract String project();
public abstract @Nullable String projectShort();
public abstract String rewards();
public abstract @Nullable String updates();
@AutoParcel.Builder
public abstract static class Builder {
public abstract Builder project(String __);
public abstract Builder projectShort(String __);
public abstract Builder rewards(String __);
public abstract Builder updates(String __);
public abstract Web build();
}
public static Builder builder() {
return new AutoParcel_Project_Urls_Web.Builder();
}
public abstract Builder toBuilder();
public @NonNull String creatorBio() {
return Uri.parse(project())
.buildUpon()
.appendEncodedPath("/creator_bio")
.toString();
}
public @NonNull String description() {
return Uri.parse(project())
.buildUpon()
.appendEncodedPath("/description")
.toString();
}
}
@AutoParcel
@AutoGson
public abstract static class Api implements Parcelable {
public abstract @Nullable String project();
public abstract @Nullable String comments();
public abstract @Nullable String updates();
@AutoParcel.Builder
public abstract static class Builder {
public abstract Builder project(String __);
public abstract Builder comments(String __);
public abstract Builder updates(String __);
public abstract Api build();
}
public static Builder builder() {
return new AutoParcel_Project_Urls_Api.Builder();
}
public abstract Builder toBuilder();
}
}
public boolean hasComments() {
return IntegerUtils.isNonZero(this.commentsCount());
}
public boolean hasRewards() {
return rewards() != null;
}
public boolean hasVideo() {
return video() != null;
}
/** Returns whether the project is in a canceled state. */
public boolean isCanceled() {
return STATE_CANCELED.equals(state());
}
/** Returns whether the project is in a failed state. */
public boolean isFailed() {
return STATE_FAILED.equals(state());
}
public boolean isFeaturedToday() {
if (featuredAt() == null) {
return false;
}
return DateTimeUtils.isDateToday(featuredAt());
}
/** Returns whether the project is in a live state. */
public boolean isLive() {
return STATE_LIVE.equals(state());
}
public boolean isFriendBacking() {
return friends() != null && friends().size() > 0;
}
public boolean isFunded() {
return isLive() && (percentageFunded() >= 100);
}
public boolean isPotdToday() {
if (potdAt() == null) {
return false;
}
return DateTimeUtils.isDateToday(potdAt());
}
/** Returns whether the project is in a purged state. */
public boolean isPurged() {
return STATE_PURGED.equals(state());
}
/** Returns whether the project is in a live state. */
public boolean isStarted() {
return STATE_STARTED.equals(state());
}
/** Returns whether the project is in a submitted state. */
public boolean isSubmitted() {
return STATE_SUBMITTED.equals(state());
}
/** Returns whether the project is in a suspended state. */
public boolean isSuspended() {
return STATE_SUSPENDED.equals(state());
}
/** Returns whether the project is in a successful state. */
public boolean isSuccessful() {
return STATE_SUCCESSFUL.equals(state());
}
public boolean isApproachingDeadline() {
if (deadline().isBeforeNow()) {
return false;
}
return deadline().isBefore(new DateTime().plusDays(2));
}
public float percentageFunded() {
if (goal() > 0.0f) {
return (pledged() / goal()) * 100.0f;
}
return 0.0f;
}
public @NonNull String param() {
final String slug = slug();
return slug != null ? slug : String.valueOf(id());
}
public @NonNull String secureWebProjectUrl() {
// TODO: Just use http with local env
return Uri.parse(webProjectUrl()).buildUpon().scheme("https").build().toString();
}
public @NonNull String newPledgeUrl() {
return Uri.parse(secureWebProjectUrl()).buildUpon().appendEncodedPath("pledge/new").toString();
}
public @NonNull String editPledgeUrl() {
return Uri.parse(secureWebProjectUrl()).buildUpon().appendEncodedPath("pledge/edit").toString();
}
public @NonNull String rewardSelectedUrl(final @NonNull Reward reward) {
return Uri.parse(newPledgeUrl())
.buildUpon().scheme("https")
.appendQueryParameter("backing[backer_reward_id]", String.valueOf(reward.id()))
.appendQueryParameter("clicked_reward", "true")
.build()
.toString();
}
@Override
public final @NonNull String toString() {
return "Project{"
+ "id=" + id() + ", "
+ "name=" + name() + ", "
+ "}";
}
@Override
public final boolean equals(final @Nullable Object o) {
if (o != null && o instanceof Project) {
final Project p = (Project) o;
return id() == p.id();
}
return false;
}
@Override
public final int hashCode() {
return (int) id();
}
}