// ECGWave.cpp : 实现文件
//

#include "stdafx.h"
#include "../Verbpo.h"
#include "ECGWave.h"


static TCHAR LeadType[12][12] = { _T("I"), _T("II"), _T("III"), _T("avF"), _T("avL"), _T("avR"),
_T("V1"), _T("V2"), _T("V3"), _T("V4"), _T("V5"), _T("V6") };

// CECGWave



INT CECGWave::m_i32NormalWidth = 930, CECGWave::m_i32NormalHeight = 180;
INT CECGWave::m_i32BigWidth = 863, CECGWave::m_i32BigHeight = 180;
INT CECGWave::m_i32ECGWidth = 930, CECGWave::m_i32ECGHeight=95;
INT CECGWave::m_i32TrendWidth = 770, CECGWave::m_i32TrendHeight = 180;



IMPLEMENT_DYNAMIC(CECGWave, CStatic)

CECGWave::CECGWave(int Width, int Height, int LeadType)
{
	m_i32Width = CECGWave::m_i32NormalWidth;
	m_i32Height = CECGWave::m_i32NormalHeight;
	m_i32Style = 0;

	//构造心电波形画笔对象
	//penECGLine = new CPen(PS_SOLID, 1, RGB(0, 255, 0));
	//构造擦除画笔对象
	penErase = new CPen(PS_SOLID, 1, RGB(0, 0, 0));
	penGrid = new CPen(PS_SOLID, 1, RGB(0, 0, 255));
	m_i32LeadType = LeadType & 0x0f;
	m_i32Grid = (LeadType & 0xf0) >> 4;
	if ((LeadType & 0xf00) == ECG_COLOR_GREEN)
	{
		penECGLine = new CPen(PS_SOLID, 1, RGB(0, 255, 0));
	}
	else if ((LeadType & 0xf00) == ECG_COLOR_YELLOW)
	{
		penECGLine = new CPen(PS_SOLID, 1, RGB(255, 215, 0));
	}
	else
	{
		penECGLine = new CPen(PS_SOLID, 1, RGB(221, 160, 221));
	}
	
	m_i32WaveDate = new int[ECG_WAVE_BUFF_LENGTH];
	m_i32WaveDateW = 0, m_i32WaveDateR = 0, m_i32WaveDateLength = 0;

	m_i32Freeze = 0;
	m_i32Speed = 1;
	m_i32LastX = 0;
	m_u16TempX = 0;
	m_i32EraseLast = 0;

	m_u16TempX = 0;
	m_i32EraseLast = 0;
	m_i32Freeze = 0;
	m_i32EraseFlag = 0;
	//m_u8PaceFalg = 0;
	m_i32Speed = 1;
}

CECGWave::~CECGWave()
{
	delete m_i32WaveDate;
	delete penErase;
	delete penGrid;
	delete penECGLine;

}

//设置波形的速度
void CECGWave::Set_Speed(int speed)
{
	m_i32Speed = speed+1;
}

//设置波形的增益，并画出比例尺
void CECGWave::Set_Gain(int gain)
{
	int temp = 0;

	temp = UnitLength_Pixel*(gain + 1);
	if (temp < m_i32Height)
	{
		//画出单位长度比例尺
		m_i32Gain = (gain + 1);
		if (dcMemGrid.m_hDC != NULL)
		{
			dcMemGrid.FillSolidRect(30, 0, 3, m_i32Height, RGB(0, 0, 0));
			dcMemGrid.SelectObject(penECGLine);
			dcMemGrid.MoveTo(30, (m_i32Height - temp) / 2);
			dcMemGrid.LineTo(30, (m_i32Height - temp) / 2 + temp);
			dcMemGrid.MoveTo(31, (m_i32Height - temp) / 2);
			dcMemGrid.LineTo(31, (m_i32Height - temp) / 2 + temp);
			dcMemGrid.MoveTo(32, (m_i32Height - temp) / 2);
			dcMemGrid.LineTo(32, (m_i32Height - temp) / 2 + temp);

			/*dcMem.FillSolidRect(30, 0, 3, m_i32Height, RGB(0, 0, 0));
			dcMem.SelectObject(penECGLine);
			dcMem.MoveTo(30, (m_i32Height - temp) / 2);
			dcMem.LineTo(30, (m_i32Height - temp) / 2 + temp);
			dcMem.MoveTo(31, (m_i32Height - temp) / 2);
			dcMem.LineTo(31, (m_i32Height - temp) / 2 + temp);
			dcMem.MoveTo(32, (m_i32Height - temp) / 2);
			dcMem.LineTo(32, (m_i32Height - temp) / 2 + temp);*/
			this->Invalidate(TRUE);
		}

	}

}
/**
*  @brief 清除心电波形缓冲区的数据
*  @author Venus
*  @param   date 心电波形数据
*  @return  0
*  @note
*  @remarks
*  @since  1.0
*/
void CECGWave::Add_WaveDate(int date)
{
	m_CSWaveData.Lock();
	m_i32WaveDate[m_i32WaveDateW] = date;
	if (++m_i32WaveDateW == ECG_WAVE_BUFF_LENGTH)
		m_i32WaveDateW = 0;

	if (m_i32WaveDateLength < ECG_WAVE_BUFF_LENGTH)
	{
		m_i32WaveDateLength++;
	}
	m_CSWaveData.Unlock();
}


void CECGWave::Clear_WaveDate()
{
	m_CSWaveData.Lock();
	m_i32WaveDateW = 0, m_i32WaveDateR = 0, m_i32WaveDateLength = 0;
	m_CSWaveData.Unlock();

}

//在屏幕上单位长度的像素点个数
void CECGWave::Set_UnitLength_Pixel(int px)
{
	UnitLength_Pixel = px;
}

//波形的单位长度的数字量
void CECGWave::Set_UnitLength_Value(int Value)
{
	UnitLength_Value = Value;

}



BEGIN_MESSAGE_MAP(CECGWave, CStatic)
	ON_WM_PAINT()
	ON_WM_ERASEBKGND()
	ON_WM_CREATE()
//	ON_WM_LBUTTONDBLCLK()
END_MESSAGE_MAP()

int CECGWave::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	//	this->MoveWindow(0, 0, m_i32Width, m_i32Height);
	// 获得控件区域
	GetClientRect(&m_rectCtrl);
	//客户区DC，可以绘画及显示
	CClientDC pDC(this);
	//依附窗口DC创建兼容内存DC
	dcMem.CreateCompatibleDC(&pDC);
	//创建兼容位图
	bmp.CreateCompatibleBitmap(&pDC, CECGWave::m_i32NormalWidth, CECGWave::m_i32NormalHeight);
	dcMem.SelectObject(&bmp); //将位图选择进内存DC
	dcMem.FillSolidRect(0, 0, CECGWave::m_i32NormalWidth, CECGWave::m_i32NormalHeight, RGB(0, 0, 0));

	dcMemGrid.CreateCompatibleDC(&pDC);
	//创建兼容位图
	bmpGrid.CreateCompatibleBitmap(&pDC, CECGWave::m_i32NormalWidth, CECGWave::m_i32NormalHeight);
	dcMemGrid.SelectObject(&bmpGrid); //将位图选择进内存DC
	dcMemGrid.FillSolidRect(0, 0, CECGWave::m_i32NormalWidth, CECGWave::m_i32NormalHeight, RGB(0, 0, 0));

	Draw_LeadType();
	int a_i32x = 0, j = 0, i = 0;

	//如果要显示 网格，则画出网格
	if (m_i32Grid)
	{
		dcMemGrid.SelectObject(penGrid);
		//画竖线
		for (i = 40; i < m_i32Width; i += UnitLength_Pixel)
		{
			for (j = 0; j < m_i32Height; j += 4)
			{
				dcMemGrid.MoveTo(i, j);
				dcMemGrid.LineTo(i, j + 1);
			}
		}

		for (i = 40; i < m_i32Width; i += 4)
		{
			for (j = 0; j < m_i32Height; j += UnitLength_Pixel)
			{
				dcMemGrid.MoveTo(i, j);
				dcMemGrid.LineTo(i, j + 1);
			}
		}
	}

	Erase();

	//	return CStatic::OnCreate(lpCreateStruct);
	return TRUE;
}

//控件鼠标左键双击
void  CECGWave::OnLButtonDblClk(UINT nFlags, CPoint point)
{
	//	this->GetParent()->PostMessage(WM_ECGWAVE_DBLCLK, 0, 0);
}


//显示导联类型
void CECGWave::Draw_LeadType()
{
	TCHAR * a_pu16;
	CPen *pOldPen;
	int temp = 0;

	a_pu16 = LeadType[m_i32LeadType];

	temp = UnitLength_Pixel*m_i32Gain;
	dcMem.FillSolidRect(0, 0, 40, m_i32Height, RGB(0, 0, 0));
	if (temp < m_i32Height)
	{
		//画出单位长度比例尺
		pOldPen = dcMem.SelectObject(penECGLine);
		dcMem.MoveTo(30, (m_i32Height - temp) / 2);
		dcMem.LineTo(30, (m_i32Height - temp) / 2 + temp);
		dcMem.MoveTo(31, (m_i32Height - temp) / 2);
		dcMem.LineTo(31, (m_i32Height - temp) / 2 + temp);
		dcMem.MoveTo(32, (m_i32Height - temp) / 2);
		dcMem.LineTo(32, (m_i32Height - temp) / 2 + temp);
	}
	dcMem.SetTextColor(RGB(0, 255, 0));
	//显示导联类型
	dcMem.DrawText(a_pu16, CRect(0, m_i32Height / 2 - 10, 30, m_i32Height / 2 + 10), 0);
}

//绘制心电波形
void CECGWave::Draw_Wave()
{
	int a_i32WaveDateLength = 0;

	m_CSWaveData.Lock();
	a_i32WaveDateLength = m_i32WaveDateLength;
	m_CSWaveData.Unlock();


	if (a_i32WaveDateLength)
	{
		CRect rect;
		this->GetWindowRect(rect);     // 获取要刷新的STATIC控件的刷新区域

		ScreenToClient(rect);   // 屏幕上指定点的屏幕坐标转换成用户坐标
		InvalidateRect(rect);
	}
}


void CECGWave::Draw_Grid()
{
	int i = 0, j = 0;
	CPen *pOldPen;

	pOldPen = dcMem.SelectObject(penGrid);
	//画竖线
	for (i = 40; i <= m_i32Width; i += UnitLength_Pixel)
	{
		for (j = 0; j <= m_i32Height; j += 2)
		{
			dcMem.MoveTo(i, j);
			dcMem.LineTo(i, j);
		}
	}

	for (i = 40; i <= m_i32Width; i += 2)
	{
		for (j = 0; j <= m_i32Height; j += UnitLength_Pixel)
		{
			dcMem.MoveTo(i, j);
			dcMem.LineTo(i, j);
		}
	}
}

//波形显示区域 完全擦除
void CECGWave::Erase()
{
	m_i32LastX = 0;
	m_u16TempX = 0;
	m_i32EraseLast = 0;
	m_i32EraseFlag = 1;
	dcMem.BitBlt(m_rectCtrl.left + 40, m_rectCtrl.top, m_i32Width, m_i32Height, &dcMemGrid, 40, 0, SRCCOPY);
}


void CECGWave::Erase_Wave(int x)
{
	CPen *pOldPen;
	int a_i32x = 0, j = 0, i = 0;


	for (i = m_i32EraseLast; i < x; i++)
	{
		pOldPen = dcMem.SelectObject(penErase);
		//通过画 黑色竖线的方法 擦除 旧的波形
		dcMem.MoveTo((41 + i) % m_i32Width, 0);
		dcMem.LineTo((41 + i) % m_i32Width, m_i32Height);
		dcMem.MoveTo((42 + i) % m_i32Width, 0);
		dcMem.LineTo((42 + i) % m_i32Width, m_i32Height);
		dcMem.MoveTo((43 + i) % m_i32Width, 0);
		dcMem.LineTo((43 + i) % m_i32Width, m_i32Height);
		dcMem.MoveTo((44 + i) % m_i32Width, 0);
		dcMem.LineTo((44 + i) % m_i32Width, m_i32Height);
		dcMem.MoveTo((45 + i) % m_i32Width, 0);
		dcMem.LineTo((45 + i) % m_i32Width, m_i32Height);
		dcMem.MoveTo((46 + i) % m_i32Width, 0);
		dcMem.LineTo((46 + i) % m_i32Width, m_i32Height);
		dcMem.MoveTo((47 + i) % m_i32Width, 0);
		dcMem.LineTo((47 + i) % m_i32Width, m_i32Height);
		if (m_i32Grid)
		{
			pOldPen = dcMem.SelectObject(penGrid);
			if ((i) % UnitLength_Pixel == 0)
			{
				for (j = 0; j < m_i32Height; j += 4)
				{
					dcMem.MoveTo(40 + i, j);
					dcMem.LineTo(40 + i, j + 1);
				}
			}
			if (i % 4 == 0)
			{
				for (j = 0; j < m_i32Height; j += UnitLength_Pixel)
				{
					dcMem.MoveTo(40 + i, j);
					dcMem.LineTo(40 + i, j + 1);
				}
			}
		}
	}
	m_i32EraseLast = x;
}

//复位 波形缓冲区的数据
int CECGWave::Reset_WaveDataBuff()
{
	m_CSWaveData.Lock();
	m_i32WaveDateW = 0, m_i32WaveDateR = 0, m_i32WaveDateLength = 0;
	m_CSWaveData.Unlock();

	return 0;
}

//波形数据 拷贝 到 缓冲区中
void CECGWave::copy_data(INT *buf, int length)
{
	int l = 0;
	l = length;
	if (l > ECG_WAVE_BUFF_LENGTH)
		l = ECG_WAVE_BUFF_LENGTH;
	memcpy(m_i32WaveDate, buf, l * 4);
	m_i32WaveDateW = (m_i32WaveDateW + l) % ECG_WAVE_BUFF_LENGTH;
	m_i32WaveDateLength += l;
	if (m_i32WaveDateLength > ECG_WAVE_BUFF_LENGTH)
	{
		m_i32WaveDateLength = ECG_WAVE_BUFF_LENGTH;
	}
}


void CECGWave::copy_data(CECGWave & ECGWave)
{
	m_CSWaveData.Lock();
	m_i32WaveDateW = ECGWave.m_i32WaveDateW, m_i32WaveDateR = ECGWave.m_i32WaveDateR, m_i32WaveDateLength = ECGWave.m_i32WaveDateLength;
	memcpy(m_i32WaveDate, ECGWave.m_i32WaveDate, ECG_WAVE_BUFF_LENGTH * 4);
	m_CSWaveData.Unlock();
}


void CECGWave::set_lead_type(int LeadType)
{
	m_i32LeadType = LeadType;
}


BOOL CECGWave::OnEraseBkgnd(CDC* pDC)
{

	return TRUE;
}


void CECGWave::OnPaint()
{
	CPen *pOldPen;
	int a_i32WaveDateLength = 0, a_i32WaveDateR, i = 0, y = 0, a_i32Temp = 0, j = 0;
	CPaintDC pDC(this);
	//
	m_CSWaveData.Lock();
	a_i32WaveDateLength = m_i32WaveDateLength;
	m_CSWaveData.Unlock();
	a_i32WaveDateR = m_i32WaveDateR;

	float a_fTemp = 0.0f, a_fSpeed = 0.0f;
	//Draw_LeadType();
	//判断接收的缓冲区中有无数据
	if (a_i32WaveDateLength)
	{
		for (i = 0; i < a_i32WaveDateLength; i++)
		{
			y = m_i32Height / 2 - ((m_i32WaveDate[a_i32WaveDateR] - 2048)*(1 << (m_i32Gain))*UnitLength_Pixel / UnitLength_Value) / 4;
			if (y >= m_i32Height)
				y = m_i32Height - 1;
			else if (y < 0)
				y = 0;

			a_fSpeed = (m_i32Speed);
			a_fTemp = (float)m_u16TempX;
			a_i32Temp = (int)(a_fTemp*1.0f *a_fSpeed/ 8.0f);

			if (a_i32Temp + 40 < m_i32Width)
			{
				//是否冻结波形
				if (!m_i32Freeze)
				{
					//if (m_i32XLast != a_i32Temp)
					{
						//是否冻结波形
						Erase_Wave(a_i32Temp);
						//冻结，就不画波形
						pOldPen = dcMem.SelectObject(penECGLine);
						if (m_i32EraseFlag)
						{
							m_i32EraseFlag = 0;
							dcMem.MoveTo(40 + m_i32LastX, y);
							dcMem.LineTo(40 + a_i32Temp, y);
						}
						else
						{
							dcMem.MoveTo(40 + m_i32LastX, m_i32LastY);
							dcMem.LineTo(40 + a_i32Temp, y);
						}
						//恢复先前的画笔
						dcMem.SelectObject(pOldPen);
						m_i32LastX = a_i32Temp;
						m_i32LastY = y;
					}
				}
				m_u16TempX++;
			}
			else
			{
				//是否冻结波形
				if (!m_i32Freeze)
				{
					//冻结，就不画波形
					//Erase_Wave(a_i32Temp);
					pOldPen = dcMem.SelectObject(penErase);
					dcMem.MoveTo(40, 0);
					dcMem.LineTo(40, m_i32Height);
					dcMem.MoveTo(41, 0);
					dcMem.LineTo(41, m_i32Height);
					pOldPen = dcMem.SelectObject(penECGLine);
					dcMem.MoveTo(40, m_i32LastY);
					dcMem.LineTo(40, y);
					//恢复先前的画笔
					dcMem.SelectObject(pOldPen);
				}
				m_i32LastX = 0;
				m_i32LastY = y;
				m_u16TempX = 1;
			}
			a_i32WaveDateR = (a_i32WaveDateR + 1) % (ECG_WAVE_BUFF_LENGTH);
		}
		m_i32WaveDateR = a_i32WaveDateR;
		m_CSWaveData.Lock();
		m_i32WaveDateLength -= a_i32WaveDateLength;
		m_CSWaveData.Unlock();
	}
	pDC.BitBlt(m_rectCtrl.left, m_rectCtrl.top, m_i32Width , m_i32Height, &dcMem, 0, 0, SRCCOPY);

	//	CStatic::OnPaint();
}


//设置 波形显示的模式 ，即波形显示区域的大小
void CECGWave::Set_Style(INT style)
{
	m_i32Style = style;


	if (m_i32Style == 0)
	{
		m_i32Width = CECGWave::m_i32NormalWidth;
		m_i32Height = CECGWave::m_i32NormalHeight;
	}
	else if (m_i32Style == 1)
	{
		m_i32Width = CECGWave::m_i32BigWidth;
		m_i32Height = CECGWave::m_i32BigHeight;
	}
	else if (m_i32Style == 2)
	{
		m_i32Width = CECGWave::m_i32ECGWidth;
		m_i32Height = CECGWave::m_i32ECGHeight;
	}
	else if (m_i32Style == 3)
	{
		m_i32Width = CECGWave::m_i32TrendWidth;
		m_i32Height = CECGWave::m_i32TrendHeight;
	}
	else
	{
		m_i32Width = CECGWave::m_i32NormalWidth;
		m_i32Height = CECGWave::m_i32NormalHeight;
	}
	/*m_u16TempX = 0;
	m_i32LastX = 0;
	m_i32EraseLast = 0;
	dcMem.FillSolidRect(0, 0, m_i32Width, m_i32Height, RGB(0, 0, 0));*/
	Erase();
	Draw_LeadType();
	Reset_WaveDataBuff();
	Invalidate();
}


//设置 是否 冻结 波形
void CECGWave::Set_Freeze(INT f)
{
	m_i32Freeze = f;
}