#import "Appender.h"
#import <appkit/Application.h>
#import <appkit/ScrollView.h>
#import <appkit/Text.h>
#import <dpsclient/dpsclient.h>
#import <appkit/publicWraps.h>
#import <strings.h>

#define BlinkRate 1.		// one second

static void blink(DPSTimedEntry teNumber, double now, char *userData)
{
    id person = (Appender *)userData;

    [person blinkDude];
};

@implementation Appender

- init;
{
    [super init];

    [NXApp loadNibSection:"HandleDeputy.nib" owner:self];
    currentPosition = 0;

    strcpy(theChars, "_");
    
    DPSAddTimedEntry(BlinkRate, (DPSTimedEntryProc)blink, 
		     (void *)self, NX_BASETHRESHOLD);
    return self;
};

//appends the string passed to the doc view of the scroll view
- appendToText:(const char *)newText
{
    static char cleanText[1024];
    int backLength=0;

    strcpy(cleanText, newText);
    [self textFilter:cleanText:&backLength];
    [[scrollView docView] setSel:currentPosition :currentPosition+backLength+1];
    [[scrollView docView] replaceSel:cleanText];
    [[scrollView docView] scrollSelToVisible];
    currentPosition += strlen(cleanText);
    currentPosition -= backLength;
    return self;
}

- blinkDude;
{
    if (theChars[0] == '_') theChars[0] = ' ';
    else theChars[0] = '_';

    [[scrollView docView] setSel:currentPosition :currentPosition + 1];
    [[scrollView docView] replaceSel:theChars];

    return self;
};
	
- docView;
{
    return [scrollView docView];
}

#define BEEP       '\x007'
#define BACKSPACE  '\x008'
#define SX         '\x002'	// erase left character, I guess

- textFilter: (char *)filtrate: (int *)length;
{
    int i, j;
    unsigned int numBackSpace = 0;

    for (i = 0, j = 0; i < strlen(filtrate); i++)
	{
	switch (filtrate[i])
	    {
	  case BEEP:
	    NXBeep();
	    break;
	  case BACKSPACE:
	  case SX:
	    if (numBackSpace % 2) currentPosition--;
	    numBackSpace++;
	    break;
	  default:
	    filtrate[j++] = filtrate[i];
	    break;
	    }
	}

    filtrate[j] = 0;
    *length = numBackSpace / 2;
    return self;
};

- inputToApp:(char *)in;
{
    [super inputToApp:in];

    return self;
};

- outputFromApp:(char *)out;
{
#ifdef Debug
    {
    int i;

    printf("<<");
    for (i = 0; i < strlen(out); i++)
	printf("%x,", out[i]);
    printf(">>");
    fflush(stdout);
    }
#endif

    [self appendToText: out];

    return self;
};

//prints the doc view of the scroll view
- print:sender
{
    [[scrollView docView] printPSCode:self];
    return self;
}

@end
