using System; using System.Collections.Generic; using System.Linq; using Iesi.Collections.Generic; using Portoa.Persistence; namespace VideoGameQuotes.Api { public class Quote : Entity { private readonly Iesi.Collections.Generic.ISet votes = new HashedSet(); private readonly Iesi.Collections.Generic.ISet flags = new HashedSet(); private readonly Iesi.Collections.Generic.ISet categories = new HashedSet(); public Quote() { Created = DateTime.UtcNow; } public virtual User Creator { get; set; } public virtual DateTime Created { get; set; } public virtual DateTime? Modified { get; set; } public virtual string Text { get; set; } public virtual Game Game { get; set; } public virtual IEnumerable Votes { get { return votes; } } public virtual IEnumerable Flags { get { return flags; } } public virtual IEnumerable Categories { get { return categories; } } #region adding and removing stuff public virtual Quote AddCategory(Category category) { categories.Add(category); return this; } public virtual void ClearCategories() { categories.Clear(); } public virtual Quote AddFlag(QuoteFlag flag) { flags.Add(flag); return this; } public virtual void ClearFlags() { flags.Clear(); } #endregion public virtual Quote VoteFor(User user, VoteDirection direction) { var currentVote = votes.SingleOrDefault(vote => vote.Voter == user); if (currentVote != null) { if (currentVote.Direction == direction) { throw new CannotVoteTwiceException(); } votes.Remove(currentVote); currentVote.Direction = direction; currentVote.Created = DateTime.UtcNow; votes.Add(currentVote); } else { votes.Add(new Vote { Direction = direction, Quote = this, Voter = user }); } return this; } public virtual int UpVotes { get { return Votes.Count(vote => vote.Direction == VoteDirection.Up); } } public virtual int DownVotes { get { return Votes.Count(vote => vote.Direction == VoteDirection.Down); } } public virtual int NetVotes { get { return Votes.Sum(vote => (int)vote); } } } public static class QuoteExtensions { public static string GetHumanReadableTimeSinceCreated(this Quote quote) { var timespan = DateTime.UtcNow.Subtract(quote.Created); if (timespan.TotalDays >= 365) { var years = (int)Math.Round(timespan.TotalDays / 365); return years == 1 ? "1 year ago" : years + " years ago"; } if (timespan.TotalDays >= 50) { var months = (int)Math.Round(timespan.TotalDays / 30); return months == 1 ? "1 month ago" : months + " months ago"; } if (timespan.TotalDays >= 10) { var weeks = (int)Math.Round(timespan.TotalDays / 7); return weeks == 1 ? "1 week ago" : weeks + " weeks ago"; } if (timespan.TotalDays >= 1) { return (int)timespan.TotalDays == 1 ? "1 day ago" : (int)timespan.TotalDays + " days ago"; } if (timespan.TotalMinutes >= 90) { return (int)timespan.TotalHours == 1 ? "1 hour ago" : (int)timespan.TotalHours + " hours ago"; } if (timespan.TotalSeconds >= 90) { return (int)timespan.TotalMinutes == 1 ? "1 minute ago" : (int)timespan.TotalMinutes + " minutes ago"; } return (int)timespan.TotalSeconds == 1 ? "1 second ago" : (int)timespan.TotalSeconds + " seconds ago"; } } }