#ifndef CONNECTION_H
#define CONNECTION_H

#include <QObject>
#include <QHostAddress>
class QStateMachine;
class QAbstractSocket;

/*
  <hash> - remote host, remote port, challenge

  */
class Connection : public QObject
{
Q_OBJECT
public:
    Connection(QAbstractSocket *source, QObject *parent = 0);

private slots:
    void onSourceSendVersionState();
    void onSourceSecurityHandshakeState();
    void onSourceSendSecurityTypesState();
    void onSourceSendErrorResponseState();
    void onSourceSendChallengeState();
    void onSourceAuthHandshakeState();
    void onSourceCheckAuthState();
    void onSourceSendAuthResultState();
    void onSourceDiscardClientInitState();

    void onTargetConnectState();
    void onTargetVersionHandshakeState();
    void onTargetSendVersionResponseState();
    void onTargetSecurityHandshakeState();
    void onTargetReadSecurityTypeState();
    void onTargetSendVNCAuthState();
    void onTargetSendAuthNoneState();
    void onTargetReadAuthChallengeState();
    void onTargetReadSecurityResultState();
    void onTargetSendClientInitState();

    void onForwardSourceToTargetState();
    void onForwardTargetToSourceState();

    void onErrorState();
    void onExitState();

signals:
    void sourceVersionHandshakeSuccess();
    void sourceVersionHandshakeFailure();
    void sourceSecurityHandshakeSuccess();
    void sourceSecurityHandshakeFailure();
    void sourceAuthSuccess();
    void sourceAuthFailure();

    void targetVersionHandshakeSuccess();
    void targetVersionHandshakeFailure();
    void targetUsesVNCAuth();
    void targetUsesNoAuth();
    void targetUsesUnsupportedAuth();
    void targetAuthSuccess();
    void targetAuthFailure();

    void sourceBytesAvailable();
    void targetBytesAvailable();

private:
    QStateMachine *m_connectionStateMachine;
    QAbstractSocket *m_targetSocket;
    QAbstractSocket *m_sourceSocket;
};

#endif // CONNECTION_H

