package net.pokeranalytics.android.util.extensions

import java.text.DateFormat
import java.text.SimpleDateFormat
import java.util.*


// Calendar

// Return a double representing the hour / minute of a date from a calendar
fun Calendar.hourMinute(): Double {
	return (this.get(Calendar.HOUR_OF_DAY) + this.get(Calendar.MINUTE).toDouble() / 60.0).roundOffDecimal()
}


// Return if the calendar dates are in the same month
fun Calendar.isSameMonth(calendar: Calendar): Boolean {
	return calendar.get(Calendar.YEAR) == this.get(Calendar.YEAR) &&
			calendar.get(Calendar.MONTH) == this.get(Calendar.MONTH)
}

// Return if the calendar dates are in the same day
fun Calendar.isSameDay(calendar: Calendar): Boolean {
	return calendar.get(Calendar.YEAR) == this.get(Calendar.YEAR) &&
			calendar.get(Calendar.MONTH) == this.get(Calendar.MONTH) &&
			calendar.get(Calendar.DAY_OF_MONTH) == this.get(Calendar.DAY_OF_MONTH)
}

// Date

// Return a short string of the date
fun Date.shortDate(): String {
	return DateFormat.getDateInstance(DateFormat.SHORT).format(this)
}

// Return a short string of the date
fun Date.mediumDate(): String {
	return DateFormat.getDateInstance(DateFormat.MEDIUM).format(this)
}

// Return a long string of the date
fun Date.longDate(): String {
	return DateFormat.getDateInstance(DateFormat.LONG).format(this)
}

// Return a short string of the date
fun Date.fullDate(): String {
	return DateFormat.getDateInstance(DateFormat.FULL).format(this)
}

// Return a short string of the time
fun Date.shortTime(): String {
	return DateFormat.getTimeInstance(DateFormat.SHORT).format(this)
}

// Return a short string of the time
fun Date.mediumTime(): String {
	return DateFormat.getTimeInstance(DateFormat.MEDIUM).format(this)
}

// Return a long string of the time
fun Date.longTime(): String {
	return DateFormat.getTimeInstance(DateFormat.LONG).format(this)
}

// Return a short string of the time
fun Date.fullTime(): String {
	return DateFormat.getTimeInstance(DateFormat.FULL).format(this)
}

// Return a short string of the date & time
fun Date.shortDateTime(): String {
	return DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT).format(this)
}

// Return a medium string of the date & time
fun Date.mediumDateTime(): String {
	return DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM).format(this)
}

// Return a long string of the date & time
fun Date.longDateTime(): String {
	return DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG).format(this)
}

// Return the full string of the date & time
fun Date.fullDateTime(): String {
	return DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL).format(this)
}

// Return the day number of the date
fun Date.getDayNumber(): String {
	return SimpleDateFormat("dd", Locale.getDefault()).format(this)
}

// Return the 3 first letters of the date's day
fun Date.getShortDayName(): String {
	return SimpleDateFormat("EEE", Locale.getDefault()).format(this)
}

// Return the month of the date
fun Date.getDateMonth(): String {
	return SimpleDateFormat("MMMM", Locale.getDefault()).format(this).capitalize()
}

// Return the year of the date
fun Date.getDateYear(): String {
	return SimpleDateFormat("yyyy", Locale.getDefault()).format(this).capitalize()
}

// Return the month & year of the date
fun Date.getMonthAndYear(): String {
	return SimpleDateFormat("MMMM yyyy", Locale.getDefault()).format(this).capitalize()
}

// Return the netDuration between two dates
fun Date.getFormattedDuration(toDate: Date): String {
	val difference = (toDate.time - this.time).toInt()
	val hours = (difference / (1000 * 60 * 60))
	val minutes = (difference / (1000 * 60)) % 60

	val hoursStr = "$hours"
	val minutesStr = if (minutes < 10) "0$minutes" else "$minutes"

	return "$hoursStr:$minutesStr"
}

// Return the date of the beginning of the current date
fun Date.startOfDay(): Date {
	val calendar = Calendar.getInstance()
	calendar.time = this
	calendar.set(Calendar.HOUR_OF_DAY, 0)
	calendar.set(Calendar.MINUTE, 0)
	calendar.set(Calendar.SECOND, 0)
	calendar.set(Calendar.MILLISECOND, 0)
	return calendar.time
}

// Return the date of the end of the current date
fun Date.endOfDay(): Date {
	val calendar = Calendar.getInstance()
	calendar.time = this
	calendar.set(Calendar.HOUR_OF_DAY, 23)
	calendar.set(Calendar.MINUTE, 59)
	calendar.set(Calendar.SECOND, 59)
	calendar.set(Calendar.MILLISECOND, 999)
	return calendar.time
}

// Return the date of the beginning of the current month
fun Date.startOfMonth(): Date {
	val calendar = Calendar.getInstance()
	calendar.time = this.startOfDay()
	calendar.set(Calendar.DAY_OF_MONTH, 1)
	return calendar.time
}

// Return the date of the beginning of the current year
fun Date.startOfYear(): Date {
	val calendar = Calendar.getInstance()
	calendar.time = this.startOfMonth()
	calendar.set(Calendar.MONTH, 0)
	return calendar.time
}

// Return the number of seconds until the next minute
fun Date.getNextMinuteInseconds(): Int {
	return (getNextMinuteInMilliseconds() / 1000).toInt()
}

// Return the number of milliseconds until the next minute
fun Date.getNextMinuteInMilliseconds(): Long {
	val calendar = Calendar.getInstance()
	calendar.add(Calendar.MINUTE, 1)
	calendar.set(Calendar.SECOND, 0)
	calendar.set(Calendar.MILLISECOND, 0)
	return calendar.time.time - this.time
}

fun Date.setHourMinutes(value: String, dateFormat: String = "HH:mm") {
	val calendar1 = Calendar.getInstance()
	calendar1.time = this
	val calendar2 = Calendar.getInstance().apply { time = SimpleDateFormat(dateFormat, Locale.getDefault()).parse(value) }
	calendar1.set(Calendar.HOUR_OF_DAY, calendar2.get(Calendar.HOUR_OF_DAY))
	calendar1.set(Calendar.MINUTE, calendar2.get(Calendar.MINUTE))
	calendar1.set(Calendar.SECOND, 0)
	calendar1.set(Calendar.MILLISECOND, 0)
	this.time = calendar1.time.time
}
