#include "StdAfx.h"
#include "TimeBox.h"
#include "commctrl.h"

TimeBox::TimeBox()
{
	type = TimeBoxType;
}

TimeBox::~TimeBox()
{
}

void TimeBox::Load(const char * b){
	_bstr_t base = b;
	SkinnableWindow::Load(base);
	hour.Load(base+"::hour");
	minute.Load(base+"::minute");
	ampm.Load(base+"::ampm");
	hours.Load(base+"::hours");
	minutes.Load(base+"::minutes");
	ampms.Load(base+"::ampms");
	hourButton.Load(base+"::hourbutton");
	minuteButton.Load(base+"::minutebutton");
	ampmButton.Load(base+"::ampmbutton");
	ItemStyle.Load(base+"::itemstyle");
	hours.scrollbar.Load(base+"::scrollbar");
	minutes.scrollbar.Load(base+"::scrollbar");
	ampms.scrollbar.Load(base+"::scrollbar");
}

int TimeBox::Create(HWND parent)
{
	SkinnableWindow::Create(parent);
	hour.Create(hWnd,ES_RIGHT);
	minute.Create(hWnd, ES_LEFT);
	ampm.Create(hWnd);
	hours.Hide();
	hours.Create(parent);
	minutes.Hide();
	minutes.Create(parent);
	ampms.Hide();
	ampms.Create(parent);
	hourButton.Create(hWnd);
	minuteButton.Create(hWnd);
	ampmButton.Create(hWnd);

	hours.SetMessageSink(hWnd);
	minutes.SetMessageSink(hWnd);
	ampms.SetMessageSink(hWnd);

	hour.SetTabTo(minute.GetTabToTarget());
	hour.SetTabFrom(ampm.GetTabFromTarget());
	minute.SetTabTo(ampm.GetTabToTarget());
	minute.SetTabFrom(hour.GetTabFromTarget());
	ampm.SetTabTo(hour.GetTabToTarget());
	ampm.SetTabFrom(minute.GetTabFromTarget());

	SetWindowRgn(hWnd,VisibleRgn(),TRUE);

	time = COleDateTime::GetCurrentTime();
	
	hour.SetText(time.Format(L"%I"));
	minute.SetText(time.Format(L"%M"));
	ampm.SetText(time.Format(L"%p"));

	int i;
	TCHAR buffer[10];
	for(i=0;i<12;i++){
		_stprintf(buffer,L"%.2d",i+1);
		ListItem * item = hours.CreateItem(buffer,i+1);
		item->Set(ItemStyle);
		hours.AddItem(item);
	}
	for(i=0;i<60;i++){
		_stprintf(buffer,L"%.2d",i);
		ListItem * item = minutes.CreateItem(buffer,i);
		item->Set(ItemStyle);
		minutes.AddItem(item);
	}
	ListItem * am = ampms.CreateItem(L"AM",0);
	am->Set(ItemStyle);
	ampms.AddItem(am);
	ListItem * pm = ampms.CreateItem(L"PM",1);
	pm->Set(ItemStyle);
	ampms.AddItem(pm);

	return 1;
}

void TimeBox::OnButton(HWND h)
{
	if(h==hourButton.hWnd){
		if(hours.hidden){
			hours.SetLocation(location.X+hour.location.X,location.Y+hour.location.Y+hour.size.Height);
			hours.Show();
			SetWindowPos(hours.hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
			BringWindowToTop(hours.hWnd);
		} else {
			hours.Hide();
		}
		//SetWindowRgn(hWnd,VisibleRgn(),TRUE);
	} else if(h==minuteButton.hWnd){
		if(minutes.hidden){
			minutes.SetLocation(location.X+minute.location.X,location.Y+minute.location.Y+minute.size.Height);
			minutes.Show();
			SetWindowPos(minutes.hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
			BringWindowToTop(minutes.hWnd);
		} else {
			minutes.Hide();
		}
		//SetWindowRgn(hWnd,VisibleRgn(),TRUE);
	} else if(h==ampmButton.hWnd){
		if(ampms.hidden){
			ampms.SetLocation(location.X+ampm.location.X,location.Y+ampm.location.Y+ampm.size.Height);
			ampms.Show();
			SetWindowPos(ampms.hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE|SWP_NOSIZE);
			BringWindowToTop(ampms.hWnd);
		} else {
			ampms.Hide();
		}
		//SetWindowRgn(hWnd,VisibleRgn(),TRUE);
	}
}

HRGN TimeBox::VisibleRgn()
{
	HRGN rgn1, rgn2;
	
	rgn1 = CreateRectRgn(hour.location.X,
		hour.location.Y,
		hour.location.X+hour.size.Width,
		hour.location.Y+hour.size.Height);

	rgn2 = CreateRectRgn(minute.location.X,
		minute.location.Y,
		minute.location.X+minute.size.Width,
		minute.location.Y+minute.size.Height);
	CombineRgn(rgn1,rgn1,rgn2,RGN_OR); 	
	DeleteObject(rgn2);

	rgn2 = CreateRectRgn(ampm.location.X,
		ampm.location.Y,
		ampm.location.X+ampm.size.Width,
		ampm.location.Y+ampm.size.Height);
	CombineRgn(rgn1,rgn1,rgn2,RGN_OR);
	DeleteObject(rgn2);

	rgn2 = CreateRectRgn(hourButton.location.X,
		hourButton.location.Y,
		hourButton.location.X+hourButton.size.Width,
		hourButton.location.Y+hourButton.size.Height);
	CombineRgn(rgn1,rgn1,rgn2,RGN_OR);
	DeleteObject(rgn2);

	rgn2 = CreateRectRgn(minuteButton.location.X,
		minuteButton.location.Y,
		minuteButton.location.X+minuteButton.size.Width,
		minuteButton.location.Y+minuteButton.size.Height);
	CombineRgn(rgn1,rgn1,rgn2,RGN_OR);
	DeleteObject(rgn2);

	rgn2 = CreateRectRgn(ampmButton.location.X,
		ampmButton.location.Y,
		ampmButton.location.X+ampmButton.size.Width,
		ampmButton.location.Y+ampmButton.size.Height);
	CombineRgn(rgn1,rgn1,rgn2,RGN_OR);
	DeleteObject(rgn2);

	if(!hours.hidden){
		rgn2 = CreateRectRgn(hours.location.X,
			hours.location.Y,
			hours.location.X+hours.size.Width,
			hours.location.Y+hours.size.Height);
		CombineRgn(rgn1,rgn1,rgn2,RGN_OR);
		DeleteObject(rgn2);
	}

	if(!minutes.hidden){
		rgn2 = CreateRectRgn(minutes.location.X,
			minutes.location.Y,
			minutes.location.X+minutes.size.Width,
			minutes.location.Y+minutes.size.Height);
		CombineRgn(rgn1,rgn1,rgn2,RGN_OR);
		DeleteObject(rgn2);
	}

	if(!ampms.hidden){
		rgn2 = CreateRectRgn(ampms.location.X,
			ampms.location.Y,
			ampms.location.X+ampms.size.Width,
			ampms.location.Y+ampms.size.Height);
		CombineRgn(rgn1,rgn1,rgn2,RGN_OR);
		DeleteObject(rgn2);
	}

	return rgn1;
}

void TimeBox::OnListSelect(HWND h, HWND hItem)
{
	ListItem * item = (ListItem*)GetWindowLongPtr(hItem,GWLP_USERDATA);
	if(item==NULL) return;

	if(h==hours.hWnd){
		hour.SetText(item->title.data());
		hours.Hide();
		//SetWindowRgn(hWnd,VisibleRgn(),TRUE);
		OnContentsChanged((WPARAM)hour.hWnd,0);
	} else if(h==minutes.hWnd) {
		minute.SetText(item->title.data());
		minutes.Hide();
		//SetWindowRgn(hWnd,VisibleRgn(),TRUE);
		OnContentsChanged((WPARAM)minute.hWnd,0);
	} else if(h==ampms.hWnd) {
		ampm.SetText(item->title.data());
		ampms.Hide();
		//SetWindowRgn(hWnd,VisibleRgn(),TRUE);
		OnContentsChanged((WPARAM)ampm.hWnd,0);
	}
}

void TimeBox::OnContentsChanged(WPARAM wParam, LPARAM lParam)
{
	HWND h = (HWND)wParam;

	if(h==hour.hWnd || h==minute.hWnd || h==ampm.hWnd){
		std::wstring buffer;
		hour.GetText(buffer);
		int i = _ttoi(buffer.data())%12;
		minute.GetText(buffer);
		int j = _ttoi(buffer.data());
		if(i<0) i = 0;
		if(i>59) i = 59;
		ampm.GetText(buffer);
		if(buffer==L"PM" || buffer==L"pm") i += 12;
		if(i<0) i = 0;
		if(i>23) i = 23;
		time.SetTime(i,j,0);
		print(L"time is now %s\n",time.Format(L"%I:%M %p"));
	} 
}

void TimeBox::SetValue(COleDateTime& t)
{
	time.SetTime(t.GetHour(),t.GetMinute(),t.GetSecond());
	hour.SetText(time.Format(L"%I"));
	minute.SetText(time.Format(L"%M"));
	ampm.SetText(time.Format(L"%p"));
}

HWND TimeBox::GetTabToTarget()
{
	return hour.GetTabToTarget();
}

HWND TimeBox::GetTabFromTarget()
{
	return ampm.GetTabFromTarget();
}

void TimeBox::SetTabTo(HWND h)
{
	ampm.SetTabTo(h);
	SkinnableWindow::SetTabTo(h);
}

void TimeBox::SetTabFrom(HWND h)
{
	hour.SetTabFrom(h);
	SkinnableWindow::SetTabFrom(h);
}

void TimeBox::OnLoseFocus()
{
	hours.Hide();
	minutes.Hide();
	ampms.Hide();
	//SetWindowRgn(hWnd,VisibleRgn(),TRUE);
}