/*!
	CNormalListener

	IPv4用系接続受付クラスの基本クラス
*/

#pragma once
#include "threadskeleton.h"
#include "ListenSocket.h"
#include "IListener.h"
#include "NormalListenerConnection.h"
#include "Settings.h"

class CListenerBase :
	private CThreadSkeleton
{
public:
	CListenerBase(void);
	virtual ~CListenerBase(void);

protected:
	/////////////////////////////////////////////////////////////////////////////////////
	//	オーバーロード
	/////////////////////////////////////////////////////////////////////////////////////
	//!	クラス名取得
	virtual LPCTSTR GetListenerClassName() = 0;

	//!	接続追加
	virtual void OnNewConnection(SOCKET newSock) = 0;

	/////////////////////////////////////////////////////////////////////////////////////
	//	操作
	/////////////////////////////////////////////////////////////////////////////////////
	//!	初期化
	void InitListenerBase(IServerToolPtr serverTool, int errorRetryTime);

	//!	開始
	void StartListenerBase();

	//!	停止
	void StopListenerBase();

	//!	設定からポート追加
	void AddPortsFromSetting(CString strPorts);

	//!	ポートの追加
	void AddPort(int port);

	//!	ポート数取得
	int GetPortCount() { return m_listeners.GetSize(); };

	//!	一時的に受け付け停止
	void ForceDisableNewConnection(int time);

private:
	/////////////////////////////////////////////////////////////////////////////////////
	//	スレッド関数
	/////////////////////////////////////////////////////////////////////////////////////
	//!	スレッド
	void ThreadMain();

	//!	クリーンアップ
	void CloseAllPorts();

	//!	受付ループ
	int AcceptLoop();

	//!	ポートを開く
	int OpenPorts();

	//!	ポートを閉じる
	void ClosePorts();

	//!	接続を受け付け
	int AcceptConnections();

	//!	接続が来るのを待つ
	void WaitNextConnection();

	//!	停止中？
	int InDisableMode();

	/////////////////////////////////////////////////////////////////////////////////////
	//	メンバ変数
	/////////////////////////////////////////////////////////////////////////////////////
	//!	サーバツール
	IServerToolPtr				m_serverTool;

	//!	リスナ配列
	CTypedPtrArray<CPtrArray,CListenSocket*>	m_listeners;

	//!	エラーリトライ時間
	int							m_errorRetryTime;

	//!	受付無効終了予定
	DWORD						m_disableNewConnectionEndTime;
};
