
// NewsgroupsMatrix.m


#import "NewsgroupsMatrix.h"

@implementation NewsgroupsMatrix

+ newFrame:(const NXRect *)frameRect
{
  self = [super newFrame:frameRect];

  numBitmaps = NEWSGROUP_NUM_BITMAPS;
  [protoCell setNumBitmaps:numBitmaps];

  numColumns = NEWSGROUP_NUM_COLUMNS;
  [protoCell setNumColumns:numColumns];
 
  tabs[0] = NEWSGROUP_TAB_0;
  tabs[1] = NEWSGROUP_TAB_1;
  tabs[2] = NEWSGROUP_TAB_2;
  [self calcTabs];
  
  bogus = TRUE;
  
  return self;
}


#ifdef bugs
- mouseDown:(NXEvent *)thisEvent
{
  int			mouseFlags = [self mouseDownFlags];
  int			shouldLoop = YES;
  int			oldMask;
  NXTrackingTimer	myTimer;
  NXEvent		*nextEvent, lastEvent;

  if (mouseFlags & (NX_SHIFTMASK | NX_ALTERNATEMASK))
    [super mouseDown:thisEvent];
  else {
  oldMask = [window addToEventMask:NX_LMOUSEDRAGGEDMASK];
  lastEvent = *thisEvent;
  NXBeginTimer(&myTimer, 0.05, 0.05);

  while (shouldLoop) { 
    nextEvent = [NXApp getNextEvent:(NX_LMOUSEUPMASK
             | NX_LMOUSEDRAGGEDMASK
             | NX_TIMERMASK)];
    switch (nextEvent->type) { 
    case NX_LMOUSEUP:  
      shouldLoop = NO; 
      break; 
    case NX_LMOUSEDRAGGED:
      lastEvent = *nextEvent;
      break;
    case NX_TIMER:
      [self autoscroll:&lastEvent];
      break;
    default:
      break; 
    }
  }

  NXEndTimer(&myTimer);
  [window setEventMask:oldMask];
  }
  return(self); 
}

 
- ( BOOL ) _mouseHit:(NXPoint * )x row:( int * )y col:( int * )z
{
  int did = [super _mouseHit:x row:y col:z];
  printf("%d mousehit point, row %d col %d\n", did, *y, *z);
  return did;
}
- ( BOOL ) _loopHit:( struct _NXPoint * )x row:( int * )y col:( int * )z ;
{
  int did = [super _loopHit:x row:y col:z];
  printf("%d loophit point, row %d col %d\n", did, *y, *z);
  return did;
}
#endif


- readNewsrc
{
  char		newsrcName[BUFFER_SIZE], buffer[BUFFER_SIZE];
  NXStream	*newsrcStream;
  Newsgroup	*group;


  // read in .newsrc
  sprintf(newsrcName, "%s/%s", NXHomeDirectory(), NEWSRC_NAME);

  [self empty];

  if ((newsrcStream = NXMapFile(newsrcName, NX_READONLY)) == NULL)
    NXRunAlertPanel("News Bulletin",
	"Can't find Newsrc file (%s).  A new one will be created.",
	NULL, NULL, NULL, newsrcName);
  else {
    while ((group = [Newsgroup newFromNewsrc:newsrcStream]) != nil)
      [itemsList addObject:group];

    if ([itemsList count]) {
      bogus = FALSE;
      
      // not empty, so back up .newsrc
      sprintf(buffer, "cp %s %s~", newsrcName, newsrcName);
      system(buffer);
    } 
  
    NXCloseMemory(newsrcStream, NX_FREEBUFFER);
  }
  return self;
}

- writeNewsrc
{
  char		newsrcName[BUFFER_SIZE];
  int		newsrcDescriptor;
  NXStream	*newsrcStream;
  int		itemIndex;
  Newsgroup	*group;



  sprintf(newsrcName, "%s/%s", NXHomeDirectory(), NEWSRC_NAME);

  if (!bogus && [itemsList count]) {
    // write out .newsrc
    newsrcDescriptor = open(newsrcName, O_WRONLY | O_CREAT | O_TRUNC,
			  VREAD | VWRITE);
  
    if (!newsrcDescriptor
	  || !(newsrcStream = NXOpenFile(newsrcDescriptor, NX_WRITEONLY))) {
      NXRunAlertPanel("News Bulletin",
	  "Can't write Newsrc file (%s).  Read messages will be forgotten.",
	  NULL, NULL, NULL, newsrcName);
    } else {
      for (itemIndex = 0; itemIndex < [itemsList count]; itemIndex++) {
	[(Newsgroup *)[itemsList objectAt:itemIndex]
					writeToNewsrc:newsrcStream];
      }
      
      NXClose(newsrcStream);
      close(newsrcDescriptor);
    }
  }
  return self;
}


- setupNNTP:(FILE *)newnntpFile;
{
  int		inCode;
  char		inCodeText[BUFFER_SIZE];
  Newsgroup	*group;
  char		name[BUFFER_SIZE];
  int		ch;
  long		first, last;
  BOOL		post;
  int		addedGroupCount = 0;
  
  nntpFile = newnntpFile;
  fprintf(nntpFile, "list\r\n");
  fflush(nntpFile);
  fseek(nntpFile, (long)0, SEEK_END);

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

  if (inCode != OK_GROUPS) {
    NXRunAlertPanel("News Flash",
	  "Can't get list of Newsgroups from NNTP (but connection is ok).",
	  NULL, NULL, NULL);
    return nil;
  }
  
  while ((ch = fgetc(nntpFile)) != '.') {
    ungetc(ch, nntpFile);
    fscanf(nntpFile, "%s %d %d %c\r\n", &name, &last, &first, &post);

    if ((group = [((HashList *)itemsList)->nameHash
		valueForKey:name]) == nil) {
      group = [Newsgroup newName:name subscribed:TRUE];
      [itemsList insertObject:group at:addedGroupCount];
      addedGroupCount++;
    }

    [group setAvailableFirst:first last:last];
    group->bogus = FALSE;
    group->moderated = !(post == 'y');
    if (group->moderated)
      [group setModerated:group->moderated];
  }
  fgetc(nntpFile);	// \r
  fgetc(nntpFile);	// \n
  fseek(nntpFile, (long)0, SEEK_END);

  [self sendAction];

  if (addedGroupCount) {
    NXRunAlertPanel("News Bulletin",
    		"Added %d new Newsgroups to beginning of Newsrc.",
    		"OK", NULL, NULL, addedGroupCount);
    bogus = FALSE;
  }

  return self;
}


- (BOOL)itemVisible:item
{
  Newsgroup	*group = item;
  BOOL		highlighted = FALSE;
  
  if (group->cell)
    highlighted = [group->cell isHighlighted];
  
  return group->shown = 
		((showUnsubscribed || group->subscribed)
	        && (showNoNewMessages || (group->newMessages > 0))
		|| highlighted)
     		&& !group->bogus;
}

#ifdef NOMORE
- updateCellVisible:(IconColumnCell *)aCell
{
  Newsgroup	*newsgroup = (Newsgroup *)aCell->aux;
  int	row, col;
  BOOL	newShown = [self itemVisible:newsgroup];
  
  if (!newShown) {
    if ([self getRow:&row andCol:&col ofCell:newsgroup->cell] != nil) {
      [self removeRowAt:row andFree:TRUE];
      [self sizeToCells];
    }
  }

  return self;
}
#endif 

- takeGroupFrom:sender
{
  const char	*groupName;
  int		groupNameLength;
  int		i, cellIndex;
  
  groupName = [sender stringValue];
  groupNameLength = strlen(groupName);

  for (i=0, cellIndex = -1; (cellIndex == -1) && (i<numRows); i++) {
    if (strncmp(groupName,
	[((Newsgroup *)((IconColumnCell *)
	((List *)cellList)->dataPtr[i])->aux) name],
    	groupNameLength) == 0)
      cellIndex = i;
  }
  
  [self selectCellAt:cellIndex :0];
  [self sendAction];

  return self;
}


- toggleSubscribed:sender
{
  [self sendAction:@selector(cellToggleSubscribed:) to:self forAllCells:FALSE];
  [[self superview] display];
  return self;
}

- cellToggleSubscribed:(IconColumnCell *)aCell
{
  [((Newsgroup *)aCell->aux) setSubscribed:
  				!((Newsgroup *)aCell->aux)->subscribed];
  return self;
}


- showUnsubscribed:sender
{
  showUnsubscribed = (BOOL)[sender intValue];
  [self sendAction];
  return self;
}

- showNoNewMessages:sender
{
  showNoNewMessages = (BOOL)[sender intValue];
  [self sendAction];
  return self;
}

- selectWayUp:sender
{
  NXBeep();
  return self;
}

- selectWayDown:sender;
{
  NXBeep();
  return self;
}

- catchUp:sender
{
  if (NXRunAlertPanel("News Bulletin",
	"This will junk all articles in selected newsgroups.",
	NULL, "Cancel", NULL) == NX_ALERTDEFAULT) {
    [self sendAction:@selector(cellCatchUp:) to:self forAllCells:FALSE];
    [[self superview] display];
    refreshTarget = TRUE;
    [self sendAction];
  }
  return self;
}

- cellCatchUp:(IconColumnCell *)aCell
{
  Newsgroup	*group = ((Newsgroup *)aCell->aux);

  [group addSeenFirst:group->available.first last:group->available.last];
  return self;
}



- setGroupForm:anObject
{
  groupForm = anObject;
  return self;
}

@end
