/*
 *  Arcanum Editor - ROM area editor
 *  Copyright (C) 1999  Lucas Wall <kthulhu@usa.net>
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 *
 *  If you make changes to the source and want to make the public you can
 *  mail the diferences to me <kthulhu@usa.net> and I'll add them to the
 *  main distribution. Of course your name will be added to the program with
 *  information about the changes you made.
 *
 *
 *  Packed on Thu Aug 19 03:02:30 1999
 *
 */


/*
 * File: fread.cpp
 *
 * Changes:
 *
 * 19/08/99 Lucas Wall <kthulhu@usa.net>
 *          First source release. Its quite messy and has no
 *          comments. I never planed to release the source code... :-)
 *
 */



#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>

#include "stdafx.h"
#include "fread.h"

int numbuf = 0;
char *tempbuf[10];

void init_buffers()
{
	int i;

	numbuf = 0;
	for ( i = 0; i < 10; i++ )
	{
		tempbuf[i] = (char *) malloc( 10000 );
		ASSERT( tempbuf[i] != NULL );
	}
}

void free_buffers()
{
	int i;

	for ( i = 0; i < 10; i++ )
		free( tempbuf[i] );
}

CString fread_word(CArchive & ar, int number)
{
	CString word;
	char c, wend;
	int neof;

	do {
		neof = ar.Read( &c, 1 );
	} while ( neof && issepchar( c, FALSE ) );
	if ( neof && !issepchar( c, FALSE ) )
	{
		if ( c == '\'' || c == '"' )
		{
			wend = c;
		}
		else
		{
			word += c;
			wend = ' ';
		}
	}

	while ( true ) {

		neof = ar.Read( &c, 1 );
		if ( neof && ( wend == ' ' ? !issepchar( c, number ) : c != wend ) )
			word += c;
		else
			break;

	}

	return word;
}

bool issepchar( char c, int number)
{
	if ( c == ' ' || c == '\n' || c == '\r' || c == '\t' )
		return true;
	if ( number && ( c < '0' || c > '9' ) && c != '-' )
		return true;
	return false;
}

CString fread_string(CArchive & ar, int clean)
{
	CString string, temp;
	char c;
	int neof, pos;

	do {
		neof = ar.Read( &c, 1 );
	} while ( neof && issepchar( c ) );
	if ( neof && !issepchar( c ) )
		string += c;

	if ( c == '~' )
	{
		string = "";
		return string;
	}

	do {

		neof = ar.Read( &c, 1 );
		if ( neof && c != '~' && c != '\r' )
			string += c;

	} while ( neof && c != '~' );

	if ( clean )
		while ( ( pos = string.Find( "\n" ) ) != -1 )
		{
			temp = string.Left( pos );
			temp += " " + string.Mid( pos + 1 );
			string = temp;
		}

	return string;
}

int fread_number(CArchive & ar)
{
	CString string;
	int num;

	string = fread_word( ar, TRUE );
	num = atoi( string );
	return num;
}

char fread_letter(CArchive & ar)
{
	char c;
	int neof;

	do {
		neof = ar.Read( &c, 1 );
	} while ( neof && issepchar( c ) );
	if ( !neof ) c = 0;

	return c;
}

int fread_flags(CArchive & ar)
{
	CString word;
	int flags, i;

	word = fread_word( ar );
	
	flags = 0;
	for ( i = 0; i < word.GetLength(); i++ )
		flags |= convert_flag( word[i] );

	return flags;
}

void fread_eol(CArchive & ar)
{
	CString temp;

	ar.ReadString( temp );
}

int convert_flag( char c )
{
	if ( c >= 'A' && c <= 'Z' )
		return 1 << ( c - 'A' );
	else if ( c >= 'a' && c <= 'f' )
		return 67108864 << ( c - 'a' );

	return 0;
}

void arprintf( CArchive &ar, char *buffer, ... )
{
	char buf[10000];
	va_list args;

	va_start( args, buffer );
	vsprintf( buf, buffer, args );
	ar.WriteString( buf );
	va_end( args );
}

char *fwrite_flag( long flags, char buf[] )
{
    char offset;
    char *cp;

    buf[0] = '\0';

    if ( flags == 0 )
    {
	strcpy( buf, "0" );
	return buf;
    }

    /* 32 -- number of bits in a long */

    for ( offset = 0, cp = buf; offset < 32; offset++ )
	if ( flags & ( (long)1 << offset ) )
	{
	    if ( offset <= 'Z' - 'A' )
		*(cp++) = 'A' + offset;
	    else
		*(cp++) = 'a' + offset - ( 'Z' - 'A' + 1 );
	}

    *cp = '\0';

    return buf;
}

char *fix_string( const char *str )
{
    char strfix[10000];
    int s, d;

    numbuf++;
    if ( numbuf > 9 ) numbuf = 0;

    if ( str == NULL )
        return '\0';

	strcpy( strfix, str );
	for ( s = d = 0; strfix[s]; s++ )
    {
        if (strfix[s] != '\r' && strfix[s] != '~')
	        strfix[d++] = strfix[s];
    }
	strfix[d] = 0;

    strcpy( tempbuf[numbuf], strfix );
    return tempbuf[numbuf];
}

char *format_string( const char *oldstring )
{
  char xbuf[10000];
  char xbuf2[10000];
  char buf[10000];
  char *rdesc;
  int i=0;
  bool cap=TRUE;

  numbuf++;
  if ( numbuf > 9 ) numbuf = 0;

  xbuf[0]=xbuf2[0]=0;

  i=0;

  strcpy( buf, oldstring );
  for (rdesc = buf; *rdesc; rdesc++)
  {
    if (*rdesc=='\n')
    {
      if (xbuf[i-1] != ' ')
      {
        xbuf[i]=' ';
        i++;
      }
    }
    else if (*rdesc=='\r') ;
    else if (*rdesc==' ')
    {
      if (xbuf[i-1] != ' ')
      {
        xbuf[i]=' ';
        i++;
      }
    }
    else if (*rdesc==')')
    {
      if (xbuf[i-1]==' ' && xbuf[i-2]==' ' &&
          (xbuf[i-3]=='.' || xbuf[i-3]=='?' || xbuf[i-3]=='!'))
      {
        xbuf[i-2]=*rdesc;
        xbuf[i-1]=' ';
        xbuf[i]=' ';
        i++;
      }
      else
      {
        xbuf[i]=*rdesc;
        i++;
      }
    }
    else if (*rdesc=='.' || *rdesc=='?' || *rdesc=='!') {
      if (xbuf[i-1]==' ' && xbuf[i-2]==' ' &&
          (xbuf[i-3]=='.' || xbuf[i-3]=='?' || xbuf[i-3]=='!')) {
        xbuf[i-2]=*rdesc;
        if (*(rdesc+1) != '\"')
        {
          xbuf[i-1]=' ';
          xbuf[i]=' ';
          i++;
        }
        else
        {
          xbuf[i-1]='\"';
          xbuf[i]=' ';
          i++;
          rdesc++;
        }
      }
      else
      {
        xbuf[i]=*rdesc;
        if (*(rdesc+1) != '\"')
        {
          if ( *(rdesc+1) != '.' )
          {
            xbuf[i+1]=' ';
            i += 2;
          }
		  else i++;
        }
        else
        {
          xbuf[i+1]='\"';
          xbuf[i+2]=' ';
          i += 3;
          rdesc++;
        }
      }
      cap = TRUE;
    }
    else
    {
      xbuf[i]=*rdesc;
      if ( cap )
        {
          cap = FALSE;
          xbuf[i] = toupper( xbuf[i] );
        }
      i++;
    }
  }
  xbuf[i]=0;
  strcpy(xbuf2,xbuf);

  rdesc=xbuf2;

  xbuf[0]=0;

  for ( ; ; )
  {
    for (i=0; i<77; i++)
    {
      if (!*(rdesc+i)) break;
    }
    if (i<77)
    {
      break;
    }
    for (i=(xbuf[0]?76:73) ; i ; i--)
    {
      if (*(rdesc+i)==' ') break;
    }
    if (i)
    {
      *(rdesc+i)=0;
      strcat(xbuf,rdesc);
      strcat(xbuf,"\n\r");
      rdesc += i+1;
      while (*rdesc == ' ') rdesc++;
    }
    else
    {
      *(rdesc+75)=0;
      strcat(xbuf,rdesc);
      strcat(xbuf,"-\n\r");
      rdesc += 76;
    }
  }
  while (*(rdesc+i) && (*(rdesc+i)==' '||
                        *(rdesc+i)=='\n'||
                        *(rdesc+i)=='\r'))
    i--;
  *(rdesc+i+1)=0;
  strcat(xbuf,rdesc);
  if (xbuf[strlen(xbuf)-2] != '\n')
    strcat(xbuf,"\n\r");

  strcpy( tempbuf[numbuf], xbuf );
  return tempbuf[numbuf];
}