
#ifndef CLIENT_IMP_H
#define CLIENT_IMP_H

#include <list>

#include "protocol.h"
#include "client.h"
#include "sender.h"
#include "receiver.h"
#include "sockets.h"
#include "threads.h"

class client_imp : public client
{
private:
    hook& hk_;
    volatile bool active_;

    sockets :: clientSocket cs;

    sender snd_;
    threads :: thread* sendThread_;

    receiver rcv_;
    threads :: thread* rcvThread_;
public:

hook basicHook;

// --------------------------------

    client_imp() : hk_(basicHook), snd_(&cs), rcv_(&basicHook, &cs)
    { 
        active_ = false; 
    };

// --------------------------------

    void setHook(hook& h)   { hk_ = h;    rcv_.setHook(&h);  };
    bool active(void)       { return active_;                };

// --------------------------------

    bool connect(const char* hostName, int port)
    {
        snd_.clear();
        if (cs.connectToHost(hostName, port))
        {
            // nastartujeme posilaci vlakno
            sendThread_ = new threads :: thread(&snd_, false);

            // nastartujeme prijimaci vlakno
            rcvThread_ = new threads :: thread(&rcv_, false);

            // vratime, ze se podarilo spojeni
            active_ = true;            
            return true;
        } else return false;
    }

// --------------------------------

    void disconnect(void)
    {
        try
        {
            cs.close();
        }
        catch (std :: exception e)
        {
            // nic nedelej
        }

        snd_.send(NULL);
        sendThread_->join();               delete sendThread_;       sendThread_ = NULL;

        rcvThread_->join();                delete rcvThread_;        rcvThread_ = NULL;

        active_ = false;
        snd_.clear();
    };

// --------------------------------

    void send(const char* msg)
    {
        if (active_)
            snd_.send(_strdup(msg));
    };
};

#endif