/*
 *   This sourcecode is part of FileSpy, a logfile observing utility.
 *   Copyright (C) 1996  Felix Rauch
 *
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *   
 *   Notice that this program may not be possessed, used, copied,
 *   distributed or modified by people having to do with nuclear
 *   weapons. See the file CONDITIONS for details.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *   You should have received a copy of the GNU General Public License
 *   along with this program; if not, write to the Free Software
 *   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 *
 *   To contact the original author, try:
 *   e-mail: Felix.Rauch@nice.ch
 *   Traditional mail:	Felix Rauch
 *			Sempacherstrasse 33
 *			8032 Zurich
 *			Switzerland
 */

#import "Finder.h"

@implementation Finder

- init
{
    [super init];

    ignoreCase = YES;
    scopeAll = NO;
    if(!findPanel) {
	if(![NXApp loadNibSection:"Findpanel.nib" owner:self withNames:NO fromZone:[self zone]]) {
	    NXLogError("Can't open Preferences.nib!");
	}
    }
    return self;
}

- setDelegate:sender
{
    delegate = sender;
    return self;
}

- caseClick:sender
{
    ignoreCase = [sender state] ? YES : NO;
    return self;
}

- findNext:sender
{
    [self findText:NO];
    return self;
}

- findPrevious:sender
{
    [self findText:YES];
    return self;
}

- findText:(BOOL)backwardsflag
{
    NXSelPt start, end;
    unsigned int i, max;
    const id textList = [delegate findTexts:scopeAll];
    BOOL succesful = NO;

    if(textList == nil) {
	NXBeep();
	return self;
    }
    max = [textList count];
    for(i = 0; i < max; i++) {
	[[textList objectAt:i] getSel:&start :&end];
	if(!backwardsflag)
	    [[textList objectAt:i] setSel:end.cp :end.cp];	// search from end of last selection
	else
	    [[textList objectAt:i] setSel:start.cp :start.cp];	// search from start of last sel. backwards
	if([[textList objectAt:i] findText:[myFormCell stringValue]
				ignoreCase:ignoreCase
				backwards: backwardsflag
				wrap: YES] == YES) {
	    [[[[textList objectAt:i] delegate] window] orderFront:self];
	    succesful = YES;
	    break;
	}
    }
    [textList free];
    if(!succesful) {
	NXBeep();
	[findStatusText setStringValue:"Not found"];
	[findForm selectTextAt:0];
    } else {
	[findStatusText setStringValue:""];
    }
    return self;
}

- scopeClick:sender
{
    scopeAll = ([[sender selectedCell] tag] == 0) ? NO : YES;
    return self;
}

- showFindPanel:sender
{
    [findStatusText setStringValue:""];
    [findPanel makeKeyAndOrderFront:self];
    return self;
}

- window
{
    return myWindow;
}

- formCell
{
    return myFormCell;
}

- windowDidBecomeKey:sender
{
    [findForm selectTextAt:0];
    return self;
}

/* taken from Yapp's FindPanel.m */

// In case the selection is shorter than this amount, we use a local buffer 
// (on the stack) rather than bothering with allocating it.

#define LOCALBUFFERLEN 100

- enterSelection:sender
{
    id obj = [self firstResponderText];

    if (!obj) {
	NXBeep();
    } else {
	char localBuffer[LOCALBUFFERLEN+1], *str;
	NXSelPt from, to;
	int bufLen; 
    
	[obj getSel:&from :&to];
	bufLen = to.cp - from.cp;
	str = (bufLen <= LOCALBUFFERLEN) ? localBuffer : NXZoneMalloc(NXDefaultMallocZone(), bufLen+1);
	    
	[obj getSubstring:str start:from.cp length:bufLen];
	str[bufLen] = '\0';
//	[self setFindString:str];
	[myFormCell setStringValue:str];
//	[myFormCell selectText:self];
	if (str != localBuffer)
	    free(str);
    }

    return self;
}

- firstResponderText
{
    id obj = [[NXApp mainWindow] firstResponder];
    return (obj && [obj isKindOf:[Text class]]) ? obj : nil;
}

@end
