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

#include "stdafx.h"
#include "elevatorsapp.h"

#include "TEnvironment.h"
#include "TElevator.h"
#include "TObject.h"

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

TEnvironment env;

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
bool TEnvironment::PressedOnStepKey::operator<( const PressedOnStepKey& r ) const
{
   if( step < r.step )
   {
      return true;
   }
   else if( step == r.step )
   {
      if( floor < r.floor )
      {
         return true;
      }
      else if( floor == r.floor )
      {
         if( updown < r.updown ) // up меньше чем down
            return true;
      }
   }

   return false;
}


TEnvironment::TEnvironment() :
   playrecord(PLAYRECORD_NONE)
{
   fileName[0] = '\0';

   recordingButtonsKey.reset();
   recordingButtons.reset();
}

TEnvironment::~TEnvironment()
{
}

void TEnvironment::pressButton( CElevatorsDlg *wnd, CPoint point )
{
   // get our client rectangle
   CRect clientRect;
   wnd->GetClientRect( &clientRect );
   
   if( point.x >= 20 + 4*ELEVATOR_XDISTANCE + ELEVATOR_GROUP_DISTANCE/2 + ELEVATOR_XDISTANCE )
   {
      point.x -= ELEVATOR_GROUP_DISTANCE;
   }

   point.x -= 20 + ELEVATOR_XDISTANCE;

   int buttNumber = 0;
   int elevNumber = 0;

   int dist = point.x/ELEVATOR_XDISTANCE + 1;
   if( dist > 8 ) dist = 8;

   point.x -= ELEVATOR_XDISTANCE*(dist-1);
   if( point.x > (ELEVATOR_XDISTANCE-ELEVATOR_WIDE) )
   {
      switch( dist )
      {
         case 1:
            buttNumber = 1;
            break;
         case 3:
            buttNumber = 2;
            break;
         case 5:
            buttNumber = 3;
            break;
         case 7:
            buttNumber = 4;
            break;
      }
   }
   else
   {
      elevNumber = dist;
   }

   point.y = clientRect.bottom - point.y - ELEVATOR_YCONST;
   int floor = point.y/ELEVATOR_HEIGHT+1;

   bool pressed;
   int  elevOrButt = 0;
   bool buttUp;

   if( floor == 23 ||
       (floor >= 14 && floor <= 15 ) ||
       (floor >= 11 && floor <= 12 ) ||
       (floor >= 2 && floor <= 7 ) )
   { 
      pressed = false; 
   }
   else
   {
      pressed = true;

      if( buttNumber )
      {
         elevOrButt = 2;
         int t = point.y/ELEVATOR_HEIGHT;
         point.y -= t*ELEVATOR_HEIGHT;
   
         if( point.y >= ELEVATOR_HEIGHT/2 )
         {
            buttUp = true;
         }
         else
         {
            buttUp = false;
         }
      }

      if( elevNumber )
      {
         elevOrButt = 1;
      }
   }

   if( pressed )
   {
      if( elevOrButt == 1 )
      {
         object.elev.pressButton(floor);
         
         if( isPlayRecord() == PLAYRECORD_RECORD )
            recordingButtons.buttons[floor-1] = 1;
      }
      else if( elevOrButt = 2 )
      {
         saveInMap();
         object.button.pressButton(floor, buttUp ? 1 : 0);

         if( isPlayRecord() == PLAYRECORD_RECORD )
         {
            recordingButtonsKey.step      = object.elev.getStepNumber();
            recordingButtonsKey.floor     = floor;
            recordingButtonsKey.updown    = buttUp ? 1 : 0;
         }
      }
   }
  
   wnd->redraw();
}

void TEnvironment::saveInMap()
{
   if( isPlayRecord() != PLAYRECORD_RECORD || 
       !recordingButtonsKey.floor )
      return;

   for( int i = 0; i < MAX_FLOOR_NUMBER; i++ )
   {
      if( recordingButtons.buttons )
         object.elev.unpressButton(i+1);
   }

   memButtons.insert( TButList::value_type( recordingButtonsKey, 
                                            recordingButtons ) );

   recordingButtonsKey.reset();
   recordingButtons.reset();
}

void TEnvironment::create()
{
   fileName[0] = '\0';
   memButtons.erase( memButtons.begin(), memButtons.end() );
}

void TEnvironment::load( const char* name )
{
   int  numb;

   create();
   
   FILE     *fp = fopen( name, "rt" );
      
   if( fp == NULL ) 
      return;
      
   fscanf( fp, "%d\n" , &numb );

   for( unsigned i = 1; i <= numb; i++ )
   {
      PressedOnStep pressed;
      PressedOnStepKey pressedKey;

      fscanf( fp, "%d %d %d",
              &pressedKey.step, 
              &pressedKey.floor, 
              &pressedKey.updown );

      fscanf( fp, "    %d %d %d %d %d %d %d %d %d %d",
              &pressed.buttons[0], 
              &pressed.buttons[1], 
              &pressed.buttons[2], 
              &pressed.buttons[3], 
              &pressed.buttons[4], 
              &pressed.buttons[5], 
              &pressed.buttons[6], 
              &pressed.buttons[7], 
              &pressed.buttons[8], 
              &pressed.buttons[9] );

      fscanf( fp, " %d %d %d %d %d %d %d %d %d %d",
              &pressed.buttons[10], 
              &pressed.buttons[11], 
              &pressed.buttons[12], 
              &pressed.buttons[13], 
              &pressed.buttons[14], 
              &pressed.buttons[15], 
              &pressed.buttons[16], 
              &pressed.buttons[17], 
              &pressed.buttons[18], 
              &pressed.buttons[19] );

      fscanf( fp, " %d %d %d %d %d %d %d %d\n",
              &pressed.buttons[20], 
              &pressed.buttons[21], 
              &pressed.buttons[22], 
              &pressed.buttons[23], 
              &pressed.buttons[24], 
              &pressed.buttons[25], 
              &pressed.buttons[26], 
              &pressed.buttons[27] );

      pressed.done = false;

      memButtons.insert( TButList::value_type( pressedKey, pressed ) );
   }

   fclose( fp );
   strcpy( fileName, name );
}

void TEnvironment::save( const char* name )
{
   if( name == NULL ) name = fileName;

   FILE *fp = fopen( name, "wt" );
   
   if( fp == NULL ) 
      return;
   
   fprintf( fp, "%d", memButtons.size() );

   if( memButtons.size() )
   {
      TButList::const_iterator iter = memButtons.begin();
      do
      {
         fprintf( fp, "\n%d %d %d    %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d",
                  iter->first.step, iter->first.floor, iter->first.updown,
                  iter->second.buttons[0], iter->second.buttons[1], iter->second.buttons[2], iter->second.buttons[3], iter->second.buttons[4], iter->second.buttons[5], iter->second.buttons[6], iter->second.buttons[7], iter->second.buttons[8], iter->second.buttons[9], 
                  iter->second.buttons[10], iter->second.buttons[11], iter->second.buttons[12], iter->second.buttons[13], iter->second.buttons[14], iter->second.buttons[15], iter->second.buttons[16], iter->second.buttons[17], iter->second.buttons[18], iter->second.buttons[19], 
                  iter->second.buttons[20], iter->second.buttons[21], iter->second.buttons[22], iter->second.buttons[23], iter->second.buttons[24], iter->second.buttons[25], iter->second.buttons[26], iter->second.buttons[27] );

         iter++;
      }
      while( iter != memButtons.end() );
   }

   fclose( fp );
   strcpy( fileName, name );
}


void TEnvironment::step( CElevatorsDlg *wnd )
{
   if( isPlayRecord() == PLAYRECORD_NONE ) return;

   PressedOnStepKey k;

   k.step = object.elev.getStepNumber();
   k.floor = 0;
   k.updown = 0;

   TButList::iterator iter = memButtons.upper_bound( k );
   bool found = ( iter != memButtons.end() ) &&
                ( iter->first.step == object.elev.getStepNumber() );
   
   while( found )
   {
      object.button.pressButton( iter->first.floor, iter->first.updown );

      iter++;
      found = ( iter != memButtons.end() ) &&
              ( iter->first.step == object.elev.getStepNumber() );
   }

   if( memButtons.size() )
   {
      iter = memButtons.begin();
      do
      {
         if( !iter->second.done && 
              iter->first.step < object.elev.getStepNumber() )
         {
            if( iter->first.floor == object.elev.getFloor() )
            {
               if( (iter->first.updown == 1 && object.elev.getTask() == ELEV_TASK_UP  ) ||
                   (iter->first.updown == 0 && object.elev.getTask() == ELEV_TASK_DOWN) ||
                   (object.elev.getTask() == ELEV_TASK_STOP) )
               {
                  for( int f = 0; f < MAX_FLOOR_NUMBER; f++ )
                  {
                     if( iter->second.buttons[f] )
                        object.elev.pressButton(f+1);
                  }
                  iter->second.done = true;
               }
            }
         }
      
         iter++;
      }         
      while( iter != memButtons.end() );
   }
   wnd->redraw();
}

void TEnvironment::reset()
{
   if( !memButtons.size() ) return;

   TButList::iterator iter = memButtons.begin();
   do
   {
      iter->second.done = false;

      iter++;
   }
   while( iter != memButtons.end() );
}
