﻿(function ($) {
   $.fn.friendlyDate = function () {

      $.friendlyDate = function (date) {
         if (date instanceof Date) {
           
         } else if (typeof date === "string") {
            
         } else {
            
         }
      };

      var $f = $.friendlyDate;
      
   };
})(jQuery);

var DateTimeFunctions = {};

/// <summary>
/// Takes a date and gets the relative friendly date describing it.
/// </summary>
/// <param name="e">The date and time that should be formatted.</param>
/// <param name="BeingUsedInScentence">Indicate, if the resulting string should be used in a scentence; and is so;
/// will not output capital letters and full stops.</param>
/// <param name="GoIntoHoursIfToday">If the date is today, indicate if an hourly countdown should be
/// used instead of giving the time.</param>
/// <param name="UseUntilInsteadOfAt">For durations, if a set event is in the future, you'll want to use 'at'; if
/// something is running from now until the future, you'll want 'until'.</param>
/// <returns>This function should be avoided if you want to show a user a precise date and time at all times. This
/// method will return different strings as we more further away from or close to the input date.</returns>
DateTimeFunctions.GetFriendlyDate = function (e,
                                             beingUsedInScentence,
                                             goIntoHoursIfToday,
                                             useUntilInsteadOfAt,
                                             timeFormatString) {

   var at = null;
   var systemUTC = new Date();

   if (!timeFormatString) {
      timeFormatString = "h:MMtt";
   }

   var sevenDaysAgo = new Date();
   sevenDaysAgo.setDate(systemUTC.getDate() - 7);

   var tomorrow = new Date();
   tomorrow.setDate(systemUTC.getDate() + 1);

   var yesterday = new Date();
   yesterday.setDate(systemUTC.getDate() - 1);

   var sevenDaysAhead = new Date();
   sevenDaysAhead.setDate(systemUTC.getDate() + 7);

   var monthAgo = new Date();
   monthAgo.setMonth(systemUTC.getMonth() - 1);

   if (useUntilInsteadOfAt) {
      if (beingUsedInScentence) {
         at = "until";
      } else {
         at = "Until";
      }
   } else {
      if (beingUsedInScentence) {
         at = "at";
      } else {
         at = "At";
      }
   }

   /* TODAY */
   if (e.getDate() == systemUTC.getDate() && e.getFullYear() == systemUTC.getFullYear() && e.getMonth() == systemUTC.getMonth()) {

      var timeAgo = TimeSpan.FromDates(e, systemUTC);
      /* WITHIN THE LAST HOUR, AND SHOWING RELATIVE TIMESTAMP (33 mins ago etc) */
      if (goIntoHoursIfToday && timeAgo.hours() <= 6 && timeAgo.hours() >= 0) {
         if (timeAgo.hours() === 0) {
            if (timeAgo.minutes() === 0) {
               var s = "A";
               if (beingUsedInScentence) {
                  s = "a";
               }
               s += " few moments ago";
               if (!beingUsedInScentence) {
                  s += ".";
               }
               return s;
            } else {
               if (timeAgo.minutes() === 1) {
                  var s = "1 minute ago";
                  if (!beingUsedInScentence) {
                     s += ".";
                  }
                  return s;
               } else {
                  var s = timeAgo.minutes() + " minutes ago";
                  if (!beingUsedInScentence) {
                     s += ".";
                  }
                  return s;
               }
            }
            //between 1 and 2 hours ago...
         }
         else {
            var s = "About";
            if (beingUsedInScentence) {
               s = "about";
            }

            var hours = timeAgo.hours();

            if (timeAgo.minutes() >= 45) {
               hours += 1;
            }

            if (timeAgo.hours() == 1) {
               s += " an hour ago";
            } else {
               s += " " + timeAgo.hours() + " hours ago";
            }

            if (!beingUsedInScentence) {
               s += ".";
            }

            return s;
         }
      }
      /* SHOWING ABSOLUTE TIMESTAMP */
      else {
         /* MORNING */
         if (e.getHours() < 12) {
            //Morning
            var s = "This Morning";
            if (beingUsedInScentence) {
               s = "this morning";
            }
            s += " at " + e.format(timeFormatString);
            if (!beingUsedInScentence) {
               s += ".";
            }
            return s;
         }
         /* EVENING */
         else if (e.getHours() > 17) {
            var s = "This Evening";
            if (beingUsedInScentence) {
               s = "this evening";
            }
            s += " at " + e.format(timeFormatString);
            if (!beingUsedInScentence) {
               s += ".";
            }
            return s;
         }
         /* AFTERNOON */
         else {
            var s = "This Afternoon";
            if (beingUsedInScentence) {
               s = "this afternoon";
            }
            s += " at " + e.format(timeFormatString);
            if (!beingUsedInScentence) {
               s += ".";
            }
            return s;
         }
      }
   }
   /* YESTERDAY */
   else if (e.getDate() == yesterday.getDate() && e.getFullYear() == yesterday.getFullYear() && e.getMonth() == yesterday.getMonth()) {
      if (e.getHours() == 0) {
         if (beingUsedInScentence) {
            return at + " midnight last night";
         } else {
            return at + " midnight last night.";
         }
      } else {
         var s = "Yesterday";
         if (beingUsedInScentence) {
            s = "yesterday";
         }

         if (e.getHours() > 17) {
            s += " evening";
         } else if (e.getHours() > 12) {
            s += " afternoon";
         } else {
            s += " morning";
         }

         s += " at " + e.format(timeFormatString);
         if (!beingUsedInScentence) {
            s += ".";
         }
         return s;
      }

   }
   /* TOMMORROW */
   else if (e.getDate() == tomorrow.getDate() && e.getFullYear() == tomorrow.getFullYear() && e.getMonth() == tomorrow.getMonth()) {
      if (e.getHours() == 0) {
         if (beingUsedInScentence) {
            return at + " midnight tonight";
         } else {
            return at + " midnight tonight.";
         }
      } else {
         var s = "Tomorrow";
         if (beingUsedInScentence) {
            s = "tomorrow";
         }

         if (e.getHours() > 17) {
            s += " evening";
         } else if (e.getHours() > 12) {
            s += " afternoon";
         } else {
            s += " morning";
         }

         s += " at " + e.format(timeFormatString);

         if (!beingUsedInScentence) {
            s += ".";
         }

         return s;
      }

      //In the last 7 days.
   }
   /* WITHIN THE LAST SEVEN DAYS */
   else if (e.getTime() >= sevenDaysAgo.getTime() && e.getTime() < systemUTC.getTime()) {

      var daySpan = TimeSpan.FromDates(sevenDaysAgo, e);
      var daysAgo = daySpan.days + 7;


      if (daysAgo <= 4) {
         if (e.getHours() == 0) {
            e = e.AddDays(-1);
            var s = at + " midnight on " + e.format("dddd");
            if (!beingUsedInScentence) {
               s += ".";
            }
            return s;
         } else {
            var s = "On";
            if (beingUsedInScentence) {
               s = "on";
            }
            s += " " + e.format("dddd") + " at " + e.format("h:MMtt");
            if (!beingUsedInScentence) {
               s += ".";
            }
            return s;

         }
      } else {
         if (e.getHours() == 0) {
            e.setDate(e.getDate() + 1);
            var s = "Midnight last";
            if (beingUsedInScentence) {
               s = "at midnight last";
            }
            s += " " + e.format("dddd");
            if (!beingUsedInScentence) {
               s += ".";
            }
            return s;
         } else {
            var s = "Last";
            if (beingUsedInScentence) {
               s = "last";
            }
            s += " " + e.format("dddd") + " at " + e.format(timeFormatString);
            if (!beingUsedInScentence) {
               s += ".";
            }
            return s;
         }
      }

      //In the next 7 days.
   }
   /* WITHIN THE NEXT SEVEN DAYS */
   else if (e.getTime() <= sevenDaysAhead.getTime() && e.getTime() > systemUTC.getTime()) {
      if (e.getHours() == 0) {
         var s = at + " midnight next ";

         e.setDate(e.getDate() - 1);
         s += e.format("dddd");
         return s;

      } else {
         var s = "At";

         if (beingUsedInScentence) {
            s = "at";
         }

         if (useUntilInsteadOfAt) {
            if (beingUsedInScentence) {
               s = "until";
            } else {
               s = "Until";
            }
         }

         s += " " + e.format(timeFormatString) + " on " + e.format("dddd");

         if (!beingUsedInScentence) {
            s += ".";
         }
         return s;

      }
      // Over 7 days in the past or future.
   }
   /* MORE THAN SEVEN DAYS IN THE FUTURE OR MORE THAN SEVEN DAYS IN THE PAST */
   else {
      var result = "";
      /* MORE THAN SEVEN DAYS IN THE FUTURE */
      if (e.getTime() > systemUTC.getTime()) {
         // In the future, so we report the time...
         if (e.getHours() == 0) {
            e.setDate(e.getDate() - 1);

            result = at + " ";

            result += "midnight on " + e.format("dddd, mmmm dS");

            if (e.getFullYear() != systemUTC.getFullYear()) {
               result += " " + e.format("yyyy");
            }

            if (!beingUsedInScentence) {
               result += ".";
            }

            return result;

         } else {

            if (e.getTime() >= sevenDaysAgo.getTime()) {
               result += at + " " + e.format(timeFormatString);

               result += " on " + e.format("dddd, mmmm dS");

               if (e.getFullYear() != systemUTC.getFullYear()) {
                  result += " " + e.format("yyyy");
               }

               if (!beingUsedInScentence) {
                  result += ".";
               }
               return result;
            } else {
               if (beingUsedInScentence) {
                  result += "on ";
               } else {
                  result += "On ";
               }

               result += e.format("dddd, mmmm dS");

               if (e.getFullYear() != systemUTC.getFullYear()) {
                  result += " " + e.format("yyyy");
               }

               if (!beingUsedInScentence) {
                  result += ".";
               }
               return result;
            }

         }
         // In the past, we omit the time.
      }
      else
      /* MORE THAN SEVEN DAYS IN THE PAST */
      {
         if (e.getTime() > monthAgo.getTime()) {
            // Within the last month, report the day name.
            if (beingUsedInScentence) {
               result += "on ";
            }

            result += e.format("dddd, mmmm dS");

            if (e.getFullYear() != systemUTC.getFullYear()) {
               result += " " + e.format("yyyy");
            }

            if (!beingUsedInScentence) {
               result += ".";
            }
            return result;
         } else {
            // Over 3 months ago, skip day name.
            if (beingUsedInScentence) {
               result += "on ";
            }

            result += e.format("mmmm dS");

            if (e.getFullYear() != systemUTC.getFullYear()) {
               result += " " + e.format("yyyy");
            }

            if (!beingUsedInScentence) {
               result += ".";
            }
            return result;
         }
      }
   }

}
