//
// This file is part of the aMule AdunanzA Project (mod of official aMule)
//
// Copyright (c) 2003-2008 aMule AdunanzA Team ( http://www.adunanza.net )
//
// Any parts of this program derived from the xMule, lMule, eMule or aMule project,
// or contributed by third-party developers are copyrighted by their
// respective authors.
//
// 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.
//
// 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, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301, USA
//

#include <iostream>   // Mr Hyde
#include <exception>  // Mr Hyde
#include <vector>     // per std::vector (Mr Hyde)
#include <memory>     // per auto_ptr Mr Hyde
#include <wx/tokenzr.h> // Mr Hyde per wxStringTokenixer

#include "RemoteSettings.h"
#include <protocol/kad/Constants.h>
#include <protocol/ed2k/Constants.h>
#include <common/Macros.h>
#include <protocol/Protocols.h>
#include "InternalEvents.h"                // Needed for CMuleInternalEvent
#include "OtherFunctions.h" // needed for GetConfigDir()
#include "HTTPDownload.h"   // needed for CHTTPDownloader
#include <wx/filefn.h>
#include <wx/url.h>         // wxURL
#include <common/StringFunctions.h>
#include "amule.h"
#include "AdunanzA.h"
#include "Preferences.h" // needed for thePrefs

#define RSEXPIRETIME HR2S(96)

#define RSRECHECKTIME HR2S(6)

#define FAILCHECKSTATIC 3

#define ADURM_TMPFILE "_tmp_adunanza.conf"

/* static*/ const wxString CRemoteSettings::ADUNANZA_CONF(wxT("adunanza.conf")); // name of adunanza.conf file

void CRemoteSettings::AllocateAdunanzaConf()
{
	wxString theAdunanzAConfigPath = m_configDir + CRemoteSettings::ADUNANZA_CONF;



	if (m_pFileConfig) delete m_pFileConfig;

	m_pFileConfig = 0;

	try {
		m_pFileConfig = new wxFileConfig(wxEmptyString, wxEmptyString, theAdunanzAConfigPath );
	}
	catch (const std::bad_alloc& ba) {
		std::cerr << "(CRemoteSettings::AllocateAdunanzaConf) Failed to allocate AdunanzA config manager - " << ba.what() << std::endl;
	}
	catch (const std::exception& e) {
		std::cerr << "(CRemoteSettings::AllocateAdunanzaConf) Failed to allocate AdunanzA config manager (exception) - " << e.what() << std::endl;
	}
	catch (...) {
		std::cerr << "(CRemoteSettings::AllocateAdunanzaConf) Failed to allocate AdunanzA config manager (unknown)" << std::endl;
	}

}

CRemoteSettings::CRemoteSettings() :
	m_validity(0x0),
	m_nextUpdate(0),
	m_failCount(0),
	m_expireTime(0),
	m_recheckTime(0),
	m_pFileConfig(0),
#if 0
	kadRepublishTimeK(KADEMLIAREPUBLISHTIMEK),
	kadRepublishTimeS(KADEMLIAREPUBLISHTIMES),
	kadRepublishTimeN(KADEMLIAREPUBLISHTIMEN),
	kadIndexLifeK(HR2S(96)), // Mr Hyde allineamento eMule AdunanzA 3.15b74
	kadIndexLifeS(HR2S(96)), // Mr Hyde allineamento eMule AdunanzA 3.15b74
	kadTotalStoreKey(KADEMLIATOTALSTOREKEY),
	kadTotalStoreSrc(KADEMLIATOTALSTORESRC),
	kadTotalStoreNotes(KADEMLIATOTALSTORENOTES),
	kadTotalSearchFile(KADEMLIATOTALFILE),
	kadMaxSrcFile(KADEMLIAMAXSOURCEPERFILE),
	kadMaxNotFile(KADEMLIAMAXNOTESPERFILE),
	kadFreshGuess_Tol(KADEMLIAFRESHGUESS_TOLERANCE),
	kadFreshGuess_Weight(KADEMLIAFRESHGUESS_WEIGHT),
	kadFreshGuess_NoNorm(KADEMLIAFRESHGUESS_NONORMSOURCES),
	kadFreshGuess_LowNorm(KADEMLIAFRESHGUESS_LOWNORMSOURCES),
#endif
	m_maxSrc(MAX_SOURCES_FILE_SOFT),
	m_maxSrcUdp(MAX_SOURCES_FILE_UDP),
#if 0
	kadFindValue(KADEMLIA_FIND_VALUE),
	kadStore(KADEMLIA_STORE),
	kadFindNode(KADEMLIA_FIND_NODE),
	kadReaskTime(KADEMLIAREASKTIME),
	kadPubTime(KADEMLIAPUBLISHTIME),
	kadReaskIncs(7),
	mVer(0),
	kadOpcode(OP_KADEMLIAHEADER),
	kadZOpcode(OP_KADEMLIAPACKEDPROT),
#endif
	m_AduValRipBanda_Std(ADUNANZA_DEF_BW_EXT), // Mr Hyde allineamento a 3.16 - ripartitore di banda
	m_UpdateURL(wxT(ADURM_URL))
{
	// wxMutexLocker rmLock(m_mutex); // Mr Hyde: per evitare casini di accessi concorrenti
	m_configDir = GetConfigDir();
	
	AllocateAdunanzaConf();
	if (!m_pFileConfig) {
		std::cerr << "AdunanzA config is NULL - cannot continue" << std::endl;
		return;
	}

	try
	{

		wxString nU;
		m_pFileConfig->Read(wxT("/Adunanza/nextUpdate") , &nU, wxT("0"));
		m_nextUpdate = strtoul(unicode2char(nU.c_str()),NULL,10);
		m_pFileConfig->Read(wxT("/Adunanza/failCount") , &m_failCount, m_failCount);

		//std::cout << "---------------- On init -----------------" << std::endl;
		//PrintAllValues();

		// ReadSettings(cfg); Mr Hyde
		ReadSettings(*m_pFileConfig); // Mr Hyde
	}
	catch(const std::exception& e)
	{
		std::cerr << "(CRemoteSettings) Got exception: " << e.what() << std::endl;
	}
	catch(...)
	{
		std::cerr << "(CRemoteSettings) Got unidentified exception" << std::endl;
	}

	time_t tmp_next = time(NULL) + (time_t)m_expireTime ;
	if ( m_nextUpdate > tmp_next )
		m_nextUpdate = tmp_next;

	// std::cout << "---------------- After reading -----------------" << std::endl;
	//PrintAllValues();
	
	setValid();
	
}

CRemoteSettings::~CRemoteSettings() {
	// wxMutexLocker rmLock(m_mutex); // Mr Hyde: per evitare casini di accessi concorrenti
	// std::cout << "---------------- On close -----------------" << std::endl;
	//PrintAllValues();

	SaveSettings();
	delete m_pFileConfig;
	m_pFileConfig = NULL; // Mr Hyde
}

void CRemoteSettings::PrintAllValues() {
#if ADU_BETA_MAJ > 0
	std::cout << "kadRepublishTimeK:     " << m_KADUSettings.m_kadRepublishTimeK << '\n'
	          << "kadRepublishTimeS:     " << m_KADUSettings.m_kadRepublishTimeS << '\n'
		  << "kadRepublishTimeN:     " << m_KADUSettings.m_kadRepublishTimeN << '\n'
		  << "kadIndexLifeK:         " << m_KADUSettings.m_kadIndexLifeK << '\n' // Mr Hyde all. eMule Adu 3.15b74
		  << "kadIndexLifeS:         " << m_KADUSettings.m_kadIndexLifeS << '\n' // Mr Hyde all. eMule Adu 3.15b74
	          << "kadTotalStoreKey:      " << m_KADUSettings.m_kadTotalStoreKey << '\n'
		  << "kadTotalStoreSrc:      " << m_KADUSettings.m_kadTotalStoreSrc << '\n'
		  << "kadTotalStoreNotes:    " << m_KADUSettings.m_kadTotalStoreNotes << '\n'
	          << "kadTotalSearchFile:    " << m_KADUSettings.m_kadTotalSearchFile << '\n'
	          << "kadMaxSrcFile:         " << m_KADUSettings.m_kadMaxSrcFile << '\n'
		  << "kadMaxNotFile:         " << m_KADUSettings.m_kadMaxNotFile << '\n'
	          << "kadFreshGuess_Tol:     " << m_KADUSettings.m_kadFreshGuess_Tol << '\n'
		  << "kadFreshGuess_Weight:  " << m_KADUSettings.m_kadFreshGuess_Weight << '\n'
		  << "kadFreshGuess_LowNorm: " << m_KADUSettings.m_kadFreshGuess_LowNorm << '\n'
		  << "kadFreshGuess_NoNorm: " << m_KADUSettings.m_kadFreshGuess_NoNorm << '\n'
	          << "maxSrc:               " << m_maxSrc << '\n'
		  << "maxSrcUdp:            " << m_maxSrcUdp << '\n'
	          << "kadFindValue:         " << m_KADUSettings.m_kadFindValue << '\n'
		  << "kadStore:             " << m_KADUSettings.m_kadStore << '\n'
		  << "kadFindNode:          " << m_KADUSettings.m_kadFindNode << '\n'
	          << "kadReaskTime:         " << m_KADUSettings.m_kadReaskTime << '\n'
		  << "kadReaskIncs:         " << m_KADUSettings.m_kadReaskIncs << '\n'
		  << "kadPubTime:           " << m_KADUSettings.m_kadPubTime << '\n'
		  << "mVer:                 " << m_KADUSettings.m_mVer << '\n'
	          << "opcodes Norm:         " << std::hex << (unsigned short) m_KADUSettings.m_kadOpcode << '\n'
		  << "Zip:                  " << std::hex << (unsigned short) m_KADUSettings.m_kadZOpcode << std::dec << '\n'
	          << "- nextUpdate in:      " << m_nextUpdate-time(NULL) << " seconds\n"
	          << "- expireTime:         " << m_expireTime << '\n'
		  << "- recheckTime:        " << m_recheckTime << '\n'
		  << "failCount:            " << m_failCount << '\n'
		  << "AduValRipBanda_Std:   " << m_AduValRipBanda_Std << '\n' // Mr Hyde allineamento 3.16, ripartitore banda
	          << "updating from:        " << (const char*)unicode2char(m_UpdateURL) << '\n';

		// Mr Hyde allineamento eMule 3.15 (mods da bannare)
		if (m_badMods.empty())
			std::cout << "No mods to ban";		
		else {
			std::cout << "Mods to ban: \n{";
			for (std::vector<wxString>::const_iterator it = m_badMods.begin();
					it != m_badMods.end();
					++it) {
				std::cout << "\n\t" << (const char*) unicode2char(*it);
			}
			std::cout << "\n}";
		}
		std::cout << std::endl;
#endif
}


void CRemoteSettings::SaveToFile() {
	SaveSettings();
	AllocateAdunanzaConf();
}

void CRemoteSettings::ReadSettings(const wxConfigBase& docfg) {
	long          kadRepublishTimeK = theApp->get_kadRepublishTimeK()  ;
	long          kadRepublishTimeS = theApp->get_kadRepublishTimeS()  ;
	long          kadRepublishTimeN = theApp->get_kadRepublishTimeN()  ;

	long          kadIndexLifeK = theApp->get_kadIndexLifeK()  ; // Mr Hyde per allineamento a eMule 3.15b74
	long          kadIndexLifeS = theApp->get_kadIndexLifeS()  ; // Mr Hyde per allineamento a eMule 3.15b74

	uint32_t      kadTotalStoreKey = theApp->get_kadTotalStoreKey()  ;   // Mr Hyde: cambiato da long a uint32_t in accordo con kademlia.h
	uint32_t      kadTotalStoreSrc = theApp->get_kadTotalStoreSrc()  ;   // Mr Hyde: cambiato da long a uint32_t in accordo con kademlia.h
	uint32_t      kadTotalStoreNotes = theApp->get_kadTotalStoreNotes()  ; // Mr Hyde: cambiato da long a uint32_t in accordo con kademlia.h

	long          kadTotalSearchFile = theApp->get_kadTotalSearchFile()  ;

	long          kadMaxSrcFile = theApp->get_kadMaxSrcFile()  ;
	long          kadMaxNotFile = theApp->get_kadMaxNotFile()  ;

	double        kadFreshGuess_Tol = theApp->get_kadFreshGuess_Tol()  ;
	double        kadFreshGuess_Weight = theApp->get_kadFreshGuess_Weight()  ;
	long          kadFreshGuess_NoNorm = theApp->get_kadFreshGuess_NoNorm()  ;
	long          kadFreshGuess_LowNorm = theApp->get_kadFreshGuess_LowNorm()  ;

	long          kadFindValue = theApp->get_kadFindValue()  ;
	long          kadStore = theApp->get_kadStore()  ;
	long          kadFindNode = theApp->get_kadFindNode()  ;

	long          kadReaskTime = theApp->get_kadReaskTime()  ;
	long          kadPubTime = theApp->get_kadPubTime()  ;

	long          kadReaskIncs = theApp->get_kadReaskIncs()  ;

	long          mVer = theApp->get_mVer()  ;

	unsigned char kadOpcode = theApp->get_kadOpcode()  ;
	unsigned char kadZOpcode = theApp->get_kadZOpcode()  ;



	docfg.Read(wxT("/Adunanza/expireTime") , &m_expireTime, m_expireTime);
	docfg.Read(wxT("/Adunanza/recheckTime") , &m_recheckTime, m_recheckTime);
	docfg.Read(wxT("/Adunanza/UpdateURL") , &m_UpdateURL, m_UpdateURL);

	if (m_expireTime > RSEXPIRETIME) m_expireTime = RSEXPIRETIME;

	if (m_recheckTime > RSRECHECKTIME) m_recheckTime = RSRECHECKTIME;

	docfg.Read(wxT("/Adunanza/kadRepublishTimeK") , &kadRepublishTimeK, kadRepublishTimeK);
	docfg.Read(wxT("/Adunanza/kadRepublishTimeS") , &kadRepublishTimeS, kadRepublishTimeS);
	docfg.Read(wxT("/Adunanza/kadRepublishTimeN") , &kadRepublishTimeN, kadRepublishTimeN);

	docfg.Read(wxT("/Adunanza/kadIndexLifeK") , &kadIndexLifeK, kadIndexLifeK); // Mr Hyde all emule Adu 3.15b74
	docfg.Read(wxT("/Adunanza/kadIndexLifeS") , &kadIndexLifeS, kadIndexLifeS); // Mr Hyde all emule Adu 3.15b74

	long long_kadTotalStoreKey   = 0;
	long long_kadTotalStoreSrc   = 0;
	long long_kadTotalStoreNotes = 0;
	long long_AduValRipBanda_Std = ADUNANZA_DEF_BW_EXT; // Mr Hyde allineamento 3.16, ripartitore banda

	docfg.Read(wxT("/Adunanza/kadTotalStoreKey")   , &long_kadTotalStoreKey,   long_kadTotalStoreKey);
	docfg.Read(wxT("/Adunanza/kadTotalStoreSrc")   , &long_kadTotalStoreSrc,   long_kadTotalStoreSrc);
	docfg.Read(wxT("/Adunanza/kadTotalStoreNotes") , &long_kadTotalStoreNotes, long_kadTotalStoreNotes);
	docfg.Read(wxT("/Adunanza/AduValRipBandaStd")  , &long_AduValRipBanda_Std, long_AduValRipBanda_Std); // Mr Hyde allineamento 3.16, ripartitore banda

	kadTotalStoreKey     = static_cast<uint32_t>(long_kadTotalStoreKey);
	kadTotalStoreSrc     = static_cast<uint32_t>(long_kadTotalStoreSrc);
	kadTotalStoreNotes   = static_cast<uint32_t>(long_kadTotalStoreNotes);
	m_AduValRipBanda_Std = static_cast<uint32_t>(long_AduValRipBanda_Std); // Mr Hyde allineamento 3.16, ripartitore banda
	
	docfg.Read(wxT("/Adunanza/kadTotalSearchFile") , &kadTotalSearchFile, kadTotalSearchFile);
	
	docfg.Read(wxT("/Adunanza/kadMaxSrcFile") , &kadMaxSrcFile, kadMaxSrcFile);
	docfg.Read(wxT("/Adunanza/kadMaxNotFile") , &kadMaxNotFile, kadMaxNotFile);

	kadFreshGuess_Tol = docfg.Read(wxT("/Adunanza/kadFreshGuess_Tol") , (long)(kadFreshGuess_Tol * 10000)) / 10000.f;
	kadFreshGuess_Weight = docfg.Read(wxT("/Adunanza/kadFreshGuess_Weight") , (long)(kadFreshGuess_Weight * 10000)) / 10000.f;
	docfg.Read(wxT("/Adunanza/kadFreshGuess_LowNorm") , &kadFreshGuess_LowNorm, kadFreshGuess_LowNorm);
	docfg.Read(wxT("/Adunanza/kadFreshGuess_NoNorm") , &kadFreshGuess_NoNorm, kadFreshGuess_NoNorm);

	docfg.Read(wxT("/Adunanza/maxSrc") , &m_maxSrc, m_maxSrc);
	docfg.Read(wxT("/Adunanza/maxSrcUdp") , &m_maxSrcUdp, m_maxSrcUdp);

	docfg.Read(wxT("/Adunanza/kadFindValue") , &kadFindValue, kadFindValue);
	docfg.Read(wxT("/Adunanza/kadStore") , &kadStore, kadStore);
	docfg.Read(wxT("/Adunanza/kadFindNode") , &kadFindNode, kadFindNode);

	docfg.Read(wxT("/Adunanza/kadReaskTime") , &kadReaskTime, kadReaskTime);
	docfg.Read(wxT("/Adunanza/kadReaskIncs") , &kadReaskIncs, kadReaskIncs);
	docfg.Read(wxT("/Adunanza/kadPubTime") , &kadPubTime, kadPubTime);
	docfg.Read(wxT("/Adunanza/mVer") , &mVer, mVer);

	kadOpcode = (unsigned char)docfg.Read(wxT("/Adunanza/kadOpcode") , (long)kadOpcode);
	kadZOpcode = (unsigned char)docfg.Read(wxT("/Adunanza/kadZOpcode") , (long)kadZOpcode);

	// Mr Hyde:
	// Per allineamento a 3.15
	wxString allBadMods;
	docfg.Read(wxT("/Adunanza/modstringban") , &allBadMods, allBadMods);
	m_badMods.clear();
	if (!allBadMods.IsEmpty()) {
		// l'elenco delle mod e' in un'unica stringa,
		// le mod sono separatre dal carattere ";" (punto e virgola)
		wxString modName;
		wxStringTokenizer tkz(allBadMods, wxT(";"));
		while ( tkz.HasMoreTokens() ) {
			wxString token = tkz.GetNextToken();
			m_badMods.push_back(token);
		}
	}

	m_KADUSettings.assign(kadRepublishTimeK,
				kadRepublishTimeS,
				kadRepublishTimeN,
				kadIndexLifeK,
				kadIndexLifeS,
				kadTotalStoreKey,
				kadTotalStoreSrc,
				kadTotalStoreNotes,
				kadTotalSearchFile,
				kadMaxSrcFile,
				kadMaxNotFile,
				kadFreshGuess_Tol,
				kadFreshGuess_Weight,
				kadFreshGuess_NoNorm,
				kadFreshGuess_LowNorm,
				kadFindValue,
				kadStore,
				kadFindNode,
				kadReaskTime,
				kadPubTime,
				kadReaskIncs,
				mVer,
				kadOpcode,
				kadZOpcode);

/* 
QUESTO NON POSSO CHIAMARLO QUI: le statistiche potrebbero non essere ancora partite
e io avrei un errore di lock. Vedo di chiamarlo in amule.cpp
Devo studiare il come ri-farlo quando viene ricaricato RemoteSettings ciclicamente

	// Per ripartitore di banda: mi assicuro di calcolare i Ratio
	if (thePrefs::ADU_GetRipBanda()) {
		thePrefs::ADU_SetValueRipBanda(m_AduValRipBanda_Std);
	}	
	CAdunanzAUtilities::CalcolaRatio(false);
*/
}

void CRemoteSettings::SaveSettings() {
	// e' assurdo tenere aperto il file di configurazione per tutto il tempo,
	// queste NON sono le preferenze.
	//

	if (!m_pFileConfig) return; // Mr Hyde
	m_pFileConfig->Write(wxT("/Adunanza/nextUpdate") , wxString::Format(wxT("%ul"),m_nextUpdate));
	m_pFileConfig->Write(wxT("/Adunanza/failCount") , m_failCount);
	m_pFileConfig->Write(wxT("/Adunanza/UpdateURL") , m_UpdateURL);
	m_pFileConfig->Write(wxT("/Adunanza/expireTime") , m_expireTime);
	m_pFileConfig->Write(wxT("/Adunanza/recheckTime") , m_recheckTime);

	m_pFileConfig->Write(wxT("/Adunanza/kadRepublishTimeK") , theApp->get_kadRepublishTimeK());
	m_pFileConfig->Write(wxT("/Adunanza/kadRepublishTimeS") , theApp->get_kadRepublishTimeS());
	m_pFileConfig->Write(wxT("/Adunanza/kadRepublishTimeN") , theApp->get_kadRepublishTimeN());

	m_pFileConfig->Write(wxT("/Adunanza/kadIndexLifeK") , theApp->get_kadIndexLifeK()); // Mr Hyde all emule Adu 3.15b74
	m_pFileConfig->Write(wxT("/Adunanza/kadIndexLifeS") , theApp->get_kadIndexLifeS()); // Mr Hyde all emule Adu 3.15b74

	long long_kadTotalStoreKey   = static_cast<long>(theApp->get_kadTotalStoreKey());
	long long_kadTotalStoreSrc   = static_cast<long>(theApp->get_kadTotalStoreSrc());
	long long_kadTotalStoreNotes = static_cast<long>(theApp->get_kadTotalStoreNotes());
	long long_AduValRipBanda_Std = static_cast<long>(m_AduValRipBanda_Std); // Mr Hyde allineamento 3.16, riparitore banda

	m_pFileConfig->Write(wxT("/Adunanza/kadTotalStoreKey") ,   long_kadTotalStoreKey);
	m_pFileConfig->Write(wxT("/Adunanza/kadTotalStoreSrc") ,   long_kadTotalStoreSrc);
	m_pFileConfig->Write(wxT("/Adunanza/kadTotalStoreNotes") , long_kadTotalStoreNotes);
	m_pFileConfig->Write(wxT("/Adunanza/AduValRipBanda")     , long_AduValRipBanda_Std); // Mr Hyde allineamento 3.16, riparitore banda

	m_pFileConfig->Write(wxT("/Adunanza/kadTotalSearchFile") , theApp->get_kadTotalSearchFile());

	m_pFileConfig->Write(wxT("/Adunanza/kadMaxSrcFile") , theApp->get_kadMaxSrcFile());
	m_pFileConfig->Write(wxT("/Adunanza/kadMaxNotFile") , theApp->get_kadMaxNotFile());

	m_pFileConfig->Write(wxT("/Adunanza/kadFreshGuess_Tol") , (long)(theApp->get_kadFreshGuess_Tol() * 10000));
	m_pFileConfig->Write(wxT("/Adunanza/kadFreshGuess_Weight") , (long)(theApp->get_kadFreshGuess_Weight() * 10000));
	m_pFileConfig->Write(wxT("/Adunanza/kadFreshGuess_LowNorm") , theApp->get_kadFreshGuess_LowNorm());
	m_pFileConfig->Write(wxT("/Adunanza/kadFreshGuess_NoNorm") , theApp->get_kadFreshGuess_NoNorm());

	m_pFileConfig->Write(wxT("/Adunanza/maxSrc") , m_maxSrc);
	m_pFileConfig->Write(wxT("/Adunanza/maxSrcUdp") , m_maxSrcUdp);

	m_pFileConfig->Write(wxT("/Adunanza/kadFindValue") , theApp->get_kadFindValue());
	m_pFileConfig->Write(wxT("/Adunanza/kadStore") , theApp->get_kadStore());
	m_pFileConfig->Write(wxT("/Adunanza/kadFindNode") , theApp->get_kadFindNode());

	m_pFileConfig->Write(wxT("/Adunanza/kadReaskTime") , theApp->get_kadReaskTime());
	m_pFileConfig->Write(wxT("/Adunanza/kadReaskIncs") , theApp->get_kadReaskIncs());
	m_pFileConfig->Write(wxT("/Adunanza/kadPubTime") , theApp->get_kadPubTime());
	m_pFileConfig->Write(wxT("/Adunanza/mVer") , theApp->get_mVer());

	m_pFileConfig->Write(wxT("/Adunanza/kadOpcode"), (long)theApp->get_kadOpcode());
	m_pFileConfig->Write(wxT("/Adunanza/kadZOpcode"), (long)theApp->get_kadZOpcode());

	if (!m_badMods.empty()) {
		wxString tmpBadMods;
		unsigned int i;
		for (i = 0; i < (m_badMods.size() - 1); i++) {
			tmpBadMods << m_badMods[i] << wxChar(';');
		}
		tmpBadMods << m_badMods[i];
		m_pFileConfig->Write(wxT("/Adunanza/modstringban") , tmpBadMods);
	}

}

void CRemoteSettings::CheckUpdate() {
	if (time(NULL) < (time_t)m_nextUpdate)
		return;

	//printf("---------------- Before update -----------------\n");
	//PrintAllValues();

	wxString strURL(m_UpdateURL);

	if (wxURL(strURL).GetError() == wxURL_NOERR) { // Mr Hyde: validate URL
		wxString tmpFile(m_configDir + wxT(ADURM_TMPFILE));
		if (wxFileExists(tmpFile)) {
			wxRemoveFile(tmpFile);
		}

		try {
			CHTTPDownloadThread *downloader = new CHTTPDownloadThread(strURL, tmpFile, HTTP_AdunanzaConf);
			downloader->Create();
			downloader->Run();
		}
		catch (...) {
			std::cerr << "(CRemoteSettings::CheckUpdate) Got exception! " << std::endl;
		}
	}
}

void CRemoteSettings::FileDownloadedCallback(int result) {
	// wxMutexLocker rmLock(m_mutex); // Mr Hyde: per evitare casini di accessi concorrenti
	//printf("---------------- Before update (2) ----------------- result: %d\n",result);
	//PrintAllValues();

	if (result == -1) {
		double scaled = rand() / (RAND_MAX + 1.0);
		m_nextUpdate = time(NULL) + (time_t) m_recheckTime + (time_t)((m_recheckTime + 1) * scaled);
		m_failCount++;
		if (m_failCount > FAILCHECKSTATIC) {
			m_UpdateURL = wxT(ADURM_URL); // perche' sta cosa??? cosi' salvo sempre la costante e mai il valore eventualmente letto dal file scaricato da remoto!
			SaveSettings();
		}
		return;
	}

	wxString tmpFile(m_configDir + wxT(ADURM_TMPFILE));
	if (!wxFileExists(tmpFile))
		return;

	try {

		// wxFileConfig *tmpcfg = new wxFileConfig(wxEmptyString, wxEmptyString, tmpFile); // Mr Hyde - uso auto_ptr
		std::auto_ptr<wxFileConfig> ptmpcfg(new wxFileConfig(wxEmptyString, wxEmptyString, tmpFile));

		ReadSettings(*ptmpcfg);
		// delete tmpcfg; // Mr Hyde: uso auto_ptr

		wxRemoveFile(tmpFile);

		SaveToFile();
	}
	catch(...)
	{
		std::cerr << "Something of wrong in CRemoteSettings::FileDownloadedCallback" << std::endl;
	}

	m_nextUpdate = time(NULL) + (time_t) m_expireTime;
	m_failCount = 0;

	std::cout << "---------------- After update -----------------" << std::endl;
	PrintAllValues();
}

