//
//  Copyright © 2004, 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__EE25013D_D5AA_4F8D_9CA4_5C1E3267F8D1__INCLUDED_)
#define AFX_SOCKETSERVER_H__EE25013D_D5AA_4F8D_9CA4_5C1E3267F8D1__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\7kSocketProtocol.h"
#include "..\..\..\Utils\NetUtils\DynamicBuffer.h"
#include "..\..\..\Utils\NetUtils\ThreadedSocket.h"

typedef CThreadedSocket<C7kSocketProtocol>  C7kThreadedSocket;

class CSocketDescriptor
{
public:

    int                  m_iIndex;
    C7kThreadedSocket   *m_pSocket;

    CSocketDescriptor   (   const int                 &riIndex  = -1,
                            C7kThreadedSocket * const &rpSocket = NULL )
    {
        m_iIndex  = riIndex;
        m_pSocket = rpSocket;
    }

    CSocketDescriptor( const CSocketDescriptor &rRhs )
    {
        if ( this != &rRhs )
        {
            m_iIndex  = rRhs.m_iIndex;
            m_pSocket = rRhs.m_pSocket;
        }
    }

    virtual ~CSocketDescriptor( 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 CSocketDescriptor & rRhs ) const
    {
        return ( m_iIndex < rRhs.m_iIndex );
    }

    bool operator == ( const CSocketDescriptor & rRhs ) const
    {
        return ( m_iIndex == rRhs.m_iIndex );
    }

private:

    CSocketDescriptor & operator = ( const CSocketDescriptor &rRhs );                               // Not implemented thus private.

};

class CSocketServer : public CAsyncSocket
{
    DECLARE_DYNAMIC( CSocketServer )

public:

    ////////////////////
    // Services.

                        CSocketServer           (   PFN_RECORD_READY        pfnDataReady,           // Data ready callback.
                                                    void                   *pvParam,                // Optional callback parameter; typically the client's this pointer.
                                                    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<CSocketDescriptor>    SocketList_t;
    typedef SocketList_t::iterator          SocketIterator_t;
    typedef SocketList_t::const_iterator    ConstantSocketIterator_t;

    ////////////////////
    // Attributes.

    const unsigned long m_ulResumeFailureCode;

    bool                m_bInitialized;

    int                 m_iSocketType;

    unsigned int        m_uiPort;

    unsigned long       m_ulMaxMessageLength;
    unsigned long       m_ulServerThreadID;

    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 thus private.
                        CSocketServer           (   const CSocketServer    &rRhs );             // Not implemented thus private.
    CSocketServer &     operator =              (   const CSocketServer    &rRhs );             // Not implemented thus private.

};

#endif // !defined(AFX_SOCKETSERVER_H__EE25013D_D5AA_4F8D_9CA4_5C1E3267F8D1__INCLUDED_)
