<html>
	<head>
		<title>Calendar generator</title>
		<meta charset="utf-8"></meta>
		<style type="text/css">
			body {
				font-family: Arial, sans;
			}
			tr {
				height: 20px;
			}
			tr.monthBanner {
				width: 140px;
				padding: 5px 5px;
				background-color: navy;
			}
			tr.monthBanner td {
				width: 140px;
				padding: 5px 5px;
				color: white;
			}
			td {
				padding: 5px 5px;
				width: 20px;
			}
			td.invalid {
				background-color: gray;
			}
			td.weekday {
				background-color: green;
			}
			td.weekend {
				background-color: yellow;
			}
			td.holiday {
				background-color: orange;
			}
		</style>
	</head>
	<body>
		<div id="input">
			<form id="calendar-input">
				<label for="start-date">Start date (YYYY-MM-DD):</label>
				<input name="start-date" id="start-date" type="date" value="2017-01-01" required />
				
				<label for="number-of-days">Number of days:</label>
				<input name="number-of-days" id="number-of-days" type="number" value="1" required />
				
				<label for="country-code">Country code (2-digit):</label>
				<input name="country-code" id="country-code" type="text" value="CR" required />
				
				<input id="generate-button" name="generate-button" type="button" value="Generate"/>
			</form>
		</div>
		<div id="output">
			
		</div>
		
		<script type="text/javascript">
			//=====
			
			window.onload = function() {
			
				var apiKey = "e98ccf69-6131-42ad-a11c-d733698dad63";
				//Above: test key, will return dummy data but is unlimited
				//Below: live key, returns actual data but limited per month
				//Comment/uncomment as necessary, or request a free key at
				//http://holidayapi.com
				//var apiKey = "177c7a48-d566-426b-bb50-cf9926f767ec";
				
				function generate() {
					var form = document.getElementById("calendar-input");
					var startDate = document.getElementById("start-date").value;
					var numberOfDays = document.getElementById("number-of-days").value;
					var countryCode = document.getElementById("country-code").value;
					
					//TODO:
					//- Count the current day of the week, fill row with
					//  blanks until reaching the week's Sunday
					//- Count the current day of the month, break table on
					//  the last one, fill row with blanks until reaching
					//  the week's Saturday, generate a new month banner,
					//  fill new row with blanks from Sunday to that month's
					//  1st
					//- After finishing, making sure that the rest of the
					//  last week is filled with blanks until the week's
					//  Saturday
					
					if (validateDate(startDate) && validateNumber(numberOfDays) && validateCountry(countryCode)){
						
						var startYear = parseInt(startDate.substr(0,4));
						var startMonth = parseInt(startDate.substr(5,2));
						var startDay = parseInt(startDate.substr(8,2));
						
						var date = new Date(startYear, startMonth-1, startDay, 0, 0, 0, 0);
						
						var outputDiv = document.getElementById("output");
						//If the outputTable already exists, remove it
						outputDiv.innerHTML = "";
						var outputTable = document.createElement("table");
						outputDiv.appendChild(outputTable);
						
						//Start loop
						//TODO: refactor loop to process per week and not
						//per day
						
						var weekRow;
						for (var i = 0; i < numberOfDays; i++){
							var weekday = date.getUTCDay();
							
							if (weekday == 0 || i == 0 || date.getUTCDate() == 1) {
								//Generate a monthBanner if a month has passed
								if (i == 0 || date.getUTCDate() == 1) {
									var monthBanner = document.createElement("tr");
									monthBanner.className = "monthBanner";
									var monthBannerString = monthName(date.getUTCMonth()) + " " + date.getUTCFullYear();
									var monthBannerTD = document.createElement("td");
									monthBannerTD.innerHTML = monthBannerString;
									monthBannerTD.setAttribute("colspan", "7");
									outputTable.appendChild(monthBanner);
									monthBanner.appendChild(monthBannerTD);
								}
								//Generate a new weekRow if a week has passed
								//or if a new table/month is created
								weekRow = document.createElement("tr");
								//Special case: first row (or first day of the month)
								//Fill from Sunday to the day with blanks
								if (weekday != 0) {
									for (var j = weekday; j > 0; j--){
										var blank = document.createElement("td");
										blank.className = "invalid";
										weekRow.appendChild(blank);
									}
								}
							}
							
							var dayField = document.createElement("td");
							//TODO: use API to mark holidays
							if (weekday == 0 || weekday == 6) {
								dayField.className = "weekend";
							} else {
								dayField.className = "weekday";
							}
							dayField.innerHTML = date.getUTCDate();
							weekRow.appendChild(dayField);
							
							if (i >= numberOfDays - 1 || lastDay(date)) {
								//Special case: last row
								//In single-week outputs it can also be the first!
								if (weekday != 6) {
									for (var j = weekday; j < 6; j++){
										var blank = document.createElement("td");
										blank.className = "invalid";
										weekRow.appendChild(blank);
									}
								}
							}
							
							
							//Print the week row.
							//weekRow.innerHTML = "TEST";
							outputTable.appendChild(weekRow);
							
							//Iterate to the next day
							date = new Date(date.getTime() + 86400000);
							
							//TODO: Set a new month marker when the month's done
						}
					}
				}
				
				function validateDate(dateString){
					//Validate date, convert to its components
					if (dateString.length == 10 && dateString[4] == "-" && dateString[7] == "-") {
						var startYear = parseInt(dateString.substr(0,4));
						var startMonth = parseInt(dateString.substr(5,2));
						var startDay = parseInt(dateString.substr(8,2));
						if (!isNaN(startYear) && !isNaN(startMonth) && !isNaN(startDay)) {
							//Good, we're validated!
							return true;
						}
					}
					//else:
					return false;
				}
				
				function validateNumber(num){
					return !isNaN(parseInt(num));
				}
				
				function validateCountry(countryCode){
					//TODO: compare with the whole list of countries in the
					//API
					return (countryCode.length == 2);
				}
				
				function monthName(monthNumber){
					monthNumber = monthNumber + 1;
					switch(monthNumber) {
						case 1:
							return "January";
							break;
						case 2:
							return "February";
							break;
						case 3:
							return "March";
							break;
						case 4:
							return "April";
							break;
						case 5:
							return "May";
							break;
						case 6:
							return "June";
							break;
						case 7:
							return "July";
							break;
						case 8:
							return "August";
							break;
						case 9:
							return "September";
							break;
						case 10:
							return "October";
							break;
						case 11:
							return "November";
							break;
						case 12:
							return "December";
							break;
						default:
							return "";
							break;
					}
				}
				
				function lastDay(date) {
					var tomorrow = new Date(date.getTime() + 86400000);
					return (tomorrow.getUTCDate() == 1);
				}
				
				document.getElementById("generate-button").onclick = generate;
			
			}
			//=====
		</script>
	</body>
</html>