//
//	MiscStringSearching.m
//		Written by Don Yacktman (c) 1993 by Don Yacktman.
//				Version 1.7  All rights reserved.
//		This notice may not be removed from this source code.
//
//	This object is included in the MiscKit by permission from the author
//	and its use is governed by the MiscKit license, found in the file
//	"LICENSE.rtf" in the MiscKit distribution.  Please refer to that file
//	for a list of all applicable permissions and restrictions.
//	

#import <misckit/MiscString.h>

@implementation MiscString(Searching)

// This category is composed of methods which search a
// MiscString and return pointers to the start of specific
// substrings within the MiscString.

- (int)spotOf:(char)aChar
{
  return [self spotOf:aChar occurrenceNum:0 caseSensitive:YES];
}

- (int)spotOf:(char)aChar caseSensitive:(BOOL)sense
{
  return [self spotOf:aChar occurrenceNum:0 caseSensitive:sense];
}

- (int)spotOf:(char)aChar occurrenceNum:(int)n
{
  return [self spotOf:aChar occurrenceNum:n caseSensitive:YES];
}

- (int)rspotOf:(char)aChar
{
  return [self rspotOf:aChar occurrenceNum:0 caseSensitive:YES];
}

- (int)rspotOf:(char)aChar caseSensitive:(BOOL)sense
{
  return [self rspotOf:aChar occurrenceNum:0 caseSensitive:sense];
}

- (int)rspotOf:(char)aChar occurrenceNum:(int)n
{
  return [self rspotOf:aChar occurrenceNum:n caseSensitive:YES];
}

- (int)spotOf:(char)aChar occurrenceNum:(int)n caseSensitive:(BOOL)sense
{
  int currnum = -1;
  int count = 0;
  
  if (n<0) return -1;
  
  while ((currnum < n) && (count < length)) {
    if (!sense) {
      if (NXToUpper(buffer[count]) == NXToUpper(aChar)) currnum++;
     }
    else {
      if (buffer[count] == aChar) currnum++;
     }
    count++;
   }
  if (currnum != n) return -1;
  return (count-1);
}

- (int)rspotOf:(char)aChar occurrenceNum:(int)n caseSensitive:(BOOL)sense
{
  int currnum = -1;
  int count = length-1;
  
  if (n<0) return -1;
  
  while ((currnum < n) && (count >= 0)) {
    if (!sense) {
      if (NXToUpper(buffer[count]) == NXToUpper(aChar)) currnum++;
     }
    else {
      if (buffer[count] == aChar) currnum++;
     }
    count--;
   }
  if (currnum != n) return -1;
  return (count+1);
}

- (const char *)rindex:(char)aChar
{
	return [self rindex:aChar occurrenceNum:0 caseSensitive:YES];
}

- (const char *)rindex:(char)aChar occurrenceNum:(int)n
{
	return [self rindex:aChar occurrenceNum:n caseSensitive:YES];
}

- (const char *)rindex:(char)aChar caseSensitive:(BOOL)sense
{
	return [self rindex:aChar occurrenceNum:0 caseSensitive:sense];
}

- (const char *)rindex:(char)aChar occurrenceNum:(int)n caseSensitive:(BOOL)sense
{
  int num;
  num = [self rspotOf:aChar occurrenceNum:n caseSensitive:sense];
  if (num == -1) return NULL;
  return buffer+num;
}

- (const char *)index:(char)aChar
{
	return [self index:aChar occurrenceNum:0 caseSensitive:YES];
}

- (const char *)index:(char)aChar occurrenceNum:(int)n
{
	return [self index:aChar occurrenceNum:n caseSensitive:YES];
}

- (const char *)index:(char)aChar caseSensitive:(BOOL)sense
{
	return [self index:aChar occurrenceNum:0 caseSensitive:sense];
}

- (const char *)index:(char)aChar occurrenceNum:(int)n caseSensitive:(BOOL)sense
{
  int num;
  num = [self spotOf:aChar occurrenceNum:n caseSensitive:sense];
  if (num==-1) return NULL;
  return buffer+num;
}

- (const char *)strstr:(const char *)subString
{
	if (!(buffer||subString)) return NULL;
	return strstr(buffer, subString);
}

- (int)spotOfChars:(const char *)aString
{
	return [self spotOfChars:aString occurrenceNum:0 caseSensitive:YES];
}

- (int)spotOfChars:(const char *)aString caseSensitive:(BOOL)sense
{
	return [self spotOfChars:aString occurrenceNum:0 caseSensitive:sense];
}

- (int)spotOfChars:(const char *)aString occurrenceNum:(int)n
{
	return [self spotOfChars:aString occurrenceNum:n caseSensitive:YES];
}

- (int)spotOfChars:(const char *)aString occurrenceNum:(int)n
		caseSensitive:(BOOL)sense
{
	int currnum = -1;
	int count = 0;
	id tempStr;
 
	if (n < 0) return -1;
	tempStr = [MiscString newWithString:aString];
	while ((currnum < n) && (count < length)) {
		if ([tempStr spotOf:buffer[count] caseSensitive:sense] != -1)
			currnum++;
		count++;
	}
	[tempStr free];
	if (currnum != n) return -1;
	return (count - 1);
}

- (int)rspotOfChars:(const char *)aString
{
	return [self rspotOfChars:aString occurrenceNum:0 caseSensitive:YES];
}

- (int)rspotOfChars:(const char *)aString caseSensitive:(BOOL)sense
{
	return [self rspotOfChars:aString occurrenceNum:0 caseSensitive:sense];
}

- (int)rspotOfChars:(const char *)aString occurrenceNum:(int)n
{
	return [self rspotOfChars:aString occurrenceNum:n caseSensitive:YES];
}

- (int)rspotOfChars:(const char *)aString occurrenceNum:(int)n
		caseSensitive:(BOOL)sense
{
	int currnum = -1;
	int count = length - 1;
	id tempStr;
 
	if (n<0) return -1;
	tempStr = [[self class] newWithString:aString];
	while ((currnum < n) && (count >= 0)) {
		if ([tempStr spotOf:buffer[count] caseSensitive:sense] != -1)
			currnum++;
		count--;
	}
	if (currnum != n) return -1;
	return (count + 1);
}

- (const char *)rindexOfChars:(const char *)aString
{
	return [self rindexOfChars:aString occurrenceNum:0 caseSensitive:YES];
}

- (const char *)rindexOfChars:(const char *)aString caseSensitive:(BOOL)sense
{
	return [self rindexOfChars:aString occurrenceNum:0 caseSensitive:sense];
}

- (const char *)rindexOfChars:(const char *)aString occurrenceNum:(int)n
{
	return [self rindexOfChars:aString occurrenceNum:n caseSensitive:YES];
}

- (const char *)rindexOfChars:(const char *)aString occurrenceNum:(int)n
		caseSensitive:(BOOL)sense
{
	int num;
	num = [self rspotOfChars:aString occurrenceNum:n caseSensitive:sense];
	if (num == -1) return NULL;
	return (const char *)(buffer+num);
}

- (const char *)indexOfChars:(const char *)aString
{
	return [self indexOfChars:aString occurrenceNum:0 caseSensitive:YES];
}

- (const char *)indexOfChars:(const char *)aString caseSensitive:(BOOL)sense
{
	return [self indexOfChars:aString occurrenceNum:0 caseSensitive:sense];
}

- (const char *)indexOfChars:(const char *)aString occurrenceNum:(int)n
{
	return [self indexOfChars:aString occurrenceNum:n caseSensitive:YES];
}

- (const char *)indexOfChars:(const char *)aString occurrenceNum:(int)n
		caseSensitive:(BOOL)sense
{
	int num;
	num = [self spotOfChars:aString occurrenceNum:n caseSensitive:sense];
	if (num == -1) return NULL;
	return (const char *)(buffer+num);
}

@end
