// Author: Dr. Mircea Puiu
// Created on: October 2005 for CodeProject
//
// ScriptDlg.cpp : implementation file
//
#include "stdafx.h"
#include "CatchCulator.h"
#include "ScriptDlg.h"
#include "CatchCulatorDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CScriptDlg dialog
CScriptDlg::CScriptDlg(CWnd* pParent /*=NULL*/)
: CDialog(CScriptDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CScriptDlg)
// NOTE: the ClassWizard will add member initialization here
//}}AFX_DATA_INIT
m_colorBkGnd = RGB(186, 198, 179);
m_brushBkGnd.CreateSolidBrush(m_colorBkGnd);
m_strCaption = " Script";
m_nID = -1;
}
void CScriptDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CScriptDlg)
DDX_Control(pDX, IDC_EDIT_SCRIPT, m_script);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CScriptDlg, CDialog)
//{{AFX_MSG_MAP(CScriptDlg)
ON_WM_CTLCOLOR()
ON_BN_CLICKED(IDC_BUTTON_UPDATE_SCRIPT, OnButtonUpdateScript)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CScriptDlg message handlers
HBRUSH CScriptDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
if ( nCtlColor != CTLCOLOR_EDIT)
{
hbr = (HBRUSH)m_brushBkGnd.GetSafeHandle();
pDC->SetBkColor(m_colorBkGnd);
}
return hbr;
}
BOOL CScriptDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
SetWindowText(m_strCaption.GetBuffer(0));
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
double CScriptDlg::ComputedValue(char *resultName)
{
// Look for the <resultName> in m_listToDo and return the result
double result = 0.0;
POSITION pos;
Calculation CL;
CString strName = resultName;
if ( m_listToDo.IsEmpty () ) return result;
// Cut the blanks at left and right, if any
strName.TrimLeft();
strName.TrimRight();
// Go through the list
pos = m_listToDo.GetHeadPosition();
while ( pos )
{
CL = m_listToDo.GetNext(pos);
if ( CL.resultName == strName )
{
result = CL.result;
break;
}
}
return result;
}
POSITION CScriptDlg::FindVariable(char *varName)
{
// Return the POSITION of [varName] in m_listToDo or NULL if not found
POSITION posName = NULL, pos, posCrt;
Calculation CL;
CString strName = varName;
if ( m_listToDo.IsEmpty () ) return posName;
// Cut the blanks at left and right, if any
strName.TrimLeft();
strName.TrimRight();
// Go through the list
pos = m_listToDo.GetHeadPosition();
while ( pos )
{
posCrt = pos;
CL = m_listToDo.GetNext(pos);
if ( CL.resultName == strName )
{
posName = posCrt;
break;
}
}
return posName;
}
void CScriptDlg::OnButtonUpdateScript()
{
// TODO: Update the script
// Supported operations: +, -, *, /
CCatchCulatorDlg *pMain = (CCatchCulatorDlg *)AfxGetMainWnd();
CString strText, strL, strR, strAux;
Calculation CL;
int i, nLines, N, posToken, posTokenName1, posTokenName2;
char chText[1024], chValue[256];
bool bIsZero;
double dValue;
if ( !pMain ) return;
// Clear the previous calculations list, if any
if ( !m_listToDo.IsEmpty() ) m_listToDo.RemoveAll();
// Go throughout the multi-line edit control
nLines = m_script.GetLineCount();
for ( i=0; i<nLines; i++ )
{
// Get line "i"
N = m_script.GetLine(i, chText, 1023);
chText[N] = 0; // make it a null-terminated string
strText = chText;
if ( strText.GetLength() < 1 ) continue; // no script in this line
// Get the operation
posToken = strText.ReverseFind('*');
if ( posToken != -1 ) CL.operation = "*";
else
{
posToken = strText.ReverseFind('/');
if ( posToken != -1 ) CL.operation = "/";
else
{
posToken = strText.ReverseFind('+');
if ( posToken != -1 ) CL.operation = "+";
else
{
posToken = strText.ReverseFind('-');
if ( posToken != -1 ) CL.operation = "-";
else continue; // unrecognized operation
}
}
}
// Get the name associated with the result
posTokenName2 = strText.Find(">");
if ( posTokenName2 == -1 ) continue; // no name
if ( posTokenName2 > posToken ) continue; // invalid naming
posTokenName1 = strText.Find("<");
if ( posTokenName1 == -1 ) continue; // no name
if ( posTokenName1 > posTokenName2 ) continue; // invalid naming syntax
CL.resultName = strText.Mid(posTokenName1 + 1,
posTokenName2 - posTokenName1 - 1);
if ( CL.resultName == "" ) continue; // no name
// Get the operands (left and right with respect to posToken)
strL = strText.Mid(posTokenName2 + 1, posToken - posTokenName2 - 1);
strR = strText.Right(strText.GetLength() - posToken - 1);
if ( (strL == "") && (CL.operation != "+") && (CL.operation != "-") )
continue; // no left operand
if ( strR == "" ) continue; // no right operand
strL.TrimLeft(); strL.TrimRight();
strR.TrimLeft(); strR.TrimRight();
// Check if strL is a constant value, else
// look for strL among the names in the catches tree and then
// among the names within the ToDo list
strAux = strL;
strAux.Replace(" ", "");
bIsZero = false;
if (strAux == "0" ) bIsZero = true;
if ( strAux.GetLength() > 255 ) strncpy(chValue, strAux.GetBuffer(0), 255);
else strcpy(chValue, strAux.GetBuffer(0));
dValue = 0.0;
sscanf(chValue, "%lf", &dValue);
if ( bIsZero && ((int)dValue == 0) )
{
// opL is constant 0
CL.opL = "3-0";
}
else if ( dValue != 0 )
{
// opL is a (non-zero) constant
sprintf(chValue, "%lf", dValue);
CL.opL = "3-";
CL.opL += chValue;
}
else if ( pMain->FindVariable(strL.GetBuffer(0)) )
{
// opL is a monitored variable
CL.opL = "1-";
CL.opL += strL;
}
else
{
if ( FindVariable(strL.GetBuffer(0)) )
{
CL.opL = "2-";
CL.opL += strL;
}
else
{
// Unknown variable, disregard script line
continue;
}
}
// Check if strR is a constant value, else
// look for strR among the names in the catches tree and then
// among the names within the ToDo list
strAux = strR;
strAux.Replace(" ", "");
bIsZero = false;
if (strAux == "0" ) bIsZero = true;
if ( strAux.GetLength() > 255 ) strncpy(chValue, strAux.GetBuffer(0), 255);
else strcpy(chValue, strAux.GetBuffer(0));
dValue = 0.0;
sscanf(chValue, "%lf", &dValue);
if ( bIsZero && ((int)dValue == 0) )
{
// opR is constant 0
CL.opR = "3-0";
}
else if ( dValue != 0 )
{
// opR is a (non-zero) constant
sprintf(chValue, "%lf", dValue);
CL.opR = "3-";
CL.opR += chValue;
}
else if ( pMain->FindVariable(strR.GetBuffer(0)) )
{
// opL is a monitored variable
CL.opR = "1-";
CL.opR += strR;
}
else
{
if ( FindVariable(strR.GetBuffer(0)) )
{
CL.opR = "2-";
CL.opR += strR;
}
else
{
// Unknown variable, disregard script line
continue;
}
}
// Initialize the result with 0
CL.result = 0.0;
// Add CL to m_listToDo
m_listToDo.AddTail(CL);
} // next line of script (i)
// Update the display
pMain->UpdateDisplay(m_nID);
}
void CScriptDlg::UpdateScript()
{
OnButtonUpdateScript();
}