/*
 * libkarma/lkarma.h
 *
 * Copyright (c) Frank Zschockelt <libkarma@freakysoft.de> 2004
 *
 * You may distribute and modify this program under the terms of 
 * the GNU GPL, version 2 or later.
 *
 */

#ifndef _LKARMA_H
#define _LKARMA_H

#include <inttypes.h>

#ifdef __cplusplus
extern "C" {
#endif

#define FDB_FILENAME "__libkarma_fdb__.gz"

/*
 * karma
 */

#define IO_LOCK_R 0
#define IO_LOCK_W 1

/*Help-Functions:*/
int      lk_karma_connect                (char *ipHostOrPath);

/*Basic Protocol Functions*/
uint32_t lk_karma_authenticate           (int rio, char *pass);
int      lk_karma_get_storage_details    (int rio, uint32_t storage_id,
                                          uint32_t *n_files, uint64_t *s_size,
                                          uint64_t *f_space,
                                          uint32_t *highest_file_id);
int      lk_karma_get_device_settings    (int rio, char **properties);
int32_t  lk_karma_request_io_lock        (int rio, uint32_t type);
int32_t  lk_karma_release_io_lock        (int rio);
int32_t  lk_karma_write_file_chunk       (int rio, uint64_t offset,
                                          uint64_t size, uint32_t file_id,
                                          uint32_t storage_id,
                                          const char *data);
int32_t  lk_karma_get_all_file_details   (int rio, char **properties);
int32_t  lk_karma_get_file_details       (int rio, uint32_t file_id,
                                          char **properties);
int32_t  lk_karma_update_file_details    (int rio, uint32_t file_id,
                                          char *properties);
int32_t  lk_karma_read_file_chunk        (int rio, uint64_t offset,
                                          uint64_t size, uint32_t file_id,
                                          char **data, uint64_t *retsize);
int32_t  lk_karma_delete_file            (int rio, uint32_t file_id);
int32_t  lk_karma_hangup                 (int rio);
void     lk_karma_use_smalldb            (void);
int      lk_karma_write_smalldb          (void);

/*Advanced Protocol Functions:*/
void     lk_karma_load_database          (int rio);


char   **lk_fdb_getlist                  (char *fdb);

/*
 * properties
 */

void     lk_properties_init             (void);
void     lk_properties_destroy          (void);
uint32_t lk_properties_import           (char * properties);
char *   lk_properties_export           (uint32_t id);

uint32_t lk_properties_new_property     (void);
int      lk_properties_del_property     (uint32_t id);
char *   lk_properties_get_property     (uint32_t id, char * key);
int      lk_properties_set_property     (uint32_t id, char * property,
                                         char * data);

int      lk_properties_load             (void);
int      lk_properties_save             (void);
int      lk_properties_cache_obsolete   (void);

/* Exact/approximate And/Or search support: */

uint32_t *lk_properties_andOrSearch     (int mode, uint32_t *search_in,
                                         char *key, char *data);

#define ORS    0                      /* mode == 00 = APPROX|ORS:  Approx,Or  */
#define ANDS   1                      /* mode == 01 = APPROX|ANDS: Approx,And */
#define APPROX 0                      /* mode == 10 =  EXACT|ORS:   Exact,Or  */
#define EXACT  2                      /* mode == 11 =  EXACT|ANDS:  Exact,And */


/*
 * errors
 */

typedef void *error_handler(void);

int  lk_errors_set(const int err);                       /* Sets error number */
void lk_errors_autoprint(const int autoPrint); /*Sets errors aoutoprint on/off*/
void lk_errors_setHandler(error_handler handler); /*Sets an error handl. func.*/
int  lk_errors_number(void);             /* checks error number and resets it */
int  lk_errors_number_noreset(void); /* checks error number without resetting */
int  lk_errors_p(const char *s1, const char *s2); /*prints s1+errStr+s2&resets*/
char * lk_errors_numberstr(int lkerrnum);  /* returns err string for lkerrnum */
                                                                /* - no reset */

#define E_NOERR      0  /* Success */
#define E_HOST       1  /* error:   gethostbyname() failed    */  /* Sys */
#define E_SOCKET     2  /* error:   socket() failed           */  /* Sys */
#define E_SENDTO     3  /* error:   sendto() failed           */  /* Sys */
#define E_CONNECT    4  /* error:   connect() failed          */  /* Sys */
#define E_RECVFROM   5  /* error:   recvfrom() failed         */  /* Sys */
#define E_SELECT     6  /* error:   select() failed           */  /* Sys */
#define E_OPEN       7  /* error:   open() failed             */  /* Sys */
#define E_ICONVO     8  /* warning: iconv_open() failed       */  /* Sys */
#define E_ICONV      9  /* warning: iconv() failed            */  /* Sys */
#define E_ICONVC    10  /* error:   iconv_close() failed      */  /* Sys */

#define E_BADHEADER 11  /* error:   broken Rio header         */
#define E_BADIDENT  12  /* error:   wrong protocol identifier */
#define E_FAILEDREQ 13  /* warning: failed request            */

#define E_BADPROP   14  /* error:   property parsing failed   */
#define E_BADID     15  /* error:   given id not found        */

#define E_NOSSDP    16  /* warning: no ssdp answer            */
#define E_SSDPPARSE 17  /* warning: ssdp parsing failed       */

#define E_MKDIR     18  /* error:   mkdir() failed            */  /* Sys */
#define E_UTIME     19  /* error:   utime() failed            */  /* Sys */

#define E_NODIR     20  /* error:   unexisting directory      */  /* USB */
#define E_NOPROP    21  /* warning: missing properties file   */  /* USB */
#define E_READ      22  /* error:   read error                */  /* USB */
#define E_WRITE     23  /* error:   write error               */  /* USB */
#define E_DELETE    24  /* warning: delete error              */  /* USB */
#define E_NODEVSET  25  /* warning: no device-settings file   */  /* USB */
#define E_UNIMPLEM  26  /* warning: unimplemented call        */  /* USB */

#define E_MFINDERR  27  /* warning: mount search error        */  /* MFIND */
#define E_NOMOUNT   28  /* warning: no mountpoints found      */  /* MFIND */
#define E_MANYMOUNT 29  /* warning: more than 1 mountpoints   */  /* MFIND */
#define E_NOSMALLDB 30  /* warning: Missing RK index file     */  /* UTIL  */

#define E_DUPE      31  /* warning: file already present      */  /* RIO_RW */
#define E_PATHCREAT 32  /* warning: dir access/create failed  */  /* RIO_RW */
#define E_NOHASH    33  /* error:   no hash found             */  /* RIO_RW */
#define E_WRCHUNK   34  /* error:   write_file_chunk() failed */  /* RIO_RW */
#define E_SMALLMP3  35  /* error:   tune file is too small    */  /* RIO_RW */
#define E_UNSUPTAG  36  /* warning: unsupported tag type      */  /* RIO_RW */
#define E_NOTAGFILE 37  /* warning: can't access tags file    */  /* RIO_RW */

#define E_BADFDB    38  /* warning: unrecognised fdb file     */  /* FDB */
#define E_UNSUPFDB  39  /* warning: unsupported fdb file      */  /* FDB */
#define E_NOPATHPR  40  /* warning: missing path properties   */  /* FDB */

#define E_NOTMPDIR  41  /* warning: no temporary directory found  */
#define E_TMPCREAT  42  /* error: can't create temporary tag file */

#define MAXLKERRORS 42


/*
 * playlist
 */

typedef struct{
    char * name;
    char * playlist;
    unsigned int length;
    uint32_t fid;
} playlist;

playlist *   lk_playlist_fid_read        (uint32_t fid);
playlist *   lk_playlist_read            (char * name);
int          lk_playlist_free            (playlist ** pl);
int          lk_playlist_set_name        (playlist * pl, char * name);
char *       lk_playlist_get_name        (playlist * pl);
int          lk_playlist_count           (playlist * pl);
int          lk_playlist_get_item        (playlist * pl, unsigned int n,
                                          uint32_t *fid,
                                          uint32_t * fid_generation);
int          lk_playlist_set_item        (playlist * pl, unsigned int n,
                                          uint32_t fid,
                                          uint32_t fid_generation);
playlist *   lk_playlist_create          (char * name);
int          lk_playlist_clear           (playlist * pl);
int          lk_playlist_append          (playlist * pl, uint32_t fid,
                                          uint32_t fid_generation);
int          lk_playlist_write           (playlist * pl, int karma); 


/*
 * rio_rw
 */
/* #define MODE_PROPERTY "play_count_limit" */
#define    MODE_PROPERTY "bpm"            /* for taxi files chmod in lkarmafs */

int lk_rio_read_playlist(int rio, uint32_t fid, const char * filename);
int lk_rio_read(int rio, uint32_t fid, const char * filename);
int lk_synchronize_necessary(int rio);
uint32_t lk_rio_write(int rio, const char * filename);
void lk_karma_write_dupes(int set);
int lk_rio_update_props_from_tags(int rio, uint32_t fid);


/*
 * auto discover
 */

int lk_ssdp_discover(char **host, uint16_t *port);
int lk_mountSearch_discover(char **device, char **mountPoint);


/*
 * util
 */

char    *simple_itoa(unsigned int i);


/*
 * utf8
 */

void   utf8_destroy      (void);
int    utf8_set_codeset  (char * codeset);
char * utf8_get_codeset  (void);
char * utf8_from_codeset (char * data);
char * utf8_to_codeset   (char * data);

#ifdef __cplusplus
}
#endif  /* C++ */

#endif /* _LKARMA_H */
