//
//   函数: InitInstance(HINSTANCE, int)
//
//   目的: 保存实例句柄并创建主窗口
//
//   注释:
//
//        在此函数中,我们在全局变量中保存实例句柄并
//        创建和显示主程序窗口。
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
	HWND hWnd;

	hInst = hInstance; // 将实例句柄存储在全局变量中

	hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
		CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

	if (!hWnd)
	{
		return FALSE;
	}

	// 打开资源
	BYTE* buff = NULL; DWORD size = 0;
	HGLOBAL hres = CResGetter::GetBinary(IDB_BMP1, _T("BMP"), buff, size);
	// 打开文件并获取解码器
	CMemFile file(buff, size); CGC gc;
	ICoderObject* coder = CImgAnalyzer::GetCoder(&file, &gc);
	// 解码文件
	imgOrig = coder->Decode();
	imgShow = imgOrig.Clone();
	// 关闭资源
	CResGetter::ReleaseBinary(hres);

	// 允许拖放
	DragAcceptFiles(hWnd, TRUE);

	ShowWindow(hWnd, nCmdShow);
	UpdateWindow(hWnd);

	return TRUE;
}
BOOL OpenFile(HWND hWnd, CString& sPath)
{
	if (sPath.Empty()) return FALSE;
	// 打开文件并获取解码器
	CIOFile file(sPath); CGC gc;
	ICoderObject* coder = CImgAnalyzer::GetCoder(&file, &gc);
	if (!coder) return FALSE;
	// 解码文件
	imgOrig = coder->Decode();
	imgShow = imgOrig.Clone();
	return TRUE;
} 
//
//  函数: WndProc(HWND, UINT, WPARAM, LPARAM)
//
//  目的: 处理主窗口的消息。
//
//  WM_COMMAND	- 处理应用程序菜单
//  WM_PAINT	- 绘制主窗口
//  WM_DESTROY	- 发送退出消息并返回
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
	int wmId, wmEvent;
	PAINTSTRUCT ps;
	HDC hdc;

	switch (message)
	{
	case WM_COMMAND:
		wmId    = LOWORD(wParam);
		wmEvent = HIWORD(wParam);
		// 分析菜单选择:
		switch (wmId)
		{
		// 文件
		case IDM_OPEN:
			{
				CString ret;
				CSysDialog::FileDialog(ret, TRUE, NULL, NULL, 
					_T("图片文件(*.bmp;*.jpg;*.png;*.ico)\0*.bmp;*.jpg;*.png;*.ico\0所有文件(*.*)\0*.*\0"));
				OpenFile(hWnd, ret);
				// 刷新窗口
				Invalidate(hWnd);
			}
			break;
		case IDM_SAVE:
			if (imgShow)
			{
				CString ret; DWORD inx = 0;
				CSysDialog::FileDialog(ret, FALSE, NULL, NULL, 
					_T("BMP文件(*.bmp)\0*.bmp\0JPG文件(*.jpg)\0*.jpg\0PNG文件(*.png)\0*.png\0ICO文件(*.ico)\0*.ico\0"), &inx);
				SaveFile(inx, ret);
			}
			break;
		// 原图
		case IDM_ORI:
			if (imgOrig)
			{
				imgShow = imgOrig.Clone();
				// 刷新窗口
				Invalidate(hWnd);
			}
			break;
		// 形变
		case IDM_PLG:
			if (imgShow)
			{
				CPoint var[2] = 
				{
					CPoint(500, 200), 
					CPoint(600, 400)
				};
				image_t tmp = CImgDeformer::PlgDeform(imgShow, var);
				if(!tmp) break;
				imgShow = tmp;
				// 刷新窗口
				Invalidate(hWnd);
			}
			break;
		case IDM_WHL:
			if (imgShow)
			{
				image_t tmp = CImgDeformer::WhlDeform(imgShow, -45);
				if(!tmp) break;
				imgShow = tmp;
				// 刷新窗口
				Invalidate(hWnd);
			}
			break;
		case IDM_ZOM:
			if (imgShow)
			{
				CImage bmp_img(imgShow);
				image_t tmp = CImgDeformer::ZomDeform(imgShow, (LONG)(bmp_img.GetWidth() * -1.2), (LONG)(bmp_img.GetHeight() * 1.5));
				if(!tmp) break;
				imgShow = tmp;
				// 刷新窗口
				Invalidate(hWnd);
			}
			break;
		// 渲染
		case IDM_GRAY:
			Filter(hWnd, &CFilterGray());
			break;
		case IDM_INVE:
			Filter(hWnd, &CFilterInverse());
			break;
		case IDM_RELI:
			{
				timeBeginPeriod(1);
				DWORD t_s = timeGetTime();
				Filter(hWnd, &CFilterRelief());
				DWORD t_e = timeGetTime();
				timeEndPeriod(1);
				t_e -= t_s;
				CString msg;
				msg.Format(_T("%d ms"), t_e);
				::MessageBox(NULL, (LPCTSTR)msg, NULL, 0);
			}
			break;
		case IDM_DIFF:
			Filter(hWnd, &CFilterDiffuse());
			break;
		case IDM_GAUS:
			{
				timeBeginPeriod(1);
				DWORD t_s = timeGetTime();
				Filter(hWnd, &CFilterGauss());
				DWORD t_e = timeGetTime();
				timeEndPeriod(1);
				t_e -= t_s;
				CString msg;
				msg.Format(_T("%d ms"), t_e);
				::MessageBox(NULL, (LPCTSTR)msg, NULL, 0);
			}
			break;
		case IDM_OUTG:
			if (imgShow)
			{
			/*	CFilterGauss filter;
				CPoint pt_flt(filter.m_Radius << 1, filter.m_Radius << 1);
				// 将图片扩大
				CRect rc(0, 0, imgShow.GetWidth(), imgShow.GetHeight());
				image_t tmp = imgShow.Clone(rc + pt_flt);
				if (!tmp) break;
				// 阴影化
				CImgFilter::Filter(tmp, CRect(), &CFilterFill(ExRGB(255, 255, 190), 0xe));
				CImgFilter::Filter(tmp, CRect(), &filter);
				// 阴影叠加
				rc.Offset(pt_flt);
				CImgRenderer::Render(tmp, imgShow, rc, CPoint());
				imgShow = tmp;
				// 刷新窗口
				Invalidate(hWnd);*/
			}
			break;
		case IDM_GRAD:
			Filter(hWnd, &CFilterGradient(
				ExRGBA(255, 255, 255, 128), ExRGBA(0, 0, 0, 128), 0x9, FALSE));
			break;
		// 关于
		case IDM_ABOUT:
			DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);
			break;
		// 退出
		case IDM_EXIT:
			DestroyWindow(hWnd);
			break;
		default:
			return DefWindowProc(hWnd, message, wParam, lParam);
		}
		break;
	case WM_PAINT:
		hdc = BeginPaint(hWnd, &ps);
		{
			RECT rect = {0};
			GetClientRect(hWnd, &rect);

			CImage mem_img;
			mem_img.Create(rect.right - rect.left, rect.bottom - rect.top);

			CDC mem_dc;
			mem_dc.Create(hdc);
			mem_dc.SetObject(mem_img.Get());

			HBRUSH brh = (HBRUSH)GetStockObject(GRAY_BRUSH);
			FillRect(mem_dc, &rect, brh);

			if(!imgShow.IsNull())
			{
				CImgRenderer::Render
					(
					mem_img, imgShow, 
					CRect
						(
						(rect.right - imgShow.GetWidth()) / 2, 
						(rect.bottom - imgShow.GetHeight()) / 2, 
						rect.right, 
						rect.bottom
						), 
					CPoint()
					);
			}

			CText text((font_t)::GetStockObject(DEFAULT_GUI_FONT), ExRGBA(255, 255, 255, 128));
			CString str(_T("Dark C.at"));
			CImage bmp_img(text.GetImage(str));
			if(!bmp_img.IsNull())
				CImgRenderer::Render(mem_img, bmp_img, CRect(
					rect.right - bmp_img.GetWidth() - 5, 
					rect.bottom - bmp_img.GetHeight() - 5, 
					rect.right, rect.bottom));

			::BitBlt(hdc, rect.left, rect.top, rect.right - rect.left, rect.bottom - rect.top, mem_dc, 0, 0, SRCCOPY);

			mem_dc.Delete();
		}
		EndPaint(hWnd, &ps);
		break;
	case WM_ERASEBKGND:
		break;
	case WM_DROPFILES:
		{
			HDROP drop = (HDROP)wParam;
			CString path;
			DragQueryFile(drop, 0, path.GetCStr(MAX_PATH), MAX_PATH);
			DragFinish(drop);
			if (path.Empty()) break;
			WIN32_FIND_DATA fd;
			HANDLE find = ::FindFirstFile(path, &fd);
			if (find == INVALID_HANDLE_VALUE)
				break;
			::FindClose(find);
			if (fd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
				break;
			OpenFile(hWnd, path);
			// 刷新窗口
			Invalidate(hWnd);
		}
		break;
	case WM_DESTROY:
		PostQuitMessage(0);
		break;
	default:
		return DefWindowProc(hWnd, message, wParam, lParam);
	}
	return 0;
}