// SettingsDlg.cpp: файл реализации
//

#include "stdafx.h"
#include "resource.h"
#include "SettingsDlg.h"
#include "afxdialogex.h"
#include <string>

// Диалоговое окно CSettingsDlg

IMPLEMENT_DYNAMIC(CSettingsDlg, CDialogEx)


const LPCTSTR CSettingsDlg::KEY_USELONGBIN = _T("UseLongBinFormat");
const LPCTSTR CSettingsDlg::KEY_FRONTANALYSE = _T("FrontAnalyse");
const LPCTSTR CSettingsDlg::KEY_FRONTALIASING = _T("FrontAliasing");
const LPCTSTR CSettingsDlg::KEY_FRONTLEVELS = _T("FrontLevels");
const LPCTSTR CSettingsDlg::KEY_IGNORECRC = _T("IgnoreCRC");
const LPCTSTR CSettingsDlg::KEY_WORKLOG = _T("StoreWorkLog");
const LPCTSTR CSettingsDlg::KEY_TUNESCATTER = _T("TuneScatter");
const LPCTSTR CSettingsDlg::KEY_DELTAIMPULSE = _T("DeltaImpulse");
const LPCTSTR CSettingsDlg::KEY_SOLIDFILE = _T("SolidFile");
const LPCTSTR CSettingsDlg::KEY_VALTRUE = _T("Yes");
const LPCTSTR CSettingsDlg::KEY_VALFALSE = _T("No");

CSettingsDlg::CSettingsDlg(CWnd *pParent /*=nullptr*/)
	: CDialogEx(IDD_SETTINGS_DIALOG, pParent)
	, bUseLongBinFormat(TRUE)
	, bFrontAnalyse(TRUE)
	, bFrontAliasing(TRUE)
	, bFrontLevels(FALSE)
	, bIgnoreCRC(FALSE)
	, bWorkLog(FALSE)
	, bSolidFile(FALSE)
	, nTuneImpScatter(3)    // для стандартной скорости 3 (при замедленных скоростях разброс возрастает а так же если скорость плавает, тоже может быть больше. Может достигать 7)
	, nProgressScale(500)
	, nTimerValue(100)
	, dDeltaImp(0.3)
{
	std::wstring s = std::to_wstring(dDeltaImp);
	m_strDeltaImp = s.c_str();
	m_strDeltaImp.TrimRight(_T('0'));
}

CSettingsDlg::~CSettingsDlg()
{
}

CSettingsDlg g_Settings;

void CSettingsDlg::DoDataExchange(CDataExchange *pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Check(pDX, IDC_CHECK_LONG_BIN, bUseLongBinFormat);
	DDX_Check(pDX, IDC_CHECK_FRONT_ANALYSE, bFrontAnalyse);
	DDX_Check(pDX, IDC_CHECK_FRONT_ALIAS, bFrontAliasing);
	DDX_Check(pDX, IDC_CHECK_FRONT_LEVELS, bFrontLevels);
	DDX_Text(pDX, IDC_EDIT_TUNESCATTER, nTuneImpScatter);
	DDV_MinMaxInt(pDX, nTuneImpScatter, 1, 20);
	DDX_Check(pDX, IDC_CHECK_IGNORECRC, bIgnoreCRC);
	DDX_Check(pDX, IDC_CHECK_WORKLOG, bWorkLog);
	DDX_Text(pDX, IDC_EDIT_DELTAIMP, m_strDeltaImp);
	DDX_Check(pDX, IDC_CHECK_SOLIDFILE, bSolidFile);
}


BEGIN_MESSAGE_MAP(CSettingsDlg, CDialogEx)
	ON_BN_CLICKED(IDC_CHECK_FRONT_ANALYSE, &CSettingsDlg::OnBnClickedCheckFrontAnalyse)
END_MESSAGE_MAP()


// Обработчики сообщений CSettingsDlg


BOOL CSettingsDlg::OnInitDialog()
{
	CDialogEx::OnInitDialog();
	UpdateData(FALSE);
	SetCheckbox();
	return TRUE;  // return TRUE unless you set the focus to a control
	// Исключение: страница свойств OCX должна возвращать значение FALSE
}


void CSettingsDlg::OnOK()
{
	UpdateData(TRUE);
	CString s = m_strDeltaImp;
	s.Replace(_T('.'), _T(','));
	dDeltaImp = _tcstod(s, nullptr);
	CDialogEx::OnOK();
}


void CSettingsDlg::OnBnClickedCheckFrontAnalyse()
{
	SetCheckbox();
}


void CSettingsDlg::SetCheckbox()
{
	auto btn = reinterpret_cast<CButton *>(GetDlgItem(IDC_CHECK_FRONT_ANALYSE));

	if (BST_CHECKED == btn->GetCheck())
	{
		GetDlgItem(IDC_CHECK_FRONT_ALIAS)->EnableWindow(TRUE);
		GetDlgItem(IDC_CHECK_FRONT_LEVELS)->EnableWindow(TRUE);
	}
	else
	{
		GetDlgItem(IDC_CHECK_FRONT_ALIAS)->EnableWindow(FALSE);
		GetDlgItem(IDC_CHECK_FRONT_LEVELS)->EnableWindow(FALSE);
	}
}

void CSettingsDlg::Init()
{
	LSTATUS lResult = ::RegOpenKeyEx(HKEY_CURRENT_USER, m_strRegKeyName, 0, KEY_ALL_ACCESS, &m_hkeyRegKey);

	if (lResult != ERROR_SUCCESS)
	{
		lResult = ::RegCreateKeyEx(HKEY_CURRENT_USER, m_strRegKeyName, 0, nullptr, 0, KEY_ALL_ACCESS,
		                           nullptr, &m_hkeyRegKey, nullptr);
	}
}

void CSettingsDlg::Done()
{
	::RegCloseKey(m_hkeyRegKey);
}

bool CSettingsDlg::SaveStringValue(LPCTSTR sName, CString &strValue)
{
	LSTATUS lResult;
	lResult = ::RegSetValueEx(m_hkeyRegKey, sName, 0, REG_SZ, reinterpret_cast<const BYTE *>(strValue.GetString()),
	                          (strValue.GetLength() + 1) * sizeof(TCHAR));
	return (lResult == ERROR_SUCCESS);
}

bool CSettingsDlg::LoadStringValue(LPCTSTR sName, CString &strValue)
{
	TCHAR pBuffer[_MAX_PATH];
	DWORD dwType;
	DWORD dwBufLength = _MAX_PATH * sizeof(TCHAR);
	memset(pBuffer, 0, dwBufLength);
	LSTATUS lResult = ::RegQueryValueEx(m_hkeyRegKey, sName, nullptr, &dwType, reinterpret_cast<LPBYTE>(pBuffer), &dwBufLength);

	if (lResult == ERROR_SUCCESS && dwType == REG_SZ)
	{
		strValue = CString(pBuffer);
		return true;
	}

	strValue = _T("");
	return false;
}


void CSettingsDlg::ConfigSettings()
{
	const CWinApp *pWinApp = AfxGetApp();
	m_hkeyRegKey = HKEY(INVALID_HANDLE_VALUE);
	m_strRegKeyName = _T("Software\\") + CString(pWinApp->m_pszRegistryKey) + _T("\\") +
	                  CString(pWinApp->m_pszProfileName);
}

void CSettingsDlg::LoadSettings()
{
	Init();
	CString strVal;
	LoadStringValue(KEY_USELONGBIN, strVal);

	if (!strVal.IsEmpty())
	{
		bUseLongBinFormat = !(strVal.CompareNoCase(_T("Yes")) && strVal.CompareNoCase(_T("1")));
	}

	LoadStringValue(KEY_FRONTANALYSE, strVal);

	if (!strVal.IsEmpty())
	{
		bFrontAnalyse = !(strVal.CompareNoCase(_T("Yes")) && strVal.CompareNoCase(_T("1")));
	}

	LoadStringValue(KEY_FRONTALIASING, strVal);

	if (!strVal.IsEmpty())
	{
		bFrontAliasing = !(strVal.CompareNoCase(_T("Yes")) && strVal.CompareNoCase(_T("1")));
	}

	LoadStringValue(KEY_FRONTLEVELS, strVal);

	if (!strVal.IsEmpty())
	{
		bFrontLevels = !(strVal.CompareNoCase(_T("Yes")) && strVal.CompareNoCase(_T("1")));
	}

	LoadStringValue(KEY_IGNORECRC, strVal);

	if (!strVal.IsEmpty())
	{
		bIgnoreCRC = !(strVal.CompareNoCase(_T("Yes")) && strVal.CompareNoCase(_T("1")));
	}

	LoadStringValue(KEY_WORKLOG, strVal);

	if (!strVal.IsEmpty())
	{
		bWorkLog = !(strVal.CompareNoCase(_T("Yes")) && strVal.CompareNoCase(_T("1")));
	}

	LoadStringValue(KEY_SOLIDFILE, strVal);

	if (!strVal.IsEmpty())
	{
		bSolidFile = !(strVal.CompareNoCase(_T("Yes")) && strVal.CompareNoCase(_T("1")));
	}

	LoadStringValue(KEY_TUNESCATTER, strVal);

	if (!strVal.IsEmpty())
	{
		nTuneImpScatter = StrToInt(strVal);
	}

	LoadStringValue(KEY_DELTAIMPULSE, strVal);

	if (!strVal.IsEmpty())
	{
		m_strDeltaImp = strVal;
		strVal.Replace(_T('.'), _T(','));
		dDeltaImp = _tcstod(strVal, nullptr);
	}

	Done();
}

void CSettingsDlg::SaveSettings()
{
	Init();
	CString strVal = bUseLongBinFormat ? KEY_VALTRUE : KEY_VALFALSE;
	SaveStringValue(KEY_USELONGBIN, strVal);
	strVal = bFrontAnalyse ? KEY_VALTRUE : KEY_VALFALSE;
	SaveStringValue(KEY_FRONTANALYSE, strVal);
	strVal = bFrontAliasing ? KEY_VALTRUE : KEY_VALFALSE;
	SaveStringValue(KEY_FRONTALIASING, strVal);
	strVal = bFrontLevels ? KEY_VALTRUE : KEY_VALFALSE;
	SaveStringValue(KEY_FRONTLEVELS, strVal);
	strVal = bIgnoreCRC ? KEY_VALTRUE : KEY_VALFALSE;
	SaveStringValue(KEY_IGNORECRC, strVal);
	strVal = bWorkLog ? KEY_VALTRUE : KEY_VALFALSE;
	SaveStringValue(KEY_WORKLOG, strVal);
	strVal = bSolidFile ? KEY_VALTRUE : KEY_VALFALSE;
	SaveStringValue(KEY_SOLIDFILE, strVal);
	strVal.Format(_T("%d"), nTuneImpScatter);
	SaveStringValue(KEY_TUNESCATTER, strVal);
	SaveStringValue(KEY_DELTAIMPULSE, m_strDeltaImp);
	Done();
}

