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

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


// TabBurstMode 대화 상자

IMPLEMENT_DYNAMIC(TabBurstMode, CDialogEx)

TabBurstMode::TabBurstMode(CWnd* pParent /*=nullptr*/)
	: CDialogEx(IDD_DLGTABBURSTMODE, pParent)
	, m_iDataCount(0)
	, bBurstData(false)
	, m_strSelData(_T(""))
{

}

TabBurstMode::~TabBurstMode()
{
}

void TabBurstMode::DoDataExchange(CDataExchange* pDX)
{
	CDialogEx::DoDataExchange(pDX);
	DDX_Text(pDX, IDC_EDIT_DATACOUNT, m_iDataCount);
	DDV_MinMaxInt(pDX, m_iDataCount, 1, 250);
	DDX_Control(pDX, IDC_SLD_DATASLD, m_sldDataSld);
	DDX_Control(pDX, IDC_PIC_BURSTGRAPH, m_pcGraph);
	DDX_Text(pDX, IDC_STATIC_SELDATA, m_strSelData);
}


BEGIN_MESSAGE_MAP(TabBurstMode, CDialogEx)
	ON_BN_CLICKED(IDC_BTN_BURSTSTART, &TabBurstMode::OnBnClickedBtnBurststart)
	ON_BN_CLICKED(IDC_BTNSAVE, &TabBurstMode::OnBnClickedBtnsave)
	ON_WM_HSCROLL()
END_MESSAGE_MAP()


// TabBurstMode 메시지 처리기

void TabBurstMode::OnBnClickedBtnBurststart()
{
	// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
	UpdateData();
	short sRtn = -1;

	lpDataList = new long*[m_iDataCount];

	for (int i = 0; i < m_iDataCount; i++)
		lpDataList[i] = new long[m_stDeviceInfo.iTotPixelNum];

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

	}

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

	}

	bBurstData = true;
	m_sldDataSld.SetRange(0, m_iDataCount - 1);
	m_sldDataSld.SetPos(0);
	DrawGraph();
}

void TabBurstMode::OnBnClickedBtnsave()
{
	// TODO: 여기에 컨트롤 알림 처리기 코드를 추가합니다.
	if (bBurstData)
	{
		CString filename = _T("BurstModeData.csv");
		CString strSave;
		CStdioFile sioFile;

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

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

		for (int i = 0; i < m_iDataCount; i++)
		{
			strSave.Format(_T("Data%d,"), i);
			sioFile.WriteString(strSave);

			for (int k = 0; k < m_stDeviceInfo.iTotPixelNum; k++)
			{
				strSave.Format(_T("%d,"), lpDataList[i][k]);
				sioFile.WriteString(strSave);
			}
			sioFile.WriteString(_T("\n"));
		}
		sioFile.Close();
	}
	else
	{
		CString strLine;
		strLine.Format(_T("Error : Empty data array"));
		AfxMessageBox(strLine);
	}
}

void TabBurstMode::DrawGraph()
{
	//CClientDC dc;//(GetDlgItem(IDC_PIC_BURSTGRAPH));
	CDC* dc;
	dc = m_pcGraph.GetDC();
	CRect rect;
	m_pcGraph.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,m_sldDataSld.GetPos());

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

	m_strSelData.Format(_T("Count : %d / %d"), m_sldDataSld.GetPos() + 1, m_iDataCount);
	UpdateData(FALSE);
}

void TabBurstMode::DrawPlotData(CDC* pDC, CRect rect, int iSelData)
{
	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 - lpDataList[iSelData][i] * dYRate);
		else
			pDC->LineTo(rect.Width() / 10 + 10 + i * dXRate, (rect.Height() / 10) * 9 - lpDataList[iSelData][i] * dYRate);
	}

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

void TabBurstMode::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	// TODO: 여기에 메시지 처리기 코드를 추가 및/또는 기본값을 호출합니다.
	DrawGraph();

	CDialogEx::OnHScroll(nSBCode, nPos, pScrollBar);
}
