/*
 *  Copyright (C) 2005 Alo Sarv <madcat_@users.sourceforge.net>
 *
 *  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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#ifndef __BASECLIENT_H__
#define __BASECLIENT_H__

#include <hnbase/osdep.h>
#include <hncore/fwd.h>
#include <boost/scoped_ptr.hpp>

class ChunkMask : public std::vector<bool> {
public:
	ChunkMask(uint32_t chunkSize) : m_chunkSize(chunkSize) {}
	uint32_t getChunkSize() const { return m_chunkSize; }
private:
	ChunkMask();
	uint32_t m_chunkSize;
};

namespace Detail {
	class ClientManagerIterator;
}

class BaseClient {
public:
	BaseClient(ModuleBase *module);
	virtual ~BaseClient() = 0;

	// base accessors
	ModuleBase* getModule()     const { return m_module;        }
	SharedFile* getReqFile()    const { return m_reqFile;       }
	PartData*   getSource()     const { return m_partData;      }
	bool        wantsUpload()   const { return m_reqFile;       }
	bool        canDownload()   const { return m_partData;      }
	bool        isUploading()   const { return m_isUploading;   }
	bool        isDownloading() const { return m_isDownloading; }
	bool        isConnected()   const { return m_isConnected;   }

	// virtual accessors
	virtual IPV4Address getAddr()              const;
	virtual std::string getNick()              const;
	virtual std::string getSoft()              const;
	virtual std::string getSoftVersion()       const;
	virtual uint64_t    getSessionUploaded()   const;
	virtual uint64_t    getSessionDownloaded() const;
	virtual uint64_t    getTotalUploaded()     const;
	virtual uint64_t    getTotalDownloaded()   const;
	virtual uint32_t    getUploadSpeed()       const;
	virtual uint32_t    getDownloadSpeed()     const;
	virtual uint32_t    getQueueRanking()      const;

	// modifiers
	void setSource(
		PartData *file,
		const std::vector<bool> &sourceMask = std::vector<bool>()
	);
	void setRequest(
		SharedFile *file,
		const std::vector<bool> &sourceMask = std::vector<bool>()
	);
	void setConnected(bool state);
	void setDownloading(bool state);
	void setUploading(bool state);

	// utilties
	Detail::LockedRangePtr getChunkReq(
		uint32_t size, const ChunkMask &pred
	);
private:
	BaseClient();
	BaseClient(const BaseClient&);
	BaseClient& operator=(const BaseClient&);

	ModuleBase          *m_module;
	SharedFile          *m_reqFile;
	PartData            *m_partData;
	bool                 m_isConnected;
	bool                 m_isUploading;
	bool                 m_isDownloading;
	Detail::UsedRangePtr m_usedRange;
	boost::scoped_ptr<Detail::ClientManagerIterator> m_iter;
};

#endif