// TabMEMAccess.cpp: 구현 파일
//

#include "pch.h"
#include "NSeries_MEMAccess.h"
#include "TabMEMAccess.h"
#include "afxdialogex.h"


// TabMEMAccess 대화 상자

IMPLEMENT_DYNAMIC(TabMEMAccess, CDialogEx)

TabMEMAccess::TabMEMAccess(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_DLGTABMEMACCESS, pParent)
	, m_strName(_T(""))
	, m_strGraphName(_T(""))
{

}

TabMEMAccess::~TabMEMAccess()
{
}

void TabMEMAccess::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_PIC_MEMREADGRAPH, m_picReadGraph);
	DDX_Control(pDX, IDC_CMB_SELMEMPAGE, m_cmbSelMemPage);
	DDX_Control(pDX, IDC_LIST_MEMLIST, m_listMemList);
	DDX_Text(pDX, IDC_EDIT_NAME, m_strName);
	DDX_Text(pDX, IDC_STATIC_GRAPHNAME, m_strGraphName);
}

void TabMEMAccess::InitMemRead()
{
	short sRtn;

	if (m_cmbSelMemPage.GetCount() > 0)
	{
		int iCount = m_cmbSelMemPage.GetCount();
		for (int i = 0; i < iCount; i++)
			m_cmbSelMemPage.DeleteString(0);
	}

	m_listMemList.DeleteAllItems();

	m_cmbSelMemPage.AddString(_T("0 : Select Memory Page"));
	m_cmbSelMemPage.AddString(_T("1 : Select Memory Page"));
	m_cmbSelMemPage.SetCurSel(0);

	CRect rect;

	m_listMemList.GetClientRect(&rect);
	m_listMemList.InsertColumn(0, _T("State"),LVCFMT_CENTER, 40);
	m_listMemList.InsertColumn(1, _T("Addr"), LVCFMT_CENTER, 40);
	m_listMemList.InsertColumn(2, _T("Name"), LVCFMT_CENTER, rect.Width() - 80);

	m_listMemList.SetExtendedStyle(LVS_EX_FULLROWSELECT);

	_MEMORYSTATE stMemState[10];

	sRtn = spNGetMemState(m_cmbSelMemPage.GetCurSel(), stMemState, m_stDeviceInfo.sChannel);
	if (sRtn < 0)
	{
		CString strLine;
		strLine.Format(_T("Error Function : spNGetMemState(). error = %d"), sRtn);
		AfxMessageBox(strLine);
		return;
	}
		
	for (int i = 0; i < 10; i++)
	{
		CString strTemp;
		
		strTemp.Format(_T("%d"), stMemState[i].sMemState);
		m_listMemList.InsertItem(i, strTemp);

		strTemp.Format(_T("0X0%d"), i);
		m_listMemList.SetItemText(i, 1, strTemp);

		if (stMemState[i].sMemState == 255)
		{
			m_listMemList.SetItemText(i, 2, _T("EMPTY"));
		}
		else
		{
			strTemp = stMemState[i].MemName;
			m_listMemList.SetItemText(i, 2, strTemp);
		}
	}
}

BEGIN_MESSAGE_MAP(TabMEMAccess, CDialogEx)
	ON_CBN_SELCHANGE(IDC_CMB_SELMEMPAGE, &TabMEMAccess::OnCbnSelchangeCmbSelmempage)
	ON_BN_CLICKED(IDC_BTN_MEMSET, &TabMEMAccess::OnBnClickedBtnMemset)
	ON_BN_CLICKED(IDC_BTN_MEMDEL, &TabMEMAccess::OnBnClickedBtnMemdel)
	ON_BN_CLICKED(IDC_BTN_MEMREAD, &TabMEMAccess::OnBnClickedBtnMemread)
	ON_BN_CLICKED(IDC_BTN_SAVEDATA, &TabMEMAccess::OnBnClickedBtnSavedata)
END_MESSAGE_MAP()


// TabMEMAccess 메시지 처리기


void TabMEMAccess::OnCbnSelchangeCmbSelmempage()
{
	// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
	int iSelCur = m_cmbSelMemPage.GetCurSel();
	short sRtn;

	m_listMemList.DeleteAllItems();

	_MEMORYSTATE stMemState[10];

	sRtn = spNGetMemState(iSelCur, stMemState, m_stDeviceInfo.sChannel);
	if (sRtn < 0)
	{
		CString strLine;
		strLine.Format(_T("Error Function : spNGetMemState(). error = %d"), sRtn);
		AfxMessageBox(strLine);
		return;
	}

	for (int i = 0; i < 10; i++)
	{
		CString strTemp;

		strTemp.Format(_T("%d"), stMemState[i].sMemState);
		m_listMemList.InsertItem(i, strTemp);

		strTemp.Format(_T("0X0%d"), i);
		m_listMemList.SetItemText(i, 1, strTemp);

		if (stMemState[i].sMemState == 255)
		{
			m_listMemList.SetItemText(i, 2, _T("EMPTY"));
		}
		else
		{
			strTemp = stMemState[i].MemName;
			m_listMemList.SetItemText(i, 2, strTemp);
		}
	}
}

void TabMEMAccess::OnBnClickedBtnMemset()
{
	// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
	UpdateData();
	short sRtn;
	int iSelPage = m_cmbSelMemPage.GetCurSel();
	int iSelMemAddress;

	sRtn = spNReadDataEx(lDataArray, m_stDeviceInfo.sChannel);
	if (sRtn < 0)
	{
		CString strLine;
		strLine.Format(_T("Error Function : spNReadDataEx(). error = %d"), sRtn);
		AfxMessageBox(strLine);
		return;
	}

	for (int i = 0; i < m_listMemList.GetItemCount(); i++)
	{
		if (m_listMemList.GetItemState(i, LVIS_SELECTED) != 0)
		{
			iSelMemAddress = i;
			break;
		}
	}

	char pcName[100];
	int iLeng = m_strName.GetLength();

	for (int i = 0; i < iLeng; i++)
		pcName[i] = m_strName[i];

	pcName[iLeng] = '\0';

	sRtn = spNSaveDataToMem(iSelPage, iSelMemAddress, pcName, lDataArray, m_stDeviceInfo.sChannel);
	if (sRtn < 0)
	{
		CString strLine;
		strLine.Format(_T("Error Function : spNSaveDataToMem(). error = %d"), sRtn);
		AfxMessageBox(strLine);
		return;
	}

	m_listMemList.SetItemText(iSelMemAddress, 0, _T("1"));
	m_listMemList.SetItemText(iSelMemAddress, 2, m_strName);

	DrawGraph(iSelMemAddress, m_strName);
}

void TabMEMAccess::OnBnClickedBtnMemdel()
{
	// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
	UpdateData();
	short sRtn;
	int iSelPage = m_cmbSelMemPage.GetCurSel();
	int iSelMemAddress;

	for (int i = 0; i < m_listMemList.GetItemCount(); i++)
	{
		if (m_listMemList.GetItemState(i, LVIS_SELECTED) != 0)
		{
			iSelMemAddress = i;
			break;
		}
	}

	sRtn = spNDeleteMemData(iSelPage, iSelMemAddress, m_stDeviceInfo.sChannel);
	if (sRtn < 0)
	{
		CString strLine;
		strLine.Format(_T("Error Function : spNDeleteMemData(). error = %d"), sRtn);
		AfxMessageBox(strLine);
		return;
	}
	m_listMemList.SetItemText(iSelMemAddress, 0, _T("255"));
	m_listMemList.SetItemText(iSelMemAddress, 2, _T("EMPTY"));
}

void TabMEMAccess::OnBnClickedBtnMemread()
{
	// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
	UpdateData();
	short sRtn;
	int iSelPage = m_cmbSelMemPage.GetCurSel();
	int iSelMemAddress;

	for (int i = 0; i < m_listMemList.GetItemCount(); i++)
	{
		if (m_listMemList.GetItemState(i, LVIS_SELECTED) != 0)
		{
			iSelMemAddress = i;
			break;
		}
	}

	sRtn = spNGetMemData(iSelPage, iSelMemAddress, lDataArray, m_stDeviceInfo.sChannel);
	if (sRtn < 0)
	{
		CString strLine;
		strLine.Format(_T("Error Function : spNGetMemData(). error = %d"), sRtn);
		AfxMessageBox(strLine);
		return;
	}

	DrawGraph(iSelMemAddress, m_listMemList.GetItemText(iSelMemAddress,2));
}

void TabMEMAccess::OnBnClickedBtnSavedata()
{
	// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
	CString filename;
	CString strSave;
	CStdioFile sioFile;

	filename.Format(_T("%s.csv"),m_strGraphName);

	sioFile.Open(filename, CFile::modeCreate | CFile::modeWrite);

	sioFile.WriteString(_T("Pixel,Intensity\n"));

	for (int i = 0; i < m_stDeviceInfo.iTotPixelNum; i++)
	{
		strSave.Format(_T("%d,%d\n"), i,lDataArray[i]);
		sioFile.WriteString(strSave);
	}
	sioFile.Close();
}

void TabMEMAccess::DrawGraph(short sAddress, CString strName)
{
	//CClientDC dc;//(GetDlgItem(IDC_PIC_BURSTGRAPH));
	CDC* dc;
	dc = m_picReadGraph.GetDC();
	CRect rect;
	m_picReadGraph.GetClientRect(&rect);

	CDC memDC;
	CBitmap* pOldBitMap, bitmap;
	CPen* pOldPen, pen;
	CFont* pOldfont, font;

	memDC.CreateCompatibleDC(dc);
	bitmap.CreateCompatibleBitmap(dc, rect.Width(), rect.Height());
	pOldBitMap = memDC.SelectObject(&bitmap);

	pen.CreatePen(PS_SOLID, 1, RGB(119, 119, 119));
	pOldPen = memDC.SelectObject(&pen);

	font.CreatePointFont(80, _T("Arial"));
	pOldfont = memDC.SelectObject(&font);

	memDC.Rectangle(rect);

	memDC.SelectObject(pOldPen);
	pen.DeleteObject();

	pen.CreatePen(PS_SOLID, 1, RGB(0, 0, 0));
	pOldPen = memDC.SelectObject(&pen);

	double dPointXLength, dPointYLength;

	dPointXLength = (rect.Width() / 10) * 9 - (rect.Width() / 10 + 10);
	dPointYLength = (rect.Height() / 10) * 9 - (rect.Height() / 10);

	dYRate = dPointYLength / 65535;
	dXRate = dPointXLength / m_stDeviceInfo.iTotPixelNum;

	memDC.MoveTo(rect.Width() / 10 + 10, rect.Height() / 10);
	memDC.LineTo(rect.Width() / 10 + 10, (rect.Height() / 10) * 9);
	memDC.LineTo((rect.Width() / 10) * 9, (rect.Height() / 10) * 9);

	memDC.MoveTo(rect.Width() / 10 + 10, (rect.Height() / 10) * 9);
	memDC.LineTo(rect.Width() / 10 + 5, (rect.Height() / 10) * 9);
	memDC.TextOutW(rect.Width() / 10 - 5, (rect.Height() / 10) * 9 - 7, _T("0"));

	memDC.MoveTo(rect.Width() / 10 + 10, (rect.Height() / 10) * 9 - 16383 * dYRate);
	memDC.LineTo(rect.Width() / 10 + 5, (rect.Height() / 10) * 9 - 16383 * dYRate);
	memDC.TextOutW(rect.Width() / 10 - 30, (rect.Height() / 10) * 9 - 16383 * dYRate - 7, _T("16383"));

	memDC.MoveTo(rect.Width() / 10 + 10, (rect.Height() / 10) * 9 - 32766 * dYRate);
	memDC.LineTo(rect.Width() / 10 + 5, (rect.Height() / 10) * 9 - 32766 * dYRate);
	memDC.TextOutW(rect.Width() / 10 - 30, (rect.Height() / 10) * 9 - 32766 * dYRate - 7, _T("32766"));

	memDC.MoveTo(rect.Width() / 10 + 10, (rect.Height() / 10) * 9 - 49149 * dYRate);
	memDC.LineTo(rect.Width() / 10 + 5, (rect.Height() / 10) * 9 - 49149 * dYRate);
	memDC.TextOutW(rect.Width() / 10 - 30, (rect.Height() / 10) * 9 - 49149 * dYRate - 7, _T("49149"));

	memDC.MoveTo(rect.Width() / 10 + 10, (rect.Height() / 10) * 9 - 65535 * dYRate);
	memDC.LineTo(rect.Width() / 10 + 5, (rect.Height() / 10) * 9 - 65535 * dYRate);
	memDC.TextOutW(rect.Width() / 10 - 30, (rect.Height() / 10) * 9 - 65535 * dYRate - 7, _T("65535"));

	CString strTemp;
	int iIndex;

	for (int i = 0; i < 5; i++)
	{
		iIndex = (m_stDeviceInfo.iTotPixelNum / 4) * i;
		if (i != 0) iIndex--;

		memDC.MoveTo(rect.Width() / 10 + 10 + iIndex * dXRate, (rect.Height() / 10) * 9);
		memDC.LineTo(rect.Width() / 10 + 10 + iIndex * dXRate, (rect.Height() / 10) * 9 + 5);

		strTemp.Format(_T("%d"), iIndex + 1);
		memDC.TextOutW(rect.Width() / 10 + 1 + iIndex * dXRate, (rect.Height() / 10) * 9 + 7, strTemp);
	}

	memDC.SelectObject(pOldPen);
	pen.DeleteObject();

	pen.CreatePen(PS_SOLID, 1, RGB(187, 187, 187));
	pOldPen = memDC.SelectObject(&pen);

	memDC.MoveTo(rect.Width() / 10 + 10, (rect.Height() / 10) * 9 - 16383 * dYRate);
	memDC.LineTo((rect.Width() / 10) * 9, (rect.Height() / 10) * 9 - 16383 * dYRate);

	memDC.MoveTo(rect.Width() / 10 + 10, (rect.Height() / 10) * 9 - 32766 * dYRate);
	memDC.LineTo((rect.Width() / 10) * 9, (rect.Height() / 10) * 9 - 32766 * dYRate);

	memDC.MoveTo(rect.Width() / 10 + 10, (rect.Height() / 10) * 9 - 49149 * dYRate);
	memDC.LineTo((rect.Width() / 10) * 9, (rect.Height() / 10) * 9 - 49149 * dYRate);

	memDC.MoveTo(rect.Width() / 10 + 10, (rect.Height() / 10) * 9 - 65535 * dYRate);
	memDC.LineTo((rect.Width() / 10) * 9, (rect.Height() / 10) * 9 - 65535 * dYRate);

	for (int i = 1; i < 5; i++)
	{
		iIndex = (m_stDeviceInfo.iTotPixelNum / 4) * i;
		if (i != 0) iIndex--;

		memDC.MoveTo(rect.Width() / 10 + 10 + iIndex * dXRate, (rect.Height() / 10) * 9);
		memDC.LineTo(rect.Width() / 10 + 10 + iIndex * dXRate, rect.Height() / 10);
	}

	DrawPlotData(&memDC, rect);

	dc->BitBlt(0, 0, rect.Width(), rect.Height(), &memDC, 0, 0, SRCCOPY);
	memDC.SelectObject(pOldPen);
	pen.DeleteObject();
	memDC.DeleteDC();

	m_strGraphName.Format(_T("Address - 0X0%d, Name - %s"), sAddress, strName);
	UpdateData(FALSE);
}

void TabMEMAccess::DrawPlotData(CDC* pDC, CRect rect)
{
	CPen* pOldPen, pen;

	pen.CreatePen(PS_SOLID, 1, RGB(255, 0, 0));
	pOldPen = pDC->SelectObject(&pen);

	for (int i = 0; i < m_stDeviceInfo.iTotPixelNum; i++)
	{
		if (i == 0)
			pDC->MoveTo(rect.Width() / 10 + 10, (rect.Height() / 10) * 9 - lDataArray[i] * dYRate);
		else
			pDC->LineTo(rect.Width() / 10 + 10 + i * dXRate, (rect.Height() / 10) * 9 - lDataArray[i] * dYRate);
	}

	pDC->SelectObject(pOldPen);
	pen.DeleteObject();
}
