//*****************************************
//******** PC Configurator V1.00 **********
//*** (C) - 2001 B.Bowling/A. Grippo ******
//** All derivatives from this software ***
//**  are required to keep this header ****
//*****************************************

static char *rcsId() { return "$Id$"; }

#include "stdafx.h"
#include "megatune.h"
#include "msDatabase.h"
#include "repository.h"
#include "Druntime.h"
#include "veconst.h"

#ifdef _DEBUG
#  define new DEBUG_NEW
#  undef THIS_FILE
   static char THIS_FILE[] = __FILE__;
#endif

extern msDatabase mdb;
extern repository rep;

//------------------------------------------------------------------------------

Druntime::Druntime(CWnd* pParent /*=NULL*/)
 : CDialog(Druntime::IDD, pParent)
{
   //{{AFX_DATA_INIT(Druntime)
   //}}AFX_DATA_INIT
}

//------------------------------------------------------------------------------

void Druntime::DoDataExchange(CDataExchange* pDX)
{
   CDialog::DoDataExchange(pDX);
   //{{AFX_DATA_MAP(Druntime)
	DDX_Control(pDX, IDC_MAT_LABEL, m_matLabel);
	DDX_Control(pDX, IDC_COOLANT_LABEL, m_coolantLabel);
	//}}AFX_DATA_MAP
}

//------------------------------------------------------------------------------

BEGIN_MESSAGE_MAP(Druntime, CDialog)
   //{{AFX_MSG_MAP(Druntime)
      ON_WM_TIMER()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

//------------------------------------------------------------------------------

BEGIN_EVENTSINK_MAP(Druntime, CDialog)
   //{{AFX_EVENTSINK_MAP(Druntime)
   //}}AFX_EVENTSINK_MAP
END_EVENTSINK_MAP()

//------------------------------------------------------------------------------

void Druntime::timer(int state)
{
   if (state == on) {
      if (SetTimer(1, mdb.timerInterval, NULL) == 0)
         MessageBox("ERROR: Cannot install timer.\nKill other useless Windows Apps.");
   }
   else {
      KillTimer(1);
      Sleep(mdb.timerInterval);
   }
}

int barScale(double value, double lo, double hi)
{
   // Returns a value 0-100 based on the range defined by lo and hi.
   return int(100 * (value-lo) / (hi-lo));
}

void Druntime::setFld(int idx, int wd, double fv, int bv)
{
   if (box[idx]) {
      char s[11];
      sprintf(s, "%.*f", wd, fv);
      box[idx]->SetWindowText(s);
   }
   if (bar[idx]) {
         bar[idx]->SetPos(bv);
   }
}

void Druntime::updateDisplay(unsigned char runtimevars[])
{
   unsigned int   it;
   double         ft;

   setFld(Rsecl, 0, runtimevars[Rsecl]);

   double press = mdb.map;
   setFld(Rmap, 0, press, barScale(press, rep.lorMAP, rep.hirMAP));

   press = mdb.kpaf[runtimevars[Rbaro]];
   char s[30];
   sprintf(s, "%.0f kPa  %.2f in-Hg", press, press*0.2953007);
   box[Rbaro]->SetWindowText(s);

   ft    = mdb.mat;
   setFld(Rmat, 0, ft, barScale(ft, mdb.tempFromDb(rep.lorMAT), mdb.tempFromDb(rep.hirMAT)));

   ft    = runtimevars[Rego]*5.0 / 255.0;
   setFld(Rego, 3, ft, barScale(ft, rep.lorEGO, rep.hirEGO));

   ft    = mdb.coolant;
   setFld(Rclt, 0, ft, barScale(ft, mdb.tempFromDb(rep.lorCT), mdb.tempFromDb(rep.hirCT)));

   setFld(Rtps, 1, mdb.throttle, barScale(mdb.throttle, rep.lorTR, rep.hirTR));

   setFld(Rbatt, 2, mdb.vBatt, barScale(mdb.vBatt, rep.lorBAT, rep.hirBAT));

   it    = runtimevars[Rrpm] * 100;
   setFld(Rrpm, 0, it, barScale(it, rep.lorRPM, rep.hirRPM));

   ft    = runtimevars[mdb.pageNo() == 0 ? Rpw : Rpw2] / 10.0;
   setFld(Rpw,  1, ft, barScale(ft, rep.lorPW, rep.hirPW));

   double dc = mdb.dualTable() ? runtimevars[RidleDC] : (100 * runtimevars[Rclt] < mdb.Const(Dfastidle));
   setFld(Rdcc,      1, dc,                     barScale(dc,                     rep.lorDC,  rep.hirDC));
   setFld(Regocorr,  0, runtimevars[Regocorr],  barScale(runtimevars[Regocorr],  rep.lorEGC, rep.hirEGC));
   setFld(Raircorr,  0, runtimevars[Raircorr],  barScale(runtimevars[Raircorr],  rep.lorADC, rep.hirADC));
   setFld(Rwarmcorr, 0, runtimevars[Rwarmcorr], barScale(runtimevars[Rwarmcorr], rep.lorWC,  rep.hirWC));
   setFld(Rtpsaccel, 0, runtimevars[Rtpsaccel], barScale(runtimevars[Rtpsaccel], rep.lorACC, rep.hirACC));
   setFld(Rbarocorr, 0, runtimevars[Rbarocorr], barScale(runtimevars[Rbarocorr], rep.lorBC,  rep.hirBC));
   int iRve = mdb.pageNo() == 0 ? Rvecurr : Rvecurr2;
   setFld(Rvecurr,   0, runtimevars[iRve],      barScale(runtimevars[iRve],      rep.lorVE,  rep.hirVE));
   setFld(Rgammae,   0, runtimevars[Rgammae],   barScale(runtimevars[Rgammae],   rep.lorGE,  rep.hirGE));

   /* Output runtime message */
   it = (unsigned int)runtimevars[Rengine];
   static_cast<CEdit *>(GetDlgItem(IDC_RUNNING_TXT   ))->EnableWindow((it &  1) != 0);
   static_cast<CEdit *>(GetDlgItem(IDC_CRANKING_TXT  ))->EnableWindow((it &  2) != 0);
   static_cast<CEdit *>(GetDlgItem(IDC_AFTERSTART_TXT))->EnableWindow((it &  4) != 0);
   static_cast<CEdit *>(GetDlgItem(IDC_WARMUP_TXT    ))->EnableWindow((it &  8) != 0);
   static_cast<CEdit *>(GetDlgItem(IDC_ACCEL_TXT     ))->EnableWindow((it & 16) != 0);
   static_cast<CEdit *>(GetDlgItem(IDC_DECEL_TXT     ))->EnableWindow((it & 32) != 0);
}

//------------------------------------------------------------------------------

void logSize(CWnd *w, char *title);

BOOL Druntime::OnInitDialog()
{
   CDialog::OnInitDialog();

   logSize(this, "runtime");

#define getWnd(idx, ced, cbr) \
   box[idx] = static_cast<CEdit *>(GetDlgItem(ced)); \
   bar[idx] = static_cast<CProgressCtrl *>(GetDlgItem(cbr))

   getWnd(Rsecl,     IDC_SECONDS,   0);
   getWnd(Rmap,      IDC_MAP,       IDC_MAP_BAR );
   getWnd(Rbaro,     IDC_BARO,      0);
   getWnd(Rmat,      IDC_MAT,       IDC_MAT_BAR );
   getWnd(Rego,      IDC_EGO,       IDC_EGO_BAR );
   getWnd(Rclt,      IDC_CLT,       IDC_CLT_BAR );
   getWnd(Rtps,      IDC_TPS,       IDC_TPS_BAR );
   getWnd(Rbatt,     IDC_BATT,      IDC_BATT_BAR );
   getWnd(Rrpm,      IDC_RPM,       IDC_RPM_BAR );
   getWnd(Rpw,       IDC_PW,        IDC_PW_BAR);
   getWnd(Regocorr,  IDC_EGOCOR,    IDC_EGOCOR_BAR );
   getWnd(Raircorr,  IDC_AIRCOR,    IDC_AIRCOR_BAR );
   getWnd(Rwarmcorr, IDC_WARMCOR,   IDC_WARMCOR_BAR );
   getWnd(Rtpsaccel, IDC_ACCELCOR,  IDC_ACCELCOR_BAR );
   getWnd(Rbarocorr, IDC_BAROCOR,   IDC_BAROCOR_BAR);
   getWnd(Rvecurr,   IDC_VECOR,     IDC_VECOR_BAR );
   getWnd(Rgammae,   IDC_GAMMAECOR, IDC_GAMMA_BAR);
   getWnd(Rdcc,      IDC_DUTYCYCLE, IDC_DUTYCYCLE_BAR);

   connected = static_cast<CEdit *>(GetDlgItem(IDC_CONNECTED_TXT));

   if (!mdb.loaded()) mdb.getConst();

   mdb.fixThermoLabel(m_coolantLabel);
   mdb.fixThermoLabel(m_matLabel);

   timer(on);

   return TRUE;
}

//------------------------------------------------------------------------------

void Druntime::OnTimer(UINT nIDEvent)
{
   unsigned char runtimevars[Rget];
   if (!mdb.getRuntime(runtimevars))
      connected->EnableWindow(false);
   else {
      connected->EnableWindow(true);
      updateDisplay(runtimevars);
   }
   CDialog::OnTimer(nIDEvent);
}

//------------------------------------------------------------------------------

BOOL Druntime::DestroyWindow()
{
   timer(off);	
	return CDialog::DestroyWindow();
}

