// TNeuroControlSystem.cpp: implementation of the TNeuroControlSystem class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "TAdaptControlSystem.h"
#include "TeacherLearnDlg.h"

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

TAdaptControlSystem adaptControlSystem;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

TAdaptControlSystem::TAdaptControlSystem()
{
}

TAdaptControlSystem::~TAdaptControlSystem()
{

}

void TAdaptControlSystem::messageHandler
( 
   TControlSystemMessages message,
   void *parm
)
{
   switch( message )
   {
      case CSM_STEP:
//         упал или увеличился критерий?
//         определяет вычислитель критерия (по статистике или нет)
//
//         если критерий сравнительно давно не менялся 
//         (определяет вычислитель критерия по статистике)
//         то вносим возмущение - применяем учитель так, как будто
//         критерий упал
//         нужно для выхода из возможного локального максимума критерия
//               
//         все это делаем перед каждым управлением
//         хотя, возможно после каждого unpress button - ведь 
//         именно там меняется критерий

         messageHandler( CSM_EFF_CRITERIA_COUNTER_PRESTEP, NULL );

         TEnvStateSet  envStateSet;
         TControlSet   controlSet;

         sensors.getEnvState( envStateSet );
         solver.solve( envStateSet, controlSet );
         actuators.move( controlSet );
         break;
      
      case CSM_UNPRESS_BUTTON:

         TNeuroControlSystem::messageHandler( message, parm );

         if( effCriteriaCounter.isNeedToAdapt() )
         {
//            solverPat.loadPattern();

            TEffCriteriaParms ecp;
            effCriteriaCounter.getECP( &ecp );

            whereKSUearly = config.ksuWhereChanged;

            oldECWhereChanged     = config.effCriteriaWhereChanged;
            ecp.oldECWhereChanged = config.effCriteriaWhereChanged;
            config.effCriteriaWhereChanged = ecp.effCritWhereChange;

            teacher.teach( ecp, solverPat );
            messageHandler( CSM_LOAD_SOLVER, &config.ksu );

            whereKE          = ecp.effCritWhereChange;
            whereKSUnow      = config.ksuWhereChanged;
         }
         break;


      case CSM_SAVE_TEACHER:
         teacher.saveToFile();
         TNeuroControlSystem::messageHandler( message, parm );
         break;

      case CSM_LOAD_TEACHER:
         teacher.loadFromFile();
         TNeuroControlSystem::messageHandler( message, parm );
         break;

      case CSM_LEARN_TEACHER:
         teacherPat.destroyPattern();
         teacherPat.loadPattern();
         teacher.learn(teacherPat);
         messageHandler( CSM_SAVE_TEACHER, NULL );
         break;

      case CSM_LEARN_TEACHER_DLG:
         {
            teacher.Randomize( 0.5 );
            TeacherLearnDlg dlg;
            dlg.DoModal();
         }
         break;

      case CSM_GET_TEACHER_CYCLE:
         *((int*)parm) = teacher.GetCycle();
         break;
      
      case CSM_SET_TEACHER_STOP_LEARNING:
         teacher.setStopLearning();
         break;

      case CSM_GET_KSU:
         *(float*)parm = config.ksu;
         break;

      case CSM_GET_REGIME:
         {
            CString* str = (CString*)parm;

            switch( whereKE )
            {
               case 0:
                  str[0] = "";
                  break;

               case 1:
                  str[0] = "КЭ упал";
                  break;
            
               case 2:
                  str[0] = "КЭ стоит";
                  break;
            
               case 3:
                  str[0] = "КЭ вырос";
                  break;
            }

            switch( oldECWhereChanged )
            {
               case 0:
                  str[1] = "";
                  break;

               case 1:
                  str[1] = "КЭ падал";
                  break;
            
               case 2:
                  str[1] = "КЭ стоял";
                  break;
            
               case 3:
                  str[1] = "КЭ рос";
                  break;
            }

            switch( whereKSUearly )
            {
               case 0:
                  str[2] = "";
                  break;

               case 1:
                  str[2] = "КCУ уменьшали";
                  break;
            
               case 2:
                  str[2] = "КСУ не меняли";
                  break;
            
               case 3:
                  str[2] = "КCУ увеличивали";
                  break;
            }

            switch( whereKSUnow )
            {
               case 0:
                  str[3] = "";
                  break;

               case 1:
                  str[3] = "КСУ уменьшаем";
                  break;
            
               case 2:
                  str[3] = "КСУ не меняем";
                  break;
            
               case 3:
                  str[3] = "КСУ увеличиваем";
                  break;
            }
         }
         break;

      case CSM_INIT:
         TNeuroControlSystem::messageHandler( message, parm );
         TNeuroControlSystem::messageHandler(  CSM_LOAD_SOLVER, 
                                              &config.ksu );
         messageHandler( CSM_LOAD_TEACHER, NULL );
         break;

      case CSM_RESET:
         whereKE           = 0;
         whereKSUearly     = 0;
         oldECWhereChanged = 0;
         whereKSUnow       = 0;
         break;

      default:
         TNeuroControlSystem::messageHandler( message, parm );
         break;
   }
}