#if defined _strutil_included
  #endinput
#endif
#define _strutil_included

stock strfind( const buf[], const find_str[], start = 0 )
{
	new len = strlen( buf );
	new len2 = strlen( find_str );
	for( new i=start ; i<len ; i++ )
	{
		for( new j=0 ; j<len2 ; j++ )
		{
			if( buf{i+j}!=find_str{j} )
			{
				break;
			}
            else if( j==len2-1 )
            {
				return i;
            }
		}
	}

	return -1;
}

stock strfind_last_of( const str[], const filter[] )
{
    new str_len = strlen(str);
    new filter_len = strlen(filter);
    for( new i=str_len-1 ; i>=0 ; i-- )
    {
        new bool:found = false;
        for( new j=0 ; j<filter_len ; j++ )
        {
            if( str{i}==filter{j} )
            {
                found = true;
                break;
            }
        }

        if( found ) return i;
    }
    return -1;
}

stock strfind_first_not_of( const str[], const filter[] )
{
    new str_len = strlen(str);
    new filter_len = strlen(filter);
    for( new i=0 ; i<str_len ; i++ )
    {
        new bool:found = false;
        for( new j=0 ; j<filter_len ; j++ )
        {
            if( str{i}==filter{j} )
            {
                found = true;
                break;
            }
        }

        if( ! found ) return i;
    }
    return -1;
}

stock strsub( dst[], dst_pos=0, const src[], src_pos=0, len = -1, dstsize = sizeof dst )
{
    new src_len = strlen(src);

    // len=-1 の場合は、srcの最後まで
    if( len == -1 ){ len = src_len-src_pos; }

    if( len + src_pos > src_len ){ len = src_len - src_pos; }
    if( len + dst_pos > dstsize * 4 -1 ){ len = dstsize * 4 -1 - dst_pos; }

    for( new i=0 ; i<len ; i++ ) dst{dst_pos+i} = src{src_pos+i};

    new zero_padding = 4 - ((dst_pos+len)%4);
    for( new i=0 ; i<zero_padding ; i++ ) dst{dst_pos+len+i} = 0;
}

stock strreplace( dst[], const src[], const from[], const to[], dstsize = sizeof dst )
{
    new count;
	new from_len = strlen( from );
	new to_len = strlen( to );

	new src_pos = 0;
	new dst_pos = 0;
	for(;;)
	{
		new ret = strfind( src, from, src_pos );
		if( ret < 0 )
        {
            strsub( dst, dst_pos, src, src_pos, _, dstsize );
            return count;
        }
        else
        {
            strsub( dst, dst_pos, src, src_pos, ret-src_pos, dstsize );
            dst_pos += ret-src_pos;

            strcat( dst, to, dstsize );

            dst_pos += to_len;
            src_pos = ret + from_len;
        }
	}

    return 0;
}

stock strcasecmp( const str1[], const str2[] )
{
    for( new i=0 ;; i++ )
    {
        new c1 = toupper(str1{i});
        new c2 = toupper(str2{i});

        if( c1==0 && c2==0 ) break;
        if( c1 == c2 ) continue;
        else if( c1 > c2 ) return 1;
        else return -1;
    }
    return 0;
}

stock strncasecmp( const str1[], const str2[], len )
{
    for( new i=0 ; i<len ; i++ )
    {
        new c1 = toupper(str1{i});
        new c2 = toupper(str2{i});

        if( c1==0 && c2==0 ) break;
        if( c1 == c2 ) continue;
        else if( c1 > c2 ) return 1;
        else return -1;
    }
    return 0;
}
