/*
    string utilities
    Copyright (C) 2011 Ladislav Vaiz <ok1zia@nagano.cz>

    This program is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    version 2 as published by the Free Software Foundation.

*/

#ifndef __ZSTR_H
#define __ZSTR_H

#include <libziaint.h>
#include <glib.h>

#include <ctype.h>
#include <string.h>

gint z_compare_string (gconstpointer a, gconstpointer b);
char *z_strstr(const char *, const char *);
char *z_strcasestr(const char *phaystack, const char *pneedle);
int z_levenshtein(const char *s, const char*t);
char *z_string_hex(GString *gs, char *data, int len);

static inline char z_char_uc(char a)
{
    if (a >= 'a' && a <= 'z') a -= 0x20;
    return a;
}

static inline char z_char_lc(char a)
{
    if (a >= 'A' && a <= 'Z') a += 0x20;
    return a;
}

static inline char *z_str_lc(char *str){
    register char *c;
    
    if (!str) return str;
    for (c = str; *c != '\0'; c++){
        if (*c >= 'A' && *c <= 'Z') *c += 0x20;
    }
    return str;
}

static inline char *z_str_uc(char *str){
    register char *c;
    
    if (!str) return str;
    for (c = str; *c != '\0'; c++){
        if (*c >= 'a' && *c <= 'z') *c -= 0x20;
    }
    return str;
}

static inline char *z_strlcpy(gchar *dest, const gchar *src, gsize dest_size){
    if (src == NULL){
        g_strlcpy(dest, "", dest_size);
    }else{
        g_strlcpy(dest, src, dest_size);
    }
    return dest;
}

static inline char *z_char_replace(char *src, char find, char replacewith){
    char *c;

    for (c = src; *c != '\0'; c++){
        if (*c == find) *c = replacewith;
    }
    return src;
}

#ifdef Z_MSC
#define strtok_r strtok_s
#endif

#ifdef Z_MINGW
char *strtok_r(char *str, const char *delim, char **saveptr);
#endif

char *z_strip_crlf(char *str);
char *z_strip_from(char *str, char charfrom);

char *z_1250_to_8859_2(char *src);

void *z_strtop(const char *str);

#ifndef Z_HAVE_G_STRING_APPEND_VPRINTF
void g_string_append_vprintf(GString *gs, const gchar *format, va_list args);
#endif

double z_qrg_parse(const char *s);
void z_qrg_format(char *s, int size, double qrg);

char *z_html2txt(char *html);


#define ZSR_ALL 0x01 // all occurences
#define ZSR_CI  0x02 // case insensitive
// returns last replace position
int z_string_replace(GString *gs, char *pattern, char *newstr, int flags);

int z_string_replace_from_to(GString *gs, char *from, char *to, char *newstr, int flags);

#ifdef Z_MSC_MINGW
#define strcasecmp _stricmp
#define strncasecmp _strnicmp
#endif


static inline char *z_trim(char *s){
    char *c;

    if (!s || !*s) return s;
    for (c = s + strlen(s) - 1; c > s; c--) {
        if (!isspace((unsigned char)*c)) break;
        *c = '\0';
    }
    for (c = s; *c != '\0'; c++) if (!isspace((unsigned char)*c)) break;
    
    if (c[0] == '\xef' && c[1] == '\xbb' && c[2] == '\xbf'){
        for (c += 3; *c != '\0'; c++) if (!isspace((unsigned char)*c)) break;
    }
    return c;
}

static inline char *z_trim_end(char *s){
    char *c;

    if (!s || !*s) return s;
    for (c = s + strlen(s) - 1; c > s; c--) {
        if (!isspace((unsigned char)*c)) break;
        *c = '\0';
    }
    return s;
}

static inline const char *z_trim_beg(const char *s){
    const char *c;

    for (c = s; *c != '\0'; c++) if (!isspace((unsigned char)*c)) break;
    
    if (c[0] == '\xef' && c[1] == '\xbb' && c[2] == '\xbf'){
        for (c += 3; *c != '\0'; c++) if (!isspace((unsigned char)*c)) break;
    }
    return c;
}



static inline gchar *z_strdup_trim(gchar *s){
    char *c1, *c2;
    c1 = g_strdup(s);
    c2 = g_strdup(z_trim(c1));
    g_free(c1);
    return c2;
}

#define ZSPL_NSTRIP 0x01
void z_split2(char *src, char delimiter, char **key, char **val, int flags);

int zstr_begins_with(const char *haystack, const char *needle, int casesensitive);

static inline char *z_trimdup(const char *src){
    return z_trim_end(g_strdup(z_trim_beg(src)));
}

char *zstr_shorten(const char *src, int maxlen);
void z_string_bytes(GString *gs, long long bytes);

#endif



