
// ArticleDisplay.m -

#import "ArticleDisplay.h"

static const char *fieldNames[FIELD_COUNT] = {
  "Date", "Followup-to", "Newsgroups", "Subject", "Summary", "Keywords",
  "Organization", "From", "Reply-To"
};

@implementation ArticleDisplay

+ new
{
  self = [super new];
  
  return self;
}

- setupNNTP:(FILE *)newnntpFile
{
  nntpFile = newnntpFile;
}

- clear
{
  int	fieldIndex;
  
  for (fieldIndex=0; fieldIndex<FIELD_COUNT; fieldIndex++)
    [field[fieldIndex] setStringValue:""];
  [bodyText setText:""];
}

- readArticle
{
  int		inCode;
  char		inCodeText[BUFFER_SIZE];
  int		ch;
  char		aLine[BUFFER_SIZE];
  int		aLineLength, charIndex;
  char		fieldName[BUFFER_SIZE];
  int		fieldIndex;
  BOOL		found;
  int		newLines;
  static char	*textBuffer;
  static int	textBufferLines = 0;
  int		textBufferOffset;

  if (selectedArticle == nil)
    return self;

  [bodyText setText:""];

  // HEAD
  fprintf(nntpFile, "head %ld\r\n", selectedArticle->number);
  fflush(nntpFile);
  fseek(nntpFile, (long)0, SEEK_END);

  fscanf(nntpFile, "%d %[^\r]\r\n", &inCode, &inCodeText);

  if (inCode != OK_HEAD)
    printf("No way, fix me HEAD2.\n"); // fix
    
  for (fieldIndex=0; fieldIndex<FIELD_COUNT; fieldIndex++)
    bogusField[fieldIndex] = TRUE;
  while ((ch = fgetc(nntpFile)) != '.') {
    ungetc(ch, nntpFile);
    fscanf(nntpFile, "%[^\r]\r\n", &aLine);

    sscanf(aLine, "%[^:]:", fieldName);
    
    for (found=FALSE,fieldIndex=0; (!found) && (fieldIndex<FIELD_COUNT);
				fieldIndex++)
      if (strcmp(fieldName, fieldNames[fieldIndex]) == 0) {
        [field[fieldIndex] setStringValue:aLine];
	bogusField[fieldIndex] = FALSE;
	found = TRUE;
      }
    if (!found) {
      if (strcmp(fieldName, "Lines") == 0) {
        sscanf(aLine, "Lines: %d", &newLines);
      }
    }
  }
  for (fieldIndex=0; fieldIndex<FIELD_COUNT; fieldIndex++)
    if (bogusField[fieldIndex]) {
      [field[fieldIndex] setStringValue:""];
    }
  fgetc(nntpFile);	// \r
  fgetc(nntpFile);	// \n
  fseek(nntpFile, (long)0, SEEK_END);

  // BODY
  fprintf(nntpFile, "%s\r\n", (verbose?"article":"body"));
  fflush(nntpFile);
  fseek(nntpFile, (long)0, SEEK_END);

  fscanf(nntpFile, "%d %[^\r]\r\n", &inCode, &inCodeText);

  if (inCode != (verbose?OK_ARTICLE:OK_BODY))
    printf("No way, fix me HEAD3.\n"); // fix
    
  if (textBufferLines == 0)
    textBuffer = calloc(newLines, BUFFER_SIZE);
  else
    textBuffer = realloc(textBuffer, newLines*BUFFER_SIZE);
  textBufferLines = newLines;
    
  textBufferOffset = 0;
  while (((ch = fgetc(nntpFile)) != '.') || ((ch = fgetc(nntpFile)) != '\r')) {
    ungetc(ch, nntpFile);
    if (fscanf(nntpFile, "%[^\r]\r\n", &aLine) == 1)
      aLineLength = strlen(aLine);
    else
      aLineLength = 0;
  
    if (rot) {
      for (charIndex=0; charIndex<aLineLength; charIndex++) {
        if (islower(aLine[charIndex]))
	  aLine[charIndex] = (((aLine[charIndex] - 'a') + 13) % 26) + 'a';
        if (isupper(aLine[charIndex]))
	  aLine[charIndex] = (((aLine[charIndex] - 'A') + 13) % 26) + 'A';
      }
    }
    
    strncpy(&(textBuffer[textBufferOffset]), aLine, aLineLength);
    textBuffer[textBufferOffset+aLineLength] = '\n';
    textBufferOffset += aLineLength+1;
  }
  textBuffer[textBufferOffset] = '\0';
  [bodyText setText:textBuffer];
  fgetc(nntpFile);	// \n
  fseek(nntpFile, (long)0, SEEK_END);

  return self;
}


- setArticle:sender
{
  IconColumnCell	*selectedCell = [sender selectedCell];
  Article		*newSelectedArticle = [selectedCell aux];
  
  if (newSelectedArticle != selectedArticle) {
    selectedArticle = newSelectedArticle;
    
    if (selectedArticle != nil) {
      if (!selectedArticle->seen) {
        [sender cellToggleSeen:selectedCell];
	[sender drawCell:selectedCell];
      }
      [self readArticle];
    } else
      [self clear];
  }
  return self;
}

- setVerbose:sender
{
  verbose = !verbose;
  
//  [sender setText:(verbose?"Hide Header":"Show Header")];
  [self readArticle];
  return self;
}

- setRot:sender
{
  rot = !rot;
  
  [self readArticle];
  return self;
}


- setDateDisplay:anObject
{
  field[DATE] = anObject;
  return self;
}
- setFollowupToTextField:anObject
{
  field[FOLLOWUP_TO] = anObject;
  return self;
}
- setNewsgroupsTextField:anObject
{
  field[NEWSGROUPS] = anObject;
  return self;
}
- setSubjectTextField:anObject
{
  field[SUBJECT] = anObject;
  return self;
}
- setSummaryTextField:anObject
{
  field[SUMMARY] = anObject;
  return self;
}
- setKeywordsTextField:anObject
{
  field[KEYWORDS] = anObject;
  return self;
}
- setOrganizationTextField:anObject
{
  field[ORGANIZATION] = anObject;
  return self;
}
- setFromTextField:anObject
{
  field[FROM] = anObject;
  return self;
}
- setReplyToTextField:anObject
{
  field[REPLY_TO] = anObject;
  return self;
}

- setBodyText:anObject
{
  bodyText = [anObject docView];	// starts as "ScrollText"
  return self;
}


@end
