/******************************************************************************
 * This file is part of Skylark project
 * Copyright ©2025 Hua andy <hua.andy@gmail.com>

 * 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 3 of the License, or
 * at your option any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 *******************************************************************************/

#ifndef _H_SKYLARK_UTIL_
#define _H_SKYLARK_UTIL_

#include <knownfolders.h>

#ifndef MAX
#define MAX(_a_, _b_) ((_a_) > (_b_) ? (_a_) : (_b_))
#endif

#ifndef MIN
#define MIN(_a_, _b_) ((_a_) < (_b_) ? (_a_) : (_b_))
#endif

#ifndef UTIL_SWAP
#define UTIL_SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
#endif

#ifndef UTIL_NUMBER
#define UTIL_NUMBER(ch) ((ch) - 0x30)
#endif

#ifndef UTIL_BASE10
#define UTIL_BASE10(ch) ((ch) >= 0x30 && (ch) <= 0x39)
#endif

#ifndef TWO_DISM
#define TWO_DISM 10
#endif

#define util_malloc(x) (HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, (x)))
#define util_free(x)   (HeapFree(GetProcessHeap(), HEAP_ZERO_MEMORY, (x)),(x = NULL))

#define util_prev(p) ((p) - (psrc) > 0 ? (p[-1]) : (0))

#define BAD_CHARACTERS ("</")
#define END_CHARACTERS (" \t\r\n\"']>.*\\")

typedef struct _HANDLE_DATA
{
    uint32_t pid;
    HWND handle;
} handle_data;

typedef struct _queue_list
{
    TCHAR path[MAX_BUFFER];
} queue_list;
#ifdef __cplusplus
extern "C"
{
#endif

// for openssl
HMODULE util_ssl_open_symbol(char *s[], int n, uintptr_t *pointer);
void util_ssl_close_symbol(HMODULE *pssl);

void util_lock(volatile long *gcs);
void util_unlock(volatile long *gcs);
void util_lock_v2(eu_tabpage *p);
void util_unlock_v2(eu_tabpage *p);

int util_aes_enc(unsigned char *dec, unsigned char *enc, int len);
int util_aes_dec(unsigned char *enc, unsigned char *dec, int len);
int util_enc_des_ecb_192(unsigned char *key_192bits, unsigned char *decrypt, long decrypt_len, unsigned char *encrypt, long *encrypt_len);
int util_dec_des_ecb_192(unsigned char *key_192bits, unsigned char *encrypt, long encrypt_len, unsigned char *decrypt, long *decrypt_len);
int util_enc_des_cbc_192(unsigned char *key_192bits, unsigned char *decrypt, long decrypt_len, unsigned char *encrypt, long *encrypt_len, unsigned char *init_vector);
int util_dec_des_cbc_192(unsigned char *key_192bits, unsigned char *encrypt, long encrypt_len, unsigned char *decrypt, long *decrypt_len, unsigned char *init_vector);

int util_file_md5(const TCHAR *path, TCHAR **pout);
int util_file_sha1(const TCHAR *path, TCHAR **pout);
int util_file_sha256(const TCHAR *path, TCHAR **pout);
int util_file_base64(const TCHAR *path, char **pout);

int util_hex_expand(char *hex_buf, int hex_len, char *asc_buf);
int util_hex_fold(char *asc_buf, int asc_len, char *hex_buf);
int util_set_title(const eu_tabpage *pnode);
int util_set_working_dir(const TCHAR *path, TCHAR **old);
int util_query_hostname(char *hostname, char *ip, int bufsize);
int util_effect_line(eu_tabpage *pnode, sptr_t *, sptr_t *);
int util_get_hex_byte(const char *p);
int util_strnspace(const char *s1, const char *s2, int *plen);
int util_count_characters(const char *pstr, const int ch);
int util_uncompress(uint8_t *dest, unsigned long *dest_len, const uint8_t *source, unsigned long *source_len);
int util_compress(uint8_t *dest, unsigned long *dest_len, const uint8_t *source, unsigned long source_len, int level);
int util_count_number(size_t number);
int util_split_attr(const char *pstr, char (*pout)[MAX_PATH], int ch);
int util_strim_end(char *pstr, int len);
int util_num_cores(void);
int util_tab_height(const HWND hwnd, const int width);

char*  util_memdup(char **p, const char *text);
char*  util_stristr(const char *str, const char *pattern);
char*  util_strrstr(const char *s1, const char *s2);
char*  util_unix_newline(const char *in, const size_t in_size);
char*  util_strdup_select(const eu_tabpage *pnode, size_t *text_len, size_t multiple);
char*  util_strdup_line(const eu_tabpage *pnode, const sptr_t line_number, size_t *plen);
char*  util_strdup_content(const eu_tabpage *pnode, size_t *plen);
char*  util_struct_to_string(void *buf, size_t bufsize);
char*  util_make_u8(const TCHAR *utf16, char *utf8, int len);
char*  util_string_match(const char *str, const char *pattern, bool incase, bool match_start, bool whole);
char*  util_str_replace(const char *in, const char *pattern, const char *by);
char*  util_trim_sides_white(const uint8_t *str);
char*  util_str_unquote(const char *path);
char*  util_url_escape(const char *url);
char*  util_has_newline(const char *dst);
void   util_trim_right_star(TCHAR *str);
void   util_push_text_dlg(eu_tabpage *pnode, HWND hwnd);
void   util_enable_menu_item(const HMENU hmenu, const uint32_t m_id, const bool enable);
void   util_set_menu_item(const HMENU hmenu, const uint32_t m_id, const bool checked);
void   util_icons_menu_item(const HMENU hmenu, const uint32_t m_id, const HBITMAP hbmp);
void   util_update_menu_chars(const HMENU hmenu, const uint32_t m_id, const int width);
void   util_upper_string(char *str);
void   util_kill_thread(uint32_t pid);
void   util_wait_cursor(const eu_tabpage *pnode);
void   util_restore_cursor(const eu_tabpage *pnode);
void   util_setforce_eol(eu_tabpage *pnode);
void   util_save_placement(const HWND hwnd);
void   util_restore_placement(const HWND hwnd);
void   util_skip_whitespace(uint8_t **cp, int n, int term);
void   util_strcat(uint8_t **dst, const char* pstr);
void   util_split(const char *pstr, const char *sep, char ***ppvec, const bool out_vec);
void   util_transparent(const HWND hwnd, int percent);
void   util_untransparent(const HWND hwnd);
void   util_postion_xy(eu_tabpage *pnode, sptr_t pos, sptr_t *px, sptr_t *py);
void   util_explorer_open(eu_tabpage *pnode);
void   util_redraw(const HWND hwnd, const bool force);
void   util_symlink_destroy(eu_tabpage *pnode);
void   util_updateui_msg(const eu_tabpage *pnode);
void   util_updateui_icon(const HWND hwnd, const bool fnshow);
void   util_updateui_titlebar(const HWND hwnd);
void   util_update_env(eu_tabpage *pnode);
void   util_switch_menu_group(HMENU hmenu, int pop_id, uint32_t first_id, uint32_t last_id, uint32_t select);
bool   util_string_space(const char *str, const size_t len);
bool   util_availed_char(int ch);
bool   util_under_wine(void);
bool   util_string_to_struct(const char *buffer, void *buf, size_t bufsize);
bool   util_creater_window(HWND hwnd, HWND hparent);
bool   util_can_selections(const eu_tabpage *pnode);
bool   util_file_size(HANDLE hfile, uint64_t *psize);
bool   util_open_file(LPCTSTR path, pf_stream pstream);
bool   util_delete_file(LPCTSTR filepath);
bool   util_exist_libcurl(void);
bool   util_upcheck_exist(void);
bool   util_get_clipboard(char **ppstr);
bool   util_try_path(LPCTSTR dir);
bool   util_shell_path(const GUID *folder, TCHAR *path, const int len);
bool   util_copy_file(LPCWSTR source, LPCWSTR dest, const bool fail_exist);
bool   util_isxdigit_string(LPCTSTR str, const int len);
bool   util_has_space(uint8_t ch);
bool   util_dark_theme(void);
bool   util_bfs_search(const TCHAR *path, file_backup **pout, const file_backup *pdata);
bool   util_product_name(LPCWSTR filepath, LPWSTR out_string, size_t len);
bool   util_file_access(LPCTSTR filename, uint32_t *pgranted);
bool   util_get_unix_file_name(LPCWSTR path, wchar_t *out, const int len);
bool   util_font_available(const char *name);
bool   util_font_xy(const HWND hwnd, const HFONT hfont, int *px, int *py);
time_t util_last_time(const TCHAR *path);
WCHAR* util_to_abs(const char *path);
TCHAR* util_make_u16(const char *utf8, TCHAR *utf16, int len);
WCHAR* util_winexy_get(void);
WCHAR* util_winexy_hide(void);
WCHAR* util_winexy_tool(void);
TCHAR* util_unix2path(TCHAR *path, const int len);
TCHAR* util_path2unix(TCHAR *path, const int len);
TCHAR* util_add_double_quotes(const TCHAR *path);
TCHAR* util_which(const TCHAR *name);
TCHAR* util_wstr_unquote(TCHAR *path);
HANDLE util_mk_temp(TCHAR *file_path, TCHAR *ext);
HWND   util_create_tips(HWND hwnd_stc, HWND hwnd, TCHAR* ptext);
HWND   util_get_hwnd(const uint32_t pid);
sptr_t util_line_header(eu_tabpage *pnode, const sptr_t start, const sptr_t end, char **pout);
sptr_t util_line_space(eu_tabpage *pnode, const sptr_t start, const sptr_t end);
sptr_t util_select_characters(eu_tabpage *pnode, const sptr_t start, const sptr_t end);
wchar_t* util_get_nt_file_name(LPCWSTR path);
const char* util_trim_left_white(const char *str, int *length);
unsigned long util_compress_bound(unsigned long source_len);
const uint32_t util_os_version(void);
const TCHAR* util_path_ext(const TCHAR *path);
const TCHAR* util_path_filename(const TCHAR *path);
uint64_t util_gen_tstamp(void);
int64_t  util_clock_interval(void);
HFONT util_create_font(const char* name, const int font_size, const bool bold);
HBITMAP util_icon_bitmap(HICON hicon, const int width, const int height);
HBITMAP util_shield_icon(HINSTANCE hinst, LPCTSTR name);
HRESULT util_shortcut(const WCHAR *pfile, const bool create);
char *util_io_file(const TCHAR *path);

#ifdef __cplusplus
}
#endif

#endif // _H_SKYLARK_UTIL_
