package com.thebluealliance.androidclient.models; import com.google.gson.Gson; import com.thebluealliance.androidclient.Utilities; import com.thebluealliance.androidclient.database.TbaDatabaseModel; import com.thebluealliance.androidclient.database.tables.EventsTable; import com.thebluealliance.androidclient.gcm.notifications.NotificationTypes; import com.thebluealliance.androidclient.helpers.EventHelper; import com.thebluealliance.androidclient.helpers.ThreadSafeFormatters; import com.thebluealliance.androidclient.types.DistrictType; import com.thebluealliance.androidclient.types.EventType; import com.thebluealliance.androidclient.viewmodels.EventViewModel; import com.thebluealliance.androidclient.viewmodels.ViewModelRenderer; import com.thebluealliance.api.model.IDistrict; import com.thebluealliance.api.model.IEvent; import android.content.ContentValues; import android.content.Context; import android.support.annotation.IntDef; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.text.ParseException; import java.util.Calendar; import java.util.Date; import javax.annotation.Nullable; public class Event implements IEvent, TbaDatabaseModel, ViewModelRenderer<EventViewModel, Integer> { @Retention(RetentionPolicy.SOURCE) @IntDef({RENDER_BASIC, RENDER_MYTBA_BUTTON}) public @interface RenderType { } public static final int RENDER_BASIC = 0; public static final int RENDER_MYTBA_BUTTON = 1; private String key; private String eventCode; private String name; private Integer year; private @Nullable Integer week; private @Nullable Integer eventType; private @Nullable String eventTypeString; private @Nullable String shortName; private @Nullable String address; private @Nullable IDistrict district; private @Nullable String districtKey; private @Nullable String gmapsUrl; private @Nullable String locationName; private @Nullable String location; private @Nullable String city; private @Nullable String webcasts; private @Nullable String website; private @Nullable Date endDate; private @Nullable Date startDate; private @Nullable String timezone; private @Nullable Long lastModified; public static final String[] NOTIFICATION_TYPES = { NotificationTypes.UPCOMING_MATCH, NotificationTypes.MATCH_SCORE, NotificationTypes.LEVEL_STARTING, NotificationTypes.ALLIANCE_SELECTION, NotificationTypes.AWARDS, NotificationTypes.SCHEDULE_UPDATED, NotificationTypes.MATCH_VIDEO, //NotificationTypes.FINAL_RESULTS }; public Event() { startDate = null; endDate = null; } @Nullable @Override public Integer getWeek() { return week; } @Override public void setWeek(@Nullable Integer competitionWeek) { if (competitionWeek == null) { /* Fall back and calculate the week, mainly for offseason events */ Date start; start = getFormattedStartDate(); Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(start.getTime()); int eventWeek = cal.get(Calendar.WEEK_OF_YEAR); int firstWeek = Utilities.getFirstCompWeek(cal.get(Calendar.YEAR)); int week = eventWeek - firstWeek; this.week = Math.max(week, 0); // Ensure that week is never <0 } else { /* TBA Server regards 'week 0' as the first competition week */ this.week = competitionWeek; } } @Override public @Nullable Date getEndDate() { return endDate; } public void setEndDate(@Nullable Date endDate) { this.endDate = endDate; } @Override public String getEventCode() { if (eventCode == null) { return EventHelper.getEventCode(key); } return eventCode; } @Override public void setEventCode(String eventCode) { this.eventCode = eventCode; } @Override @Nullable public IDistrict getDistrict() { return district; } @Override public void setDistrict(@Nullable IDistrict district) { this.district = district; } @Nullable public String getDistrictKey() { return districtKey; } public void setDistrictKey(@Nullable String districtKey) { this.districtKey = districtKey; } @Nullable @Override public Integer getEventType() { return eventType; } @Override public void setEventType(Integer eventType) { this.eventType = eventType; } @Nullable @Override public String getEventTypeString() { return eventTypeString; } @Override public void setEventTypeString(@Nullable String eventTypeString) { this.eventTypeString = eventTypeString; } @Override public String getKey() { return key; } @Override public void setKey(String key) { this.key = key; } @Nullable @Override public Long getLastModified() { return lastModified; } @Override public void setLastModified(@Nullable Long lastModified) { this.lastModified = lastModified; } @Override @Nullable public String getAddress() { return address; } @Override public void setAddress(@Nullable String address) { this.address = address; } @Override public String getName() { return name; } @Override public void setName(String name) { this.name = name; } @Nullable @Override public String getShortName() { if (shortName == null || shortName.isEmpty()) { return getName(); } return shortName; } @Override public void setShortName(@Nullable String shortName) { this.shortName = shortName; } @Override public void setStartDate(@Nullable Date startDate) { this.startDate = startDate; } @Override @Nullable public Date getStartDate() { return startDate; } @Nullable @Override public String getTimezone() { return timezone; } @Override public void setTimezone(@Nullable String timezone) { this.timezone = timezone; } @Nullable @Override public String getWebcasts() { return webcasts; } @Override public void setWebcasts(@Nullable String webcasts) { this.webcasts = webcasts; } @Nullable @Override public String getWebsite() { return website; } @Override public void setWebsite(String website) { this.website = website; } @Override public void setYear(Integer year) { this.year = year; } @Override public Integer getYear() { if (year == null) { int year = EventHelper.getYear(getKey()); setYear(year); return year; } return year; } @Override @Nullable public String getGmapsUrl() { return gmapsUrl; } @Override public void setGmapsUrl(@Nullable String gmapsUrl) { this.gmapsUrl = gmapsUrl; } @Override @Nullable public String getLocationName() { return locationName; } @Override public void setLocationName(@Nullable String locationName) { this.locationName = locationName; } @Nullable public String getLocation() { return location; } @Nullable public String getCity() { return city; } public void setCity(@Nullable String city) { this.city = city; } public void setLocation(@Nullable String location) { this.location = location; } public void setStartDate(String startString) { if (startString.isEmpty()) { return; } try { startDate = ThreadSafeFormatters.parseEventDate(startString); setStartDate(startDate); } catch (ParseException ex) { //can't parse the date throw new IllegalArgumentException( "Invalid date format: " + startString + ". Should be like yyyy-MM-dd"); } } public void setStartDate(long timestamp) { startDate = new Date(timestamp); } public Date getFormattedStartDate() { if (startDate == null) { startDate = new Date(0); } return startDate; } public void setEndDate(String endString) { if (endString.isEmpty()) { return; } try { endDate = ThreadSafeFormatters.parseEventDate(endString); setEndDate(endDate); } catch (ParseException ex) { //can't parse the date throw new IllegalArgumentException("Invalid date format. Should be like yyyy-MM-dd"); } } public void setEndDate(long timestamp) { endDate = new Date(timestamp); } public Date getFormattedEndDate() { if (endDate == null) { endDate = new Date(0); } return endDate; } /** * Gets the event key with the year stripped out. * * @return Event key without the year */ public String getYearAgnosticEventKey() { return getKey().replaceAll("[0-9]", ""); } public void setCompetitionWeekFromStartDate() { Date start; start = getFormattedStartDate(); Calendar cal = Calendar.getInstance(); cal.setTimeInMillis(start.getTime()); int eventWeek = cal.get(Calendar.WEEK_OF_YEAR); int firstWeek = Utilities.getFirstCompWeek(cal.get(Calendar.YEAR)); int week = eventWeek - firstWeek; week = Math.max(week, 0); // Ensure that week is never <0 setWeek(week); } public boolean isHappeningNow() { Date startDate = getFormattedStartDate(), endDate = getFormattedEndDate(); //since the Dates are at time 0:00, we need to add one day to the end date so that times // during that day count as part of the event Calendar c = Calendar.getInstance(); c.setTime(endDate); c.add(Calendar.DATE, 1); endDate = c.getTime(); if (startDate == null) { return false; } Date now = new Date(); return now.after(startDate) && now.before(endDate); } public boolean isChampsEvent() { Integer typeInt = getEventType(); if (typeInt == null) { return false; } EventType type = EventType.fromInt(typeInt); return (type == EventType.CMP_DIVISION || type == EventType.CMP_FINALS); } public String getDateString() { if (getStartDate() == null || getEndDate() == null) { return ""; } Date startDate = getFormattedStartDate(), endDate = getFormattedEndDate(); if (startDate.equals(endDate)) { return ThreadSafeFormatters.renderEventDate(startDate); } return ThreadSafeFormatters.renderEventShortFormat(startDate) + " to " + ThreadSafeFormatters.renderEventDate(endDate); } public EventType getEventTypeEnum() { @Nullable Integer eventType = getEventType(); return eventType != null ? EventType.fromInt(eventType) : EventType.NONE; } public DistrictType getEventDistrictEnum() { @Nullable IDistrict district = getDistrict(); return district != null ? DistrictType.fromAbbreviation(district.getAbbreviation()) : DistrictType.NO_DISTRICT; } public String getEventDistrictString() { DistrictType districtType = getEventDistrictEnum(); return districtType.getName(); } public String getSearchTitles() { Integer year = getYear(); return String.format("%1$s,%2$s %3$s,%4$s %5$s,%6$s", getKey(), year, getName(), year, getShortName(), getEventCode()); } @Nullable @Override public EventViewModel renderToViewModel(Context context, @Nullable @RenderType Integer renderType) { if (renderType == null) { return null; } EventViewModel model; model = new EventViewModel(getKey(), getYear(), getShortName(), getDateString(), getLocation(), getEventDistrictString()); switch (renderType) { case RENDER_MYTBA_BUTTON: model.setShowMyTbaSettings(true); } return model; } @Override public ContentValues getParams(Gson gson) { @Nullable Date startDate = getStartDate(); @Nullable Date endDate = getEndDate(); @Nullable IDistrict district = getDistrict(); ContentValues params = new ContentValues(); params.put(EventsTable.KEY, getKey()); params.put(EventsTable.YEAR, getYear()); params.put(EventsTable.NAME, getName()); params.put(EventsTable.SHORTNAME, getShortName()); params.put(EventsTable.LOCATION, getLocation()); params.put(EventsTable.CITY, getCity()); params.put(EventsTable.VENUE, getLocationName()); params.put(EventsTable.ADDRESS, getAddress()); params.put(EventsTable.TYPE, getEventType()); params.put(EventsTable.DISTRICT_KEY, district != null ? district.getKey() : ""); params.put(EventsTable.START, startDate != null ? startDate.getTime() : 0); params.put(EventsTable.END, endDate != null ? endDate.getTime() : 0); params.put(EventsTable.WEEK, getWeek()); params.put(EventsTable.WEBCASTS, getWebcasts()); params.put(EventsTable.WEBSITE, getWebsite()); params.put(EventsTable.LAST_MODIFIED, getLastModified()); return params; } }