
// C++YjYScaleDemo.cpp: 定义应用程序的类行为。
//

#include "stdafx.h"
#include "C++YjYScaleDemo.h"
#include "C++YjYScaleDemoDlg.h"
#include<list>	
#include <iostream>
#include <vector>
#include <sstream>
#include <string.h>
#include <direct.h>
#include <io.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

HINSTANCE hDLL;
SDK_Initialize initialize;
SDK_Finalize finalize;
SDK_ExecTask execTask;
SDK_ExecTaskW execTaskW;
SDK_ExecTaskA execTaskA;
SDK_WaitForTask waitForTask;
SDK_GetDeviceInfo getDeviceInfo;
_progress progress;
CCYjYScaleDemoDlg* pdlg;
BOOL ContentIsNull;

struct ProgressSetting
{
	int index; int total;
};
ProgressSetting ProgressSet;
// CCYjYScaleDemoApp

BEGIN_MESSAGE_MAP(CCYjYScaleDemoApp, CWinApp)
	ON_COMMAND(ID_HELP, &CWinApp::OnHelp)
END_MESSAGE_MAP()


// CCYjYScaleDemoApp 构造

CCYjYScaleDemoApp::CCYjYScaleDemoApp()
{
	// 支持重新启动管理器
	m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_RESTART;

	// TODO: 在此处添加构造代码，
	// 将所有重要的初始化放置在 InitInstance 中
}


// 唯一的 CCYjYScaleDemoApp 对象

CCYjYScaleDemoApp theApp;


// CCYjYScaleDemoApp 初始化

BOOL CCYjYScaleDemoApp::InitInstance()
{
	// 如果一个运行在 Windows XP 上的应用程序清单指定要
	// 使用 ComCtl32.dll 版本 6 或更高版本来启用可视化方式，
	//则需要 InitCommonControlsEx()。  否则，将无法创建窗口。
	INITCOMMONCONTROLSEX InitCtrls;
	InitCtrls.dwSize = sizeof(InitCtrls);
	// 将它设置为包括所有要在应用程序中使用的
	// 公共控件类。
	InitCtrls.dwICC = ICC_WIN95_CLASSES;
	InitCommonControlsEx(&InitCtrls);
	CWinApp::InitInstance();
	AfxEnableControlContainer();

	// 创建 shell 管理器，以防对话框包含
	// 任何 shell 树视图控件或 shell 列表视图控件。
	CShellManager *pShellManager = new CShellManager;

	// 激活“Windows Native”视觉管理器，以便在 MFC 控件中启用主题
	CMFCVisualManager::SetDefaultManager(RUNTIME_CLASS(CMFCVisualManagerWindows));

	// 标准初始化
	// 如果未使用这些功能并希望减小
	// 最终可执行文件的大小，则应移除下列
	// 不需要的特定初始化例程
	// 更改用于存储设置的注册表项
	// TODO: 应适当修改该字符串，
	// 例如修改为公司或组织名
	SetRegistryKey(_T("应用程序向导生成的本地应用程序"));

	CCYjYScaleDemoDlg dlg;
	m_pMainWnd = &dlg;
	INT_PTR nResponse = dlg.DoModal();
	if (nResponse == IDOK)
	{
		// TODO: 在此放置处理何时用
		//  “确定”来关闭对话框的代码
	}
	else if (nResponse == IDCANCEL)
	{
		// TODO: 在此放置处理何时用
		//  “取消”来关闭对话框的代码
	}
	else if (nResponse == -1)
	{
		TRACE(traceAppMsg, 0, "警告: 对话框创建失败，应用程序将意外终止。\n");
		TRACE(traceAppMsg, 0, "警告: 如果您在对话框上使用 MFC 控件，则无法 #define _AFX_NO_MFC_CONTROLS_IN_DIALOGS。\n");
	}

	// 删除上面创建的 shell 管理器。
	if (pShellManager != nullptr)
	{
		delete pShellManager;
	}

#if !defined(_AFXDLL) && !defined(_AFX_NO_MFC_CONTROLS_IN_DIALOGS)
	ControlBarCleanUp();
#endif

	// 由于对话框已关闭，所以将返回 FALSE 以便退出应用程序，
	//  而不是启动应用程序的消息泵。
	return FALSE;
}


void init()
{
	bool initState = false;
	hDLL = LoadLibrary(L"SyncSDK.dll");
	initialize = (SDK_Initialize)GetProcAddress(hDLL, "SDK_Initialize");
	finalize = (SDK_Finalize)GetProcAddress(hDLL, "SDK_Finalize");
	execTask = (SDK_ExecTask)GetProcAddress(hDLL, "SDK_ExecTask");
	execTaskW = (SDK_ExecTaskW)GetProcAddress(hDLL, "SDK_ExecTaskW");
	execTaskA = (SDK_ExecTaskA)GetProcAddress(hDLL, "SDK_ExecTaskA");
	waitForTask = (SDK_WaitForTask)GetProcAddress(hDLL, "SDK_WaitForTask");
	getDeviceInfo = (SDK_GetDeviceInfo)GetProcAddress(hDLL, "SDK_GetDeviceInfo");
	initState = initialize(nullptr);
}

void FinalizeFree()
{
	finalize();
}

UINT MyThreadProc(LPVOID pParam)
{
	ProgressSetting* a = (ProgressSetting*)pParam;
	pdlg->setProgress(a->total);
	pdlg->showProgress(a->index, a->total);
	return 0;
}
static void __stdcall taskProgressEvent(int errCode, int index, int total, void *userData)
{
	ProgressSet.index = index;
	ProgressSet.total = total;
	if (total == 0) {
		ContentIsNull = true;
	}
	AfxBeginThread(&MyThreadProc, (LPVOID)&ProgressSet);
}

//bool transferItem(const int&DateType, const string & addr, const string &fileName, const HWND hWnd)
bool DownFileAdrr(const int&DateType, const string & addr, const HWND hWnd)
{
	ContentIsNull = false;
	unsigned long host = MakeHostToDWord(addr);
	if (getDeviceInfo(host).ProtocolType == SDK_ProtocolType_None) {
		MessageBox(hWnd, _T("未找到设备"), _T("状态"), MB_OK);
		return false;
	}
	pdlg = (CCYjYScaleDemoDlg*)AfxGetMainWnd();
	pdlg->setProgress(10);
	pdlg->showProgress(0, 10);
	waitForTask(execTaskA(host, Sync_Action_DownLoad, DateType, returnFileAddr(Sync_Action_DownLoad,DateType), taskProgressEvent, nullptr));
	if (ContentIsNull) {
		MessageBox(hWnd, _T("下载文件内容为空"), _T("状态"), MB_OK);
	}
	return false;
}

bool DelFileAdrr(const int & DateType, const string & addr, const HWND hWnd)
{
	ContentIsNull = false;
	unsigned long host = MakeHostToDWord(addr);
	if (getDeviceInfo(host).ProtocolType == SDK_ProtocolType_None) {
		MessageBox(hWnd, _T("未找到设备"), _T("状态"), MB_OK);
		return false;
	}
	pdlg = (CCYjYScaleDemoDlg*)AfxGetMainWnd();
	pdlg->setProgress(10);
	pdlg->showProgress(0, 10);
	waitForTask(execTaskA(host, Sync_Action_Delete, DateType, returnFileAddr(Sync_Action_Delete,DateType), taskProgressEvent, nullptr));
	if (ContentIsNull) {
		MessageBox(hWnd, _T("上传文件内容为空"), _T("状态"), MB_OK);
	}
	return false;
}

bool UpFileAdrr(const int & DateType, const string & addr, const HWND hWnd)
{
	ContentIsNull = false;
	unsigned long host = MakeHostToDWord(addr);
	if (getDeviceInfo(host).ProtocolType == SDK_ProtocolType_None) {
		MessageBox(hWnd, _T("未找到设备"), _T("状态"), MB_OK);
		return false;
	}
	pdlg = (CCYjYScaleDemoDlg*)AfxGetMainWnd();
	pdlg->setProgress(10);
	pdlg->showProgress(0, 10);
	//如果上传文件夹不存在就创建
	CreateFileAddr();
	waitForTask(execTaskA(host, Sync_Action_UpLoad, DateType, returnFileAddr(Sync_Action_UpLoad,DateType), taskProgressEvent, nullptr));
	if (ContentIsNull) {
		MessageBox(hWnd, _T("上传文件内容为空"), _T("状态"), MB_OK);
	}
	return false;
}

void CreateFileAddr()
{
	std::wstring ws(returnProgramAddr());
	std::string GetAddr;
	GetAddr.assign(ws.begin(), ws.end());

	//判断上传文件夹是否存在，不存在则创建
	const char* dir = GetAddr.c_str();
	 //_access也可用来判断文件是否存在
	if (_access(dir, 0) == -1)
	{
		_mkdir(dir);
		cout << "该文件夹不存在，已自动创建" << endl;
	}
	else {
		cout << "该文件夹存在，已自动创建" << endl;
	}
}

char * returnFileAddr(const int&ProcType,const int&DateType)
{
	CString fileName, fileName1, strPath;
	if (ProcType == Sync_Action_DownLoad || ProcType == Sync_Action_Delete)
	{
		strPath = returnProgramAddr()+CString("DownFile\\");
	}
	else  if (ProcType == Sync_Action_UpLoad)
	{
		strPath = returnProgramAddr() + CString("UpFile\\");
	}
	fileName1 = returnFileName(DateType);
	fileName = strPath + fileName1;
	std::wstring ws(fileName);
	std::string s;
	s.assign(ws.begin(), ws.end());
	char * file = new char[255];
	stringstream sstr;
	sstr.clear();
	sstr << s;
	sstr >> file;
	return file;
}

CString returnFileName(int ADataType)
{
	CString returnFile;

	switch (ADataType)
	{
		case Sync_DataType_PLU:
			returnFile = "PLU.txt";
			break;
		case
			Sync_DataType_Department:
			returnFile = "Department.txt";
			break;
		case Sync_DataType_Unit: // 单位
			returnFile = "Unit.txt";
			break;
		case Sync_DataType_Hotkey: // 热键
			returnFile = "Hotkey.txt";
			break;
		case Sync_DataType_CustomBarcode: // 自定义条码
			returnFile = "CustomBarcode.txt";
			break;
	    case Sync_DataType_Note1: // 信息1
			returnFile = "Note1.txt";
			break;
		case Sync_DataType_Note2: // 信息2
			returnFile = "Note2.txt";
			break;
        case Sync_DataType_Note3: // 信息3
			returnFile = "Note3.txt";
			break;
        case Sync_DataType_Note4: // 信息4
			returnFile = "Note4.txt";
			break;
        case Sync_DataType_SystemOptions:// 系统参数
			returnFile = "SystemOptions.txt";
			break;
		case Sync_DataType_Time: // 下载时间  // 实际上, 下载时间不需要文档, 传个存在的文档名就行
			returnFile = "PLU.txt";
			break;
		case Sync_DataType_Label:
			returnFile = "DefaultLabel.lbl";
			break;
	    case Sync_DataType_LabelBackGround:
			returnFile = "DefaultLabel.lbl";
			break;
		case Sync_DataType_LabelFile:
			returnFile = "DefaultLabel.lbl";
			break;

	}
	return returnFile;



}

CString returnProgramAddr()
{
	//CString fileName, fileName1;
	TCHAR _szPath[MAX_PATH + 1] = { 0 };
	GetModuleFileName(NULL, _szPath, MAX_PATH);
	(_tcsrchr(_szPath, _T('\\')))[1] = 0;//删除文件名，只获得路径 字串
	CString strPath;
	for (int n = 0; _szPath[n]; n++)
	{
		if (_szPath[n] != _T('\\'))
		{
			strPath += _szPath[n];
		}
		else
		{
			strPath += _T('\\');
		}
	}
	return strPath;
}

vector<string> splitStr(string str, char delimiter) {
	vector<string> r;
	string tmpstr;
	while (!str.empty()) {
		int ind = str.find_first_of(delimiter);
		if (ind == -1) {
			r.push_back(str);
			str.clear();
		}
		else {
			r.push_back(str.substr(0, ind));
			str = str.substr(ind + 1, str.size() - ind - 1);
		}
	}
	return r;
}


unsigned long MakeHostToDWord(const string &addr)
{
	vector<string> segments;
	unsigned long result = 0;
	segments = splitStr(addr, '.');
	if (segments.size() != 4)
		return result;
	for (int i = 0; i < (segments.size()); i++)
	{
		unsigned long tmp = stoi(segments.at(i).c_str(), nullptr, 10);
		if (tmp >= 0 && tmp <= 255)
		{
			result += tmp << ((3 - i) * 8);
		}
		else
			return result;
	}
	return result;
}