/***************************************************************************
 *   copyright           : (C) 2002 by Hendrik Sattler                     *
 *   mail                : post@hendrik-sattler.de                         *
 *                                                                         *
 *   This program is free software; you can redistribute it 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.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef CHARSETS_H
#define CHARSETS_H

/** You MUST call this function before all other charset functions.
 *  @param charset if NULL, locale specific charset will be returned
 *                 on get_system_charset().
 *  @param announce if non-zero, prints a informational message to stderr
 */
void charset_init (char* charset, int announce);

/** returns the system character set
 */
char* get_system_charset (); /* considers setting from charset_init() */
char* get_system_charset_raw(); /* only what the system tells */

enum repmode {
  /* replace all unknown character with a \XXXX replacement
   * it is used for all output that we might read again
   */
  REPMODE_ESCAPE_CHARS = 0,
  /* replace all unknown character with a '?'
   * it is used for all output that we may not read again
   */
  REPMODE_QUESTIONMARK,
  /* ignore any failure (prints an error message)
   */
  REPMODE_IGNORE
};

#include "intincl.h"
#define ucs4char_t uint32_t
#define ucs2char_t uint16_t
#define gsmchar_t  uint8_t

#include <stdlib.h>

/* return memory count of elements */
size_t ucs4len (const ucs4char_t* input);
size_t ucs2len (const ucs2char_t* input);
#define gsmlen(input) str_len(input)

/* return the count of characters */
size_t gsmwidth (const gsmchar_t* input);

/* almost like strndup()/strdup() but return NULL if s == NULL */
ucs4char_t* ucs4ndup(const ucs4char_t* s, size_t n);
ucs4char_t* ucs4dup(const ucs4char_t* s);
ucs2char_t* ucs2ndup(const ucs2char_t* s, size_t n);
ucs2char_t* ucs2dup(const ucs2char_t* s);

/* just like strncmp()/strcmp() */
int ucs4ncmp (const ucs4char_t* s1, const ucs4char_t* s2, size_t n);
int ucs4cmp (const ucs4char_t* s1, const ucs4char_t* s2);

/* just like strstr() */
ucs4char_t* ucs4str (const ucs4char_t* haystack, const ucs4char_t* needle);

/* not like strncpy but copies n-1 characters with a terminating 0 */
ucs4char_t* ucs4ncpy (ucs4char_t* dest, const ucs4char_t* src, size_t n);

/* these two are mainly used by the other function from below */
ucs4char_t* convert_to_internal (const char* from_code,
				 char* input,
				 size_t insize);
char* convert_from_internal (const char* to_code,
			     ucs4char_t* input,
			     enum repmode replacement_mode);

/* convert from/to the system's charset */
char* convert_to_system (ucs4char_t* input,
			 enum repmode replacement_mode);
ucs4char_t* convert_from_system (char* input);

/* convert from/to 7bit GSM charset */
gsmchar_t* convert_to_gsm (ucs4char_t* input);
ucs4char_t* convert_from_gsm (gsmchar_t* input);

/* convert from/to UCS-2 unicode charset
 * input must be in host endianess
 */
ucs2char_t* convert_to_ucs2 (ucs4char_t* input);
ucs4char_t* convert_from_ucs2 (ucs2char_t* input);
/* fromhe and tohe define function to convert from and to host endianess */
char* convert_to_ucs2_hexstring (ucs4char_t* input,
				 uint16_t (*fromhe)(uint16_t i));
ucs4char_t* convert_from_ucs2_hexstring (char* input,
					 uint16_t (*tohe)(uint16_t i));

/* Count how many GSM-encoded UCS-4 characters fit into
 * a max of count septets.
 * A count of zero counts the septets needed by input.
 */
unsigned int gsm_count (ucs4char_t* input, unsigned int count);

#endif
