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

#include "stdafx.h"
#include "TSensors.h"

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

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

TSensors::TSensors()
{

}

TSensors::~TSensors()
{
   if( floorsPresses )
   {
      delete [] floorsPresses;
      floorsPresses = NULL;
   }
}

void TSensors::init()
{
   floorsPresses = new int[config.stepToCountPopulestFloor];
   reset();
}

void TSensors::reset()
{
   for( int i = 0; i < config.stepToCountPopulestFloor; i++ )
      floorsPresses[i] = 0;

   floorsPresses[config.stepToCountPopulestFloor-1] = config.populestFloor;

   changed = false;
   cachePopulest = config.populestFloor;
}

void TSensors::pressButton( int floor )
{
   for( int i = 0; i < config.stepToCountPopulestFloor-1; i++ )
      floorsPresses[i] = floorsPresses[i+1];

   floorsPresses[config.stepToCountPopulestFloor-1] = floor;

   changed = true;
}

int TSensors::getPopulestFloor()
{
   if( !changed ) return cachePopulest;

   int floors[MAX_FLOOR_NUMBER];
   for( int i = 0; i < MAX_FLOOR_NUMBER; i++ )
      floors[i] = 0;

   for( i = 0; i < config.stepToCountPopulestFloor; i++ )
   {
      if( floorsPresses[i] - 1 < 0 ) continue;
      floors[floorsPresses[i]-1]++;
   }

   int populestFloor = 0;
   int presses = 0;
   for( i = 0; i < MAX_FLOOR_NUMBER; i++ )
   {
      if( presses < floors[i] )
      {
         presses = floors[i];
         populestFloor = i+1;
      }
   }
   changed = false;

   if( config.constPopulest ) populestFloor = config.constPopulest;

   cachePopulest = populestFloor;
   config.populestFloor = populestFloor;
   return populestFloor;
}


void TSensors::getEnvState( TEnvStateSet &set )
{
   int floor = object.elev.getFloor();
   int eU = object.elev.getUpperFloor();
   int eL = object.elev.getLowerFloor();
   int bU = object.button.getUpperFloor();
   int bL = object.button.getLowerFloor();

   set.doorsState = (TDoorsState)object.elev.getDoorsState();
   set.elevState  = (TElevState)object.elev.getState();
   set.elevTask   = (TElevTask)object.elev.getTask();

   // описанная ниже ситуация может быть только, если едем 
   // на массовый этаж без задания - адаптация
   if( set.elevState != ELEV_STATE_STOP &&
       set.elevTask  == ELEV_TASK_STOP     )
      set.elevState = ELEV_STATE_STOP;

   set.wherePopulestFloor = 0.0;

   if( eU )
   {
      if( eU > floor )
         set.whereUppestButt = 3;
      else if( eU < floor )
         set.whereUppestButt = 1;
      else
         set.whereUppestButt = 2;
   }
   else if( bU )
   {
      if( bU > floor )
         set.whereUppestButt = 3;
      else if( bU < floor )
         set.whereUppestButt = 1;
      else
         set.whereUppestButt = 2;
   }
   else
      set.whereUppestButt =  9;
      
   set.isElevOnThisFloorPressed     = object.elev.checkButton( floor );
   set.isButtUpOnThisFloorPressed   = object.button.checkButton( floor, 1 );
   set.isButtDownOnThisFloorPressed = object.button.checkButton( floor, 0 );

   // дорабатываем вход так, чтобы сетка смогла распознать

   if( set.doorsState == ELEV_DOORS_STATE_OPEN )
   {
      set.doorsState                   = ELEV_DOORS_STATE_OPEN;
      set.elevState                    = ELEV_STATE_STOP;
      set.elevTask                     = ELEV_TASK_STOP;
      set.whereUppestButt              = 9;
      set.isElevOnThisFloorPressed     = 0;
      set.isButtUpOnThisFloorPressed   = 0;
      set.isButtDownOnThisFloorPressed = 0;
      
      return;
   }

   if( set.isElevOnThisFloorPressed == 1 )
   {
      set.doorsState                   = ELEV_DOORS_STATE_CLOSE;
      set.elevState                    = ELEV_STATE_STOP;
      set.elevTask                     = ELEV_TASK_STOP;
      set.whereUppestButt              = 9;
      set.isElevOnThisFloorPressed     = 1;
      set.isButtUpOnThisFloorPressed   = 0;
      set.isButtDownOnThisFloorPressed = 0;
      
      return;
   }

   if( set.elevState != ELEV_STATE_STOP )
   {
      if( set.elevState == ELEV_STATE_MOVING_UP )
      {
         if(  set.whereUppestButt == 2         &&
             !set.isButtUpOnThisFloorPressed   &&
              set.isButtDownOnThisFloorPressed    )
         {
         }
         else
         {
            set.whereUppestButt              = 9;
            return;
         }
      }

      if( set.elevState == ELEV_STATE_MOVING_DOWN )
      {
         if(  set.whereUppestButt == 2         &&
              set.isButtUpOnThisFloorPressed   &&
             !set.isButtDownOnThisFloorPressed    )
         {
         }
         else
         {
            set.whereUppestButt              = 9;
            return;
         }
      }
   }
   
   if( set.elevState == ELEV_STATE_STOP &&
       set.elevTask  != ELEV_TASK_STOP    )
   {
      set.whereUppestButt              = 9;
      
      return;
   }

   if( set.doorsState                   == ELEV_DOORS_STATE_CLOSE &&
       set.elevState                    == ELEV_STATE_STOP &&
       set.elevTask                     == ELEV_TASK_STOP &&
       set.whereUppestButt              == 9 &&
       set.isElevOnThisFloorPressed     == 0 &&
       set.isButtUpOnThisFloorPressed   == 0 &&
       set.isButtDownOnThisFloorPressed == 0 
     )
   {
      set.elevState = ELEV_STATE_STOP;

      int populest = getPopulestFloor();
      set.wherePopulestFloor = (populest - floor)*1.0/(MAX_FLOOR_NUMBER/2);
      
      if( set.wherePopulestFloor < -1.0 )
         set.wherePopulestFloor = -1.0;

      if( set.wherePopulestFloor > 1.0 )
         set.wherePopulestFloor = 1.0;
   }
}
