<template>
	<view class="calendar">
		<view class="table">
			<view class="chose-head">
				<view class="chose-item">
					<view class="btn" @click="yearsub">
						<image src="../../static/images/arrow_left12.png" mode=""></image>
					</view>
					<view class="year-td">
						<picker mode="selector" :range="years" @change="yearchange" :value="y">
							<view class="text">{{years[y]}}年</view>
						</picker>
					</view>
					<view class="btn" @click="yearadd">
						<image src="../../static/images/arrow_right12.png" mode=""></image>
					</view>
				</view>
				
				<view class="chose-item">
					<view class="btn" @click="monthsub">
						<image src="../../static/images/arrow_left12.png" mode=""></image>
					</view>
					<view class="month-td">
						<picker mode="selector" :range="months" @change="monthchange" :value="m">
							<view class="text">{{months[m]}}月</view>
						</picker>
					</view>
					<view class="btn" @click="monthadd">
						<image src="../../static/images/arrow_right12.png" mode=""></image>
					</view>
				</view>
			</view>

			<view class="week">
				<view class="item">日</view>
				<view class="item">一</view>
				<view class="item">二</view>
				<view class="item">三</view>
				<view class="item">四</view>
				<view class="item">五</view>
				<view class="item">六</view>
			</view>


			<view class="date-tr" v-for="(i,index) in dates" :key="index">
				<view v-for="(j,k) in i" :key="k" :style="{color:j[0]}" :class="j[2]=='#FF5C03'?'td active':'td'" @click="itemChose(j,index,k)">{{j[1]}}</view>
			</view>
		</view>
	</view>
</template>

<script>
	export default {
		data() {
			return {
				year: 2022,
				month: 12,
				date: 19,
				/* 年月是当天的日期，日是这个月日历的第一天，
				其实就是上个月的最后一个周日，这里是随便定义的，
				后面在mounted里面根据当前日期赋值 */
				years: [], //存放1900到2100共200年
				months: [], //存放1到12月
				y: 0,
				m: 0, //picker的迭代器
				dates: [
					[],
					[],
					[],
					[],
					[],
					[]
				], //外层括号表示一个月，内层括号表示一周，每个元素是一天
				activeDateStr: '', // 当前选中的时间
			}
		},
		
		mounted() {
			for (let i = 1900; i <= 2100; i++) {
				this.years.push(i);
			}
			for (let i = 1; i <= 12; i++) {
				this.months.push(i);
			}
		
			//获取当前时间和月份
			var date = new Date();
			this.year = date.getFullYear();
			this.month = date.getMonth() + 1;
			let dayNum = date.getDate();
		
			for (let i = 0; i < 200; i++) {
				if (this.years[i] == this.year) {
					this.y = i;
					break;
				}
			}
			for (let i = 0; i < 12; i++) {
				if (this.months[i] == this.month) {
					this.m = i;
					break;
				}
			}
		
			//当前月份的天数和上个月的天数
			var maxdays = this.maxdformat();
			var maxday = maxdays[0];
			var premaxday = maxdays[1];
		
			//通过当月一号的星期来计算上个月的最后一个星期日时几号
			date.setDate(1);
			var weekday = date.getDay();
			this.date = premaxday - weekday + 1;
		
			//编排这个月的日历
			this.datesformat(maxday, premaxday);
			
			let mothnum = this.months[this.m]
			if(mothnum<10) {
				mothnum = '0'+mothnum
			}
			if(dayNum<10) {
				dayNum = '0'+dayNum
			}
			this.activeDateStr = this.years[this.y] + '-' + mothnum + '-' + dayNum
		},
		methods: {
			//编排日历
			datesformat(maxday, premaxday) {
				//获取当前日期，用来突出显示当前日期
				var date = new Date();
				var y = date.getFullYear();
				var m = date.getMonth() + 1;
				var d = date.getDate();

				var i = 0,
					j = 0;
				for (i; i < 3; i++) {
					for (j = 0; j < 7; j++) {
						let cache = ['#222222', '', '#fff']; //第一个元素用来定义字体颜色，第二个是日期，第三个元素是背景色，用来突出显示当前日期
						if (this.date > 21 && this.date <= premaxday) {
							cache[0] = '#BBBBBB';
						}
						/* 上个月的日期显示为灰色，只能判断前半个月,
						   因为如果到这个月的21号之后的话造成这个月的日期也变为灰色，
						   选21是因为前3周不可能到21号（1号在周日的话会放在第二周），
						   并且上个月的最后一个星期日必然是21号之后 */
						else if (this.year == y && this.month == m && this.date == d) {
							cache[2] = '#FF5C03'; // 当前日期背景颜色
							cache[0] = '#fff'; // 当前日期文字颜色
						}
						if (this.date <= premaxday) {
							cache[1] = this.date++;
						} else {
							this.date = 1;
							cache[1] = this.date++; //日期递增，如果超过上个月的最后一天的话重新从1号开始
						}
						this.dates[i].push(cache);
					}
				}
				for (i; i < 6; i++) {
					for (j = 0; j < 7; j++) {
						let cache = ['#222222', '', "#fff"]
						if (this.date < 14 || this.date == maxday + 1) {
							cache[0] = '#BBBBBB'
						} else if (this.year == y && this.month == m && this.date == d) {
							cache[2] = '#FF5C03'
							cache[0] = '#fff'; // 当前日期文字颜色
						}
						if (this.date <= maxday) {
							cache[1] = this.date++;
						} else {
							this.date = 1;
							cache[1] = this.date++;
						}
						/* 基本与上半月相似，下个月的日期显示为灰色，
						   选14是因为第4周的第一天最早是15号（1号在周日并放在第二周的情况），
						   并且下个月出现最多日期的情况（2月1号是周一）也不会有14天 */
						this.dates[i].push(cache);
					}
				}
			},

			//计算当月的天数和上个月的天数
			maxdformat() {
				var maxday = 30;
				var premaxday = 30; //都定义为30天，这样小月就不用判断了
				if (this.month == 2) {
					if (this.year % 400 == 0 || (this.year % 4 == 0 && this.year % 100 != 0)) { //二月判断平闰年
						maxday = 29;
					} else {
						maxday = 28;
					}
				} else if (this.month == 1 || this.month == 3 || this.month == 5 || this.month == 7 ||
					this.month == 8 || this.month == 10 || this.month == 12) { //给大月赋值
					maxday = 31;
				}

				//计算上个月的天数，月份+1直接用上面的
				if (this.month == 3) {
					if (this.year % 400 == 0 || (this.year % 4 == 0 && this.year % 100 != 0)) {
						premaxday = 29;
					} else {
						premaxday = 28;
					}
				} else if (this.month == 2 || this.month == 4 || this.month == 6 || this.month == 8 ||
					this.month == 9 || this.month == 11 || this.month == 1) {
					premaxday = 31;
				}
				return [maxday, premaxday];
			},

			//下一个月
			monthadd() {
				//月份加一，十二月下一个月是一月
				if (this.month == 12) {
					this.y++;
					this.year++;
					this.m = 0;
					this.month = 1;
				} else {
					this.m++;
					this.month++;
				}

				var maxdays = this.maxdformat();
				var maxday = maxdays[0];
				var premaxday = maxdays[1];

				//这个月的最后一个周日，就是下个月日历的第一天
				if (this.dates[5][0][1] > 14) {
					this.date = this.dates[5][0][1];
				} else {
					this.date = this.dates[4][0][1];
				}
				this.dates = [
					[],
					[],
					[],
					[],
					[],
					[]
				]; //日历初始化
				this.datesformat(maxday, premaxday); //编排下个月的日历
			},

			//上一个月
			monthsub() {
				if (this.month == 1) {
					this.m = 11;
					this.month = 12;
					this.y--;
					this.year--;
				} else {
					this.m--;
					this.month--;
				}
				var maxdays = this.maxdformat();
				var maxday = maxdays[0];
				var premaxday = maxdays[1];

				//根据上个月的最后一个周日，计算上个月日历的第一天
				if (this.dates[0][0][1] <= 28) {
					this.date = premaxday + this.dates[0][0][1] - 28;
				} else {
					this.date = premaxday + this.dates[0][0][1] - 35;
				}
				this.dates = [
					[],
					[],
					[],
					[],
					[],
					[]
				];

				this.datesformat(maxday, premaxday)
			},

			//下一年，就是把下一个月运行12次
			yearadd() {
				for (let c = 0; c < 12; c++) {
					this.monthadd();
				}
			},

			//上一年，就是把上一个月运行12次
			yearsub() {
				for (let c = 0; c < 12; c++) {
					this.monthsub();
				}
			},

			//picker直接选择年份，计算中间差几年，然后运行几次上一年或下一年
			yearchange(e) {
				this.y = e.target.value
				let d = this.year - this.years[this.y];
				if (d > 0) {
					for (let i = 0; i < d; i++) {
						this.yearsub();
					}
				} else {
					for (let i = 0; i < 0 - d; i++) {
						this.yearadd();
					}
				}
				this.y += d;
			},

			//picker直接选择月份
			monthchange(e) {
				this.m = e.target.value
				let d = this.month - this.months[this.m];
				if (d > 0) {
					for (let i = 0; i < d; i++) {
						this.monthsub();
					}
				} else {
					for (let i = 0; i < 0 - d; i++) {
						this.monthadd();
					}
				}
				this.m += d;
			},
			// 日期选择
			itemChose(day,w,k) {
				if(day[0] == '#222222'){ // 取消所有选中数据
					for(let i=0;i<6;i++) {
						for(let j=0;j<7;j++) {
							if(this.dates[i][j][0] != '#BBBBBB' && this.dates[i][j][2] == '#FF5C03') {
								this.dates[i][j][2] = '#fff'
								this.dates[i][j][0] = '#222222'
							}
						}
					}
					this.dates[w][k][2] = '#FF5C03'
					this.dates[w][k][0] = '#fff'
					let newValue = ['#fff', day[1], "#FF5C03"]
					this.$set(this.dates[w], k, newValue)
				}
				let mothnum = this.months[this.m]
				if(mothnum<10) {
					mothnum = '0'+mothnum
				}
				let dayNum = day[1]
				if(dayNum<10) {
					dayNum = '0'+dayNum
				}
				this.activeDateStr = this.years[this.y] + '-' + mothnum + '-' + dayNum
			}
		},
	}
</script>

<style scoped lang="scss">
	.calendar{
		display: flex;
		flex-direction: column;
		justify-content: center;
		align-items: center;
		.chose-head{
			width: 100%;
			height: 88upx;
			border-bottom: 2upx solid #EEEEEE;
			display: flex;
			align-items: center;
			justify-content: space-between;
			padding: 0 97upx 0 67upx;
			.chose-item{
				display: flex;
				align-items: center;
				.btn{
					width: 40upx;
					height: 40upx;
					background: #F2F4F5;
					border-radius: 6upx;
					display: flex;
					align-items: center;
					justify-content: center;
					image{
						width: 11upx;
						height: 18upx;
					}
				}
				.year-td{
					width: 160upx;
					display: flex;
					align-items: center;
					justify-content: center;
					.text{
						font-size: 30upx;
						font-family: PingFang SC;
						font-weight: 500;
						color: #222222;
					}
				}
				.month-td{
					width: 100upx;
					display: flex;
					align-items: center;
					justify-content: center;
					.text{
						font-size: 30upx;
						font-family: PingFang SC;
						font-weight: 500;
						color: #222222;
					}
				}
			}
		}
		.table{
			width: 100%;
			.week{
				display: flex;
				align-items: center;
				justify-content: space-between;
				padding: 0 20upx;
				.item{
					width: 10%;
					height: 60upx;
					line-height: 60upx;
					margin: 12upx 0;
					font-size: 26upx;
					font-family: PingFang SC;
					font-weight: 500;
					color: #222222;
					text-align: center;
				}
			}
			.date-tr{
				display: flex;
				align-items: center;
				justify-content: space-between;
				padding: 0 20upx;
				.td{
					width: 10%;
					height: 60upx;
					line-height: 60upx;
					margin: 12upx 0;
					font-size: 26upx;
					text-align: center;
					font-family: PingFang SC;
					font-weight: 500;
					color: #222222;
					border-radius: 6upx;
					&.active{
						background-color: #FF5C03;
					}
				}
			}
		}
	}
	
</style>
