// -------------------------------------------------------------------------------------
// TestClass.m
// -------------------------------------------------------------------------------------

#import <appkit/appkit.h>
#import <libc.h>
#import <stdlib.h>
#import <string.h>
#import "ScrollText.h"
#import "ReadConfig.h"
#import "TestClass.h"

// -------------------------------------------------------------------------------------
@implementation TestClass

// -------------------------------------------------------------------------------------
// application initialization
// -------------------------------------------------------------------------------------

/* new application */
+ new
{
    objectThreadPerformInit();
    return [super new];
}

/* application initialization */
- appDidInit:sender
{
    
    /* make an italic font from the Text objects normal font */
    fontNormal = [[myScrollText docView] font];
    fontItalic = [[FontManager new] convert:fontNormal toHaveTrait:NX_ITALIC];
    
    /* init thread count and start ReadConfig */
    threadCount = 0;
    [ReadConfig readAppConfig:"testConfig.cfg" target:self];
    
    return self;
}

// -------------------------------------------------------------------------------------
// outlets
// -------------------------------------------------------------------------------------

- setScrollView:anObject
{
    myScrollText = [ScrollText newScrollText:anObject];
    [myScrollText clearScrollText];
    return self;
}

// -------------------------------------------------------------------------------------
// thread support routines
// -------------------------------------------------------------------------------------

/* secondary thread routine */
- testThread:(char*)string
{
    int i;

    [myScrollText setTextAttributeGray:NX_DKGRAY];
    textPrintf(myScrollText, "\nTest thread started...\n\n");
    
    [myScrollText setTextAttributeGray:NX_BLACK];
    textPrintf(myScrollText, "(from cfg file) => ");
    [myScrollText setTextAttributeFont:fontItalic];
    textPrintf(myScrollText, "%s\n", string);
    [myScrollText setTextAttributeFont:fontNormal];

    textPrintf(myScrollText, "\nI can also print in ");
    [myScrollText setTextAttributeGray:NX_LTGRAY];
    textPrintf(myScrollText, "Light-Gray, ");
    [myScrollText setTextAttributeColor:NX_COLORRED];
    textPrintf(myScrollText, "or Red, ");
    [myScrollText setTextAttributeColor:NX_COLORBLUE];
    textPrintf(myScrollText, "or Blue, ");
    [myScrollText setTextAttributeGray:NX_BLACK];
    textPrintf(myScrollText, "etc.\n\n");
    
    for (i = 1; i <= 5; i++) textPrintf(myScrollText, "Test Record #%d\n", i);
    textPrintf(myScrollText, "\n");
    
    [myScrollText setTextAttributeGray:NX_DKGRAY];
    textPrintf(myScrollText, "Test thread terminating...\n");
    
    free(string);
    
    [self mainThreadPerform:@selector(threadIsDone) wait:YES];
    
    return self;
}

/* main thread routine */
- threadIsDone
{

    /* decrement thread count */
    threadCount--;
    
    /* this just makes sure everying has been displayed */
    NXPing();
    
    return self;
}

// -------------------------------------------------------------------------------------
// config file routines
// Note: The two string print methods below are for example purposes only.  It is
// generally not a good idea to mix printing from two separate threads into one Text
// object because may be difficult to control the order in which the lines are printed.
// -------------------------------------------------------------------------------------

/* print string from main thread */
- (int)printString:(char*)string
{
    [myScrollText setTextAttributeFont:fontItalic];
    textPrintf(myScrollText, "main thread ", string);
    [myScrollText setTextAttributeFont:fontNormal];
    textPrintf(myScrollText, "=> %s\n", string);
    return NO;
}

/* print string from secondary thread */
- (int)printFromThread:(char*)string
{

    /* example to return an error to ReadConfig */
    if (threadCount) {  // only one thread at a time
        NXLogError("TestClass: A thread is already running...");
        return YES;
    }
    
    /* count and start thread */ 
    threadCount++;
    [self forkPerform:@selector(testThread:) with:(id)NXCopyStringBuffer(string) detach:YES];
    
    return NO;
}

@end
