<template>
<div class="mk-calendar" :data-melt="design == 4 || design == 5">
	<template v-if="design == 0 || design == 1">
		<button @click="prev" title="%i18n:@prev%">%fa:chevron-circle-left%</button>
		<p class="title">{{ '%i18n:@title%'.replace('{1}', year).replace('{2}', month) }}</p>
		<button @click="next" title="%i18n:@next%">%fa:chevron-circle-right%</button>
	</template>

	<div class="calendar">
		<template v-if="design == 0 || design == 2 || design == 4">
		<div class="weekday"
			v-for="(day, i) in Array(7).fill(0)"
			:data-today="year == today.getFullYear() && month == today.getMonth() + 1 && today.getDay() == i"
			:data-is-donichi="i == 0 || i == 6"
		>{{ weekdayText[i] }}</div>
		</template>
		<div v-for="n in paddingDays"></div>
		<div class="day" v-for="(day, i) in days"
			:data-today="isToday(i + 1)"
			:data-selected="isSelected(i + 1)"
			:data-is-out-of-range="isOutOfRange(i + 1)"
			:data-is-donichi="isDonichi(i + 1)"
			@click="go(i + 1)"
			:title="isOutOfRange(i + 1) ? null : '%i18n:@go%'"
		>
			<div>{{ i + 1 }}</div>
		</div>
	</div>
</div>
</template>

<script lang="ts">
import Vue from 'vue';

const eachMonthDays = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

function isLeapYear(year) {
	return (year % 400 == 0) ? true :
		(year % 100 == 0) ? false :
			(year % 4 == 0) ? true :
				false;
}

export default Vue.extend({
	props: {
		design: {
			default: 0
		},
		start: {
			type: Date,
			required: false
		}
	},
	data() {
		return {
			today: new Date(),
			year: new Date().getFullYear(),
			month: new Date().getMonth() + 1,
			selected: new Date(),
			weekdayText: [
				'%i18n:common.weekday-short.sunday%',
				'%i18n:common.weekday-short.monday%',
				'%i18n:common.weekday-short.tuesday%',
				'%i18n:common.weekday-short.wednesday%',
				'%i18n:common.weekday-short.thursday%',
				'%i18n:common.weekday-short.friday%',
				'%i18n:common.weekday-short.saturday%'
			]
		};
	},
	computed: {
		paddingDays(): number {
			const date = new Date(this.year, this.month - 1, 1);
			return date.getDay();
		},
		days(): number {
			let days = eachMonthDays[this.month - 1];

			// うるう年なら+1日
			if (this.month == 2 && isLeapYear(this.year)) days++;

			return days;
		}
	},
	methods: {
		isToday(day) {
			return this.year == this.today.getFullYear() && this.month == this.today.getMonth() + 1 && day == this.today.getDate();
		},

		isSelected(day) {
			return this.year == this.selected.getFullYear() && this.month == this.selected.getMonth() + 1 && day == this.selected.getDate();
		},

		isOutOfRange(day) {
			const test = (new Date(this.year, this.month - 1, day)).getTime();
			return test > this.today.getTime() ||
				(this.start ? test < (this.start as any).getTime() : false);
		},

		isDonichi(day) {
			const weekday = (new Date(this.year, this.month - 1, day)).getDay();
			return weekday == 0 || weekday == 6;
		},

		prev() {
			if (this.month == 1) {
				this.year = this.year - 1;
				this.month = 12;
			} else {
				this.month--;
			}
		},

		next() {
			if (this.month == 12) {
				this.year = this.year + 1;
				this.month = 1;
			} else {
				this.month++;
			}
		},

		go(day) {
			if (this.isOutOfRange(day)) return;
			const date = new Date(this.year, this.month - 1, day, 23, 59, 59, 999);
			this.selected = date;
			this.$emit('chosen', this.selected);
		}
	}
});
</script>

<style lang="stylus" scoped>
@import '~const.styl'

root(isDark)
	color isDark ? #c5ced6 : #777
	background isDark ? #282C37 : #fff
	border solid 1px rgba(#000, 0.075)
	border-radius 6px
	overflow hidden

	&[data-melt]
		background transparent !important
		border none !important

	> .title
		z-index 1
		margin 0
		padding 0 16px
		text-align center
		line-height 42px
		font-size 0.9em
		font-weight bold
		color isDark ? #c5ced6 : #888
		box-shadow 0 1px rgba(#000, 0.07)

		if isDark
			background #313543

		> [data-fa]
			margin-right 4px

	> button
		position absolute
		z-index 2
		top 0
		padding 0
		width 42px
		font-size 0.9em
		line-height 42px
		color isDark ? #9baec8 : #ccc

		&:hover
			color isDark ? #b2c1d5 : #aaa

		&:active
			color isDark ? #b2c1d5 : #999

		&:first-of-type
			left 0

		&:last-of-type
			right 0

	> .calendar
		display flex
		flex-wrap wrap
		padding 16px

		*
			user-select none

		> div
			width calc(100% * (1/7))
			text-align center
			line-height 32px
			font-size 14px

			&.weekday
				color isDark ? #43d5dc : #19a2a9

				&[data-is-donichi]
					color isDark ? #ff6679 : #ef95a0

				&[data-today]
					box-shadow 0 0 0 1px isDark ? #43d5dc : #19a2a9 inset
					border-radius 6px

					&[data-is-donichi]
						box-shadow 0 0 0 1px isDark ? #ff6679 : #ef95a0 inset

			&.day
				cursor pointer
				color isDark ? #c5ced6 : #777

				> div
					border-radius 6px

				&:hover > div
					background rgba(#000, isDark ? 0.1 : 0.025)

				&:active > div
					background rgba(#000, isDark ? 0.2 : 0.05)

				&[data-is-donichi]
					color isDark ? #ff6679 : #ef95a0

				&[data-is-out-of-range]
					cursor default
					color rgba(isDark ? #c5ced6 : #777, 0.5)

					&[data-is-donichi]
						color rgba(isDark ? #ff6679 : #ef95a0, 0.5)

				&[data-selected]
					font-weight bold

					> div
						background rgba(#000, isDark ? 0.1 : 0.025)

					&:active > div
						background rgba(#000, isDark ? 0.2 : 0.05)

				&[data-today]
					> div
						color $theme-color-foreground
						background $theme-color

					&:hover > div
						background lighten($theme-color, 10%)

					&:active > div
						background darken($theme-color, 10%)

.mk-calendar[data-darkmode]
	root(true)

.mk-calendar:not([data-darkmode])
	root(false)

</style>
