// SSubControl.cpp : implementation file
//

#include "stdafx.h"
#include "Simulator.h"
#include "SSubControl.h"
#include "Subsumption.h"
#include "MessageMap.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
// SSubControl dialog


SSubControl::SSubControl(CWnd* pParent /*=NULL*/)
	: CDialog(SSubControl::IDD, pParent)
{
	//{{AFX_DATA_INIT(SSubControl)
	m_ErrorMargin = 0;
	m_FrontThreshold = 0;
	m_RightIdeal = 0;
	m_PollingDelay = 0;
	m_PollingCount = 0;
	m_WEAngleFactor = 0;
	m_WESpeedFacotr = 0;
	m_EEAngleFactor = 0;
	m_EEDelayCount = 0;
	m_EESpeedFactor = 0;
	m_TAngleFactor = 0;
	m_TDelayCount = 0;
	m_TSpeedFactor = 0;
	//}}AFX_DATA_INIT

    m_pParent = pParent;  // used to enable the modeless dialog, don't ask!
	m_nID = SSubControl::IDD;   
}


void SSubControl::DoDataExchange(CDataExchange* pDX)
{

	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(SSubControl)
	DDX_Text(pDX, IDC_ERRORMARGIN, m_ErrorMargin);
	DDV_MinMaxInt(pDX, m_ErrorMargin, MINERRORMARGIN, MAXERRORMARGIN);
	DDX_Text(pDX, IDC_FRONTTHRESHOLD, m_FrontThreshold);
	DDV_MinMaxInt(pDX, m_FrontThreshold, MINIR, MAXIR);
	DDX_Text(pDX, IDC_RIGHTIDEAL, m_RightIdeal);
	DDV_MinMaxInt(pDX, m_RightIdeal, MINIR, MAXIR);
	DDX_Text(pDX, IDC_POLLINGDELAY, m_PollingDelay);
	DDV_MinMaxInt(pDX, m_PollingDelay, MINDELAY, MAXDELAY);
	DDX_Text(pDX, IDC_POLLINGCOUNT, m_PollingCount);
	DDV_MinMaxInt(pDX, m_PollingCount, MINPOLLINGCOUNT, MAXPOLLINGCOUNT);
	DDX_Text(pDX, IDC_WEANGLEFACTOR, m_WEAngleFactor);
	DDV_MinMaxInt(pDX, m_WEAngleFactor, MINANGLE, MAXANGLE);
	DDX_Text(pDX, IDC_WESPEEDFACTOR, m_WESpeedFacotr);
	DDV_MinMaxInt(pDX, m_WESpeedFacotr, MINSPEED, MAXSPEED);
	DDX_Text(pDX, IDC_EEANGLEFACTOR, m_EEAngleFactor);
	DDV_MinMaxInt(pDX, m_EEAngleFactor, MINANGLE, MAXANGLE);
	DDX_Text(pDX, IDC_EEDELAYCOUNT, m_EEDelayCount);
	DDV_MinMaxInt(pDX, m_EEDelayCount, MINDELAY, MAXDELAY);
	DDX_Text(pDX, IDC_EESPEEDFACTOR, m_EESpeedFactor);
	DDV_MinMaxInt(pDX, m_EESpeedFactor, MINSPEED, MAXSPEED);
	DDX_Text(pDX, IDC_TANGLEFACTOR, m_TAngleFactor);
	DDV_MinMaxInt(pDX, m_TAngleFactor, MINANGLE, MAXANGLE);
	DDX_Text(pDX, IDC_TDELAYCOUNT, m_TDelayCount);
	DDV_MinMaxInt(pDX, m_TDelayCount, MINDELAY, MAXDELAY);
	DDX_Text(pDX, IDC_TSPEEDFACTOR, m_TSpeedFactor);
	DDV_MinMaxInt(pDX, m_TSpeedFactor, MINSPEED, MAXSPEED);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(SSubControl, CDialog)
	//{{AFX_MSG_MAP(SSubControl)
	ON_EN_KILLFOCUS(IDC_WESPEEDFACTOR, OnKillfocusWespeedfactor)
	ON_EN_KILLFOCUS(IDC_WEANGLEFACTOR, OnKillfocusWeanglefactor)
	ON_EN_KILLFOCUS(IDC_TSPEEDFACTOR, OnKillfocusTspeedfactor)
	ON_EN_KILLFOCUS(IDC_TDELAYCOUNT, OnKillfocusTdelaycount)
	ON_EN_KILLFOCUS(IDC_TANGLEFACTOR, OnKillfocusTanglefactor)
	ON_EN_KILLFOCUS(IDC_RIGHTIDEAL, OnKillfocusRightideal)
	ON_EN_KILLFOCUS(IDC_POLLINGDELAY, OnKillfocusPollingdelay)
	ON_EN_KILLFOCUS(IDC_POLLINGCOUNT, OnKillfocusPollingcount)
	ON_EN_KILLFOCUS(IDC_FRONTTHRESHOLD, OnKillfocusFrontthreshold)
	ON_EN_KILLFOCUS(IDC_ERRORMARGIN, OnKillfocusErrormargin)
	ON_EN_KILLFOCUS(IDC_EESPEEDFACTOR, OnKillfocusEespeedfactor)
	ON_EN_KILLFOCUS(IDC_EEDELAYCOUNT, OnKillfocusEedelaycount)
	ON_EN_KILLFOCUS(IDC_EEANGLEFACTOR, OnKillfocusEeanglefactor)
	ON_BN_CLICKED(IDC_HIDE, OnHide)
	ON_BN_CLICKED(IDC_DEFAULTS, OnDefaults)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// SSubControl message handlers

// Used for Modeless operation
BOOL SSubControl::Create()
{
    return CDialog::Create(IDD, m_pParent);
}

void SSubControl::OnKillfocusWespeedfactor() 
{
		UpdateData(true);
    // only if valid
    
    if ((m_WESpeedFacotr <= MAXSPEED) && (m_WESpeedFacotr >= MINSPEED))
    {
        ActuaWESpeedFacotr = m_WESpeedFacotr;
        SendUpdateMessage();
    }
    else
    {
        // reset to a valid speed
        m_WESpeedFacotr = ActuaWESpeedFacotr;
        UpdateData(false);

    }
	
}

void SSubControl::OnKillfocusWeanglefactor() 
{
    UpdateData(true);
    // only if valid
    
    if ((m_WEAngleFactor <= MAXANGLE) && (m_WEAngleFactor >= MINANGLE))
    {
        ActuaWEAngleFactor = m_WEAngleFactor;
        SendUpdateMessage();
    }
    else
    {
        // reset to a valid speed
        m_WEAngleFactor = ActuaWEAngleFactor;
        UpdateData(false);

    }
	
}

void SSubControl::OnKillfocusTspeedfactor() 
{
	UpdateData(true);
    // only if valid
    
    if ((m_TSpeedFactor <= MAXSPEED) && (m_TSpeedFactor >= MINSPEED))
    {
        ActuaTSpeedFactor = m_TSpeedFactor;
        SendUpdateMessage();
    }
    else
    {
        // reset to a valid speed
        m_TSpeedFactor = ActuaTSpeedFactor;
        UpdateData(false);

    }
	
}

void SSubControl::OnKillfocusTdelaycount() 
{
	UpdateData(true);
    // only if valid
    
    if ((m_TDelayCount <= MAXDELAY) && (m_TDelayCount >= MINDELAY))
    {
        ActuaTDelayCount = m_TDelayCount;
        SendUpdateMessage();
    }
    else
    {
        // reset to a valid speed
        m_TDelayCount = ActuaTDelayCount;
        UpdateData(false);

    }	
}

void SSubControl::OnKillfocusTanglefactor() 
{
	UpdateData(true);
    // only if valid
    
    if ((m_TAngleFactor <= MAXANGLE) && (m_TAngleFactor >= MINANGLE))
    {
        ActuaTAngleFactor = m_TAngleFactor;
        SendUpdateMessage();
    }
    else
    {
        // reset to a valid speed
        m_TAngleFactor = ActuaTAngleFactor;
        UpdateData(false);

    }	
}

void SSubControl::OnKillfocusRightideal() 
{
	UpdateData(true);
    // only if valid
    
    if ((m_RightIdeal <= MAXIR) && (m_RightIdeal >= MINIR))
    {
        ActuaRightIdeal = m_RightIdeal;
        SendUpdateMessage();
    }
    else
    {
        // reset to a valid speed
        m_RightIdeal = ActuaRightIdeal;
        UpdateData(false);

    }	
}

void SSubControl::OnKillfocusPollingdelay() 
{
	UpdateData(true);
    // only if valid

    if ((m_PollingDelay <= MAXDELAY) && (m_PollingDelay >=MINDELAY))
    {
        ActuaPollingDelay = m_PollingDelay;
        SendUpdateMessage();
    }
    else
    {
        // reset to a valid speed
        m_PollingDelay = ActuaPollingDelay;
        UpdateData(false);

    }	
}

void SSubControl::OnKillfocusPollingcount() 
{
	UpdateData(true);
    // only if valid

    if ((m_PollingCount <= MAXPOLLINGCOUNT) && (m_PollingCount >=MINPOLLINGCOUNT))
    {
        ActuaPollingCount = m_PollingCount;
        SendUpdateMessage();
    }
    else
    {
        // reset to a valid speed
        m_PollingCount = ActuaPollingCount;
        UpdateData(false);

    }	
}

void SSubControl::OnKillfocusFrontthreshold() 
{
	UpdateData(true);
    // only if valid    

    if ((m_FrontThreshold <= MAXIR) && (m_FrontThreshold >=MINIR))
    {
        ActuaFrontThreshold = m_FrontThreshold;
        SendUpdateMessage();
    }
    else
    {
        // reset to a valid speed
        m_FrontThreshold = ActuaFrontThreshold;
        UpdateData(false);

    }	
}

void SSubControl::OnKillfocusErrormargin() 
{
	UpdateData(true);
    // only if valid
    
    if ((m_ErrorMargin <= MAXERRORMARGIN) && (m_ErrorMargin >=MINERRORMARGIN))
    {
        ActualErrorMargin = m_ErrorMargin;
        SendUpdateMessage();
    }
    else
    {
        // reset to a valid speed
        m_ErrorMargin = ActualErrorMargin;
        UpdateData(false);

    }	
}

void SSubControl::OnKillfocusEespeedfactor() 
{
	UpdateData(true);
    // only if valid
    
    if ((m_EESpeedFactor <= MAXSPEED) && (m_EESpeedFactor >=MINSPEED))
    {
        ActuaEESpeedFactor = m_EESpeedFactor;
        SendUpdateMessage();
    }
    else
    {
        // reset to a valid speed
        m_EESpeedFactor = ActuaEESpeedFactor;
        UpdateData(false);

    }	
}

void SSubControl::OnKillfocusEedelaycount() 
{
	UpdateData(true);
    // only if valid
    
    if ((m_EEDelayCount <= MAXDELAY) && (m_EEDelayCount >=MINDELAY))
    {
        ActuaEEDelayCount = m_EEDelayCount;
        SendUpdateMessage();
    }
    else
    {
        // reset to a valid speed
        m_EEDelayCount = ActuaEEDelayCount;
        UpdateData(false);

    }	
}

void SSubControl::OnKillfocusEeanglefactor() 
{
	UpdateData(true);
    // only if valid
    
    if ((m_EEAngleFactor <= MAXANGLE) && (m_EEAngleFactor >=MINANGLE))
    {
        ActuaEEAngleFactor = m_EEAngleFactor;
        SendUpdateMessage();
    }
    else
    {
        m_EEAngleFactor = ActuaEEAngleFactor;
        UpdateData(false);

    }	
}

void SSubControl::LoadDefaults()
{
	m_ErrorMargin = ActualErrorMargin = DEFAULTERRORMARGIN;
	m_FrontThreshold = ActuaFrontThreshold = DEFAULTFRONTTHRESHOLD;
	m_RightIdeal = ActuaRightIdeal = DEFAULTRIGHTIDEAL;
	m_PollingDelay = ActuaPollingDelay = DEFAULTPOLLINGDELAY;
	m_PollingCount = ActuaPollingCount = DEFAULTPOLLINGCOUNT;
	m_WEAngleFactor = ActuaWEAngleFactor = DEFAULTFWWITHINANGLEADJUST;
	m_WESpeedFacotr = ActuaWESpeedFacotr = DEFAULTFWWITHINSPEED;
	m_EEAngleFactor = ActuaEEAngleFactor = DEFAULTFWEXCEEDANGLEADJUST;
	m_EEDelayCount = ActuaEEDelayCount = DEFAULTDELAY;
	m_EESpeedFactor = ActuaEESpeedFactor = DEFAULTFWEXCEEDSPEED;
	m_TAngleFactor = ActuaTAngleFactor = DEFAULTFWSTRAIGHTENANGLEADJUST;
    m_TDelayCount = ActuaTDelayCount = DEFAULTDELAY;
	m_TSpeedFactor = ActuaTSpeedFactor = DEFAULTFWSTRAIGHTENSPEED;

    UpdateData(false);
}

BOOL SSubControl::OnInitDialog() 
{
	CDialog::OnInitDialog();
	
    LoadDefaults(); 
	
	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void SSubControl::SendUpdateMessage()
{
    Subsumption::SUBSUMPTIONOPTIONS Options;

    Options.ErrorMargin = ActualErrorMargin;
    Options.FrontThreshHold = ActuaFrontThreshold;
    Options.FWExceedAngleAdjust = ActuaEEAngleFactor;
    Options.FWExceedDelay = ActuaEEDelayCount;
    Options.FWExceedSpeed = ActuaEESpeedFactor;
    Options.FWStraightenAngleAdjust = ActuaTAngleFactor;
    Options.FWStraightenDelay = ActuaTDelayCount;
    Options.FWStraightenSpeed = ActuaTSpeedFactor;
    Options.FWWithinAngleAdjust = ActuaWEAngleFactor;
    Options.FWWithinSpeed = ActuaWESpeedFacotr;
    Options.PollingCount = ActuaPollingCount;
    Options.PollingDelay = ActuaPollingDelay;
    Options.RightIdeal = ActuaRightIdeal;

  ::SendMessage(m_pParent->m_hWnd,WM_SUBOPTIONS,(WPARAM )&Options, NULL);

}



BOOL SSubControl::PreTranslateMessage(MSG* pMsg) 
{
		// TODO: Add your specialized code here and/or call the base class


     // disable the escape key
    BOOL bHandleNow = FALSE;

    switch (pMsg->message)
    {
    case WM_KEYDOWN:
        switch (pMsg->wParam)
        {
        case VK_UP:
        case VK_DOWN:
        case VK_LEFT:
        case VK_DELETE:
        case 's':
            OnHide();
        case 'S':            
            OnHide();
        // disable the enter key
        case 13:
            SetFocus();
            return true;
        }
        if (bHandleNow)
            OnKeyDown(pMsg->wParam, LOWORD(pMsg 
                ->lParam), HIWORD(pMsg->lParam));
        break;
    }

	return CDialog::PreTranslateMessage(pMsg);

}

void SSubControl::OnHide()
{
    ShowWindow(SW_HIDE);
    // need to deactivate window so the parent could get the focus
    EnableWindow(false);
    ::SendMessage(m_pParent->m_hWnd,WM_USER_SET_FOCUS,0,0);

}


void SSubControl::OnDefaults() 
{
    LoadDefaults();	
    SendUpdateMessage();
}
