#include <string.h>
#include "filematch.h"

// LordHavoc: some portable directory listing code I wrote for lmp2pcx, now used in darkplaces to load id1/*.pak and such...

int matchpattern( const char *in, const char *pattern, int caseinsensitive ){
	return matchpattern_with_separator( in, pattern, caseinsensitive, "/\\:", 0 );
}

// wildcard_least_one: if true * matches 1 or more characters
//                     if false * matches 0 or more characters
int matchpattern_with_separator( const char *in, const char *pattern, int caseinsensitive, const char *separators, int wildcard_least_one ){
	int c1, c2;
	while ( *pattern )
	{
		switch ( *pattern )
		{
		case 0:
			return 1; // end of pattern
		case '?': // match any single character
			if ( *in == 0 || strchr( separators, *in ) ) {
				return 0; // no match
			}
			in++;
			pattern++;
			break;
		case '*': // match anything until following string
			if ( wildcard_least_one ) {
				if ( *in == 0 || strchr( separators, *in ) ) {
					return 0; // no match
				}
				in++;
			}
			pattern++;
			while ( *in )
			{
				if ( strchr( separators, *in ) ) {
					break;
				}
				// see if pattern matches at this offset
				if ( matchpattern_with_separator( in, pattern, caseinsensitive, separators, wildcard_least_one ) ) {
					return 1;
				}
				// nope, advance to next offset
				in++;
			}
			break;
		default:
			if ( *in != *pattern ) {
				if ( !caseinsensitive ) {
					return 0; // no match
				}
				c1 = *in;
				if ( c1 >= 'A' && c1 <= 'Z' ) {
					c1 += 'a' - 'A';
				}
				c2 = *pattern;
				if ( c2 >= 'A' && c2 <= 'Z' ) {
					c2 += 'a' - 'A';
				}
				if ( c1 != c2 ) {
					return 0; // no match
				}
			}
			in++;
			pattern++;
			break;
		}
	}
	if ( *in ) {
		return 0; // reached end of pattern but not end of input
	}
	return 1; // success
}
