#include "CMainEditor.h"
#include "resource.h"
#include "CNewOS.h"
#include <time.h>
#include "CCalendarBK.h"
#include "CDiary.h"

IMPLEMENT_DYNAMIC(CMainEditor, CDialog)

BEGIN_MESSAGE_MAP(CMainEditor, CDialog)
	ON_WM_PAINT()
	ON_WM_SIZE()
	ON_WM_TIMER()
	ON_WM_LBUTTONDBLCLK()
	ON_COMMAND(ID_NEW_OS, &CMainEditor::OnNewOS)
	ON_COMMAND(ID_OPEN_OS, &CMainEditor::OnOpenOs)
	ON_COMMAND(ID_CLOSE_OS, &CMainEditor::OnCloseOs)
	ON_COMMAND(ID_CALENTAR_BK, &CMainEditor::OnCalentarBk)
	ON_COMMAND(ID_OSINFO, &CMainEditor::OnOsinfo)
	ON_COMMAND(ID_MC_EDITOR, &CMainEditor::OnMcEditor)
	ON_COMMAND(ID_WORLD_EDITOR, &CMainEditor::OnWorldEditor)
	ON_COMMAND(ID_PID_EDITOR, &CMainEditor::OnPidEditor)
	ON_COMMAND(ID_PXA_EDITOR, &CMainEditor::OnPxaEditor)
	ON_COMMAND(ID_MAP_EDITOR, &CMainEditor::OnMapEditor)
	ON_COMMAND(ID_GAME_SETTING, &CMainEditor::OnGameSetting)
	ON_COMMAND(ID_BOOT_GAME, &CMainEditor::OnBootGame)
	ON_COMMAND(ID_YEAR_DOWN, &CMainEditor::OnYearDown)
	ON_COMMAND(ID_YEAR_UP, &CMainEditor::OnYearUp)
END_MESSAGE_MAP()

CMainEditor::CMainEditor(CWnd* pParent)
	: CDialog(IDD_CMAINEDITOR, pParent)
{
}

CMainEditor::~CMainEditor()
{
	if (pFont_sourcesun28)
		TTF_CloseFont(pFont_sourcesun28);
	for (auto& p : pFontMap28)
	{
		if (p.second.pTexture)
			p.second.pTexture->Release();
		if (p.second.pSRV)
			p.second.pSRV->Release();
	}
	if (pTextureBk)
		pTextureBk->Release();
	if (pSRV)
		pSRV->Release();
	if (pTextureBk_bkup)
		pTextureBk_bkup->Release();
	if (pSRV_bkup)
		pSRV_bkup->Release();
}

void CMainEditor::CloseDB(sqlite3* db)
{
	if (!db)
		return;
	//关闭数据库
	HRESULT hr = sqlite3_close(db);
	while (hr == SQLITE_BUSY)
	{
		// set rc to something that will exit the while loop
		hr = SQLITE_OK;
		sqlite3_stmt* stmt = sqlite3_next_stmt(db, nullptr);
		if (stmt != nullptr)
		{
			hr = sqlite3_finalize(stmt);
			if (hr == SQLITE_OK)
				hr = sqlite3_close(db);
		}
	}
	db = nullptr;
}

sqlite3* CMainEditor::OpenDB()
{
	if (osFilePath.GetLength() == 0)
		return nullptr;
	std::vector<char> filepath_utf8;
	UTF16ToUTF8(osFilePath.GetString(), &filepath_utf8);
	sqlite3* db = nullptr;//数据库文件
	sqlite3_open(filepath_utf8.data(), &db);
	return db;
}

CString CMainEditor::GetDBFieldValue(CString table, CString field, CString field_val, CString value)
{
	std::vector<char> cmdbuff_utf8;
	std::vector<wchar_t> valueName_utf16;
	CString sql;
	sql.Format(L"SELECT COUNT(*) FROM %s where %s = '%s';", table.GetString(), field.GetString(), field_val.GetString());
	UTF16ToUTF8(sql.GetString(), &cmdbuff_utf8);

	auto db = OpenDB();
	//检查[table]表里有没有属性[field]字段
	sqlite3_stmt* stmt;
	sqlite3_prepare(db, cmdbuff_utf8.data(), -1, &stmt, nullptr);
	sqlite3_step(stmt);
	auto count = sqlite3_column_int(stmt, 0);
	sqlite3_finalize(stmt);
	if (count > 0)
	{
		//有值 再次查询返回具体值
		sql.Format(L"SELECT %s FROM %s where %s = '%s';", value.GetString(), table.GetString(), field.GetString(), field_val.GetString());
		UTF16ToUTF8(sql.GetString(), &cmdbuff_utf8);
		sqlite3_prepare(db, cmdbuff_utf8.data(), -1, &stmt, nullptr);
		sqlite3_step(stmt);
		auto valueName_utf8 = sqlite3_column_text(stmt, 0);
		UTF8ToUTF16((const char*)valueName_utf8, &valueName_utf16);
		sqlite3_finalize(stmt);
		CloseDB(db);
		return CString(valueName_utf16.data());
	}
	else
	{
		//无值返回""
		CloseDB(db);
		return CString(L"");
	}
}

void CMainEditor::SetDBFieldValue(CString table, CString field, CString field_val, CString value, CString value_val)
{
	std::vector<char> cmdbuff_utf8;
	CString sql;
	auto db = OpenDB();
	//查询字段是否存在
	sql.Format(L"SELECT COUNT(*) FROM %s where %s = '%s';", table.GetString(), field.GetString(), field_val.GetString());
	UTF16ToUTF8(sql.GetString(), &cmdbuff_utf8);
	//检查[table]表里有没有属性[field]字段
	sqlite3_stmt* stmt;
	sqlite3_prepare(db, cmdbuff_utf8.data(), -1, &stmt, nullptr);
	sqlite3_step(stmt);
	auto count = sqlite3_column_int(stmt, 0);
	sqlite3_finalize(stmt);
	if (count > 0)
	{
		//使用update
		sql.Format(L"update %s set %s = ? where %s = '%s';", table.GetString(), value.GetString(), field.GetString(), field_val.GetString());
		UTF16ToUTF8(sql.GetString(), &cmdbuff_utf8);
		sqlite3_prepare(db, cmdbuff_utf8.data(), -1, &stmt, nullptr);
		//准备缓冲区
		int utf8_buffSize_valueValue;
		UTF16ToUTF8(value_val.GetString(), &cmdbuff_utf8, &utf8_buffSize_valueValue);
		//绑定位置
		sqlite3_bind_text(stmt, 1, cmdbuff_utf8.data(), utf8_buffSize_valueValue, nullptr);
		sqlite3_step(stmt);
		sqlite3_finalize(stmt);
	}
	else
	{
		//使用insert
		sql.Format(L"insert into %s(%s,%s) values('%s',?);", table.GetString(), field.GetString(), value.GetString(), field_val.GetString());
		UTF16ToUTF8(sql.GetString(), &cmdbuff_utf8);
		sqlite3_prepare(db, cmdbuff_utf8.data(), -1, &stmt, nullptr);
		//准备缓冲区
		int utf8_buffSize_valueValue;
		UTF16ToUTF8(value_val.GetString(), &cmdbuff_utf8, &utf8_buffSize_valueValue);
		//绑定位置
		sqlite3_bind_text(stmt, 1, cmdbuff_utf8.data(), utf8_buffSize_valueValue, nullptr);
		sqlite3_step(stmt);
		sqlite3_finalize(stmt);
	}
	CloseDB(db);
}

void CMainEditor::DelDBField(CString table, CString field, CString field_val)
{
	std::vector<char> cmdbuff_utf8;
	CString sql;
	sql.Format(L"delete from %s where %s = '%s';", table.GetString(), field.GetString(), field_val.GetString());
	UTF16ToUTF8(sql.GetString(), &cmdbuff_utf8);
	auto db = OpenDB();
	sqlite3_exec(db, cmdbuff_utf8.data(), nullptr, nullptr, nullptr);
	CloseDB(db);
}

void CMainEditor::SetDBField(CString table, CString field, CString field_val, CString field_val_new)
{
	std::vector<char> cmdbuff_utf8;
	CString sql;
	auto db = OpenDB();
	//查询字段是否存在
	sql.Format(L"SELECT COUNT(*) FROM %s where %s = '%s';", table.GetString(), field.GetString(), field_val.GetString());
	UTF16ToUTF8(sql.GetString(), &cmdbuff_utf8);
	//检查[table]表里有没有属性[field]字段
	sqlite3_stmt* stmt;
	sqlite3_prepare(db, cmdbuff_utf8.data(), -1, &stmt, nullptr);
	sqlite3_step(stmt);
	auto count = sqlite3_column_int(stmt, 0);
	sqlite3_finalize(stmt);
	if (count > 0)
	{
		//使用update
		sql.Format(L"update %s set %s = '%s' where %s = '%s';", table.GetString(), field.GetString(), field_val_new.GetString(), field.GetString(), field_val.GetString());
		UTF16ToUTF8(sql.GetString(), &cmdbuff_utf8);
		sqlite3_exec(db, cmdbuff_utf8.data(), nullptr, nullptr, nullptr);
	}
	else
	{
		//使用insert
		sql.Format(L"insert into %s(%s) values('%s');", table.GetString(), field.GetString(), field_val_new.GetString());
		UTF16ToUTF8(sql.GetString(), &cmdbuff_utf8);
		sqlite3_exec(db, cmdbuff_utf8.data(), nullptr, nullptr, nullptr);
	}
	CloseDB(db);
}

void CMainEditor::GetDBField_List(std::vector<CString>* outList, CString table, CString field)
{
	outList->clear();
	std::vector<char> cmdbuff_utf8;
	std::vector<wchar_t> wchar_buff;
	CString sql;
	sqlite3_stmt* stmt;
	auto db = OpenDB();
	sql.Format(L"SELECT %s FROM %s;", field.GetString(), table.GetString());
	UTF16ToUTF8(sql.GetString(), &cmdbuff_utf8);
	sqlite3_prepare(db, cmdbuff_utf8.data(), -1, &stmt, nullptr);
	while (sqlite3_step(stmt) == SQLITE_ROW)
	{
		auto utf8 = sqlite3_column_text(stmt, 0);
		UTF8ToUTF16((const char*)utf8, &wchar_buff);
		outList->push_back(wchar_buff.data());
	}
	sqlite3_finalize(stmt);
	CloseDB(db);
}

int CMainEditor::GetDBTabelCount(CString table)
{
	std::vector<char> cmdbuff_utf8;
	CString sql;
	auto db = OpenDB();
	sql.Format(L"SELECT COUNT(*) FROM %s;", table.GetString());
	UTF16ToUTF8(sql.GetString(), &cmdbuff_utf8);
	sqlite3_stmt* stmt;
	sqlite3_prepare(db, cmdbuff_utf8.data(), -1, &stmt, nullptr);
	sqlite3_step(stmt);
	auto count = sqlite3_column_int(stmt, 0);
	sqlite3_finalize(stmt);
	CloseDB(db);
	return count;
}

void CMainEditor::GetDBMyCharacter_List(std::vector<MyCharacterInfo>* outList)
{
	std::vector<char> cmdbuff_utf8;
	std::vector<wchar_t> wchar_buff;
	CString sql;
	sqlite3_stmt* stmt;
	MyCharacterInfo info;

	outList->clear();
	auto db = OpenDB();
	sql.Format(L"SELECT * FROM %s;", DBTABLENAME_MYCHARACTER);
	UTF16ToUTF8(sql.GetString(), &cmdbuff_utf8);
	sqlite3_prepare(db, cmdbuff_utf8.data(), -1, &stmt, nullptr);
	while (sqlite3_step(stmt) == SQLITE_ROW)
	{
		//id
		info.id = sqlite3_column_int(stmt, 0);
		//facePng
		UTF8ToUTF16((const char*)sqlite3_column_text(stmt, 1), &wchar_buff);
		info.facePng = wchar_buff.data();
		//lifeType
		info.lifeType = sqlite3_column_int(stmt, 2);
		//image
		const char* image = (const char*)sqlite3_column_text(stmt, 3);
		if (strlen(image) > 0)
		{
			int wchar_buffSize_image;
			UTF8ToUTF16(image, &wchar_buff, &wchar_buffSize_image);
			info.image = wchar_buff.data();
		}
		else
			info.image = L"";
		//name
		UTF8ToUTF16((const char*)sqlite3_column_text(stmt, 4), &wchar_buff);
		info.name = wchar_buff.data();
		//mcpos
		UTF8ToUTF16((const char*)sqlite3_column_text(stmt, 5), &wchar_buff);
		info.mcpos = wchar_buff.data();
		//mcchar
		UTF8ToUTF16((const char*)sqlite3_column_text(stmt, 6), &wchar_buff);
		info.mcChar = wchar_buff.data();
		//gender
		info.gender = sqlite3_column_int(stmt, 7);
		//ideal
		const char* ideal = (const char*)sqlite3_column_text(stmt, 8);
		if (strlen(ideal) > 0)
		{
			int wchar_buffSize_ideal;
			UTF8ToUTF16(ideal, &wchar_buff, &wchar_buffSize_ideal);
			info.ideal = wchar_buff.data();
		}
		else
			info.ideal = L"";
		//labelXML
		const char* labelXML = (const char*)sqlite3_column_text(stmt, 9);
		if (strlen(labelXML) > 0)
		{
			int wchar_buffSize_labelXML;
			UTF8ToUTF16(labelXML, &wchar_buff, &wchar_buffSize_labelXML);
			info.labelXML = wchar_buff.data();
		}
		else
			info.labelXML = "";
		outList->push_back(info);
	}
	sqlite3_finalize(stmt);
	CloseDB(db);
}

bool CMainEditor::GetDBTableExist(CString table)
{
	std::vector<char> cmdbuff_utf8;
	CString sql;
	auto db = OpenDB();
	sql.Format(L"SELECT COUNT(*) FROM sqlite_master WHERE type='table' AND name ='%s';", table.GetString());
	UTF16ToUTF8(sql.GetString(), &cmdbuff_utf8);
	sqlite3_stmt* stmt;
	sqlite3_prepare(db, cmdbuff_utf8.data(), -1, &stmt, nullptr);
	sqlite3_step(stmt);
	auto count = sqlite3_column_int(stmt, 0);
	sqlite3_finalize(stmt);
	CloseDB(db);
	return count != 0;
}

CString CMainEditor::GetDBWorldSet()
{
	std::vector<char> cmdbuff_utf8;
	std::vector<wchar_t> wchar_buff;
	CString sql;
	auto db = OpenDB();
	sql.Format(L"SELECT * FROM %s;", DBTABLENAME_WORLDSET);
	UTF16ToUTF8(sql.GetString(), &cmdbuff_utf8);
	sqlite3_stmt* stmt;
	sqlite3_prepare(db, cmdbuff_utf8.data(), -1, &stmt, nullptr);
	sqlite3_step(stmt);
	UTF8ToUTF16((const char*)sqlite3_column_text(stmt, 0), &wchar_buff);
	sqlite3_finalize(stmt);
	CloseDB(db);
	return CString(wchar_buff.data());
}

void CMainEditor::SetDBWorldSet(CString xml)
{
	std::vector<char> cmdbuff_utf8;
	CString sql;
	auto db = OpenDB();
	sql.Format(L"UPDATE %s SET xml = ?;", DBTABLENAME_WORLDSET);
	UTF16ToUTF8(sql.GetString(), &cmdbuff_utf8);

	sqlite3_stmt* stmt;
	sqlite3_prepare(db, cmdbuff_utf8.data(), -1, &stmt, nullptr);

	int utf8_buffSize_xml;
	UTF16ToUTF8(xml.GetString(), &cmdbuff_utf8, &utf8_buffSize_xml);
	sqlite3_bind_text(stmt, 1, cmdbuff_utf8.data(), utf8_buffSize_xml, nullptr);
	sqlite3_step(stmt);
	sqlite3_finalize(stmt);
	CloseDB(db);
}

void CMainEditor::GetXMLLabel_Map(std::unordered_map<std::wstring, MyLabelXML>* outMap, CString xml)
{
	outMap->clear();
	std::vector<char> xml_utf8;
	std::vector<wchar_t> wchar_buff;
	UTF16ToUTF8(xml.GetString(), &xml_utf8);
	tinyxml2::XMLDocument xmlDoc;
	xmlDoc.Parse(xml_utf8.data());
	for (auto set_xml = xmlDoc.FirstChildElement(); set_xml != nullptr; set_xml = set_xml->NextSiblingElement())
	{
		MyLabelXML lable;
		auto name_utf8 = set_xml->Attribute("Name");
		UTF8ToUTF16(name_utf8, &wchar_buff);
		lable.name = wchar_buff.data();
		if (outMap->find(lable.name.GetString()) == outMap->end())
			outMap->insert(std::make_pair(lable.name.GetString(), lable));
	}
}

CString CMainEditor::GetXMLString(std::unordered_map<std::wstring, MyLabelXML>& xmlMap)
{
	tinyxml2::XMLDocument xmlDoc;
	std::vector<char> utf8_buff;
	std::vector<wchar_t> wchar_buff;
	for (auto& p : xmlMap)
	{
		auto node = xmlDoc.NewElement("Set");
		UTF16ToUTF8(p.second.name.GetString(), &utf8_buff);
		node->SetAttribute("Name", utf8_buff.data());
		xmlDoc.InsertEndChild(node);
	}
	tinyxml2::XMLPrinter xmlPrinter;
	xmlDoc.Print(&xmlPrinter);
	UTF8ToUTF16(xmlPrinter.CStr(), &wchar_buff);
	return CString(wchar_buff.data());
}

void CMainEditor::UpdateWindowTitle()
{
	CString str;
	str.Format(L"%s(已制作%d天) 已工作%lld分钟", osName.GetString(), dayCount, workMinute);
	SetWindowTextW(str.GetString());
}

void CMainEditor::UpdateDisplayDiary()
{
	CString dateValue;
	//更新日记绘制
	for (auto& p : clickRectArr)
	{
		dateValue.Format(L"%d-%d-%d", yearDisplay, p.month, p.day);
		CString diary = GetDBFieldValue(DBTABLENAME_CALENDAR, L"date", dateValue.GetString(), L"diary");
		p.diary = diary.GetLength() > 0;
	}
	//统计所有的制作天数
	dayCount = GetDBTabelCount(DBTABLENAME_CALENDAR);
}

void CMainEditor::Draw()
{
	//绘制背景
	if (pTextureBk != nullptr && pSRV != nullptr)
	{
		if (pTextureBk_bkup != nullptr && pSRV_bkup != nullptr)
		{
			pRenderer.RenderClear(1.0f, 1.0f, 1.0f);
			MyRect rectSrc, rectDst;
			pRenderer.GetRenderCopyDefaultRect(pSRV_bkup, &rectSrc, &rectDst);
			rectSrc.AdjustBk(rectDst);
			pRenderer.SetTPenDraw(pSRV_bkup);
			pRenderer.AddRenderCopy(nullptr, &rectSrc, RGBA(0xff, 0xff, 0xff, alpha_bkup));
			pRenderer.DrawRenderCopy();
		}
		else
		{
			pRenderer.RenderClear(1.0f, 1.0f, 1.0f);
			MyRect rectSrc, rectDst;
			pRenderer.GetRenderCopyDefaultRect(pSRV, &rectSrc, &rectDst);
			rectSrc.AdjustBk(rectDst);
			pRenderer.SetTPenDraw(pSRV);
			pRenderer.AddRenderCopy(nullptr, &rectSrc, RGBA(0xff, 0xff, 0xff, alpha));
			pRenderer.DrawRenderCopy();
		}
	}
	else
	{
		//绘制窗口背景色
		pRenderer.RenderClear(192.0f / 255.0f, 192.0f / 255.0f, 192.0f / 255.0f);
	}
	//绘制矩形
	pRenderer.SetPenDraw();
	for (auto& p : clickRectArr)
		if (p.diary)
			pRenderer.AddFillRect(&p.rect, RGBA(0, 0x80, 0xff, 0x80));
	pRenderer.DrawFillRect();
	//绘制日历
	float offx = 10;
	float offy = 10;
	float dx = 0;
	float dy = 0;
	float incX = 310;
	float incY = 310;
	for (int y = 0; y < 3; y++)
	{
		for (int x = 0; x < 4; x++)
		{
			DrawCalendar(dx + offx, dy + offy, yearDisplay, y * 4 + x + 1);
			dx += incX;
		}
		dy += incY;
		dx = 0;
	}
	if (setClickRectArr)
	{
		UpdateDisplayDiary();
		//绘制矩形
		pRenderer.SetPenDraw();
		for (auto& p : clickRectArr)
			if (p.diary)
				pRenderer.AddFillRect(&p.rect, RGBA(0, 0x80, 0xff, 0x80));
		pRenderer.DrawFillRect();
		//重新绘制日历
		setClickRectArr = false;
		dx = 0;
		dy = 0;
		for (int y = 0; y < 3; y++)
		{
			for (int x = 0; x < 4; x++)
			{
				DrawCalendar(dx + offx, dy + offy, yearDisplay, y * 4 + x + 1);
				dx += incX;
			}
			dy += incY;
			dx = 0;
		}
	}
	//绘制方格
	offx = 10;
	offy = 10;
	dx = 0;
	dy = 0;
	incX = 310;
	incY = 310;
	float width = 300.0f;
	pRenderer.SetPenDraw();
	MyRect rc;
	for (int y = 0; y < 3; y++)
	{
		for (int x = 0; x < 4; x++)
		{
			float X = dx + offx;
			float Y = dy + offy;
			rc.Set2(X, X + width, Y, Y + width);
			pRenderer.AddRect(&rc, RGBA(0, 0, 0, 0xff));
			dx += incX;
		}
		dy += incY;
		dx = 0;
	}
	pRenderer.DrawLine();
	pRenderer.RenderPresent();
}

CString CMainEditor::GetBasePath()
{
	wchar_t buff[MAX_PATH];
	CString basePath;
	GetModuleFileNameW(nullptr, buff, _countof(buff));
	basePath = buff;
	auto index = basePath.ReverseFind(L'\\');
	basePath.Delete(index, basePath.GetLength() - index);
	basePath.Append(L"\\");
	return basePath;
}

void CMainEditor::UpdateContext()
{
	pMCEditor.UpdateContext();
	pWorldEditor.UpdateContext();
}

CString CMainEditor::ImportPNG(CString filepath)
{
	//如果没有目录则已经是内部的文件
	if (filepath.ReverseFind('\\') == -1)
		return filepath;

	CString localPngPath = GetBasePath();
	localPngPath.Append(L"data\\png\\");

	CString pngName;
	pngName = filepath.GetString() + filepath.ReverseFind('\\') + 1;
	
	CString localPng = localPngPath;
	localPng.Append(pngName);
	//检查本地png目录里有没有同名文件
	FILE* fp;
	_wfopen_s(&fp, localPng.GetString(), L"r");
	if (fp)
	{
		fclose(fp);
		//存在同名文件
		return pngName;
	}
	//不存在同名文件 直接复制
	CopyFileW(filepath.GetString(), localPng.GetString(), false);
	return pngName;
}

void CMainEditor::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

BOOL CMainEditor::OnInitDialog()
{
	CDialog::OnInitDialog();
	//载入快捷键
	LOADHOTKEY(IDR_ACC_MAINEDITOR);
	//调整窗口大小
	CRect rc;
	rc.left = 0;
	rc.top = 0;
	rc.right = MAINEDITOR_WIDTH;
	rc.bottom = MAINEDITOR_HEIGHT;
	AdjustWindowRect(&rc, GetStyle(), true);
	RECT rc2;
	rc2.left = 0;
	rc2.top = 0;
	rc2.right = rc.Width();
	rc2.bottom = rc.Height();
	MoveWindow(&rc2);
	//设置应用程序图标
	auto hIcon = AfxGetApp()->LoadIcon(IDI_APPICON);//1251x942
	SetIcon(hIcon, true);
	//设置默认标题
	SetWindowText(TEXT("设定仓库编辑器（未载入数据库）"));
	//设置默认菜单状态
	LockMenu();
	//初始化渲染器
	pRenderer.Init(m_hWnd);
	//初始化字体
	pFont_sourcesun28 = pRenderer.MyLoadFont("SourceHanSansSC-Normal", 28);
	//初始化日历
	time_t currentTime = time(nullptr);
	tm tmNow;
	localtime_s(&tmNow,&currentTime);
	UpdateDisplayYear(tmNow.tm_year + 1900);
	//初始化子窗口
	pMCEditor.pMainEditor = this;
	pMCEditor.Create(IDD_CMCEDITOR, this);
	pWorldEditor.pMainEditor = this;
	pWorldEditor.Create(IDD_CWORLDEDITOR, this);
	pPidEditor.pMainEditor = this;
	pPidEditor.Create(IDD_CPIDEDITOR, this);
	pPxaEditor.pMainEditor = this;
	pPxaEditor.Create(IDD_CPXAEDITOR, this);
	pMapEditor.pMainEditor = this;
	pMapEditor.Create(IDD_CMAPEDITOR, this);
	//尝试打开最后一次打开的文件
	CString str;
	OpenLastFile(str);
	if (str.GetLength())
	{
		FILE* fp;
		_wfopen_s(&fp, str.GetString(), L"rb");
		if (fp)
		{
			fclose(fp);
			Load(str);
		}
	}
	//设置更新计时器
	timeId = SetTimer(1, 1000, nullptr);
	return 0;
}

void CMainEditor::Load(CString string)
{
	//读取数据库
	osFilePath = string;
	//读取仓库名和设定名
	CString sql;
	std::vector<char> utf8;
	std::vector<char> filepath_utf8;
	std::vector<wchar_t> osName_utf16;
	std::vector<wchar_t> osAuthor_utf16;
	UTF16ToUTF8(osFilePath.GetString(), &filepath_utf8);
	sqlite3* db = nullptr;//数据库文件
	sqlite3_open(filepath_utf8.data(), &db);
	sqlite3_stmt* stmt;
	sql.Format(L"select * from %s", DBTABLENAME_INFO);
	UTF16ToUTF8(sql.GetString(), &utf8);
	sqlite3_prepare(db, utf8.data(), -1, &stmt, nullptr);
	sqlite3_step(stmt);
	auto name_utf8 = sqlite3_column_text(stmt, 0);
	auto author_utf8 = sqlite3_column_text(stmt, 1);
	UTF8ToUTF16((const char*)name_utf8, &osName_utf16);
	UTF8ToUTF16((const char*)author_utf8, &osAuthor_utf16);
	sqlite3_finalize(stmt);
	CloseDB(db);
	osName = osName_utf16.data();
	osAuthor = osAuthor_utf16.data();
	//载入日历背景设置
	CString bkfile = GetDBFieldValue(DBTABLENAME_OPTION, L"field", L"calendar_bk_filename", L"value");
	if (bkfile.GetLength() > 0)
	{
		CString bkfilename;
		bkfilename.Format(L"./data/png/%s", bkfile.GetString());
		UTF16ToUTF8(bkfilename.GetString(), &filepath_utf8);
		if (pTextureBk)
			pTextureBk->Release();
		if (pSRV)
			pSRV->Release();
		pRenderer.MyLoadTexture(&pTextureBk, filepath_utf8.data());
		pRenderer.MyCreateShaderResourceView(&pSRV, pTextureBk);
		//取透明度值
		CString bkAlphaStr = GetDBFieldValue(DBTABLENAME_OPTION, L"field", L"calendar_bk_alpha", L"value");
		int a;
		swscanf_s(bkAlphaStr.GetString(), L"%d", &a);
		alpha = (BYTE)a;
	}
	//解锁菜单
	UnlockMenu();
	SaveLastFile();
	//更新显示日记
	UpdateDisplayDiary();
	UpdateWindowTitle();
	//更新所有子窗口的内容
	UpdateContext();
	//重绘
	Draw();
}

int CalcWeekDay(int y,int m,int d)
{
	if (m == 1 || m == 2)
	{
		m += 12;
		y--;
	}
	return (d + 2 * m + 3 * (m + 1) / 5 + y + y / 4 - y / 100 + y / 400) % 7 + 1;
}

int CalcDayNum(int year, int month)
{
	month--;
	static const int days0[] = 
	{
		31,28,31,30,31,30,31,31,30,31,30,31
	};
	static const int days1[] =
	{
		31,29,31,30,31,30,31,31,30,31,30,31
	};
	if (year % 4 == 0)
		return days1[month];
	else
		return days0[month];
}

bool DateCompareGreaterThan(int srcYear, int srcMonth, int srcDay, int dstYear, int dstMonth, int dstDay)
{
	if (srcYear > dstYear)
		return true;
	else if (srcYear == dstYear && srcMonth > dstMonth)
		return true;
	else if (srcYear == dstYear &&
		srcMonth == dstMonth &&
		srcDay > dstDay)
		return true;
	return false;
}

void CMainEditor::DrawCalendar(float x, float y, int year, int month)
{
	time_t currentTime = time(nullptr);
	tm tmNow;
	localtime_s(&tmNow, &currentTime);
	//绘制字
	float offx = x + 10;
	float nextX = offx;
	float nextY = y + 0;
	CString str;
	str.Format(L"%d年%d月\n\n", year, month);
	pRenderer.DrawText_Unicode(&pFontMap28, pFont_sourcesun28, str.GetString(), offx, &nextX, &nextY, RGBA(0, 0, 0, 0xff));
	pRenderer.DrawText_Unicode(&pFontMap28, pFont_sourcesun28, L"一", offx, &nextX, &nextY, RGBA(0, 0, 0, 0xff));	nextX += 14;
	pRenderer.DrawText_Unicode(&pFontMap28, pFont_sourcesun28, L"二", offx, &nextX, &nextY, RGBA(0, 0, 0, 0xff));	nextX += 14;
	pRenderer.DrawText_Unicode(&pFontMap28, pFont_sourcesun28, L"三", offx, &nextX, &nextY, RGBA(0, 0, 0, 0xff));	nextX += 14;
	pRenderer.DrawText_Unicode(&pFontMap28, pFont_sourcesun28, L"四", offx, &nextX, &nextY, RGBA(0, 0, 0, 0xff));	nextX += 14;
	pRenderer.DrawText_Unicode(&pFontMap28, pFont_sourcesun28, L"五", offx, &nextX, &nextY, RGBA(0, 0, 0, 0xff));	nextX += 14;
	pRenderer.DrawText_Unicode(&pFontMap28, pFont_sourcesun28, L"六", offx, &nextX, &nextY, RGBA(0, 0, 0, 0xff));	nextX += 14;
	pRenderer.DrawText_Unicode(&pFontMap28, pFont_sourcesun28, L"日", offx, &nextX, &nextY, RGBA(0, 0, 0, 0xff));
	int dayNum = CalcDayNum(year, month);
	nextY = y + 20 + 96;
	//绘制日历字的颜色
	DWORD color = RGBA(0, 0, 0, 0xff);
	for (int i = 1; i <= dayNum; i++)
	{
		//大于今天的日期绘制灰底
		if (DateCompareGreaterThan(year, month, i, tmNow.tm_year + 1900, tmNow.tm_mon + 1, tmNow.tm_mday))
			color = RGBA(0x80, 0x80, 0x80, 0xff);
		else
			color = RGBA(0, 0, 0, 0xff);
		int week = CalcWeekDay(year, month, i);
		str.Format(L"%d", i);
		nextX = x + 10 + (week - 1) * 42;
		if (setClickRectArr)
		{
			//绘制同时记录点击矩形区域
			bool first = true;
			for (int j = 0; j < str.GetLength(); j++)
			{
				CString ch = str.GetAt(j);
				pRenderer.DrawText_Unicode(&pFontMap28, pFont_sourcesun28, ch.GetString(), offx, &nextX, &nextY, color);
				if (first)
				{
					//保存绘制区域
					MyCalendarClickZone ccz;
					pRenderer.GetRenderCopyLastRect(nullptr, &ccz.rect);
					ccz.day = i;
					ccz.month = month;
					MyRect& rc = ccz.rect;
					rc.right += 17;
					rc.left -= 2;
					rc.top += 10;
					rc.bottom -= 6;
					clickRectArr.push_back(ccz);
					first = false;
				}
			}
		}
		else
		{
			pRenderer.DrawText_Unicode(&pFontMap28, pFont_sourcesun28, str.GetString(), offx, &nextX, &nextY, color);
		}
		if (week == 7)
			nextY += 28;
	}
}

void CMainEditor::UpdateDisplayYear(int year)
{
	//更新点击区域
	yearDisplay = year;
	setClickRectArr = true;
	clickRectArr.clear();
	Draw();
	setClickRectArr = false;
}

void CMainEditor::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	// 不为绘图消息调用 CDialog::OnPaint()
	Draw();
}

void CMainEditor::OnSize(UINT nType, int cx, int cy)
{
	CDialog::OnSize(nType, cx, cy);
	if (pRenderer.GetContext() != nullptr)
		Draw();
}

void CMainEditor::OnTimer(UINT_PTR nIDEvent)
{
	// TODO: 在此添加消息处理程序代码和/或调用默认值
	if (nIDEvent == timeId)
	{
		//是否载入了数据库
		if (osFilePath.GetLength() > 0)
		{
			//更新运动
			SportBody();
		}
	}
	CDialog::OnTimer(nIDEvent);
}

void CMainEditor::OnLButtonDblClk(UINT nFlags, CPoint point)
{
	//弹出一个日记填写窗口
	//检查鼠标落在哪个区域内
	for (auto& p : clickRectArr)
	{
		MyRect& rect = p.rect;
		if (point.x >= rect.left && point.x < rect.right &&
			point.y >= rect.top && point.y < rect.bottom)
		{
			//如果落在区域内
			CDiary dlg;
			dlg.pMainEditor = this;
			dlg.year = yearDisplay;
			dlg.month = p.month;
			dlg.day = p.day;
			dlg.DoModal();
			UpdateDisplayDiary();
			UpdateWindowTitle();
		}
	}
	CDialog::OnLButtonDblClk(nFlags, point);
}

void CMainEditor::OnNewOS()
{
	CNewOS dlg;
	if (dlg.DoModal() != IDOK)
		return;
	osName = dlg.outName;
	osAuthor = dlg.outAuthor;
	osFilePath = dlg.outFilePath;
	InitDBTable();
	//解锁菜单
	UpdateWindowTitle();
	UnlockMenu();
	SaveLastFile();
}

void CMainEditor::OnOpenOs()
{
	//打开数据库
	CFileDialog fd(true, TEXT(""), TEXT(""), OFN_FILEMUSTEXIST, TEXT("数据库文件(*.db)|*.db|所有文件(*.*)|*.*||"), this);
	if (fd.DoModal() != IDOK)
		return;
	//读取数据库
	Load(fd.GetPathName());
}

void CMainEditor::OnCloseOs()
{
	//解除数据库
	osFilePath = L"";
	osName = L"";
	osAuthor = L"";
	SetWindowText(TEXT("设定仓库编辑器（未载入数据库）"));
	if (pTextureBk)
		pTextureBk->Release();
	pTextureBk = nullptr;
	if (pSRV)
		pSRV->Release();
	pSRV = nullptr;
	//锁住菜单
	LockMenu();
	//点击区域取消点选
	for (auto& p : clickRectArr)
		p.diary = false;
	//重置和隐藏所有子窗口
	pMCEditor.ShowWindow(SW_HIDE);
	pWorldEditor.ShowWindow(SW_HIDE);
	pPidEditor.ResetContext();
	pPidEditor.ShowWindow(SW_HIDE);
	//重绘
	Draw();
}

void CMainEditor::OnCalentarBk()
{
	CCalendarBK dlg;
	dlg.pMainEditor = this;
	BYTE alpha_last = alpha;
	auto retID = dlg.DoModal();
	if (retID == IDOK)
	{
		//更新设置 数据上传到数据库
		SetDBFieldValue(DBTABLENAME_OPTION, L"field", L"calendar_bk_filename", L"value", dlg.outFileName.GetString());
		SetDBFieldValue(DBTABLENAME_OPTION, L"field", L"calendar_bk_alpha", L"value", dlg.outAlpha.GetString());
	}
	else
	{
		//还原设置
		if (pTextureBk_bkup)
		{
			pTextureBk_bkup->Release();
			pTextureBk_bkup = nullptr;
		}
		if (pSRV_bkup)
		{
			pSRV_bkup->Release();
			pSRV_bkup = nullptr;
		}
		alpha = alpha_last;
	}
	Draw();
}

void CMainEditor::OnOsinfo()
{
	CNewOS dlg;
	dlg.load = true;
	dlg.pMainEditor = this;
	if (dlg.DoModal() != IDOK)
		return;
	osName = dlg.outName;
	osAuthor = dlg.outAuthor;
	//更新数据到数据库
	CString sql;
	std::vector<char> utf8;
	auto db = OpenDB();
	sqlite3_stmt* stmt;
	//清空info表
	sql.Format(L"delete from %s;", DBTABLENAME_INFO);
	UTF16ToUTF8(sql.GetString(), &utf8);
	sqlite3_exec(db, utf8.data(), nullptr, nullptr, nullptr);
	//写入仓库名称和标题
	sql.Format(L"insert into %s(name,author) values(?,?);", DBTABLENAME_INFO);
	UTF16ToUTF8(sql.GetString(), &utf8);
	sqlite3_prepare(db, utf8.data(), -1, &stmt, nullptr);
	std::vector<char> osName_utf8;
	std::vector<char> osAuthor_utf8;
	int utf8_buffSize_osName;
	int utf8_buffSize_osAuthor;
	UTF16ToUTF8(osName.GetString(), &osName_utf8, &utf8_buffSize_osName);
	UTF16ToUTF8(osAuthor.GetString(), &osAuthor_utf8, &utf8_buffSize_osAuthor);
	sqlite3_bind_text(stmt, 1, osName_utf8.data(), utf8_buffSize_osName, nullptr);
	sqlite3_bind_text(stmt, 2, osAuthor_utf8.data(), utf8_buffSize_osAuthor, nullptr);
	sqlite3_step(stmt);
	sqlite3_finalize(stmt);
	CloseDB(db);
	//更新仓库名称和作者名称
	UpdateWindowTitle();
}

void CMainEditor::OnMcEditor()
{
	pMCEditor.ShowWindow(pMCEditor.IsWindowVisible() ? SW_HIDE : SW_SHOW);
}

void CMainEditor::OnWorldEditor()
{
	pWorldEditor.ShowWindow(pWorldEditor.IsWindowVisible() ? SW_HIDE : SW_SHOW);
}

void CMainEditor::OnPidEditor()
{
	pPidEditor.ShowWindow(pPidEditor.IsWindowVisible() ? SW_HIDE : SW_SHOW);
}

void CMainEditor::OnPxaEditor()
{
	pPxaEditor.ShowWindow(pPxaEditor.IsWindowVisible() ? SW_HIDE : SW_SHOW);
}

void CMainEditor::OnMapEditor()
{
	pMapEditor.ShowWindow(pMapEditor.IsWindowVisible() ? SW_HIDE : SW_SHOW);
}

void CMainEditor::OnGameSetting()
{
	wchar_t buff[MAX_PATH];
	CString filepath;
	GetModuleFileNameW(nullptr, buff, _countof(buff));
	filepath = buff;
	auto index = filepath.ReverseFind(L'\\');
	filepath.Delete(index, filepath.GetLength() - index);
	filepath.Append(L"\\data\\setting.xml");

	CString cmd;
	cmd.Format(L"explorer \"%s\"", filepath.GetString());
	MyWinExec(cmd.GetString());
}

void CMainEditor::OnBootGame()
{
	MyWinExec(L"spiky.exe");
}

void CMainEditor::OnYearDown()
{
	yearDisplay++;
	UpdateDisplayYear(yearDisplay);
}


void CMainEditor::OnYearUp()
{
	yearDisplay--;
	UpdateDisplayYear(yearDisplay);
}

void CMainEditor::LockMenu()
{
	//锁定菜单
	GetMenu()->GetSubMenu(CMAINEDITOR_MENUINDEX_FILE)->EnableMenuItem(ID_SAVEAS_OS, MF_DISABLED);
	GetMenu()->GetSubMenu(CMAINEDITOR_MENUINDEX_FILE)->EnableMenuItem(ID_EXPORT_OS, MF_DISABLED);
	GetMenu()->GetSubMenu(CMAINEDITOR_MENUINDEX_FILE)->EnableMenuItem(ID_CLOSE_OS, MF_DISABLED);
	GetMenu()->GetSubMenu(CMAINEDITOR_MENUINDEX_OPTION)->EnableMenuItem(ID_CALENTAR_BK, MF_DISABLED);
	GetMenu()->GetSubMenu(CMAINEDITOR_MENUINDEX_OPTION)->EnableMenuItem(ID_OSINFO, MF_DISABLED);
	GetMenu()->GetSubMenu(CMAINEDITOR_MENUINDEX_STORYEDITOR)->EnableMenuItem(ID_MC_EDITOR, MF_DISABLED);
	GetMenu()->GetSubMenu(CMAINEDITOR_MENUINDEX_STORYEDITOR)->EnableMenuItem(ID_WORLD_EDITOR, MF_DISABLED);
}

void CMainEditor::UnlockMenu()
{
	//解锁菜单
	GetMenu()->GetSubMenu(CMAINEDITOR_MENUINDEX_FILE)->EnableMenuItem(ID_SAVEAS_OS, MF_ENABLED);
	GetMenu()->GetSubMenu(CMAINEDITOR_MENUINDEX_FILE)->EnableMenuItem(ID_EXPORT_OS, MF_ENABLED);
	GetMenu()->GetSubMenu(CMAINEDITOR_MENUINDEX_FILE)->EnableMenuItem(ID_CLOSE_OS, MF_ENABLED);
	GetMenu()->GetSubMenu(CMAINEDITOR_MENUINDEX_OPTION)->EnableMenuItem(ID_CALENTAR_BK, MF_ENABLED);
	GetMenu()->GetSubMenu(CMAINEDITOR_MENUINDEX_OPTION)->EnableMenuItem(ID_OSINFO, MF_ENABLED);
	GetMenu()->GetSubMenu(CMAINEDITOR_MENUINDEX_STORYEDITOR)->EnableMenuItem(ID_MC_EDITOR, MF_ENABLED);
	GetMenu()->GetSubMenu(CMAINEDITOR_MENUINDEX_STORYEDITOR)->EnableMenuItem(ID_WORLD_EDITOR, MF_ENABLED);
}

void CMainEditor::SaveLastFile()
{
	wchar_t buff[MAX_PATH];
	CString inipath;
	GetModuleFileNameW(nullptr, buff, _countof(buff));
	inipath = buff;
	auto index = inipath.ReverseFind(L'\\');
	inipath.Delete(index, inipath.GetLength() - index);
	inipath.Append(L"\\ocstore.ini");
	WritePrivateProfileStringW(L"OCSTORE", L"LastOpenFile", osFilePath.GetString(), inipath.GetString());
}

void CMainEditor::OpenLastFile(CString& str)
{
	wchar_t buff[MAX_PATH];
	CString inipath;
	GetModuleFileNameW(nullptr, buff, _countof(buff));
	inipath = buff;
	auto index = inipath.ReverseFind(L'\\');
	inipath.Delete(index, inipath.GetLength() - index);
	inipath.Append(L"\\ocstore.ini");
	//检查文件是否存在
	FILE* fp;
	_wfopen_s(&fp, inipath.GetString(), L"rb");
	if (!fp)
	{
		str = L"";
		return;
	}
	GetPrivateProfileStringW(L"OCSTORE", L"LastOpenFile", nullptr, buff, _countof(buff), inipath.GetString());
	fclose(fp);
	str = buff;
}

void CMainEditor::InitDBTable()
{
	sqlite3* db = nullptr;//数据库文件
	sqlite3_stmt* stmt;
	//新建文件
	CString sql;
	std::vector<char> utf8;
	std::vector<char> filepath_utf8;
	UTF16ToUTF8(osFilePath.GetString(), &filepath_utf8);
	remove(filepath_utf8.data());//删除已存在的文件
	//打开一个空数据库文件
	sqlite3_open(filepath_utf8.data(), &db);//创建新的数据库文件
	/*-------------------创建基本信息表---------------*/
	sql.Format(L"CREATE TABLE %s (name TEXT,author TEXT);", DBTABLENAME_INFO);
	UTF16ToUTF8(sql.GetString(), &utf8);
	sqlite3_exec(db, utf8.data(), nullptr, nullptr, nullptr);
	//写入仓库名称和标题
	sql.Format(L"insert into %s(name,author) values(?,?);", DBTABLENAME_INFO);
	UTF16ToUTF8(sql.GetString(), &utf8);
	sqlite3_prepare(db, utf8.data(), -1, &stmt, nullptr);
	std::vector<char> osName_utf8;
	std::vector<char> osAuthor_utf8;
	int utf8_buffSize_osName;
	int utf8_buffSize_osAuthor;
	UTF16ToUTF8(osName.GetString(), &osName_utf8, &utf8_buffSize_osName);
	UTF16ToUTF8(osAuthor.GetString(), &osAuthor_utf8, &utf8_buffSize_osAuthor);
	sqlite3_bind_text(stmt, 1, osName_utf8.data(), utf8_buffSize_osName, nullptr);
	sqlite3_bind_text(stmt, 2, osAuthor_utf8.data(), utf8_buffSize_osAuthor, nullptr);
	sqlite3_step(stmt);
	sqlite3_finalize(stmt);
	//创建日历表
	sql.Format(L"CREATE TABLE %s (date TEXT PRIMARY KEY NOT NULL UNIQUE,diary TEXT);", DBTABLENAME_CALENDAR);
	UTF16ToUTF8(sql.GetString(), &utf8);
	sqlite3_exec(db, utf8.data(), nullptr, nullptr, nullptr);
	//创建系统设置表
	sql.Format(L"CREATE TABLE %s (field TEXT PRIMARY KEY UNIQUE NOT NULL,value TEXT);", DBTABLENAME_OPTION);
	UTF16ToUTF8(sql.GetString(), &utf8);
	sqlite3_exec(db, utf8.data(), nullptr, nullptr, nullptr);
	//创建角色定位标签表
	sql.Format(L"CREATE TABLE %s (mcpos TEXT PRIMARY KEY UNIQUE NOT NULL);", DBTABLENAME_MYCHAR_POSITION);
	UTF16ToUTF8(sql.GetString(), &utf8);
	sqlite3_exec(db, utf8.data(), nullptr, nullptr, nullptr);
	//创建角色性格标签表
	sql.Format(L"CREATE TABLE %s (mcchar TEXT PRIMARY KEY UNIQUE NOT NULL);", DBTABLENAME_MYCHAR_CHARACTER);
	UTF16ToUTF8(sql.GetString(), &utf8);
	sqlite3_exec(db, utf8.data(), nullptr, nullptr, nullptr);
	//创建角色表
	sql.Format(L"CREATE TABLE %s (id INTEGER PRIMARY KEY AUTOINCREMENT UNIQUE NOT NULL,facepng TEXT,lifetype INTEGER,image TEXT,name TEXT,mcpos TEXT REFERENCES ocsys_mcpos (mcpos),mcchar TEXT REFERENCES ocsys_mcchar (mcchar),gender INTEGER,ideal TEXT,label TEXT);", DBTABLENAME_MYCHARACTER);
	UTF16ToUTF8(sql.GetString(), &utf8);
	sqlite3_exec(db, utf8.data(), nullptr, nullptr, nullptr);
	//创建世界设定表
	sql.Format(L"CREATE TABLE %s (xml TEXT);", DBTABLENAME_WORLDSET);
	UTF16ToUTF8(sql.GetString(), &utf8);
	sqlite3_exec(db, utf8.data(), nullptr, nullptr, nullptr);
	/*sql.Format(L"INSERT INTO %s (xml) VALUES ('');", DBTABLENAME_WORLDSET);
	UTF16ToUTF8(sql.GetString(), &utf8);
	sqlite3_exec(db, utf8.data(), nullptr, nullptr, nullptr);*/
	//创建身体活动表
	sql.Format(L"CREATE TABLE %s (lastsport INTEGER(8));", DBTABLENAME_SPORTBODY);
	UTF16ToUTF8(sql.GetString(), &utf8);
	sqlite3_exec(db, utf8.data(), nullptr, nullptr, nullptr);
	//关闭数据库
	CloseDB(db);
}

void CMainEditor::SportBody()
{
	if (sportRemind)
		return;

	CString sql;
	std::vector<char> utf8;
	//查询运动表是否存在
	if (!GetDBTableExist(DBTABLENAME_SPORTBODY))
	{
		auto db = OpenDB();//数据库文件
		//不存在则创建运动表
		sql.Format(L"CREATE TABLE %s (lastsport INTEGER(8));", DBTABLENAME_SPORTBODY);
		UTF16ToUTF8(sql.GetString(), &utf8);
		sqlite3_exec(db, utf8.data(), nullptr, nullptr, nullptr);
		CloseDB(db);
	}
	//检查表是否有内容
	//如果有内容，如果内容不是今天时间，则删除这条记录
	if (GetDBTabelCount(DBTABLENAME_SPORTBODY) > 0)
	{
		auto db = OpenDB();
		//检查[table]表里有没有属性[field]字段
		sqlite3_stmt* stmt = nullptr;
		sql.Format(L"SELECT lastsport FROM %s;", DBTABLENAME_SPORTBODY);
		UTF16ToUTF8(sql.GetString(), &utf8);
		sqlite3_prepare(db, utf8.data(), -1, &stmt, nullptr);
		sqlite3_step(stmt);
		time_t lastTime = sqlite3_column_int64(stmt, 0);
		sqlite3_finalize(stmt);
		tm lastTm;
		localtime_s(&lastTm, &lastTime);
		time_t currentTime = time(nullptr);
		tm currentTm;
		localtime_s(&currentTm, &currentTime);
		if (lastTm.tm_yday != currentTm.tm_yday)
		{
			//则删除这条
			sql.Format(L"DELETE FROM %s;", DBTABLENAME_SPORTBODY);
			UTF16ToUTF8(sql.GetString(), &utf8);
			sqlite3_exec(db, utf8.data(), nullptr, nullptr, nullptr);
		}
		CloseDB(db);
	}
	//没有内容则立即记录当前时间
	if (GetDBTabelCount(DBTABLENAME_SPORTBODY) == 0)
	{
		//没有内容则立即记录当前时间
		time_t currentTime = time(nullptr);
		//插入到表中
		sqlite3* db = OpenDB();//数据库文件
		sql.Format(L"INSERT INTO %s (lastsport)VALUES ('%lld');", DBTABLENAME_SPORTBODY, currentTime);
		UTF16ToUTF8(sql.GetString(), &utf8);
		sqlite3_exec(db, utf8.data(), nullptr, nullptr, nullptr);
		CloseDB(db);
	}
	else
	{
		//如果有内容则查看是否过了40分钟
		auto db = OpenDB();
		//检查[table]表里有没有属性[field]字段
		sqlite3_stmt* stmt = nullptr;
		sql.Format(L"SELECT lastsport FROM %s;", DBTABLENAME_SPORTBODY);
		UTF16ToUTF8(sql.GetString(), &utf8);
		sqlite3_prepare(db, utf8.data(), -1, &stmt, nullptr);
		sqlite3_step(stmt);
		time_t lastTime = sqlite3_column_int64(stmt, 0);
		sqlite3_finalize(stmt);
		time_t currentTime = time(nullptr);
		//如果超出了40分钟，则弹窗
		workMinute = (currentTime - lastTime) / 60;
		UpdateWindowTitle();
		if (currentTime - lastTime >= 40LL * 60LL)
		{
			CString str;
			str.Format(L"已经工作了%lld分钟，该休息一下了！", workMinute);
			sportRemind = true;
			SetForegroundWindow();
			MessageBoxW(str.GetString(), L"运动或休息", MB_ICONINFORMATION);
			//确认之后，更新记录
			currentTime = time(nullptr);
			sql.Format(L"UPDATE %s SET lastsport = '%lld'", DBTABLENAME_SPORTBODY, currentTime);
			UTF16ToUTF8(sql.GetString(), &utf8);
			sqlite3_exec(db, utf8.data(), nullptr, nullptr, nullptr);
			sportRemind = false;
		}
		CloseDB(db);
	}
}

BOOL CMainEditor::PreTranslateMessage(MSG* pMsg)
{
	HOTKEYPROC;
}
