#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef unsigned int   dword;
typedef unsigned int   uint;
typedef unsigned short uchar;

uint flen( FILE* f )
{
  fseek( f, 0, SEEK_END );
  uint len = ftell(f);
  fseek( f, 0, SEEK_SET );
  return len;
}

uint BytesLoaded;
void* fload( char* fname )
{
  FILE* temp = fopen(fname,"rb");
  if (temp==0) return 0;
  unsigned int len = flen(temp);
  BytesLoaded = len;
  char* buf = new char[len];
  fread( buf, len, 1, temp );
  fclose( temp );
  return buf;
}

void fsave( void* buf, unsigned int len, char* fname )
{
  FILE* temp = fopen(fname,"wb");
  fwrite( buf, len, 1, temp );
  fclose( temp );
}

dword   inplen;
uchar*  inpbuf;
uchar*  outbuf;
uchar** inpbufptr;
  
int __cdecl compare (const void* src, const void* dst)
{
  int ls,lsr;
  uchar* csrc = *((uchar**)src);
  uchar* cdst = *((uchar**)dst);
  if (csrc<cdst)
  {
    while ( csrc>=inpbuf )
      if (*csrc!=*cdst) return (*csrc<*cdst) ? -1 : 1;
        else csrc--,cdst--;
    return 1;
  }
  else 
  if (csrc>cdst)
  {
    while ( cdst>=inpbuf )
      if (*csrc!=*cdst) return (*csrc<*cdst) ? -1 : 1;
        else csrc--,cdst--;
    return -1;
  };
  return 0;
};


int main( int argc, char** argv )
{
  short c;
  uchar d;
  dword i, j, k;
  uchar* p;
  int l;

  printf("BWT Calculator (c) Shelwien, 1999\n");

  if ( argc<2 ) 
  {
    printf("Usage:\n");
    printf("  BWT <inpfile> <outfile>\n");
    exit(0);
  }

  char* inp_n = "book1.";    if ( argc>1 ) inp_n = argv[1];
  char* out_n = "book1.bwt"; if ( argc>2 ) out_n = argv[2];

  inpbuf = (uchar*)fload(inp_n);
  inplen = BytesLoaded/2;
  inpbufptr = new uchar*[ inplen ];
  for ( i=0, p=inpbuf; i<inplen; i++,p++ ) inpbufptr[i] = p;

  qsort( inpbufptr, inplen, sizeof(uchar*), &compare );

  outbuf = new uchar[ inplen ];

  for ( i=0; i<inplen; i++ )
  {
    l = inpbufptr[i]-inpbuf+1;
    if (l>inplen-1) l-=inplen;
    outbuf[i] = inpbuf[l];
  }

  fsave( outbuf, inplen*2, out_n );
  return 0;
}

