/*
        CommandScroll.m
	by Joe Freeman
        Subprocess Example, Release 2.0
        NeXT Computer, Inc.

	You may freely copy, distribute and reuse the code in this example.
	NeXT disclaims any warranty of any kind, expressed or implied, as to
	its fitness for any particular use.
*/

#import "CommandScroll.h"
#import <appkit/nextstd.h>
#import <appkit/Font.h>
#import <appkit/Text.h>

@implementation CommandScroll

- initFrame:(const NXRect *)frameRect
{	
    [super initFrame:frameRect];
    [self setVertScrollerRequired: YES];
    [self setBackgroundGray: NX_WHITE];
    [self awake];
    return self;
}

- awake
    // these initializations implemented here so that this object can be
    // made an IB palatte more easily 
{    
    NXRect textRect;
    id theText;
    
    textRect.origin.x = textRect.origin.y = 0.0;
    [self getContentSize: &(textRect.size)];
    theText =
	[[Text alloc]
	    initFrame:&BgxtRect  text:NULL alignment: NX_LEFTALIGNED];
    [theText notifyAncestorWhenFrameChanged:YES];
    [theText setHorizResizable:NO];
    [theText setVertResizable:YES];
    
    textRect.size.width = 0.0;
    [theText setMinSize:&(textRect.size)];
    [self getContentSize: &(textRect.size)];
    textRect.size.height = 1000000;
    [theText setMaxSize:&(textRect.size)];
    
    [[theText superview] setAutoresizeSubviews:YES];
    [[theText superview] setAutosizing: NX_HEIGHTSIZABLE | NX_WIDTHSIZABLE];
    
    [theText setCharFilter: NXFieldFilter];
    [theText setMonoFont:FALSE];
    [self setDocView: theText];
    machineFont = [Font newFont:"Ohlfs" size:12];
    userFont = [Font newFont:"Courier-Bold" size:13];
    return self;
}

- setDocView:anObject
{
    [super setDocView:anObject];
    docView = anObject;
    [docView setDelegate:self];
    return self;
}

/*==========================================================
 *
 * New method for subclass
 *
 *==========================================================*/
 
- appendString:(char *)buffer
    // append the buffer to the end of the text object
{
    [docView setSel:[docView textLength] :0];
    [docView setSelFont:machineFont];
    [docView replaceSel:buffer];
    [docView scrollSelToVisible];
    lastTextCount = [docView textLength];
    return self;
}

/*==========================================================
 *
 * Text Object Delegation
 *
 *==========================================================*/
 
- (BOOL)textWillChange:textObject 
    // moving the selection to the end before the change means the keys
    // the user hits will always appear at the end of the scroll view
{
    [docView setSel:[docView textLength] :0];
    [docView setSelFont:userFont];
    [docView scrollSelToVisible];
    return NO;
}

- textDidEnd:textObject endChar:(unsigned short)whyEnd  
    // Get this on every Return if using NXFieldFilter
    // really simplistic.  Assumes user does not type ahead
{
    [docView setSel:[docView textLength] :0];
    [docView replaceSel: "\n"];
    lastTextCount = [docView textLength];
    if (delegate && [delegate respondsTo:@selector(userEntered:)])
	[delegate perform:@selector(userEntered:) with:(void *)"\n"];
    return self;
}

- textDidGetKeys:textObject isEmpty:(BOOL)flag 
    // Send each character as it is entered.
    /&Bhe delta calculation is in case the user has backspaced.
{	
    int	delta;		// the difference in this length from previous
    int	theLength;	// current length of text object
    char *theText, miniBuffer[2];
    BOOL mallocedTheText = NO;
    
    theLength = [docView textLength];
    delta = theLength - lastTextCount;
    if (delta > 0)
    {
        theText = (char *)malloc(delta + 1);
        mallocedTheText = YES;
	[docView
	    getSubstring:theText
	    start:([docView textLength]-delta)
	    length:delta];
	theText[delta] = '\0';
    }
    else
    {
        theText = miniBuffer;
	strcpy(theText,"\177");
    }
    if (delegate && [delegate respondsTo:@selector(userEntered:)])
	[delegate perform:@selector(userEntered:) with:(void *)theText];
    lastTextCount = theLength;
    
    if (mallocedTheText) {
        free(theText);
    }
    
    return self;
}

@end
