// QuestionDoc.m
//
// Free software created 30 Nov 1992
// by Paul Burchard <burchard@math.utah.edu>.

#import "Wais.h"
#import "WAISControl.h"
#import "QuestionDoc.h"
#import "IconWell.h"
#import "IconWellControl.h"
#import "BrowserBarChart.h"
#import "string.h"
#import <appkit/appkit.h>


@implementation QuestionDoc

+ (const char *)fileType
{
    return "qst";
}

+ (const char *)nibName
{
    return "QuestionDoc.nib";
}

+ (const char *)miniIconName
{
    return "WaisQuestion.tiff";
}

+ (const char *)defaultFolder
{
    return [[WaisQuestion folderList] elementAt:0];
}

- init
{
    [super init];
    waisQuestion = [[WaisQuestion alloc] initKey:NULL];
    iconWellControl = [[IconWellControl alloc] initWindow:window];
    [[[resultBrowser setAbbreviated:YES] setAlphabetized:NO] setEditable:NO];
    [resultWell setDraggable:YES droppable:NO];
    [[[similarBrowser setAbbreviated:YES] setAlphabetized:YES] setEditable:YES];
    [similarWell setDraggable:YES droppable:YES];
    [[[sourceBrowser setAbbreviated:YES] setAlphabetized:YES] setEditable:YES];
    [sourceWell setDraggable:YES droppable:YES];
    [[[keyWordField docView] setDelegate:self] setSelectable:YES];
    [[keyWordField docView] setCharFilter:(NXCharFilterFunc)NXFieldFilter];
    [window makeFirstResponder:[keyWordField docView]];
    [[keyWordField docView] setSel:0 :0];
    return self;
}

- free
{
    [waisQuestion free];
    [iconWellControl free];
    return [super free];
}

- textDidEnd:sender endChar:(unsigned short)whyEnd
{
    // Search when user hits Return in text window.
    if(whyEnd == NX_RETURN) [searchButton performClick:self];
    
    // Return first responder status back to text object.
    [window makeFirstResponder:[keyWordField docView]];
    [[keyWordField docView] setSel:0 :0];
    return self;
}

- updateToWindow
{
    int i, j, n;
    id theList, doc;
    
    // Report keywords.
    if([waisQuestion valueForStringKey:":seed-words"])
    	[[keyWordField docView] setText:[waisQuestion 
	    valueForStringKey:":seed-words"]];

    // Report sources.
    theList = [waisQuestion sourceList];
    n = [theList count];
    [sourceBrowser clear];
    for(i=0; i<n; i++) [sourceBrowser addEntry:[[theList objectAt:i] key]];
    [sourceBrowser update];

    // Report relevant docs.
    theList = [waisQuestion relevantList];
    n = [theList count];
    [similarBrowser clear];
    for(i=0; i<n; i++) [similarBrowser addEntry:[[theList objectAt:i] key]];
    [similarBrowser update];

    // Report result documents and their scores.
    theList = [waisQuestion resultList];
    n = [theList count];
    [resultBrowser clear];
    for(i=0; i<n; i++)
    {
    	doc = [theList objectAt:i];
    	j = [resultBrowser indexAddEntry:[doc key]];
	[resultBrowser setBarValue:[waisQuestion scoreForDocument:doc] at:j];
    }
    [resultBrowser update];
    return self;
}

- updateFromWindow
{
    int i;
    const char *dockey, *srckey;
    char buf[MAX_QUERY_SIZE+1];
    id doc, source, stringTable;

    // Update keywords.
    [window setDocEdited:YES];
    [[keyWordField docView] getSubstring:buf start:0 length:MAX_QUERY_SIZE];
    [waisQuestion setKeywords:buf];
    
    // Update relevant document list.
    // Load in any unknown new docs.
    // Ignore doc if it is still being retrieved (to avoid thread collisions).
    [waisQuestion clearRelevantDocuments];
    for(i=0; dockey=[similarBrowser entryAt:i]; i++)
    {
    	if(!(doc = [WaisDocument objectForKey:dockey]))
	{
	    doc = [[WaisDocument alloc] initKey:dockey];
	    if(![doc readWaisFile]) 
	    {
	    	[doc free];
		stringTable = [[NXApp delegate] stringTable];
		if(stringTable) NXRunAlertPanel(
		    [stringTable valueForStringKey:"WAIS Question Error!"],
		    [stringTable valueForStringKey:
			"Can't find WAIS specifications for document %s"],
		    [stringTable valueForStringKey:"OK"], NULL, NULL, dockey);
		continue;
	    }
	}
	if(![[NXApp delegate] isDocumentBeingRetrieved:doc])
	    [waisQuestion addRelevantDocument:doc];
    }
    
    // Update source list.
    // Load in any unknown new sources.
    [waisQuestion clearSources];
    for(i=0; srckey=[sourceBrowser entryAt:i]; i++)
    {
    	if(!(source = [WaisSource objectForKey:srckey]))
	{
	    source = [[WaisSource alloc] initKey:srckey];
	    if(![source readWaisFile])
	    {
	    	[source free];
		stringTable = [[NXApp delegate] stringTable];
		if(stringTable) NXRunAlertPanel(
		    [stringTable valueForStringKey:"WAIS Question Error!"],
		    [stringTable valueForStringKey:
			"Can't find WAIS specifications for source %s"],
		    [stringTable valueForStringKey:"OK"], NULL, NULL, srckey);
		continue;
	    }
	}
	[waisQuestion addSource:source];
    }
    return self;
}

- dump:sender
{
    if(!fileName) return nil;
    [self updateFromWindow];
    if(![waisQuestion writeWaisFile]) return nil;
    return self;
}

- load:sender
{
    if(!fileName) return nil;
    if(![waisQuestion readWaisFile]) return nil;
    [self updateToWindow];
    return self;
}

- setFileName:(const char *)aName
{
    id rtn = [super setFileName:aName];
    if(rtn) [waisQuestion setKey:fileName];
    return(rtn);
}

- search:sender
{
    [self updateFromWindow];
    if(![waisQuestion search]) return nil;
    [self updateToWindow];
    return self;
}

- (int)prepFile:(const char *)fileKey ok:(int *)flag
{
    // Begin retrieval of documents as they are dragged out.
    *flag = NO;
    if(![[NXApp delegate] retrieveDocuments:fileKey]) return 0;
    *flag = YES;
    return 0;
}

- (int)openFile:(const char *)fileKey ok:(int *)flag
{
    id rtn, doc, source;
    
    // If known source, open in this application.
    if(source = [WaisSource objectForKey:fileKey])
	return [[NXApp delegate] openFile:fileKey ok:flag];
    
    // If retrieved document, open in this application (and so in Workspace).
    // If unretrieved document, call WAIS to retrieve.
    if(doc = [WaisDocument objectForKey:fileKey])
    {
    	if([[NXApp delegate] isDocumentBeingRetrieved:doc])
	    return 0;
    	if([doc isRetrieved])
	    return [[NXApp delegate] openFile:fileKey ok:flag];
	else
	{
	    rtn = [[NXApp delegate] retrieveDocuments:[doc key]];
	    if(rtn) *flag = YES;
	    else *flag = NO;
	    return 0;
	}
    }
    
    // Unknown file key---ignore.
    return 0;
}

@end


