
#include "RobboLito.h"

#include "RobboTotalBase.h"

static void BlockTotalIndexAdd (char* DIR, char* NOME, FILE* F)
{
  char E[1024];
  uint8 A[4];
  FILE* iF;
  int i, num_indici = 0;
  if (NOME[0] != 'i')
    return; /* not index */
  sprintf (E, "%s/%s", DIR, NOME + 1);
  if (STAT (E) == -1)
    {
      SEND ("Worry: No %s file yet iCOMP found\n", E);
      return;
    }
  sprintf (E, "%s/%s", DIR, NOME);
  NOME += strlen ("iCOMP.");
  if (NOME[0] == 'K' || NOME[0] == 'k')
    un_windows (NOME);
  i = 0;
  while (NOME[i])
    i++;
  while (i <= 4)
    NOME[i++] = 0;
  fputc (0xee, F);
  fputc (0x63, F);
  fputc (0x70, F);
  fputc (0x41, F);
  fwrite (NOME, 1, 4, F);
  iF = fopen (E, "rb");
  fread (A, 1, 4, iF); /* mask */ /* omit */
  fread (A, 1, 4, iF); /* block size + compression */
  fwrite (A, 1, 4, F);
  fread (A, 1, 4, iF); /* empty */ /* omit */
  fread (A, 1, 4, iF); /* index counting */
  fwrite (A, 1, 4, F);
  for (i = 0; i < 4; i++)
    num_indici |= A[i] << (8 * i);
  for (i = 0; i < num_indici; i++)
    {
      fread (A, 1, 4, iF);
      fwrite (A, 1, 4, F);
    }
  fclose (iF);
}

#ifdef WINDOWS /* HACK */
void MakeTotalBlockIndex (char* A)
{
  char B[1024], NOME[1024];
  WIN32_FIND_DATA ffd;
  HANDLE hFind = INVALID_HANDLE_VALUE;
  FILE* F;
  
  strcpy (B, A);
  strcat (B, "\\*");
  hFind = FindFirstFile (B, &ffd);
  if (hFind == INVALID_HANDLE_VALUE)
    {
      SEND ("Failure: Directory %s not found\n", A);
      return;
    }
  sprintf (NOME, "%s/BLOCK.INDEX", A);
  F = fopen (NOME, "wb");
  if (!F)
    {
      SEND ("Failure: Cannot write to %s\n", NOME);
      return;
    }
  SEND ("info string Reading directory %s\n", A);
  do
    {
      if (!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) /* recurse ? */
        BlockTotalIndexAdd (A, ffd.cFileName, F);
    }
  while (FindNextFile (hFind, &ffd));
  FindClose (hFind);
  fclose (F);
  SEND ("Finish: %s/BLOCK.INDEX\n", A);
}
#else
#include <fcntl.h>
#include <dirent.h>
#include <string.h>
void MakeTotalBlockIndex (char* A)
{
  DIR *dir;
  struct dirent *DE;
  char NOME[1024];
  FILE* F;
  dir = opendir (A);
  if (!dir)
    {
      SEND ("Failure: Directory %s not found\n", A);
      return;
    }
  sprintf (NOME, "%s/BLOCK.INDEX", A);
  F = fopen (NOME, "w");
  if (!F)
    {
      SEND ("Failure: Cannot write to %s\n", NOME);
      return;
    }
  SEND ("info string Reading directory %s\n", A);
  while ((DE = readdir (dir)))
    BlockTotalIndexAdd (A, DE->d_name, F);
  closedir (dir);
  fclose (F);
  SEND ("Finish: %s/BLOCK.INDEX\n", A);
}
#endif

#include "RobboTripleBase.h"

static void BlockTripleIndexAdd (char* DIR, char* NOME, FILE* F)
{
  char E[1024];
  uint8 A[4];
  FILE* iF;
  int h, heaps, i, num_indici = 0;
  if (memcmp (NOME, "TRIPLE", 6))
    return;
  sprintf (E, "%s/%s", DIR, NOME);
  NOME += strlen ("TRIPLE3."); /* format */
  if (NOME[0] == 'K' || NOME[0] == 'k')
    un_windows_triple (NOME);
  i = 0;
  while (NOME[i])
    i++;
  if (i <= 2)
    {
      SEND ("No value with BLOCK_TRIPLE unless 5s + 6s: %s \n", NOME);
      while (i <= 4)
	NOME[i++] = 0;
      fputc (0x09, F);
      fputc (0x36, F);
      fputc (0xf4, F);
      fputc (0x2b, F);
      fwrite (NOME, 1, 4, F);      
      return;
    }
  while (i <= 4)
    NOME[i++] = 0;
  fputc (0x09, F);
  fputc (0x36, F);
  fputc (0xf4, F);
  fputc (0x2b, F);
  fwrite (NOME, 1, 4, F);
  iF = fopen (E, "rb");
  fread (A, 1, 4, iF); /* results + variant */
  if (A[1] == 0)
    A[2] = A[3] = 0;
  fwrite (A, 1, 4, F);
  if (A[1] == 0)
    return;
  fread (A, 1, 4, iF); /* mask */ /* omit */
  fread (A, 1, 4, iF); /* demand 64 */ /* stream size */ /* giga count */
  heaps = A[3];
  fwrite (A, 1, 4, F);
  fread (A, 1, 4, iF); /* buffer */ /* omit */
  for (h = 0; h < heaps; h++)
    {
      num_indici = 0;
      fread (A, 1, 4, iF);
      fwrite (A, 1, 4, F); /* index count */
      for (i = 0; i < 4; i++)
	num_indici |= A[i] << (8 * i); /* ENDIAN ? */
      for (i = 0; i < num_indici; i++)
	{
	  fread (A, 1, 4, iF); /* index */
	  fwrite (A, 1, 4, F);
	}
      for (i = 0; i < num_indici; i++)
	{
	  fread (A, 1, 4, iF); /* packet offset */
	  fwrite (A, 1, 4, F);
	}
    }
  fclose (iF);
}

boolean DemandOK_BlockTriple (char* A)
{
  int a = strlen (A);
  while (A[a - 1] == '/') /* attend */
    a--;
  A[a] = 0;
  while (A[a - 1] != '/') /* HACK */
    a--;
  A += a;
  if ((!strcmp (A, "4")) || (!strcmp (A, "3")) || (!strcmp (A, "2")))
    {
      SEND ("Failure: No value for BLOCK_TRIPLE.INDEX with 2/ 3/ 4/\n");
      return FALSE;
    }
  return TRUE;
}

#ifdef WINDOWS /* HACK */
void MakeTripleBlockIndex (char* A)
{
  char B[1024], NOME[1024];
  WIN32_FIND_DATA ffd;
  HANDLE hFind = INVALID_HANDLE_VALUE;
  FILE* F;
  
  if (!DemandOK_BlockTriple (A))
    return;
  strcpy (B, A);
  strcat (B, "\\*");
  hFind = FindFirstFile (B, &ffd);
  if (hFind == INVALID_HANDLE_VALUE)
    {
      SEND ("Failure: Directory %s not found\n", A);
      return;
    }
  sprintf (NOME, "%s/BLOCK_TRIPLE.INDEX", A);
  F = fopen (NOME, "wb");
  if (!F)
    {
      SEND ("Failure: Cannot write to %s\n", NOME);
      return;
    }
  SEND ("info string Reading directory %s\n", A);
  do
    {
      if (!(ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) /* recurse ? */
        BlockTripleIndexAdd (A, ffd.cFileName, F);
    }
  while (FindNextFile (hFind, &ffd));
  FindClose (hFind);
  fclose (F);
  SEND ("Finish: %s/BLOCK_TRIPLE.INDEX\n", A);
}
#else
#include <fcntl.h>
#include <dirent.h>
#include <string.h>
void MakeTripleBlockIndex (char* A)
{
  DIR *dir;
  struct dirent *DE;
  char NOME[1024];
  FILE* F;
  if (!DemandOK_BlockTriple (A))
    return;
  dir = opendir (A);
  if (!dir)
    {
      SEND ("Failure: Directory %s not found\n", A);
      return;
    }
  sprintf (NOME, "%s/BLOCK_TRIPLE.INDEX", A);
  F = fopen (NOME, "w");
  if (!F)
    {
      SEND ("Failure: Cannot write to %s\n", NOME);
      return;
    }
  SEND ("info string Reading directory %s\n", A);
  while ((DE = readdir (dir)))
    BlockTripleIndexAdd (A, DE->d_name, F);
  closedir (dir);
  fclose (F);
  SEND ("Finish: %s/BLOCK_TRIPLE.INDEX\n", A);
}
#endif
