/* $Header: https://svn.mpia.de/gulli/TwiceAsNice/branch/unstable/TwiceAsNice/nice/src/libNice/Nice/Chat/Core.h 15549 2018-11-12 04:02:26Z briegel $
*/

#pragma once

#include <iostream>

#include <Nice/Log.h>
#include <Nice/Util/Exception.h>
#include <Nice/Log/LoggerObject.h>
#include <Nice/Time/Time.h>

#define NICE_CHAT_TIMEOUT_IN_SECONDS 4.0

namespace Nice
{
    struct ChatException : Nice::Exception
    {
    };

    namespace Chat
    {
        struct TimeOutException : ChatException
        {
        };

        struct BlockingIOException : ChatException
        {
        };

        struct ConnectionRefusedException : ChatException
        {
        };

        struct ConnectionFormatException : ChatException
        {
        };

        struct ConnectionAlreadyOpenException : ChatException
        {
        };
    };


    /**
    * @class ChatCore
    * @author Florian Briegel
    * @version 11.02.04
    * @date 2012-08-10 11:04:58 AM
    * @brief core communication library for serial tty and sockets tcp
    */

    class ChatCore : public Nice::Shared
    {
        public:
            enum ChatVERBOSE
            { ChatVERBOSE = 0x1, ChatCOLOR = 0x2, ChatTIME = 0x4, ChatECHO = 0x8 };

            //! constructor
            ChatCore ();
            //! constructor with devicename  tcp://HOSTNAME:PORT or tty:/dev/ttyX:BAUD.
            ChatCore ( const char *_device );
            //! constructor with file descriptor
            ChatCore ( int _fd );
            //! destructor
            virtual ~ChatCore ();

            virtual int open () ;
            //! open device with name  tcp://HOSTNAME:PORT or tty:/dev/ttyX:BAUD.
            virtual int open ( const char *_device ) ;
            //! open device with file descriptor
            virtual int open ( int _fd ) ;
            //! closedevice
            virtual int close ();

            //! check if its connected
            virtual bool isConnected() const {return m_fd > 0;};

            //! wait _time sec for data, returns earlier as soon as data has arrived.
            virtual int wait ( Nice::Time _time );

            //! open a listen socket.
            virtual int openListenSocket ( int _port ) ;
            //! try accepting for X secs. X is set by member setTimeout
            virtual int tryAccept ( ChatCore & _newConnection );

            //! set read timeout in seconds, -1 = wait forever.
            void setTimeout ( Nice::Time _t )
            {
                m_timeout = _t;
            };

            Nice::Time timeout ()
            {
                return m_timeout;
            };
            //! set verbosity parameters
            /** The following flags can be combined:
            @verbatim
                ChatCore::VERBOSE        verbosity - prints sent and rcvd lines.
                ChatCore::COLOR          ansi color - if you like color in your live.
                ChatCore::TIME           prints time between sent and rcvd lines.
                ChatCore::ECHO           prints every received character.
            @endverbatim
            *
            */
            void setVerbose ( int _v )
            {
                verbose_ = _v;
            };

            void setName(std::string _name)
            {
            	m_name = _name;
            }

            std::string name()
            {
                return m_name;
            }

        protected:
            int openTCP ( std::string & _host,
                          uint16_t _port ) ;
            int openTTY ( std::string & _device,
                          int _baud,
                          int _numbits,
                          std::string _parity ) ;
            virtual void setStdSettings ();
            virtual void timeoutAktion ( const std::string & ) =0;

            std::string m_device_name;
            int m_fd;
            Nice::Time m_timeout;
            int verbose_;
            bool m_persistent;


            std::string m_name;

        private:
            std::string createMessageForErrno(int errorNumber);
    };
}
