#ifndef CLIENT_H
#define CLIENT_H

#include <QQueue>
#include <QSettings>
#include <pimutex.h>
#include "SH_server_base.h"
#include "SH_client_channel.h"
#include "SH_ui_sync.h"
#include "SH_network_types.h"
#include "SH_packages.h"
#include "pultwindow_base.h"

const PIString URIScheme("shsserver://");

class RemoteClient: public QObject, public PIObject {
	Q_OBJECT
	PIOBJECT(RemoteClient)
public:
	RemoteClient(PultWindowBase * v);
	~RemoteClient();

	void connect(const QString & addr);
	void stop();

protected:
	void timerEvent(QTimerEvent * e) override;
	void cacheData(const QByteArray & data, const QString & type);
	QByteArray restoreData(const QString & type);
	QByteArray stringHash(const QString & s);
	void setStatus(QString s);
	void packageNameReceived(const PIString & pname);
	void packageReceived(const SHPackages::Package & p);
	void keyProbe();
	void sendGraphicsRequest();
	EVENT_HANDLER(void, connectedP);
	EVENT_HANDLER(void, disconnectedP);
	EVENT_HANDLER1(void, receiveEvent, PIByteArray, data);
	EVENT_HANDLER(void, grConnectedP);
	EVENT_HANDLER(void, grDisconnectedP);
	EVENT_HANDLER1(void, grReceiveEvent, PIByteArray, data);

	static const PIByteArray & key();

	PultWindowBase * view;
	QObject * form;
	QString last_key, last_addr, server_name;
	SHUISync sync;
	SHClientChannel channel, channel_gr;
	PIString package_dir;
	PacketServerInfo server_info;
	QMap<QByteArray, QString> keys_;
	QByteArray rcc_content, ui_content;
	QSettings settings;
	int rec_sync_ver, timer_diff;
	bool force_download, sleeping;
	uchar kres;

private slots:
	void objectEvent(QByteArray data);
	void appStateChanged(Qt::ApplicationState state);
	void changeRoleRequest(int index);

public slots:
	void reconnect();
	void setForm(QObject * f, SHSUiLoader * loader);
	void keyProbe(QString key);
	void connectRequest(QString addr);
	void disconnectRequest();
	void exited();

signals:
	//void tcpConnected(PacketServerInfo server);
	void serverConnected(PacketServerInfo server);
	void packageUpdating();
	void packageNoSuchOnServer();
	void packageExists(QString);
	void packageDownloadStarted();
	void packageDownloadFinished();
	void packageReady(QString, bool);
	void statusChanged(QString);

};

#endif // CLIENT_H
