//
//  myProject.m
//  TA2 hot
//
//  Created by matthew on Sat Apr 05 2003.
//  Copyright (c) 2003 __MyCompanyName__. All rights reserved.
//
#import "MWFile.h"
#import "myProject.h"
#import "MyDocument.h"
#import "tams.h"
#import "utils.h"
#import "myResults.h"
//#import "ctReadChar.h"
#import "tableBrowser.h"
#import "prefBoss.h"
#import "TAMSCharEngine.h"


int menuStringComp(id first, id second, void *key)
{
    return [first caseInsensitiveCompare: second];
}

int aStringComp(id first, id second, void *key)
{
    return [(NSString *) first compare: second];
}

@implementation myProject



- (NSString *)windowNibName
{
    // Override returning the nib file name of the document
    // If you need to use a subclass of NSWindowController or if your document supports multiple NSWindowControllers, you should remove this method and override -makeWindowControllers instead.
    return @"myProject";
}



- (NSData *)dataRepresentationOfType:(NSString *)aType
{
    NSMutableArray *masterArray = [NSMutableArray array];
    // Insert code here to write your document from the given data.  You can also choose to override -fileWrapperRepresentationOfType: or -writeToFile:ofType: instead.
    //make an array
    //add to it a version #
    [masterArray addObject: @"3"];
    //add to it the search file list
    [masterArray addObject: openFiles];
    //add to it the init file
    [masterArray addObject: [initFile path]];
    //add to it the code dictionary
    [masterArray addObject: codeList];
    //serialize it
    return [NSArchiver archivedDataWithRootObject: masterArray];
}

- (BOOL)loadDataRepresentation:(NSData *)data ofType:(NSString *)aType
{
    // Insert code here to read your document from the given data.  You can also choose to override -loadFileWrapperRepresentation:ofType: or -readFromFile:ofType: instead.
    NSMutableArray * masterArray;
    masterArray = [NSUnarchiver unarchiveObjectWithData: data];
    [openFiles addObjectsFromArray: [masterArray objectAtIndex: 1]];
    initFile = [[MWFile alloc] initWithPath: [masterArray objectAtIndex: 2]];
    [codeList addEntriesFromDictionary: [masterArray objectAtIndex: 3]];
    return YES;
}

-(id) init
{
    [super init];
    
    //globals
    
    //multiFileFlag = 0;
    uniqueNumber = 0;
    openFiles = [[NSMutableArray alloc] init];
    searchFiles = [[NSMutableArray alloc] init];
    codeList = [[NSMutableDictionary alloc] init];
    
    //locals
    return self;
}

- (void) shoveWindow
{
    int row;
    
    row = [fileListView selectedRow];
    if([(MWFile *)[openFiles objectAtIndex: row] open] == YES)
    {
        [[[openFiles objectAtIndex: row] filePointer] moveForward];
        //[[openFiles objectAtIndex: row] moveForward];
    }
    else
    {
        id myfile = [[NSDocumentController sharedDocumentController] 
            openDocumentWithContentsOfFile:[[openFiles objectAtIndex: row] path] display:YES];
        [[openFiles objectAtIndex: row] setOpenFile: myfile];
        [myfile setMWFile: [openFiles objectAtIndex: row]];
        [myfile setGWorkBench: self];
        [myfile retain];
    }

}
-(void) openMWFile: (MWFile *) who
{
        id myfile = [[NSDocumentController sharedDocumentController] 
            openDocumentWithContentsOfFile:[who path] display:YES];
        [who setOpenFile: myfile];
        [myfile setMWFile: who];
        [myfile setGWorkBench: self];
        [myfile retain];

}

-(BOOL) mwFileExists: (MWFile *) who
{
    FORALL(openFiles)
    {
        if(who == temp) return YES;
    }
    ENDFORALL;
    return NO;
}
- (void)windowControllerDidLoadNib:(NSWindowController *) aController
{

    [codeListView setTarget: self];
    [codeListView setDoubleAction: @selector(displaySelData)];
    [fileListView setTarget: self];
    [fileListView setDoubleAction: @selector(shoveWindow)];

}
- (void)windowDidLoad
{
}
- (id)initWithWindowNibName:(NSString *)windowNibName
{
    [super init];
     //globals
    //multiFileFlag = 0;
    //gSearchList = [[NSMutableArray alloc] init];
    openFiles = [[NSMutableArray alloc] init];
    searchFiles = [[NSMutableArray alloc] init];
    
    //locals
    return self;
}
 
-(int) emptyF{ return emptyF;}
-(int) exactF {return exactF;}
-(int) rawF {return rawF;}
-(int) simpleF {return simpleF;}

-(MWFile *) getMWFile
{
    int row;
    row = [fileListView selectedRow];
    return [openFiles objectAtIndex: row];
}

-(MWFile *) searchFileName
{
    int row;
    row = [searchListView selectedRow];
    return [searchFiles objectAtIndex: row];
}

/*
-(void) registerWindow: (MyDocument *) who
{
    [openFiles addObject: who];
    [fileListView reloadData];
}
*/

- (void) unregisterWindow: (MyDocument *) who
{
#ifdef TAVER1
    [searchFiles removeObject: who];
    [openFiles removeObject: who];
    if(who == codeSource) 
    {
	gCentralCodeFile = codeSource = nil;
	[codeSourceView setStringValue: @""];
	[codeSourceBox setState: NSOffState];
	/* ideally this too, but could be too slow...
	FORALL(openFiles)
	{
	    [temp updateCodeWindow];
	}
	ENDFORALL;
	*/
	//the alternative
	FORALL(openFiles)
	{
	    [temp zapCodeWindow];
	}
	ENDFORALL;
	
    }
    [fileListView reloadData];
    [searchListView reloadData];
#endif
    FORALL(openFiles)
    {
        if(who == [temp filePointer])
        {
            [temp setPath: [who fileName]];
            [temp setOpenFile: nil];
        }
    }
    ENDFORALL;

}

//may need to change
- (BOOL) isInitFile: (MWFile *) who
{
    if(who == initFile) return YES;
    else return NO;
}

-(NSString *) uniqueString;
{
	return [NSString stringWithFormat: @"TAMSSTRING %d", uniqueNumber++];
}
- (NSMutableArray *) fileList
{
    return openFiles;
}
- (NSMutableArray *) searchList
{
    return searchFiles;
}
- (void) newCode: (NSString *) what definition: (NSString *) info
{
    NSMutableDictionary *myEntry;
    NSMutableString *myDef = [[NSMutableString alloc] init];
    
    myEntry = [codeList objectForKey: what];
    if(myEntry)
    {
        [myDef setString: [myEntry objectForKey: @"definition"]];
        [myDef appendString: @" "];
        [myDef appendString: info];
        [myEntry setObject: myDef forKey: what];
    }
    else
    {
        myEntry = [[NSMutableDictionary alloc] init];
        [myDef setString: info];
        [myEntry setObject: myDef forKey: @"definition"];
        [myEntry setObject: @"YES" forKey: @"active"];
        [codeList setObject: myEntry forKey: what];
    }
        
/*        
    
#ifdef TAVER1    
    NSMutableString *s = [[NSMutableString alloc] init];
     if(!gCentralCodeFile) return;
   //make a proper code out of it
    [s appendString: @"{"];
    [s appendString: what];
    [s appendString: @"}"];
    if([gPrefBoss dateTimeValue])
    {
	[s appendString: [[NSDate date] description]];
	if(info)
	    if([info length])
		[s appendString: @": "];
    }
    if(info)
	[s appendString: info];
    [s appendString: @"{/"];
    [s appendString: what];
    [s appendString: @"}"];
    [s ADDCHAR('\n')];
    
    //send it to the current
    [gCentralCodeFile appendString: s];
    //update the masses
    [gCentralCodeFile refreshCodeList: self];
    FORALL(openFiles)
    {
	[temp updateCodeWindow];
    }
    ENDFORALL;
#endif */
}

/*
- (IBAction)centralCode:(id)sender
{
    if([sender state] == NSOffState)
    {
	gCentralCodeFile = nil;
    }
    else
    {
	if(codeSource)
	    gCentralCodeFile = codeSource;
	else
	    [sender setState: NSOffState];
    }
}
*/

- (IBAction)clearSearch:(id)sender
{
    [searchStringView setStringValue: @""];
}

- (IBAction)doAdd:(id)sender
{
    //don't add the init file
    if([self isInitFile: [self getMWFile]] == YES) return;
   [searchFiles addObject: [self getMWFile]]; 
   [searchListView reloadData];
}

- (IBAction)doAddAll:(id)sender
{
    [self doRemoveAll: self];
    [searchFiles addObjectsFromArray: openFiles];
    if(initFile)
    {
	[searchFiles removeObject: initFile];
    }
#ifdef TAVER1
    if(gCentralCodeFile)
    {
	[searchFiles removeObject: gCentralCodeFile];
    }
#endif

   [searchListView reloadData];
}

- (IBAction)doRefresh:(id)sender
{
}

- (IBAction)doRemove:(id)sender
{
    [searchFiles removeObject: [self searchFileName]];
    [searchListView reloadData];
}

- (IBAction)doRemoveAll:(id)sender
{
    [searchFiles removeAllObjects];
    [searchListView reloadData];
}
- (IBAction) setInitFile: (id) sender
{
    MWFile *who;
    who = [self getMWFile];
    if (initFile == who)
    {
	[initFileName setStringValue: @""];
	initFile = nil;
    }
    else
    {
	initFile = who;
	[initFileName setStringValue: [who name]];
	[searchFiles removeObject: who];
	[searchListView reloadData];
    }

}

-(NSMutableString *) getDefinition: (NSString *) what
{
    NSMutableDictionary *myWord;
    
    myWord = [codeList objectForKey: what];
    if(myWord)
        return [myWord objectForKey: @"definition"];
    else
        return [NSMutableString string];

#ifdef TAVER1
           ctQChar *q;
      NSMutableString *ss;
      int inZoneFlag;
    TAMSCharEngine *tce = [[TAMSCharEngine alloc] initWithFileAndStart: gCentralCodeFile];
   if(!gCentralCodeFile) return nil;
   q = [[ctQChar alloc] init];
    [q retain];
    
    //gCurrentDataSource = gCentralCodeFile;
    //clearSearchList();
    //addFileToSearchList(gCentralCodeFile);
    //startSearch();
    inZoneFlag = 0;
    ss = [[NSMutableString alloc] init];
    while([tce readnext: q] != EOF)
    {
	if([q tokentype] == TOKEN)
	{
	    if([[q buff] isEqualToString: what] == YES)
	    {
		inZoneFlag = 1;
	    }
	}
	if([q tokentype] == CHAR && inZoneFlag)
	{
	    [ss appendString: [q buff]];
	}
	if([q tokentype] == ENDTOKEN)
	{
	    if([[q buff] isEqualToString: what] == YES)
	    {
		inZoneFlag = 0;
		[ss ADDCHAR('\n')];
	    }
	}
    }
    [ss autorelease];
    [tce release];
    return ss;
#endif
}

-(IBAction) generateCount: (id) Sender
{
    NSMutableArray *hc;
     NSMutableArray *sl;
   tableBrowser *mt;
    TAMSCharEngine *tce;
#ifdef TAVER1
    if(!gCentralCodeFile)
    {
	NSWARNING(@"You need to establish a central code file.");
	return;
    }
#endif
    sl = [[NSMutableArray alloc] init];
   // [gCentralCodeFile refreshCodeList: nil];
   // gCurrentDataSource = self;
    hc = [NSMutableArray arrayWithArray: [self hotCodeList]];
     //is there anyone to search?
    if(initFile) [sl addObject: initFile];
    [sl addObjectsFromArray: searchFiles];
    if([sl count] == 0) return;
    tce = [[TAMSCharEngine alloc] initWithArrayAndStart: searchFiles];
    //make me the current data source
    mt = [[tableBrowser alloc] init];
    [mt setCharEngine: tce];
    [mt setHotCodeList: hc];
    [mt setDataType: @"count"];
    [NSBundle loadNibNamed: @"FreqCount" owner: mt];
    [mt windowControllerDidLoadNib: nil];

    [[mt window] makeKeyAndOrderFront: self];
    
}
-(IBAction) generateCrossReference: (id) Sender
{
    NSMutableArray *hc;
    tableBrowser *mt;
    NSMutableArray *sl;
     TAMSCharEngine *tce;
    sl = [[NSMutableArray alloc] init];
      
   // gCurrentDataSource = self;
    hc = [NSMutableArray arrayWithArray: [self hotCodeList]];
    //is there anyone to search?
    if(initFile) [sl addObject: initFile];
    [sl addObjectsFromArray: searchFiles];
    if([sl count] == 0) return;
    
    //make me the current data source
    tce = [[TAMSCharEngine alloc] initWithArrayAndStart: sl];

    [tce setGCurrentDataSource: self];
     mt = [[tableBrowser alloc] init];
     [mt setCharEngine: tce];
    [mt setHotCodeList: hc];
    [mt setDataType: @"xref"];
    [NSBundle loadNibNamed: @"FreqCount" owner: mt];
    [mt windowControllerDidLoadNib: nil];

    [[mt window] makeKeyAndOrderFront: self];
    
}

- (IBAction)doSearch:(id)sender
{
    myResults *aa;
    NSDocumentController *who;
    NSMutableArray *sl;
    NSMutableString *myLimStr = [[NSMutableString alloc] init];
     TAMSCharEngine   *tce;
     
    sl = [[NSMutableArray alloc] init];
    
    //set the flags
    if([rawButton state] == NSOnState) rawF = 1; else rawF = 0;
    if([exactButton state] == NSOnState) exactF = 1; else exactF = 0;
    if([emptyButton state] == NSOnState) emptyF = 1; else emptyF = 0;
    if([simpleButton state] == NSOnState)
    {
	int i,ln;
	int sflg;
	char c;
	
	sflg = 1;
	[myLimStr setString: [searchStringView stringValue]];
	trimNSS(myLimStr);
	if([myLimStr isEqualToString: @""])
	    sflg = 1;
	else
	{
	    ln = [myLimStr length];
	    for(i = 0; i < ln; i++)
	    {
		c = [myLimStr characterAtIndex: i];
		//if(c == '*' || c == '+' || c == ',')
		if( c == '+')// || c == ',')
		{
		    sflg = 0;
		    break;
		}
	    }
	    simpleF = sflg;
	    if(simpleF)
		[simpleButton setState: NSOnState];
	    else
		[simpleButton setState: NSOffState];
	}
    }
    else
    {
	simpleF = 0;
	[myLimStr setString: [searchStringView stringValue]];
	trimNSS(myLimStr);
	if([myLimStr isEqualToString: @""])
	    simpleF = 1;
	if(simpleF)
	    [simpleButton setState: NSOnState];
	else
	    [simpleButton setState: NSOffState];
    }
  [myLimStr release];
    
    //is there anyone to search?
    if(initFile) [sl addObject: initFile];
    [sl addObjectsFromArray: searchFiles];
    if([searchFiles count] == 0) 
    {
	NSWARNING(@"Search list is empty");
	return;
    }
    
    //make me the current data source
    tce = [[TAMSCharEngine alloc] initWithArrayAndStart: sl];
    [tce setGCurrentDataSource: self];
 
    //find the controller
    who = [NSDocumentController sharedDocumentController];
    //make the window
    [who setShouldCreateUI: YES];
    //ans = [[myResults alloc] init];
    //[who addDocument: ans];
    aa = [who openUntitledDocumentOfType: @"ViewType" display: YES];
    [aa setGWorkBench: self];
    [aa setCharEngine: tce];
    [aa executeTAMS];
    [aa retain];

}
- (BOOL) fileExists: (NSString *) who
{
    FORALL(openFiles)
    {
        if([who isEqualToString: [temp path]]) return YES;
    }
    ENDFORALL;
    return NO;
    
#ifdef TAVER1
    if([openFiles indexOfObject: who] == NSNotFound)
	return NO;
    else
	return YES;
#endif
}

- (IBAction)myAction:(id)sender
{
}

-(void) back
{
    [myWindow orderBack: self];
}
-(void) front
{
    [myWindow makeKeyAndOrderFront: self];
}
#ifdef TAVER1
- (IBAction)setCodeSource:(id)sender
{
   codeSource =  gCentralCodeFile =[self fileName];
   [codeSourceView setStringValue: [gCentralCodeFile getTitle]];
    [codeSourceBox setState: NSOnState];
//   [gCentralCodeFile remakeCodeList];
   FORALL(openFiles)
   {
	[temp updateCodeWindow];
    }
    ENDFORALL;
    
}
-(void) setCodeSourceWithName: (NSString *) name
{
    int i, cnt;
    FORALL(openFiles)
    {
	if([name isEqualToString: [temp fileName]] == YES)
	{
	    codeSource = gCentralCodeFile = temp;
	    [codeSourceView setStringValue: [gCentralCodeFile getTitle]];
	    [codeSourceBox setState: NSOnState];
	    cnt = [openFiles count];
	    for(i = 0; i < cnt; i++)
	    {
		[[openFiles objectAtIndex: i] updateCodeWindow];
	    }
	    return;
	}
    }
    ENDFORALL;
}
#endif

- (IBAction) setInitFileWithName: (NSString *) fname
{
    FORALL(openFiles)
    {
	if([fname isEqualToString: [temp fileName]] == YES)
	{
	    if(temp == initFile)
	    {
		[initFileName setStringValue: @""];
		initFile = nil;
		return;
	    }
	    initFile = temp;
	    [initFileName setStringValue: [temp getTitle]];
	    [searchFiles removeObject: temp];
	    [searchListView reloadData];
	    return;
	}
    }
    ENDFORALL;

}
/*
	    
- (MyDocument *) codeSource
{
    return codeSource;
}
*/
-(NSString *) theLimitString
{
    return [searchStringView stringValue];
}
-(void) displaySelData
{
    int row;
    NSMutableString *ss, *tt;
    
    ss = [[NSMutableString alloc] init];
    tt = [[NSMutableString alloc] init];
    [ss setString: [searchStringView stringValue]];
    row = [codeListView selectedRow];
    
    [tt setString: [[self hotCodeList] objectAtIndex: row]];
    
    [ss appendString: tt];
    [searchStringView setStringValue: ss];
}

-(NSArray *) hotCodeList
{
    NSMutableArray *hc;
    hc = [NSMutableArray arrayWithArray: [codeList allKeys]];
    [hc sortUsingFunction: aStringComp context: nil];
    [hc autorelease];
    return hc;
}

-(NSArray *) getHotCodeList
{
    NSMutableArray *hc;
    hc = [NSMutableArray arrayWithArray: [codeList allKeys]];
    [hc sortUsingFunction: aStringComp context: nil];
    [hc autorelease];
    return hc;
#ifdef TAVER1
    if(gCentralCodeFile)
    {
	//[gCentralCodeFile setData];
	//[self setData];
	[gCentralCodeFile remakeCodeList];
	return [gCentralCodeFile hotCodeList];
    }
    else
    {
	return nil;
    }
#endif

}


-(NSString *) theWindowName
{
    return [windowNameView stringValue];
}

- (void)windowWillClose:(NSNotification *)aNotification
{
    /* need to do some serious workhere with notifying the other windows */
    //gCentralCodeFile = nil;
    //gWorkBench = nil;

}
- (void)windowDidUpdate:(NSNotification *)aNotification
{
    [fileListView reloadData];
    [codeListView reloadData];
    [searchListView reloadData];
    [codeListView setTarget: self];
    [codeListView setDoubleAction: @selector(displaySelData)];
    [fileListView setTarget: self];
    [fileListView setDoubleAction: @selector(shoveWindow)];
    [[NSApplication sharedApplication] addWindowsItem: myWindow title: @"*Work Bench" filename: NO];

}
-(NSString *) codersList
{
    return [coderIDView stringValue];
}

- (void) openPanelDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCode contextInfo:(void  *)contextInfo
{
    NSArray *theFiles;
    int i, n;
    
    if(returnCode)
    {
        theFiles = [[NSOpenPanel openPanel] filenames];
        n = [theFiles count];
        for(i = 0; i < n; i++)
        {
            [openFiles addObject: [[MWFile alloc] initWithPath: [theFiles objectAtIndex: i]]];
        }
    }
}

-(IBAction) addFileToProj: (id) Sender
{
    [[NSOpenPanel openPanel] setAllowsMultipleSelection: YES];

    [[NSOpenPanel openPanel] beginSheetForDirectory: nil file: nil types:
        [NSArray arrayWithObjects: @"txt", @"rtf", @"RTF", @"TXT", nil]
        modalForWindow: myWindow modalDelegate:self 	didEndSelector:@selector(openPanelDidEnd:returnCode:contextInfo:) 
        contextInfo: nil];


}
@end
