#pragma once

class COctSpinButtonCtrl;
class COctalEdit : public CEdit
{
		DECLARE_DYNAMIC(COctalEdit)

		COctSpinButtonCtrl *m_pSpin;

	public:
		COctalEdit();
		virtual ~COctalEdit() override;
		void AttachSpin(COctSpinButtonCtrl *pSpin)
		{
			m_pSpin = pSpin;
		}

	protected:
		afx_msg void OnChar(UINT nChar, UINT nRepCnt, UINT nFlags);
		afx_msg void OnEnUpdate();
		DECLARE_MESSAGE_MAP()
};


class COctSpinButtonCtrl : public CSpinButtonCtrl
{
		DECLARE_DYNAMIC(COctSpinButtonCtrl)
		COctalEdit *m_pOctBuddy;
		bool m_bSpinChange;
	public:
		COctSpinButtonCtrl();
		virtual ~COctSpinButtonCtrl() override;
		void SetOctBuddy(COctalEdit *pOctBuddy);
		bool isSpinChange() const
		{
			return m_bSpinChange;
		}
	protected:
		afx_msg void OnDeltapos(NMHDR *pNMHDR, LRESULT *pResult);
		DECLARE_MESSAGE_MAP()
};


//From dlgdata.cpp
static void AFXAPI DDX_OctText(CDataExchange *pDX, int nIDC, int &value)
{
	CString str;
	const HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);

	if (pDX->m_bSaveAndValidate)
	{
		const int nLen = ::GetWindowTextLength(hWndCtrl);
		::GetWindowText(hWndCtrl, str.GetBufferSetLength(nLen), nLen + 1);
		str.ReleaseBuffer();
		value = Global::OctStringToWord(str);
	}
	else
	{
		Global::WordToOctString(value, str);
		AfxSetWindowText(hWndCtrl, str);
	}
}

static void AFXAPI DDV_MyMinMaxInt(CDataExchange *pDX, int nIDC, int value, int minVal, int maxVal)
{
	ASSERT(minVal <= maxVal);

	if (value < minVal || value > maxVal)
	{
		constexpr UINT nIDPrompt = AFX_IDP_PARSE_INT_RANGE;

		if (!pDX->m_bSaveAndValidate)
		{
			TRACE(traceAppMsg, 0, "Warning: initial dialog data is out of range.\n");
			return;     // don't stop now
		}

		CString strMin;
		CString strMax;
		Global::WordToOctString(minVal, strMin);
		Global::WordToOctString(maxVal, strMax);
		CString prompt;
		AfxFormatString2(prompt, nIDPrompt, strMin.GetString(), strMax.GetString());
		strMin.Empty();
		strMax.Empty();
		AfxMessageBox(prompt, MB_ICONEXCLAMATION, nIDPrompt);

		if (value < minVal)
		{
			value = minVal;
		}
		else if (value > maxVal)
		{
			value = maxVal;
		}

		HWND hWndCtrl = pDX->PrepareEditCtrl(nIDC);
		Global::WordToOctString(value, prompt);
		AfxSetWindowText(hWndCtrl, prompt);
		prompt.Empty(); // exception prep
		pDX->Fail();
	}
}

