/****************************************************************************
 *   Copyright (C) 2004 by Arboretum Systems, Inc.                          *
 *   Technical administrator: Alain Mazy, hav@mazy.be                       *
 *   Lead program designer: Georges Jaroslaw, gjaro@arboretum.com           *
 *                                                                          *
 *   HyperEngine-AV is a video, audio and text editor that can be used to   *
 *   record, import, edit, process and arrange together video, sound and    *
 *   text. These are all achieved in the program's free-form document       *
 *   window, with no limitations to the number of tracks.                   *
 *   The purpose of this program is to provide to users at all levels of    *
 *   expertise a readily accessible tool enabling them to create movies,    *
 *   slide shows or presentations.                                          *
 *                                                                          *
 *   HyperEngine-AV itself is free software. However, plug-ins that can be  *
 *   used as add-ons to HyperEngine-AV may or may not be free software, at  *
 *   the discretion of each plug-in developer and as specified by these     *
 *   plug-ins' respective licenses.                                         *
 *   You can redistribute HyperEngine-AV itself 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.                                             *
 *                                                                          *
 *   HyperEngine-AV 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 all applicable details.                 *
 *                                                                          *
 *   You should have received a copy of the GNU General Public License      *
 *   along with this program; if not, write to:                             *
 *   Free Software Foundation, Inc.,                                        *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.              *
 ****************************************************************************/

#import "MITopLevelContainerRep.h"
#import "MIObject.h"
#import "MIObjectRep.h"
#import "MIMainViewController.h"
#import "MIWSSelection.h"
#import "TArmeWSObj.h"
#include <regex.h>

#import "MIFindDlgController.h"

@implementation MIFindDlgController

+ (id)sharedFindController
{
    static id sharedFindController = nil;
    if ( !sharedFindController )
	{
        sharedFindController = [[self alloc] initWithWindowNibName:@"MIFindDlg"];
    }
    return sharedFindController;
}

- (id)init
{
	self = [super init];
	
	fLastResult = nil;
	fTLC = nil;
	fSelectAll = NO;
	
	return self;
}

- (IBAction)findBoxCliqued:(id)sender
{
	fLastResult = nil;
	
	[self findAgain];
	[self close];
}

- (void)setTLC:(MITopLevelContainerRep*)tlc
{
	fTLC = tlc;
}

- (void)findAgain
{
	BOOL matched = NO;
	fSelectAll = NO;
	fNewResult = nil;
	// look for next result
	
	if ( !fTLC )
		NSBeep();
		
	matched = [self findInChildrenOfObject:[fTLC representedObject]];
	
	if ( !matched && fLastResult )
	{
		fLastResult = nil;
		matched = [self findInChildrenOfObject:[fTLC representedObject]];
	}
	
	if ( !matched )
		NSBeep();
		
	fLastResult = fNewResult;

	// select it
	if ( fNewResult )
	{
		[[[fTLC mainViewController] selection] clear];
		[[fTLC mainViewController] addObjectToSelection:fNewResult];
		
		// make it visible
		
		[fTLC scrollRectToVisible:[fNewResult getTLCFrame]];
	}
	
}

- (BOOL)findInChildrenOfObject:(MIObject*)obj
{
	NSEnumerator	*childEnum;
	MIObjectRep		*aChild;
	BOOL			matched = NO;
	BOOL			lastFound = NO;
	int				extraCrit = 0;
	BOOL			stringFound = NO;
/*
	regex_t			*prog = malloc(sizeof(regex_t));
	int				status;
	long unsigned	numRes;
*/
	
	if ( !fLastResult )
		lastFound = YES;
	
	childEnum = [[obj getChildren] objectEnumerator];
	
	if ( [fIgnoreCaseCheckBox state] == NSOnState )
		extraCrit = NSCaseInsensitiveSearch;

/*	
	if ( [[fSearchType cellWithTag:1] state] == NSOnState && ![[fFindText stringValue] isEqualToString:@""])
		status = regcomp( prog, [[fFindText stringValue] cString], REG_BASIC);
*/	
	while ( (aChild = [[childEnum nextObject] findRepresentationInTLC:fTLC]) && !matched )
	{
/*	
		if ( [[fSearchType cellWithTag:1] state] == NSOnState )
		{
//				stringFound = regexec(prog, [[[aChild representedObject] title] cString]);
				stringFound = !regexec(prog, [[[aChild representedObject] title] cString], numRes, NULL, 0);
//int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags);
		}
		else
*/
		{
			if ([[fFindText stringValue] isEqualToString:@""] ||
				[[[aChild representedObject] title] rangeOfString:[fFindText stringValue] options:extraCrit].location != NSNotFound )
				stringFound = YES;
			else
				stringFound = NO;
		}
		
		
		if ( stringFound )
		{
			SInt32	type = [[aChild representedObject] getType];

			if (	(type == (TArmeWSObj::kContainer) && [[fObjectTypeMatrix cellWithTag:5] state] == NSOnState )
				||	(type == (TArmeWSObj::kAudioProcessor) && [[fObjectTypeMatrix cellWithTag:3] state] == NSOnState )
				||	(type == (TArmeWSObj::kAudioClip) && [[fObjectTypeMatrix cellWithTag:0] state] == NSOnState )
				||	(type == (TArmeWSObj::kVideoClip) && [[fObjectTypeMatrix cellWithTag:1] state] == NSOnState )
				||	(type == (TArmeWSObj::kTextClip) && [[fObjectTypeMatrix cellWithTag:2] state] == NSOnState )
				||	(type == (TArmeWSObj::kVideoEffect) && [[fObjectTypeMatrix cellWithTag:4] state] == NSOnState )
				||	(type == (TArmeWSObj::kVideoXFadeEffect) && [[fObjectTypeMatrix cellWithTag:4] state] == NSOnState ) )
			{
				if ( fSelectAll )
				{
					[[fTLC mainViewController] addObjectToSelection:aChild];
				}
				else
				{
					if ( aChild == fLastResult )
						lastFound = YES;
					else if ( lastFound )
					{
						fNewResult = aChild;
						matched = YES;
					}
				}
			}
		}
		
		if ( !matched )
		{
			matched = [self findInChildrenOfObject:[aChild representedObject]]; 
		}
	}
/*
	if ( prog )
		free(prog); // has been malloc'ed, can be freed safely (see "man regexp" for more info) 
*/
	
	return matched;
}

- (IBAction)selectAllMatches:(id)sender
{
	if ( !fTLC )
		NSBeep();
	
	fSelectAll = YES;
	[self findInChildrenOfObject:[fTLC representedObject]];
	fSelectAll = NO;
	
	[self close];
	fLastResult = nil;
}


@end