/*
	Converts between ASCII and Flexowriter code.

	(C) Copyright 2001 by Mogens Kjaer


   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
   (at your option) 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
*/

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#define _GNU_SOURCE
#include <getopt.h>

extern char *optarg;
extern int optind, opterr, optopt;

extern unsigned char a2flx(char, int*);
extern unsigned char set_parity(unsigned char);

#define BUFFERSIZE 1024
static char buffer[BUFFERSIZE];
static int blen, bpnt, ateof;

int makesum=0;
int sum=0;

static unsigned char nextchar()
{
  if(bpnt >= blen)
  {
    blen=read(0, buffer, BUFFERSIZE);
    if(blen == 0)
    {
      ateof = 1;
      return 255;
    }
    bpnt = 0;
  }
  return buffer[bpnt++];
}

static void outchar(unsigned char c)
{
  printf("%c", set_parity(c));
  if(makesum)
  {
    sum = (sum + 1 + (int) c)&1023;
  }
}

static void printusage()
{
  fprintf(stderr, "Usage: a2flx [options] <input.asc >output.flx\n");
  fprintf(stderr, "Option:   -s    Include sum code.\n");
}

int main(int argc, char *argv[])
{
  int uppercase, old_uppercase;
  int blen,i,linepos;
  unsigned char c1,c2,c3;
  int opt;
  int sum2;

  while((opt=getopt(argc, argv, "s"))!= -1)
  {
    if(opt == 's') makesum=1;
    else
    {
      printusage();
      exit(-1);
    }
  }

  uppercase=0;
  blen = -1;
  bpnt = 0;
  ateof = 0;
  linepos = 0;

  if(makesum)
  {
    outchar(28);
    sum=0;
  }

  for(;;)
  {
    c1 = nextchar();
    if(ateof) break;

    if(c1 == '\t')
    {
      do
      {
        outchar(0);
	linepos++;
      } while(linepos%8!=0);
    }
    else
    {
      if(c1 == '#')
      {
	c2=0;
	for(i=0; i<3; i++)
	{
	  c1 = nextchar();
	  if(c1<'0' || c1>'9' || ateof)
	  {
	    fprintf(stderr, "Error in #<number> construction. The # sign should be followed by three digits.\n");
	    exit(1);
	  }
	  c2=c2*10+c1-'0';
	}
	if(c2>127)
	{
	  fprintf(stderr, "Error in #<number> construction. Number should be less than 128.\n");
	  exit(1);
	}
      }
      else
      {
	old_uppercase = uppercase;
	c2 = a2flx(c1, &uppercase);

	if(old_uppercase != uppercase)
	{
	  outchar(uppercase?60:58);
	}
      }
      outchar(c2);
      if(c2 == 64)
        linepos=0;
      else
        linepos++;
    }
  }

  if(makesum)
  {
    sum2 = (sum + sum/32)%32 + 31;
    outchar(61);
    outchar((unsigned char) sum2);
  }

  return 0;
}

