// ElevatorsDlg.cpp : implementation file
//

#include "stdafx.h"
#include "ElevatorsApp.h"
#include "ElevatorsDlg.h"
#include "AboutDlg.h"
#include "ConfigDlg.h"
#include "LearnDlg.h"

#include "TConfig.h"

#include "TDetControlSystem.h"
#include "TNeuroControlSystem.h"
#include "TAdaptControlSystem.h"
#include "TObject.h"
#include "TEnvironment.h"

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

/////////////////////////////////////////////////////////////////////////////
// CElevatorsDlg dialog

CElevatorsDlg::CElevatorsDlg(CWnd* pParent /*=NULL*/)
   : CDialog(CElevatorsDlg::IDD, pParent)
{
   //{{AFX_DATA_INIT(CElevatorsDlg)
      // NOTE: the ClassWizard will add member initialization here
   //}}AFX_DATA_INIT
   // Note that LoadIcon does not require a subsequent DestroyIcon in Win32
   m_hIcon = AfxGetApp()->LoadIcon(IDI_SMALL_ICON);
   object.elev.setStepNumber(0);
}


void CElevatorsDlg::DoDataExchange(CDataExchange* pDX)
{
   CDialog::DoDataExchange(pDX);
   //{{AFX_DATA_MAP(CElevatorsDlg)
      // NOTE: the ClassWizard will add DDX and DDV calls here
   //}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CElevatorsDlg, CDialog)
   //{{AFX_MSG_MAP(CElevatorsDlg)
   ON_WM_PAINT()
   ON_WM_LBUTTONDOWN()
   ON_WM_TIMER()
   ON_BN_CLICKED(IDC_START_BUTTON, OnStartButton)
   ON_BN_CLICKED(IDC_STOP_BUTTON, OnStopButton)
   ON_COMMAND(ID_HELP_ABOUT, OnHelpAbout)
   ON_COMMAND(ID_FILE_EXIT, OnFileExit)
   ON_BN_CLICKED(IDC_STEP_BUTTON, OnStepButton)
   ON_WM_CLOSE()
   ON_COMMAND(ID_CONFIG, OnConfig)
   ON_BN_CLICKED(IDC_RESET_BUTTON, OnResetButton)
   ON_COMMAND(ID_RECORD_PLAY, OnRecordPlay)
   ON_COMMAND(ID_RECORD_RECORD, OnRecordRecord)
   ON_COMMAND(ID_RECORD_STOP, OnRecordStop)
   ON_COMMAND(ID_RECORD_OPEN, OnRecordOpen)
   ON_COMMAND(ID_RECORD_SAVE, OnRecordSave)
   ON_COMMAND(ID_RECORD_SAVEAS, OnRecordSaveas)
   ON_COMMAND(ID_RECORD_NEW, OnRecordNew)
   ON_BN_CLICKED(IDC_RADIO1, OnRadio1)
   ON_BN_CLICKED(IDC_RADIO2, OnRadio2)
   ON_BN_CLICKED(IDC_LEARN_BUTTON, OnLearnButton)
   ON_BN_CLICKED(IDC_SAVE_BUTTON, OnSaveButton)
   ON_BN_CLICKED(IDC_LOAD_BUTTON, OnLoadButton)
   ON_BN_CLICKED(IDC_RADIO3, OnRadio3)
	ON_BN_CLICKED(IDC_LOAD_BUTTON2, OnLoadButton2)
	ON_BN_CLICKED(IDC_LEARN_BUTTON2, OnLearnButton2)
	ON_BN_CLICKED(IDC_SAVE_BUTTON2, OnSaveButton2)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CElevatorsDlg message handlers

BOOL CElevatorsDlg::OnInitDialog() 
{
   CDialog::OnInitDialog();
   
   // TODO: Add extra initialization here
   
   SetIcon(m_hIcon, TRUE);       // Set big icon
   SetIcon(m_hIcon, FALSE);      // Set small icon

   config.setDefault();
   config.load();

   ((CButton*)GetDlgItem(IDC_RADIO3))->SetCheck(1);
   controlSystem = &adaptControlSystem;

   controlSystem->messageHandler( CSM_INIT, NULL );

//   changeToNeuro();

   learnDlg.init(this);
   effCriteriaGraph.init(this);

   drawKSU();
   drawPopulestFloor();

   return TRUE;  // return TRUE unless you set the focus to a control
                 // EXCEPTION: OCX Property Pages should return FALSE
}

void CElevatorsDlg::OnPaint() 
{
   CPaintDC *dc = new CPaintDC(this); // device context for painting
   
   // TODO: Add your message handler code here
   object.draw( this, dc );

   CBrush dbrush(RGB(0,255,0)); 
   CBrush *pOldBrush = dc->SelectObject( &dbrush );

   CPen dpen( PS_SOLID, 1, RGB(0,255,0) );
   CPen *pOldPen = dc->SelectObject( &dpen );
   CRect rect;

   dc->SetBkMode( TRANSPARENT );

   char s[3];
   CString str = "Шаг: ";

   str += itoa( object.elev.getStepNumber(), s, 10 );

   rect.left = 85;
   rect.right = 160;
   rect.top = 55;
   rect.bottom = 87;

   dc->DrawText( str, &rect, DT_LEFT );

   CString regimeStr[4];
   controlSystem->messageHandler( CSM_GET_REGIME, &regimeStr );

   rect.left = 85; rect.right = 180; rect.top = 120; rect.bottom = 140;
   dc->DrawText( regimeStr[0], &rect, DT_LEFT );
   rect.left = 85; rect.right = 180; rect.top = 140; rect.bottom = 160;
   dc->DrawText( regimeStr[1], &rect, DT_LEFT );
   rect.left = 85; rect.right = 180; rect.top = 160; rect.bottom = 180;
   dc->DrawText( regimeStr[2], &rect, DT_LEFT );
   rect.left = 85; rect.right = 180; rect.top = 210; rect.bottom = 230;
   dc->DrawText( regimeStr[3], &rect, DT_LEFT );

   switch( env.isPlayRecord() )
   {
      case PLAYRECORD_NONE:
         str = "";
         break;

      case PLAYRECORD_PLAY:
         str = "Повтор";
         break;

      case PLAYRECORD_RECORD:
         str = "Запись";
         break;
   }
   rect.left = 85;
   rect.right = 150;
   rect.top = 75;
   rect.bottom = 110;

   dc->DrawText( str, &rect, DT_LEFT );

   dc->SelectObject(pOldBrush);
   dc->SelectObject(pOldPen);
   
   // Do not call CDialog::OnPaint() for painting messages

   delete dc;
}

void CElevatorsDlg::OnLButtonDown(UINT nFlags, CPoint point) 
{
   // TODO: Add your message handler code here and/or call default
//   char buff[20];
//   sprintf(buff, "x=%d y=%d", point.x, point.y);
//   CString str(buff);
//   theApp.DoMessageBox(str, MB_OK, 0);
   
   env.pressButton( this, point );

   redraw();

   CDialog::OnLButtonDown(nFlags, point);
}

void CElevatorsDlg::redraw()
{
   CRect rect;
   GetClientRect( &rect );
   rect.right = rect.left + 180;
   RedrawWindow(rect);
}

void CElevatorsDlg::step()
{
   env.saveInMap();

   env.step( this );
   controlSystem->messageHandler( CSM_STEP, NULL );
   object.step();      

   redraw();
   object.elev.setStepNumber(object.elev.getStepNumber()+1);
}

void CElevatorsDlg::OnTimer(UINT nIDEvent) 
{
   // TODO: Add your message handler code here and/or call default
   //   theApp.DoMessageBox("!", MB_OK, 0);

   switch( nIDEvent )
   {
      case 1:
         OnStepButton();
         break;

      case 2:
         learnDlg.draw();
         break;
   }
   
   CDialog::OnTimer(nIDEvent);
}

void CElevatorsDlg::OnStartButton() 
{
   // TODO: Add your control notification handler code here
   if( env.isPlayRecord() == PLAYRECORD_RECORD ) return;
   
   timer = SetTimer( 1, config.getTimeDelay(), 0 );
}

void CElevatorsDlg::OnStopButton() 
{
   // TODO: Add your control notification handler code here
   KillTimer( timer );
}

void CElevatorsDlg::OnHelpAbout() 
{
   // TODO: Add your command handler code here
   AboutDlg dlg;
   dlg.DoModal(); 
}

void CElevatorsDlg::OnFileExit() 
{
   // TODO: Add your command handler code here
   EndDialog(0);
}

void CElevatorsDlg::drawPopulestFloor()
{
   CEdit* edit = (CEdit*)GetDlgItem(IDC_EDIT_POPULEST_FLOOR);
   int populest;
   controlSystem->messageHandler( CSM_GET_POPULEST_FLOOR, &populest );
   CString str;
   str.Format( "%d", populest );
   edit->SetWindowText( str );

   edit->Invalidate();
   edit->UpdateWindow();
}

void CElevatorsDlg::drawKSU()
{
   CEdit* edit = (CEdit*)GetDlgItem(IDC_EDIT_KSU);
   float ksu;
   controlSystem->messageHandler( CSM_GET_KSU, &ksu );
   CString str;
   str.Format( "%1.2f", ksu );
   edit->SetWindowText( str );

   edit->Invalidate();
   edit->UpdateWindow();

   edit = (CEdit*)GetDlgItem( IDC_EDIT_OLD_KSU );
   float oldKsu;
   controlSystem->messageHandler( CSM_GET_OLD_KSU, &oldKsu );
   str.Format( "%1.2f", oldKsu );
   edit->SetWindowText( str );

   edit->Invalidate();
   edit->UpdateWindow();

   edit = (CEdit*)GetDlgItem( IDC_EDIT_SOLVER_IMAGE_NAME );
   char name[_MAX_PATH];
   controlSystem->messageHandler( CSM_GET_SOLVER_IMAGE_NAME, name );
   str = name;
   edit->SetWindowText( str );

   edit->Invalidate();
   edit->UpdateWindow();
}

void CElevatorsDlg::OnStepButton() 
{
   // TODO: Add your control notification handler code here
   drawPopulestFloor();
   drawKSU();
   step();
}

void CElevatorsDlg::OnClose() 
{
   // TODO: Add your message handler code here and/or call default

   config.save(); 

   CDialog::OnClose();
}

void CElevatorsDlg::OnConfig() 
{
   // TODO: Add your command handler code here
   ConfigDlg dlg;
   dlg.DoModal(); 
}

void CElevatorsDlg::OnResetButton() 
{
   // TODO: Add your control notification handler code here
   
   OnStopButton();
   object.elev.setStepNumber(0);
   
   object.reset();
   env.reset();
   effCriteriaGraph.reset();

   controlSystem->messageHandler( CSM_INIT, NULL );
   drawPopulestFloor();
   drawKSU();

   redraw();
}

void CElevatorsDlg::OnRecordPlay() 
{
   // TODO: Add your command handler code here

   env.setPlayRecord(PLAYRECORD_PLAY);
   redraw();
}

void CElevatorsDlg::OnRecordRecord() 
{
   // TODO: Add your command handler code here
   OnStopButton();

//   env.create();

   env.setPlayRecord(PLAYRECORD_RECORD);
   redraw();
}

void CElevatorsDlg::OnRecordStop() 
{
   // TODO: Add your command handler code here
   env.setPlayRecord(PLAYRECORD_NONE);
   redraw();
}

void CElevatorsDlg::OnRecordOpen() 
{
   // TODO: Add your command handler code here
   
   // Заголовок блока диалога
   TCHAR title[] = "Открыть файл последовательностей нажатий";

   // Создаем объект блока диалога
   CFileDialog fileDlg(TRUE);

   // Формируем шаблоны имен отображаемых файлов
   CString str("Последовательности нажатий (*.but)"); str += (TCHAR)NULL;
   str += "*.but"; str += (TCHAR)NULL;
//   str += ("Файлы исходных текстов (cpp, h)"); str += (TCHAR)NULL;
//   str += "*.cpp; *.h"; str += (TCHAR)NULL;
//   str += "Исполняемые файлы (*.exe)"; str += (TCHAR)NULL;
//   str += "*.exe"; str += (TCHAR)NULL;

   // Устанавливает фильтр
   fileDlg.m_ofn.lpstrFilter = str;

   // При открытии блока диалога отображается список
   // файлов, имеющих расширение .cpp или .h
   fileDlg.m_ofn.nFilterIndex = 1;

   // Готовим буфер для полного имени выбранного файла
   TCHAR strName[_MAX_PATH];

   // Этот буфер должен быть пуст
   strName[0] = (TCHAR)NULL;
   fileDlg.m_ofn.lpstrFile = strName;

   // Передаем заголовок блока диалога
   fileDlg.m_ofn.lpstrTitle = title;

   // К флагам устанавливаемым по умолчанию добавляем возможность
   // выбора нескольких файлов одновременно
//   fileDlg.m_ofn.Flags |= OFN_ALLOWMULTISELECT;

   // Выводим блок диалога на экран
   if (fileDlg.DoModal() == IDOK)
   {
      // Если блок диалога закрыт нажатием кнопки OK,
      // в заголовок текущего активного дочернего окна
      // выводим имя первого выбранного файла
//      CChildWnd *pWnd = (CChildWnd *)GetActiveFrame();
//      pWnd->SetWindowText(fileDlg.m_ofn.lpstrFile);

      env.load( fileDlg.m_ofn.lpstrFile );
   }
}

void CElevatorsDlg::OnRecordSave() 
{
   // TODO: Add your command handler code here
   if( *env.getFileName() != '\0' ) 
      env.save();
   else
      OnRecordSaveas();
}

void CElevatorsDlg::OnRecordSaveas() 
{
   // TODO: Add your command handler code here
   
   // Создаем объект блока диалога
   CFileDialog fileDlg(FALSE);

   // Определяем расширение, которое будет присваиваться
   // имени файла по умолчанию
   CString ext("but");
   fileDlg.m_ofn.lpstrDefExt = ext;

   // Формируем шаблоны имен отображаемых файлов
   CString str("Последовательности нажатий (*.but)"); str += (TCHAR)NULL;
   str += "*.but"; str += (TCHAR)NULL;
//   str += ("Файлы исходных текстов (cpp, h)"); str += (TCHAR)NULL;
//   str += "*.cpp; *.h"; str += (TCHAR)NULL;
//   str += "Исполняемые файлы (*.exe)"; str += (TCHAR)NULL;
//   str += "*.exe"; str += (TCHAR)NULL;

   // Устанавливает фильтр
   fileDlg.m_ofn.lpstrFilter = str;

   // Заголовок блока диалога
   TCHAR title[] = "Сохранить файл последовательностей нажатий";
   fileDlg.m_ofn.lpstrTitle = title;

   // Задаем вывод флажка "Только для чтения" (Read Only) и
   // снимаем режим Проводник (Explorer)
//   fileDlg.m_ofn.Flags &= ~(OFN_HIDEREADONLY  | OFN_EXPLORER);

   // Выводим блок диалога на экран
   if(fileDlg.DoModal() == IDOK)
   {
      // Если блок диалога закрыт нажатием кнопки OK,
      // в заголовок текущего активного дочернего окна
      // выводим имя первого выбранного файла
//      CChildWnd *pWnd = (CChildWnd *)GetActiveFrame();
//      pWnd->SetWindowText(fileDlg.GetFileName());
      env.save(fileDlg.GetFileName());
   }
}


void CElevatorsDlg::OnRecordNew() 
{
   // TODO: Add your command handler code here
   
   env.create();  
}

void CElevatorsDlg::OnRadio1() 
{
   // TODO: Add your control notification handler code here
   controlSystem = &detControlSystem;
   OnResetButton();
}

void CElevatorsDlg::OnRadio2() 
{
   // TODO: Add your control notification handler code here
   controlSystem = &neuroControlSystem;
//   changeToNeuro();
   OnResetButton();
}

void CElevatorsDlg::OnRadio3() 
{
   // TODO: Add your control notification handler code here
   controlSystem = &adaptControlSystem;
   OnResetButton();
}

void CElevatorsDlg::OnLearnButton() 
{
   // TODO: Add your control notification handler code here
   controlSystem->messageHandler( CSM_LEARN_SOLVER_DLG, &learnDlg );
}

void CElevatorsDlg::OnSaveButton() 
{
   // TODO: Add your control notification handler code here
   controlSystem->messageHandler( CSM_SAVE_SOLVER, NULL );
}

void CElevatorsDlg::OnLoadButton() 
{
   // TODO: Add your control notification handler code here
   controlSystem->messageHandler( CSM_LOAD_SOLVER, NULL );
}

void CElevatorsDlg::OnLoadButton2() 
{
	// TODO: Add your control notification handler code here
	controlSystem->messageHandler( CSM_LOAD_TEACHER, NULL );
}

void CElevatorsDlg::OnLearnButton2() 
{
	// TODO: Add your control notification handler code here
	controlSystem->messageHandler( CSM_LEARN_TEACHER_DLG, NULL );
}

void CElevatorsDlg::OnSaveButton2() 
{
	// TODO: Add your control notification handler code here
	controlSystem->messageHandler( CSM_SAVE_TEACHER, NULL );
}
