package com.schneeloch.bostonbusmap_library.data;
import java.util.Calendar;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.google.common.base.Joiner;
import com.google.common.base.Objects;
import com.google.common.collect.ComparisonChain;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.schneeloch.bostonbusmap_library.util.AlertInfoConstants;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.Html;
import android.text.Spanned;
/**
* Immutable alert data
*
* @author schneg
*
*/
public class Alert implements Parcelable, Comparable<Alert>
{
private final Date date;
private final String title;
private final String description;
public Alert(Date date, CharSequence title, CharSequence description)
{
this.date = date;
this.title = title.toString();
this.description = description.toString();
}
public Date getDate() {
return date;
}
public String getTitle() {
return title;
}
public String getDescription() {
return description;
}
public static Map<String, Spanned> makeSnippetMap(List<Alert> alerts)
{
String ret = Alert.makeSnippet(alerts);
return ImmutableMap.of(AlertInfoConstants.textKey, Html.fromHtml(ret));
}
/**
*
* @param alerts Some collection of alerts with the same description
* @return Pseudo HTML which is shown in the AlertInfo screen
*/
private static String makeSnippet(List<Alert> alerts)
{
StringBuilder builder = new StringBuilder();
if (alerts.size() == 0) {
return "";
}
Set<String> titles = Sets.newTreeSet();
for (Alert alert : alerts) {
String title = alert.getTitle();
if (title != null && title.length() != 0) {
titles.add(title);
}
}
builder.append("<b>").append(Joiner.on("<br />").join(titles)).append("</b><br />");
Alert firstAlert = alerts.get(0);
String description = firstAlert.getDescription();
if (description != null && description.length() != 0)
{
String newDescription = description.replace("\n", "<br/>");
builder.append(newDescription).append("<br />");
}
return builder.toString();
}
private boolean sameDay(Calendar date1, Calendar date2)
{
return date1.get(Calendar.DATE) == date2.get(Calendar.DATE) &&
date1.get(Calendar.MONTH) == date2.get(Calendar.MONTH) &&
date1.get(Calendar.YEAR) == date2.get(Calendar.YEAR);
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel dest, int flags)
{
long time;
if (date != null)
{
time = date.getTime();
}
else
{
time = 0;
}
dest.writeLong(time);
dest.writeString(title);
dest.writeString(description);
}
public static final Creator<Alert> CREATOR = new Creator<Alert>() {
@Override
public Alert[] newArray(int size) {
return new Alert[size];
}
@Override
public Alert createFromParcel(Parcel source) {
long epoch = source.readLong();
Date date = epoch == 0 ? null : new Date(epoch);
String title = source.readString();
String description = source.readString();
Alert alert = new Alert(date, title, description);
return alert;
}
};
@Override
public int compareTo(Alert another) {
return ComparisonChain.start().compare(date, another.date)
.compare(title, another.title)
.compare(description, another.description).result();
}
@Override
public int hashCode() {
return Objects.hashCode(date, title, description);
}
@Override
public boolean equals(Object o) {
if (o instanceof Alert) {
Alert another = (Alert)o;
return Objects.equal(date, another.date) &&
Objects.equal(title, another.title) &&
Objects.equal(description, another.description);
}
else
{
return false;
}
}
public static List<List<Alert>> groupAlerts(Collection<Alert> alerts) {
HashMap<String, List<Alert>> commonAlerts = Maps.newHashMap();
for (Alert alert : alerts)
{
if (commonAlerts.containsKey(alert.getDescription()) == false) {
List<Alert> alertList = Lists.newArrayList();
commonAlerts.put(alert.getDescription(), alertList);
}
commonAlerts.get(alert.getDescription()).add(alert);
}
List<List<Alert>> alertGroups = Lists.newArrayList();
for (Map.Entry<String, List<Alert>> entry : commonAlerts.entrySet()) {
List<Alert> alertsInGroup = entry.getValue();
Collections.sort(alertsInGroup, new Comparator<Alert>() {
@Override
public int compare(Alert lhs, Alert rhs) {
return lhs.getTitle().compareTo(rhs.getTitle());
}
});
alertGroups.add(alertsInGroup);
}
Collections.sort(alertGroups, new Comparator<List<Alert>>() {
@Override
public int compare(List<Alert> lhs, List<Alert> rhs) {
String lhsDescription = lhs.get(0).getTitle();
String rhsDescription = rhs.get(0).getTitle();
return lhsDescription.compareTo(rhsDescription);
}
});
return alertGroups;
}
}