#include<iostream>
#include<string>
#include<sstream>
#include"Date.h"

using namespace std;

Date::Date(int m,int d,int y)
{
	day=d;
	month=m;
	year=y;
}

Date::Date(string s)
{
	size_t position1=s.find_first_of("/");
	s.replace(position1,1," ");
	size_t position2=s.find_last_of("/");
	s.replace(position2,1," ");
	istringstream inputString(s);
	inputString>>month>>day>>year;


}



int Date::daysSinceStart()const{

	int days=0;
	for(int y=1900;y<year;y++){
		leapYear(y) ? days+=366 : days+=365;
	}

	return days+dayOfTheYear();
}

int Date::dayOfTheYear()const {
	
	int days=0;
	switch (month) {
		case 1:
			days+=day; 
			break;
		case 2:
			days+=day+31;
			break;
		case 3:
			days+=31+(leapYear(year) ? 29 : 28 )+day;
			break;
		case 4:
			days+=31+(leapYear(year) ? 29 : 28 )+31+day;
			break;
		case 5:
			days+=31+(leapYear(year) ? 29 : 28 )+31+30+day;
			break;
		case 6:
			days+=31+(leapYear(year) ? 29 : 28 )+31+30+31+day;
			break;
		case 7:
			days+=31+(leapYear(year) ? 29 : 28 )+31+30+31+30+day;
			break;
		case 8:
			days+=31+(leapYear(year) ? 29 : 28 )+31+30+31+30+31+day;
			break;
		case 9:
			days+=31+(leapYear(year) ? 29 : 28 )+31+30+31+30+31+31+day;
			break;
		case 10:
			days+=31+(leapYear(year) ? 29 : 28 )+31+30+31+30+31+31+30+day;
			break;
		case 11:
			days+=31+(leapYear(year) ? 29 : 28 )+31+30+31+30+31+31+30+31+day;
			break;
		case 12:
			days+=31+(leapYear(year) ? 29 : 28 )+31+30+31+30+31+31+30+31+30+day;
			break;
	}

	return days;
}
	
string Date::dayOfTheWeek()const{
	static string dayOfTheWeek[7]={"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"};
	return dayOfTheWeek[daysSinceStart()%7];
}

string Date::nameOfMonth()const{
	static string Months[13]={"invalid","January","February","March","April","May","June","July","August","September","October","November","December"};
	return Months[month];
}

void Date::printDate()const{
cout<<month<<"/"<<day<<"/"<<year<<endl;
}

void Date::printVerbose()const{
	cout<<dayOfTheWeek()<<", "<<nameOfMonth()<<" "<<day<<", "<<year<<endl;
}

int Date::getMonth()const{
	return month;
}

int Date::getDay()const{
	return day;
}

int Date::getYear()const{
	return year;
}

Date::~Date()
{
}

Date daysToDate(int d){

	int year;
	int yy=1900;

	while(d>0)
	{
		d-=(leapYear(yy)? 366:365);
		yy++;
	}
	year=yy-1;

	d+=(leapYear(year)?366:365);

	Date date=daysOfYearToDate(d,year);
	return date;
}

Date daysOfYearToDate(int d, int y){

	if( d>(leapYear(y)?366:365))
		return daysToDate(d);

	int da;
	int mo;

	if (d<=31){
		mo=1;
		da=d;}	
	else 
		if (d<=31+(leapYear(y)?29:28)){
			mo=2;
			da=d-31;
	}
	else 
		if(d<=31+(leapYear(y)?29:28)+31){
			mo=3;
			da=d-31-(leapYear(y)?29:28);
		}
	else
		if(d<=31+(leapYear(y)?29:28)+31+30){
			mo=4;
			da=d-(31+(leapYear(y)?29:28)+31);
		}
	else
		if(d<=31+(leapYear(y)?29:28)+31+30+31){
			mo=5;
			da=d-(31+(leapYear(y)?29:28)+31+30);
		}
	else
		if(d<=31+(leapYear(y)?29:28)+31+30+31+30){
			mo=6;
			da=d-(31+(leapYear(y)?29:28)+31+30+31);
		}
	else
		if(d<=31+(leapYear(y)?29:28)+31+30+31+30+31){
			mo=7;
			da=d-(31+(leapYear(y)?29:28)+31+30+31+30);
		}
	else
		if(d<=31+(leapYear(y)?29:28)+31+30+31+30+31+31){
			mo=8;
			da=d-(31+(leapYear(y)?29:28)+31+30+31+30+31);
		}
	else
		if(d<=31+(leapYear(y)?29:28)+31+30+31+30+31+31+30){
			mo=9;
			da=d-(31+(leapYear(y)?29:28)+31+30+31+30+31+31);
		}
	else
		if(d<=31+(leapYear(y)?29:28)+31+30+31+30+31+31+30+31){
			mo=10;
			da=d-(31+(leapYear(y)?29:28)+31+30+31+30+31+31+30);
		}
	else
		if(d<=31+(leapYear(y)?29:28)+31+30+31+30+31+31+30+31+30){
			mo=11;
			da=d-(31+(leapYear(y)?29:28)+31+30+31+30+31+31+30+31);
		}
	else
		if(d<=31+(leapYear(y)?29:28)+31+30+31+30+31+31+30+31+30+31){
			mo=12;
			da=d-(31+(leapYear(y)?29:28)+31+30+31+30+31+31+30+31+30);
		}

	Date date(mo,da,y);
	return date;
}
bool leapYear(int y)
{
	return(y % 4==0 && (y % 100 != 0 || y % 400==0));
}





