/***************************************************************************
 * C++ Implementation:                                                     *
 * Copyright (C) 2012-2017 by Eduard Kalinowski                            *
 * Germany, Lower Saxony, Hanover                                          *
 * eduard_kalinowski@yahoo.de                                              *
 *                                                                         *
 * HTTraQt is free software; may be distributed and/or modified under the  *
 * terms of the GNU General Public License version 3 as published by the   *
 * Free Software Foundation and appearing in the file LICENSE_GPLv3        *
 * included in the packaging of this file.                                 *
 *                                                                         *
 * 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 Lesser General Public        *
 * License along with HTTraQt. If not, see  http://www.gnu.org/licenses    *
 ***************************************************************************/

#ifndef HTINTERFACE_H
#define HTINTERFACE_H

#ifdef __cplusplus
extern "C"
{
#endif

#include <httrack-library.h>
#include <htsopt.h>
#include <htsnet.h>
#include <htswrap.h>

#include <htsdefines.h>



// #ifdef __cplusplus
// }
// #endif


// #ifndef DEBUG
// #define ASSERT(x)
// #else
#define ASSERT(x) \
    if (! (x) && !(x-1)) { \
        qDebug() << "ERROR!! Assert " << #x << " failed\n"; \
        qDebug() << " on line " << __LINE__  << "\n"; \
        qDebug() << " in file " << __FILE__ << "\n";  \
        return 1; \
    }

#ifdef _DEBUG

#define VERIFY_ISWRITEPOINTER(a) \
    { if(::IsBadWritePtr(a, sizeof(LPDWORD))) \
        { ::OutputDebugString(_T("Parameter ") _T(#a) \
                              _T(" is not a valid write pointer\r\n"));}}
#define VERIFY_ISREADPOINTER(a) \
    { if(::IsBadReadPtr(a, sizeof(LPDWORD)))\
        { ::OutputDebugString(_T("Parameter ") _T(#a) \
                              _T(" is not a valid read pointer\r\n"));}}

#define VERIFY_ISWRITEDATA(a, l)\
    { if(::IsBadWritePtr(a, l)) \
        { ::OutputDebugString(_T("Parameter ") _T(#a) \
                              _T(" is not a valid write area\r\n"));}}
#define VERIFY_ISREADDATA(a, l)\
    { if(::IsBadReadPtr(a, l))  \
        { ::OutputDebugString(_T("Parameter ") _T(#a) \
                              _T(" is not a valid read area\r\n"));}}

#define ASSERT_ISWRITEPOINTER(a)\
    { if(::IsBadWritePtr(a, sizeof(LPDWORD))) \
        { ::OutputDebugString(_T("Parameter ") _T(#a) \
                              _T(" is not a valid write pointer\r\n")); ASSERT(false);}}
#define ASSERT_ISREADPOINTER(a)\
    { if(::IsBadReadPtr(a, sizeof(LPDWORD)))  \
        { ::OutputDebugString(_T("Parameter ") _T(#a) \
                              _T(" is not a valid read pointer\r\n")); ASSERT(false);}}

#define ASSERT_ISWRITEDATA(a, l)\
    { if(::IsBadWritePtr(a, l)) \
        { ::OutputDebugString(_T("Parameter ") _T(#a) \
                              _T(" is not a valid write area\r\n")); ASSERT(false);}}
#define ASSERT_ISREADDATA(a, l)   { if(::IsBadReadPtr(a, l))  \
        { ::OutputDebugString(_T("Parameter ") _T(#a)\
                              _T(" is not a valid read area\r\n")); ASSERT(false);}}

#else

#define VERIFY_ISWRITEPOINTER(a)
#define VERIFY_ISREADPOINTER(a)

#define VERIFY_ISWRITEDATA(a, l)
#define VERIFY_ISREADDATA(a, l)

#define ASSERT_ISWRITEPOINTER(a)
#define ASSERT_ISREADPOINTER(a)

#define ASSERT_ISWRITEDATA(a, l)
#define ASSERT_ISREADDATA(a, l)

#endif


// hotfix for the htsglobal macros
// to disable
#ifdef maximum
#undef maximum
#endif

#ifdef minimum
#undef minimum
#endif

// #ifdef __cplusplus
// extern "C" {
// #endif


#if __WIN32
#else
#define __cdecl
#endif

void httraq_main();
void htinfo_state_url(char* c);
void htinfo_mirror_info(char* c);

//     int scan_end(void);
void __cdecl wrapper_init(t_hts_callbackarg* carg);
void __cdecl wrapper_uninit(t_hts_callbackarg* carg);
int __cdecl wrapper_start(t_hts_callbackarg* carg, httrackp *opt);
int __cdecl wrapper_chopt(t_hts_callbackarg* carg, httrackp *opt);
int __cdecl wrapper_end(t_hts_callbackarg* carg, httrackp *opt);
int __cdecl wrapper_checkhtml(t_hts_callbackarg* carg, httrackp *opt, char* html, int len, char* url_adresse, char* url_fichier);
int __cdecl wrapper_preprocesshtml(t_hts_callbackarg* carg, httrackp *opt, char** html, int* len, const char* url_address, const char* url_file);
int __cdecl wrapper_postprocesshtml(t_hts_callbackarg* carg, httrackp *opt, char** html, int* len, const char* url_address, const char* url_file);
int __cdecl wrapper_loop(t_hts_callbackarg* carg, httrackp *opt, lien_back* back, int back_max, int back_index, int lien_tot, int lien_ntot, int stat_time, hts_stat_struct* stats); // appel� � chaque boucle de HTTrack
//     int __cdecl wrapper_loop ( void* _back, int back_max, int back_index, int lien_n, int lien_tot, int stat_time, hts_stat_struct* stats );
const char* __cdecl wrapper_query(t_hts_callbackarg* carg, httrackp *opt, const char* question);
const char* __cdecl wrapper_query2(t_hts_callbackarg* carg, httrackp *opt, const char* question);
const char* __cdecl wrapper_query3(t_hts_callbackarg* carg, httrackp *opt, const char* question);
int __cdecl wrapper_check(t_hts_callbackarg* carg, httrackp *opt, const char* adr, const char* fil, int status);
int __cdecl wrapper_check_mime(t_hts_callbackarg* carg, httrackp *opt, const char* adr, const char* fil, const char* mime, int status);
void __cdecl wrapper_pause(t_hts_callbackarg* carg, httrackp *opt, const char* lockfile);
void __cdecl wrapper_filesave(t_hts_callbackarg* carg, httrackp *opt, const char* file);
void __cdecl wrapper_filesave2(t_hts_callbackarg* carg, httrackp *opt, const char* adr, const char* fil, const char* save, int is_new, int is_modified, int not_updated);
int __cdecl wrapper_linkdetected(t_hts_callbackarg* carg, httrackp *opt, char* link);
int __cdecl wrapper_linkdetected2(t_hts_callbackarg* carg, httrackp *opt,  char* link, const char* start_tag);
int __cdecl wrapper_xfrstatus(t_hts_callbackarg* carg, httrackp *opt, void* back);
int __cdecl wrapper_savename(t_hts_callbackarg* carg, httrackp *opt, char* adr_complete, char* fil_complete, char* referer_adr, char* referer_fil, char* save);
int __cdecl wrapper_sendheader(t_hts_callbackarg* carg, httrackp *opt,  char* buff, const char* adr, const char* fil, const char* referer_adr, const char* referer_fil, htsblk* outgoing);
int __cdecl wrapper_receiveheader(t_hts_callbackarg* carg, httrackp *opt,  char* buff, const char* adr, const char* fil, const char* referer_adr, const char* referer_fil, htsblk* incoming);
//   void htinfo_errors ( char* chaine );
//   void htinfo_active_connections ( char* chaine );
//   void htinfo_files_updated ( char* chaine );
//   void htinfo_transfer_rate ( char* chaine );
//   void htinfo_files_written ( char* chaine );
//   void htinfo_bytes_saved ( char* chaine );
//   void htinfo_time ( char* chaine );
//     void htinfo_link_detected(char* chaine);
// void htcommandend(void);


#ifdef __cplusplus
}
#endif


typedef struct {
    //     int ask_refresh;
    int refresh;
    LLint stat_bytes;
    int stat_time;
    int lien_n;
    int lien_tot;
    int stat_nsocket;
    int rate;
    int irate;
    int ft;
    LLint stat_written;
    int stat_updated;
    int stat_errors;
    int stat_warnings;
    int stat_infos;
    TStamp stat_timestart;
    int stat_back;
} t_InpInfo;


#endif