//
//  Copyright © 2001 - 2002, RESON Inc. All Rights Reserved.
//
//  No part of this file may be reproduced or transmitted in any form or by
//  any means, electronic or mechanical, including photocopy, recording, or
//  information storage or retrieval system, without permission in writing
//  from RESON Inc.
//
//  Filename:   SocketServer.h
//
//  Project:    6046.
//
//  Author(s):  W. Arcus
//
//  Purpose:    
//
//  Notes:
//

#if !defined(AFX_SOCKETSERVER_H__95126415_1435_4920_91B3_F210510B80DF__INCLUDED_)
#define AFX_SOCKETSERVER_H__95126415_1435_4920_91B3_F210510B80DF__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#pragma warning( push, 3 )                                          // Microsoft's STL list implementation is dirty at warning level 4.
#include <list>
#include <algorithm>
#pragma warning( pop )

#include "..\Utils\NetUtils\ThreadedSocket.h"
#pragma warning ( disable: 4018 )
#include "..\Utils\NetUtils\7kSocketProtocol.h"
#pragma warning ( default: 4018 )

typedef CThreadedSocket<C7kSocketProtocol>  C7kThreadedSocket;

typedef struct tagDESCRIPTOR
{
    int                  m_iIndex;
    C7kThreadedSocket   *m_pSocket;

    tagDESCRIPTOR(  const int                 &riIndex  = -1,
                    C7kThreadedSocket * const &rpSocket = NULL )
    {
        m_iIndex  = riIndex;
        m_pSocket = rpSocket;
    }

    virtual ~tagDESCRIPTOR( void )
    {
        m_iIndex  = -1;
        m_pSocket = NULL;
    }

    void Destroy( void )
    {
        if ( IsValid() )
        {
            delete m_pSocket;
            m_pSocket = NULL;

            m_iIndex = -1;
        }
    }

    bool IsValid( void ) const
    {
        return ( ( m_iIndex != -1 ) && ( m_pSocket != NULL ) );
    }

    bool operator < ( const tagDESCRIPTOR & rRhs ) const
    {
        return ( m_iIndex < rRhs.m_iIndex );
    }

    bool operator == ( const tagDESCRIPTOR & rRhs ) const
    {
        return ( m_iIndex == rRhs.m_iIndex );
    }

}
SOCKETDESCRIPTOR;

class CSocketServer : public CAsyncSocket
{
    DECLARE_DYNAMIC( CSocketServer )

public:

    // Construction and destruction.

                    CSocketServer       (   PFN_RECORD_READY        pfnDataReady,           // Data ready callback.
                                            void                   *pvParam,
                                            unsigned long           ulMaxMessageLength,     // Maximum message length.
                                            unsigned int            uiPort );               // Server listen socket port number.

    virtual        ~CSocketServer       (   void );                                         // Destructor.

    bool            IsInitialized       (   void ) const;                                   // Returns the construction success/failure status.

    bool            Send                (   BYTE                   *pbyStream,
                                            unsigned long           ulNumBytes,
                                            int                     iSocketIndex );

    void            DestroySocket       (   const int              &riSocketIndex );

    DWORD           GetServerThreadID   (   void ) const;

private:

    // Definitions.

    typedef std::list<SOCKETDESCRIPTOR>     SocketList_t;
    typedef SocketList_t::iterator          SocketIterator_t;
    typedef SocketList_t::const_iterator    ConstantSocketIterator_t;

    // Attributes.

    const DWORD                     m_dwResumeFailCode;

    bool                            m_bInitialized;

    int                             m_iSocketType;
    unsigned int                    m_uiPort;
    unsigned long                   m_ulMaxMessageLength;
    DWORD                           m_dwServerThreadID;

    PFN_RECORD_READY                m_pfnCallback;
    void                           *m_pvParam;
    SocketList_t                    m_SocketList;

    // Services.

    bool                            InitiateSocketServer    (   void );

    int                             GetAvailableIndex       (   void );
                        
    C7kThreadedSocket *             GetSocket               (   const int              &riSocketIndex );

    bool                            PushSocketOnList        (   const int              &riIndex,
                                                                C7kThreadedSocket  *   &rpSocket );

    // Overrides for CAsyncSocket's virtual notification handlers.

    void                            OnClose                 (   int                     iErrorCode );
    void                            OnAccept                (   int                     iErrorCode );

    // Make the default and copy constructors and the assignment operator private so that we get a 
    // compile error if the compiler uses them behind our back.

                                    CSocketServer           (   void );                                     // Not implemented.
                                    CSocketServer           (   const CSocketServer    &rRhs );             // Not implemented.
    CSocketServer &                 operator =              (   const CSocketServer    &rRhs );             // Not implemented.

};

#endif // !defined(AFX_SOCKETSERVER_H__95126415_1435_4920_91B3_F210510B80DF__INCLUDED_)
