#ifndef SDK_STDLIB_H
#define SDK_STDLIB_H

#include <typedefs.h>

/* ***************************************************
 * Minimum and maximum macros
 */
#define __max(a,b)  (((a) > (b)) ? (a) : (b))
#define __min(a,b)  (((a) < (b)) ? (a) : (b))


#define abs(i)		(i<0 ? -i : i)


#ifdef __cplusplus
extern "C" {
#endif

/* ***************************************************
 * ANSI strings routines
 */

/* ВНИМАНИЕ!
     по стандарт?лимитированные ?ци??запись??dst являет? небезопасным?
	  иб?если длин?строки src больше че?n, то ?dst не буде?записа?символ окончания строки '\0'
*/

size_t  strlen( const char * str );								// Длин?строки
char *  strcat( char * dst, const char * src );					// Конкатенац? стро?
char *  strchr( const char * str, int s );						// Поис?символ??строке
int     strcmp( const char * s1, const char * s2 );				// Сравнени?стро?
char *  strcpy( char * dst, const char * src );					// Копировани?стро?

char *  strncat( char * dst, const char * src, size_t n );		// Лимитированая конкатенац?
int     strncmp( const char * s1, const char * s2, size_t n );	// Лими? сравнени?
char *  strncpy( char * dst, const char * src, size_t n );		// Лими? копировани?

char *  strstr( const char * str, const char * srch );			// Поис?подстрок?
char *  strrchr( const char * str, int s );						// Поис?символ??строке (реверс)
char *  strtok( char *, const char * );

int toupper( int c );		// Символ ?верхнему регистру
int tolower( int c );		// Символ ?нижнем?регистру

size_t strcspn( const char * str1, const char * str2 );		// возвращает индекс символ??str1 которы?совпадае??одни?из символов str2
size_t strspn( const char * str1, const char * str2 );		// аналогично, только `НЕ`

/* ***************************************************
 * Unicode strings routines
 */

size_t	u_strlen( const WCHAR * );

WCHAR *	u_strcat( WCHAR * dst, const WCHAR * str );

// добавляет n символов из src ?строке dst
WCHAR * u_strncat( WCHAR * dst, const WCHAR * src, UINT32 n );		

WCHAR *	u_strcmp( const WCHAR * s1, const WCHAR * s2 );
WCHAR *	u_strcpy( WCHAR * dst, const WCHAR * src );

WCHAR *	u_strncmp( const WCHAR * s1, const WCHAR * s2, size_t count );
WCHAR *	u_strncpy( WCHAR * dst, const WCHAR * src, size_t count );

// ищет ?str первое вхождени?символ?chr
WCHAR * u_strchr( WCHAR * src, WCHAR chr );
// ищет ?str последне?вхождени?символ?chr
WCHAR * u_strrchr( WCHAR * src, WCHAR chr );

// ищет search ?src (?учётом регистра)
WCHAR * u_strstr( WCHAR * src, WCHAR * search );
// тоже, но бе?учёт?регистра
WCHAR * u_stristr( WCHAR * src, WCHAR * search );

// удаляет част?строки длиной n символов ?позици?pos
INT32 u_strcut( WCHAR * str, UINT16 len_str, UINT16 pos, int n ); 

WCHAR *	u_strmakeupper( WCHAR * str );		// Unicode Строку ?верхнему регистру
WCHAR *	u_strmakelower( WCHAR * str );		// Unicode Строку ?нижнем?регистру


/* ***************************************************
 * Convert
 */

// ANSI string to Unicode
WCHAR *	u_atou( const char * src, WCHAR * dst );

// Unicode string to ANSI (valid only for ascii-range symbols)
char *	u_utoa( const WCHAR * src, char * dst );

// Unicode to UTF-8
UINT16 DL_Char_convUCS2toUTF8String( const WCHAR * src,	UINT16 src_len,
									UINT8 * dst,		UINT16 dst_len );		
// UTF-8 to Unicode
UINT16 DL_Char_convUTF8toUCS2String( const UINT8 * src,	UINT16 src_len,
									WCHAR * dst,		UINT16 dst_len );

// CP-1251 to Unicode									
UINT16 DL_Char_convCP1251toUCS2String( const UINT8 * src,	UINT16 src_len,
										WCHAR * dst_ptr,	UINT16 dst_len);
UINT16 DL_Char_convGB2312toUCS2Buf( const UINT8   *src_ptr,
									  UINT16  src_len,
									  WCHAR   *trg_ptr,
									  UINT16  trg_len);
UINT16 DL_Char_convBig5toUCS2Buf ( const UINT8   *src_ptr,
									  UINT16  src_len,
									  WCHAR   *trg_ptr,
									  UINT16  trg_len);

/* ***************************************************
 *     Преобразование СТРОКА <-> ЧИСЛ?
 *  str - указател?на трок?
 *  end - ввозвращается указател?на строку ?мест? гд?закончилос?преобразование
 *  base, radix - основани?СС.
 *     Если 0, то буде?использовать? "умно? определени?- "0x..." = HEX / "0..." = OCT / остально?DEC
 */
// преобразуе?строку ?числ?long (INT32)
long strtol( const char * str, char ** end, int base );

// строка -> unsigned long (UINT32)
unsigned long strtoul( const char * str, char ** end, int base );

// числ?-> строку
char * _itoa( int value, char * string, int radix );
#define itoa(v,s,r)		_itoa(v,s,r)

// числ?-> строку Unicode
WCHAR *	u_ltou( long number, WCHAR * str );

// Unicode строка -> unsigned long (UINT32)
long u_atol( WCHAR * str );

// преобразуе?из dec ?HEX
WCHAR * u_itoh( int value, WCHAR * dst );

/* ***************************************************
 * end string funcs
 */

// Quick compare strings
UINT32 namecmp( const char * str1, const char * str2 ); //returns 1 if equal

/* ***************************************************
 * other functions
 */

void * bsearch( const void * key, const void * buf, size_t num, size_t size, int (*compare)(const void *, const void *) );
void qsort( void * buf, size_t num, size_t size, int (*compare)(const void *, const void *) );

int rand( void );
void srand( unsigned int seed );
#define randomize()		srand((UINT32)suPalReadTime())
#define rand_init()		srand((UINT32)suPalReadTime())


int abs_0( int );

int sprintf( char * str, const char * format, ... );


#ifdef __cplusplus
} /* extern "C" */
#endif

#endif // SDK_STDLIB_H
