// motordlg.cpp : implementation file
//

#include "stdafx.h"
#include "resource.h"
#include "types.h"
#include "axis.h"
#include "datamgr.h"
#include "encoder.h"
#include "MotorIndicator.h"
#include "motordlg.h"

Boolean CMotorDlg::_bitmapsLoaded = FALSE;
CBitmap CMotorDlg::_flsBitmap;
CBitmap CMotorDlg::_rlsBitmap;
CBitmap CMotorDlg::_homeBitmap;
CBitmap CMotorDlg::_clrBitmap;
CBitmap CMotorDlg::_stopBitmap;


/////////////////////////////////////////////////////////////////////////////
// CMotorDlg dialog
/////////////////////////////////////////////////////////////////////////////
CMotorDlg::CMotorDlg(CWnd* pParent, Axis *pAxis, Nat16 id)
	: CDialog(CMotorDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CMotorDlg)
	_jogIncrement = 0;
	//}}AFX_DATA_INIT

	CString s;
	_jogging = 9999;
	_axis = pAxis;
	_motor = (Motor *)pAxis;
	_motorID = id;
	m_pDialog = pParent;	

	
	if (!_bitmapsLoaded) {
		// First CMotorDlg constructed must load static bitmaps
		_clrBitmap.LoadBitmap(IDB_CLRBMP);
		_flsBitmap.LoadBitmap(IDB_FLSBMP);
		_rlsBitmap.LoadBitmap(IDB_RLSBMP);
		_homeBitmap.LoadBitmap(IDB_HOMEBMP);
		_stopBitmap.LoadBitmap(IDB_STOPBMP);
		_bitmapsLoaded = TRUE;
	}
	_indicator = 
		new CMotorIndicator(IDC_STATUS_LED, _motor, this, IDB_LED_OFF, IDB_LED_ON);

}
CMotorDlg::~CMotorDlg()
{
	delete _indicator;
}


void CMotorDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CMotorDlg)
	DDX_Text(pDX, IDC_DESIREDPOS, _jogIncrement);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CMotorDlg, CDialog)
	//{{AFX_MSG_MAP(CMotorDlg)
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_JOG, OnJog)
	ON_BN_CLICKED(IDC_FINDHOME, OnFindHome)
	ON_BN_CLICKED(IDC_STOP, OnStop)
	ON_WM_CLOSE()
	ON_COMMAND_RANGE(IDC_POSMAP0, IDC_POSMAP4, OnIncrementSelect)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CMotorDlg message handlers

BOOL CMotorDlg::OnInitDialog() 
{
Nat16 i;
char text[50];
CWnd *pWnd;
CString s;
Int32 cnt = 0;
Axis::jogMapType type;

	s.Format("GENOSENSOR %s MOTOR DIALOG", _motor->name());

	SetWindowText(s);

	SendDlgItemMessage(IDC_STOP, BM_SETIMAGE,IMAGE_BITMAP, (LPARAM)(HBITMAP)_stopBitmap);

	for(i=0;i<NUM_POS_MAPS;i++){

		_axis->getPosMap(i, text, &cnt, &type);

		pWnd = GetDlgItem(IDC_POSMAP0 + i);
		if(pWnd != NULL){
			pWnd->EnableWindow(FALSE);	
			if(text != NULL){
				pWnd->SetWindowText(text);		
				pWnd->EnableWindow(TRUE);	
			}
		}
			
	}

	if(_motor->encoder()->units() == DEGREE){
		s.Format("Counts per Degree ");
		SetDlgItemText(IDC_STATIC, s);
	}

	s.Format("%d", _motor->encoder()->cntsPerUnit());	
	SetDlgItemText(IDC_CNTSPERUNIT,s);	

	s.Format("%d",0);
	SetDlgItemText(IDC_DESIREDPOS,s);	


	s.Format("%d",_motor->encoder()->cnts());
	SetDlgItemText(IDC_ACTUALPOS,s);	

	_nTimer = SetTimer(1,500,NULL); //~1/2 second
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CMotorDlg::UpdateBitmap(UINT id, CBitmap & bitmap)
{
	BITMAP bmp;
	CWnd* pWnd;	
	CDC* pDC;
	CDC DC;

	bitmap.GetBitmap(&bmp);

	pWnd = GetDlgItem(id);
	if(pWnd != NULL && &bmp != NULL)
	{
		pDC = pWnd->GetDC();
		DC.CreateCompatibleDC(pDC);
		DC.SelectObject(bitmap);			
		pDC->BitBlt(0,0,bmp.bmWidth,bmp.bmHeight,&DC, 0, 0, SRCCOPY);
		ReleaseDC(pDC);		
	}
}


void CMotorDlg::UpdateStatus()
{

	CString s;
	MBool jogging;
	jogging = _motor->jogging();

	if (jogging || jogging != _jogging)
	{
		Int32 data32 = _motor->encoder()->cnts();
		s.Format("%d", data32);			
		SetDlgItemText(IDC_ACTUALPOS, s);
		s.Format("%d", _motor->getPosErr());	
 		SetDlgItemText(IDC_POS_ERR, s);	
	}
	_jogging = jogging;
	if(_axis->foundHome())
		UpdateBitmap(IDC_HOME_BITMAP, CMotorDlg::_homeBitmap);				

	UpdateStopCode();
	_indicator->update();

}


void CMotorDlg::UpdateStopCode()
{
	int stopCode;
	if ((stopCode = _motor->getStopCode()) > 0) 
	{
		switch (stopCode) {

			case MOTOR_STOP_BY_FLS:
			UpdateBitmap(IDC_FLS_BITMAP, CMotorDlg::_flsBitmap);		
			break;

			case MOTOR_STOP_BY_RLS:
			UpdateBitmap(IDC_RLS_BITMAP, CMotorDlg::_rlsBitmap);		
			break;

			default:
			UpdateBitmap(IDC_FLS_BITMAP, CMotorDlg::_clrBitmap);
			UpdateBitmap(IDC_RLS_BITMAP, CMotorDlg::_clrBitmap);		
			UpdateBitmap(IDC_HOME_BITMAP, CMotorDlg::_clrBitmap);
			break;
		}
	}

}


void CMotorDlg::OnPaint() 
{
	UpdateStatus();
}

void CMotorDlg::OnTimer(UINT nIDEvent) 
{
	UpdateStatus();
}


void CMotorDlg::OnJog() 
{
	UpdateData(TRUE);
	_motor->jogRelative((Int32 )_jogIncrement);	
}

void CMotorDlg::OnFindHome() 
{
	UpdateStopCode();	//clear bitmap
	_axis->requestFindHome();
}

void CMotorDlg::OnStop() 
{
	_motor->stop();
	UpdateStatus();
}

void CMotorDlg::OnIncrementSelect(UINT nID) 
{
	Nat16 index = (Nat16) nID - IDC_POSMAP0;				//calc index
	Int32 pos = _motor->encoder()->cnts();
	Int32 mapCnt;
	Axis::jogMapType type;

	_axis->getPosMap(index, NULL, &mapCnt, &type);		//get abosolute cnt from pos map

	if(type == Axis::ABSOLUTE_JOG)
		_jogIncrement = mapCnt - pos;				//calc jog increment; 0-2 maps
	else
		_jogIncrement = mapCnt;					//calc jog increment ccw/cw increment

	UpdateData(FALSE);
}

void CMotorDlg::OnClose() 
{
	KillTimer(_nTimer);
	if(m_pDialog != NULL)
		m_pDialog->PostMessage(WM_MODELESSEXIT,IDD_MOTOR_DIALOG, _motorID);					
	
	CDialog::OnClose();
}

