////////////////////////////////////////////////////////////////////////////////
//
// testmove.cpp - 
//
////////////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <ldefin2d.h>

#ifdef __LIGHT_VERSION__
#include <klAPI5.h>
#else
#include <kAPI5.h>
#endif

#ifndef __TESTMOVE_H
#include "testmove.h"
#endif

#ifndef	__SLIDE_RH
#include <slide.rh>
#endif

extern KompasObject kompas;

// ------------------------------------------------------------------------
//        FileSlide
//        
//   , fileBuff -    
//-------------------------------------------------------------------------
FileSlide::FileSlide( char * fileNameOld, char * fileNameNew ) :
                     fCommentary( FALSE ) {
  OFSTRUCT ofs;
  if ( ::OpenFile(fileNameOld , &ofs, OF_EXIST) != HFILE_ERROR ) {
    fOld = new CFile( ofs.szPathName, CFile::modeRead );
    long s;
    if ( (error = (s = fOld->GetLength()) == -1) != TRUE ) {
      size = ( unsigned ) s;
      fileBuff = new char[ size ];
      fOld->Read( fileBuff, size );
      ToBegin();
      fNew = new CFile( fileNameNew, CFile::modeCreate | CFile::modeWrite );
      return;
    }
  }
  else
    kompas.ksError( "!   " ); //  "!   "
  fileBuff = NULL;
}

// -----------------------------------------------------------------------
//         TFile
//------------------------------------------------------------------------
FileSlide::~FileSlide() {
  if ( !error ) {
    fNew->Close();
    delete fNew;

    delete [] fileBuff;
    delete fOld;
  }
}

//////////////////////////////////////////////////////////////////////
//       
//  len  
// buff  
// ---
char* FileSlide::FGetS( char *buff, int len ) {
  if ( numb < size ) {
    char *c, *b;
    int i = 0;
    b = buff;
    c = fileBuff;
    while ( i < len - 1 && numb < size ) {
      register cc = c[ (numb)++ ];
      if ( cc != '\r' && cc != '\n' )
        b[i++] =(char ) cc;
      else {
        if ( numb < size ) {
          if ( (cc == '\r' && c[ numb ] == '\n') ||
               (cc == '\n' && c[ numb ] == '\r') )
            numb++;
        }
        break;
      }
    }
    b[i] = '\0';
    return buff;
  }
  return NULL;
}

//-------------------------------------------------------------------------------
//
// ---
static int strpos( char *s, int c ) {
 char *pS= strchr( s, c );
 if ( pS )
   return int( pS - s );
 else
   return -1;
}


//-------------------------------------------------------------------------------
//
// ---
static int pr_str( char *vh, char *rez, int t ) {
int i, j, k, m;

  j= strlen( vh );
  for ( i = j-1; i > 0; i-- )
    if ( *(vh+i) != ' ' )
      break;
  m = i;

  for ( i = 0; i < m; i++ )
    if ( *(vh+i) != ' ' )
      break;
  k = i;
  switch ( t ) {
    case 'H' : i = k;        break;
    case 'E' : i = 0; j = m; break;
    case 'B' : i = k; j = m; break;
  }

  k = j - i;

  for ( ;  i <= j; i++ )
    *rez++ = *( vh+i );
  *rez = '\0';

  return ( k );
}

//--------------------------------------------------------------------------
//         
//  - /* ..... */, //......
//    fCommentary =  TRUE 
//  0
//-------------------------------------------------------------------------
int FileSlide::CheckCommentary ( char *s ) {
  char *c;
  c = s;
  if ( *c == '\0' )
    return 0;
  while ( *c == ' ' && *c != '\0' ) c++;
  if ( !fCommentary ) { //  
    if ( *c == '/' ) {
      while ( *c == ' ' && *c != '\0' ) c++;
      c++;
      if ( *c  == '/' )
        return 0;
      if (  *c == '*' ) {
        fCommentary = TRUE;
        c++;
      }
    }
  }
  if ( fCommentary ) { // 
    while ( *c != '\0' ) {
      if ( *c == '*' ) {
        while ( *c == ' ' && *c != '\0' ) c++;
        c++;
        if ( *c  == '/' ) {
          fCommentary = FALSE;
          return 0;
        }
        if ( *c == '\0' )
          break;
      }
      c++;
    }
  }
  return !fCommentary ? 1 : 0;
}

//--------------------------------------------------------------------------
//      
//--------------------------------------------------------------------------
static int ReturnNumberOperation( char *s ) {
  if ( !strcmp( s, "LN") )     // 
    return LN;
  else {
    if ( !strcmp( s, "CR") )   // 
      return CR;
    else {
      if ( !strcmp( s, "AR") )    //   
        return AR;
      else {
          if ( !strcmp( s, "AR1") )  //    
          return AR1;
        else {
          if ( !strcmp( s, "MA") )   //  
            return MA;
          else {
            if ( !strcmp( s, "LA") ) //   
              return LA;
            else {
              if ( !strcmp( s, "EL") ) // 
                return EL;
              else {
                if ( !strcmp( s, "PS") )  // 
                  return PS;
                else {
                  if ( !strcmp( s, "RT") )  // 
                    return RT;
                  else {
                    if ( !strcmp( s, "BR") ) //   
                      return BR;
                    else {
                      if ( !strcmp( s, "DP") ) //  
                        return DP;
                      else {
                        if ( !strcmp( s, "FP") ) // 
                          return FP;
                        else {
                          if ( !strcmp( s, "FF") ) // 
                            return FF;
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  return 0;
}

//--------------------------------------------------------------------------
//
//--------------------------------------------------------------------------
static int CheckCount(int numb, BYTE count ) {
  switch (numb) {
    case LN  :return count == 4 ? 1 : 0;   // LN, x1, y1, x2, y2,
    case MA  :return count == 2 ? 1 : 0;   // MA, x, y,
    case LA  :return count == 2 ? 1 : 0;   // LA, x, y,
    case AR  :return count == 5 ? 1 : 0;   // AR, xc, yc, fst, fen, rad
    case PS  :return count == 5 ? 1 : 0;   // PS, xc, yc, fst, fen, rad
    case EL  :return count == 6 ? 1 : 0;   // EL, xc, yc, fst, fen, rx, ry,
    case AR1 :return count == 7 ? 1 : 0;   // AR1, xc, yc, rad, x1, y1, x2, y2,
    case CR  :return count == 3 ? 1 : 0;   // CR, xc, yc, rad,
    case BR  :return count == 4 ? 1 : 0;   // BR, x1, y1, x2, y2,
    case FF  :return count == 3 ? 1 : 0;   // FF, x, y, b,
    case DP  :return !(count % 2) ? 1 : 0; //DP, x1,y1,...,xn,yn,
    case FP  :return !(count % 2) ? 1 : 0; //FP, x1,y1,...,xn,yn,
    case RT  :return count == 4 ? 1 : 0;   // RT, x1, y1, x2, y2,
  }
  return 0;
}

//--------------------------------------------------------------------------
//
//--------------------------------------------------------------------------
static void MoveEl(int numb, int* component, int x, int y, int count ) {
  switch (numb) {
    case LN  : // LN, x1, y1, x2, y2,
    case BR  : // BR, x1, y1, x2, y2,
    case RT  : // RT, x1, y1, x2, y2,
      component[0] += x; component[1] += y;
      component[2] += x; component[3] += y;
      break;
    case MA  : // MA, x, y,
    case LA  : // LA, x, y,
    case FF  : // FF, x, y, b,
    case CR  : // CR, xc, yc, rad,
    case AR  : // AR, xc, yc, fst, fen, rad
    case PS  : // PS, xc, yc, fst, fen, rad
    case EL  : // EL, xc, yc, fst, fen, rx, ry,
      component[0] += x; component[1] += y;
      break;
    case AR1 : // AR1, xc, yc, rad, x1, y1, x2, y2,
      component[0] += x; component[1] += y;
      component[3] += x; component[4] += y;
      component[5] += x; component[6] += y;
      break;
    case DP  : //DP, x1,y1,...,xn,yn,
    case FP  :{ //DP, x1,y1,...,xn,yn,
      for( int i = 0; i < count; i+=2 ){
        component[0+i] += x; component[1+i] += y;
      }
      break;
    }
  }
}

//-------------------------------------------------------------------------------
//
// ---
static void FillNComponent( char* s, int *ic, int count ) {
  char *c= s + strlen( s );
  for ( int i=0; i < count; i+=2 ) {
    sprintf ( c, " %d, %d,",ic[0+i], ic[1+i] );
    c += strlen( c );
  }
  strcat( s, "\r\n");
}

//--------------------------------------------------------------------------
//
//--------------------------------------------------------------------------
void FillStr(int numb, char *s, int *ic, int count ) {
  switch (numb) {
    case LN  :   // LN, x1, y1, x2, y2,
      sprintf ( s, "  LN, %d, %d, %d, %d,\r\n",ic[0], ic[1], ic[2], ic[3] );
      break;
    case MA  :   // MA, x, y,
      sprintf ( s, "  MA, %d, %d,\r\n",ic[0], ic[1] );
      break;
    case LA  :   // LA, x, y,
      sprintf ( s, "  LA, %d, %d,\r\n",ic[0], ic[1] );
      break;
    case AR  :   // AR, xc, yc, fst, fen, rad
      sprintf ( s, "  AR, %d, %d, %d, %d, %d,\r\n",ic[0], ic[1], ic[2],
                                                              ic[3], ic[4] );
      break;
    case PS  :   // PS, xc, yc, fst, fen, rad
      sprintf ( s, "  PS, %d, %d, %d, %d, %d,\r\n",ic[0], ic[1], ic[2],
                                                              ic[3], ic[4] );
      break;
    case EL  :   // EL, xc, yc, fst, fen, rx, ry,
      sprintf ( s, "  EL, %d, %d, %d, %d, %d, %d,\r\n",ic[0], ic[1], ic[2],
                                                       ic[3], ic[4], ic[5] );
      break;
    case AR1 :   // AR1, xc, yc, rad, x1, y1, x2, y2,
      sprintf ( s, "  AR1, %d, %d, %d, %d, %d, %d, %d,\r\n",ic[0], ic[1],
                                       ic[2], ic[3], ic[4], ic[5], ic[6] );
      break;
    case CR  :   // CR, xc, yc, rad,
      sprintf ( s, "  CR, %d, %d, %d,\r\n",ic[0], ic[1], ic[2] );
      break;
    case BR  :   // BR, x1, y1, x2, y2,
      sprintf ( s, "  BR, %d, %d, %d, %d,\r\n",ic[0], ic[1], ic[2], ic[3] );
      break;
    case FF  :   // FF, x, y, b,
      sprintf ( s, "  FF, %d, %d, %d,\r\n",ic[0], ic[1], ic[2] );
      break;
    case DP  :   //DP, x1,y1,...,xn,yn,
      strcpy ( s, "  DP,");
      FillNComponent( s, ic, count );
      break;
    case FP  :   //FP, x1,y1,...,xn,yn,
      strcpy ( s, "  FP,");
      FillNComponent( s, ic, count );
      break;
    case RT  :   // RT, x1, y1, x2, y2,
      sprintf ( s, "  RT, %d, %d, %d, %d,\r\n",ic[0], ic[1], ic[2], ic[3] );
      break;
  }
}

//--------------------------------------------------------------------------
//    sOld   
//        (int*count)
//    int,      s
// djpdhfoftncz 1
//         0
//--------------------------------------------------------------------------
int FileSlide::MoveElement( char * s, int x, int y ) {
  if ( ! error ) {
    char *c;
    c = s;
    char name[10];
    int len;
    if ( (len = strpos(s, ',')) > 0 ) {
      strncpy ( name, s , len );
      name[ len ] = '\0';

      pr_str(name, name, 'B');
      int numb = ReturnNumberOperation( name );
      if ( numb ) {
        c += len+1;
        //   
        BYTE count = 0;
        while ( *c!='\0' ) {
          c++;
          if( *c == ',' )
            count++;
        }

        if( CheckCount(numb, count ) )  {
          int * component =  new int [sizeof(int)*count];
          c = s;
          c += len+1;
          //    int
          for( int i = 0; i < count; i++ ){
            c++;
            component[i] = atoi( c );
            while( *c != ',' && *c !='\0') c++;
          }
          MoveEl( numb, component,  x,  y, count  );
          FillStr( numb, s, component, count );
          delete []component;
          return 1;
        }
      }
    }
  }
  return 0;

}

//--------------------------------------------------------------------------
//
//--------------------------------------------------------------------------
void FileSlide::FSetS ( char *buff ) {
  if( fNew )
    fNew->Write( buff, strlen(buff) );
}

//-------------------------------------------------------------------------------
//
// ---
void MoveSlide() {
  //  
  CString fileNameOld( kompas.ksChoiceFile("*.rc", 0, false) );
	CString fileNameNew( kompas.ksSaveFile("*.rc", 0, 0, false) );
  char s[128];
	if ( !fileNameOld.IsEmpty() && !fileNameNew.IsEmpty() ) {
		char nameOld[255];
		char nameNew[255];
		::strcpy( nameOld, fileNameOld );
		::strcpy( nameNew, fileNameNew );
    long x, y;
    if ( kompas.ksReadInt("   X", 0, -2000, 2000, &x) 
					&& kompas.ksReadInt("   Y", 0, -2000, 2000, &y) ) {
      FileSlide* file = new FileSlide( nameOld, nameNew );
      if ( !file->IsError() ) {
        while ( file->FGetS(s, 128) ) {
          if ( file->CheckCommentary(s) ) {
            if ( !file->MoveElement(s, x, y) )
              ::strcat( s, "\r\n");
          }
          else
            ::strcat( s, "\r\n" );
          file->FSetS( s );
        }
      }
      delete file;
      kompas.ksMessageBoxResult();
    }
  }
}
