#include <stdio.h>
#include "lgi/common/Gdc2.h"
#include "lgi/common/MonthView.h"

// These are the localized strings for days and months.
const char *ShortDayNames[7]	= {"Sun", "Mon", "Tues", "Wed", "Thur", "Fri", "Sat"};
const char *FullDayNames[7]		= {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
const char *ShortMonthNames[12]	= {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
const char *FullMonthNames[12]	= {"January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"};
char MonthView::Buf[256];

MonthView::MonthView(LDateTime *dt)
{
	MonthX = MonthY = 0;
	Sx = Sy = 0;
	Set(dt);
}

void MonthView::Set(LDateTime *dt)
{
	if (dt)
	{
		Cursor = *dt;
		First = Cursor;
		First.Day(1);
		Start = First;

		auto Offset = FirstDayOfWeek - Start.DayOfWeek();
		if (Offset > 0)
			Offset -= 7;
		Start.AddDays(Offset);

		int DayOfWeek = First.DayOfWeek();
		MonthX = 7;
		MonthY = (Cursor.DaysInMonth() + DayOfWeek - 1) / 7 + 1;
	}
}

LDateTime &MonthView::Get()
{
	return Cursor;
}

void MonthView::SetCursor(int x, int y)
{
	// Wrap x
	if (x < 0)
	{
		y--;
		x = 6;
	}
	else if (x > 6)
	{
		y++;
		x = 0;
	}

	LDateTime n = Start;
	n.AddDays( (y * MonthX) + x );
	Set(&n);
}

LPoint MonthView::GetCursor()
{
	auto diff = Cursor.Ts() - Start.Ts();
	double days = (double)diff / (LDateTime::Second64Bit * LDateTime::DayLength);
	int d = (int)(days + 0.5);
	return LPoint(d % 7, d / 7);
}

void MonthView::SelectCell(int x, int y)
{
	Sx = limit(x, 0, MonthX);
	Sy = limit(y, 0, MonthY);
	if (Start.IsValid())
	{
		Cell = Start;
		Cell.AddDays( (Sy * MonthX) + Sx );
	}
}

char *MonthView::Title()
{
	sprintf_s(Buf, sizeof(Buf), "%s %i", FullMonthNames[Cursor.Month()-1], Cursor.Year());
	return Buf;
}

char *MonthView::Day(bool FromCursor)
{
	sprintf_s(Buf, sizeof(Buf), "%i", FromCursor ? Cursor.Day() : Cell.Day());
	return Buf;
}

char *MonthView::Date(bool FromCursor)
{
	if (FromCursor)
		Cursor.GetDate(Buf, sizeof(Buf));
	else
		Cell.GetDate(Buf, sizeof(Buf));

	return Buf;
}

int MonthView::X()
{
	return MonthX;
}

int MonthView::Y()
{
	return MonthY;
}

bool MonthView::IsMonth()
{
	return Cell.Month() == First.Month();
}

bool MonthView::IsToday()
{
	LDateTime Now;
	Now.SetNow();
	return	Now.Day() == Cell.Day() &&
			Now.Month() == Cell.Month() &&
			Now.Year() == Cell.Year();
}

bool MonthView::IsSelected()
{
	return	Cell.Day() == Cursor.Day() &&
			Cell.Month() == Cursor.Month() &&
			Cell.Year() == Cursor.Year();
}

