#include "main.h"
#include "extern.h"
#include "net.h"
#include "ytitlefile.h"

#define		LISTBOX_SERVICEPROVIDER_X				73
#define		LISTBOX_SERVICEPROVIDER_Y				120
#define		LISTBOX_SERVICEPROVIDER_WIDTH			224
#define		LISTBOX_SERVICEPROVIDER_HEIGHT			105
#define		LISTBOX_SERVICEPROVIDER_SELLWIDTH		LISTBOX_SERVICEPROVIDER_WIDTH
#define		LISTBOX_SERVICEPROVIDER_SELLHEIGHT		20

#define		LISTBOX_SERVICEPROVIDER_UP_X			302
#define		LISTBOX_SERVICEPROVIDER_UP_Y			120
#define		LISTBOX_SERVICEPROVIDER_UP_WIDTH		15
#define		LISTBOX_SERVICEPROVIDER_UP_HEIGHT		15
#define		LISTBOX_SERVICEPROVIDER_DOWN_X			LISTBOX_SERVICEPROVIDER_UP_X
#define		LISTBOX_SERVICEPROVIDER_DOWN_Y			210
#define		LISTBOX_SERVICEPROVIDER_DOWN_WIDTH		LISTBOX_SERVICEPROVIDER_UP_WIDTH
#define		LISTBOX_SERVICEPROVIDER_DOWN_HEIGHT		LISTBOX_SERVICEPROVIDER_UP_HEIGHT

#define		SELECT_SINGLEORMULTI_SINGLE				0
#define		SELECT_SINGLEORMULTI_MULTI				1
#define		SELECT_SINGLEORMULTI_SINGLE_X			110		
#define		SELECT_SINGLEORMULTI_SINGLE_Y			315
#define		SELECT_SINGLEORMULTI_SINGLE_WIDTH		170
#define		SELECT_SINGLEORMULTI_SINGLE_HEIGHT		20
#define		SELECT_SINGLEORMULTI_MULTI_X			SELECT_SINGLEORMULTI_SINGLE_X			
#define		SELECT_SINGLEORMULTI_MULTI_Y			340
#define		SELECT_SINGLEORMULTI_MULTI_WIDTH		SELECT_SINGLEORMULTI_SINGLE_WIDTH	
#define		SELECT_SINGLEORMULTI_MULTI_HEIGHT		SELECT_SINGLEORMULTI_SINGLE_HEIGHT

static	_ServiceProviderButton		BServiceProvider[SERVICE_PROVIDER_MAX];
static	_EnumSessionButton			BEnumSessions[ENUM_SESSIONS_MAX];
static	LPVOID						g_SelectedServiceProvider;
//static	_EnumPlayerButton			BEnumPlayers[MAX_MULTI_PLAYER];
static	BOOL						g_bPush;
static	UINT						TimerID;
//static	SHORT						SProvider;
static	SHORT						SessionMenuSwitch;
static	SHORT						g_PrevServiceProvider;
static	GUID						g_PrevSessionGuid;

//타이머 관련 함수.
static	void	StartTimer(DWORD Flag, DWORD Parameter=0);
static	void	StopTimer();
static	void	CALLBACK	TimerFuncEnumSessions(UINT wID, UINT wUser, DWORD dwUser, DWORD dw1, DWORD dw2);
//static	void	CALLBACK	TimerFuncEnumPlayers(UINT wID, UINT uiMsg, DWORD dwUser, DWORD dw1, DWORD dw2);

static	BOOL	StartEnumSession();
static	void	StopEnumSession();

static	void	StartEnumPlayers();
static	void	StopEnumPlayers();

static	UINT	ServiceProvider(SHORT* ServiceProvider);
static	UINT	Session(LPGUID lpGuid);
//static	UINT	Lobby();

static	_EnumButtonInfo	EnumButtonInfo;
static	_EnumButtonInfo	EnumButtonInfoSessions;
static	_EnumButtonInfo EnumButtonInfoPlayers;

static	SHORT		nExpansionPercent;
static	RECT		rcSetMultiTitle;

extern	BOOL       gbSessionLost;    // 세션을 잃어 버렸음
extern	BOOL       gbIaminaLobby;     // 게임 시작시 Lobby에서 시작한다.


extern	GENERICMSG      StartGame;        // 시작을 알려주는 구조체 
extern	NOMESSAGE       NoMessage;        // 메시지가 없음을 알리는 구조체
extern	GENERICMSG      NoPermit;

extern DWORD      gdwReceiveBufferSize;  // 주고 받을 메시지의 버퍼크기
extern LPVOID     glpvReceiveBuffer;      // 주고 받을 메시지의 버퍼번지 

extern DPLAYINFO	   DPInfo;
extern NOMESSAGE       NoMessage;        // 메시지가 없음을 알리는 구조체
extern GENERICMSG      NoPermit;
extern CHATMESSAGE     ChatMessage; 
extern MYMESSAGE       PlayersQue;
extern PLAYERSDPIDMSG  PlayersdpId;      // 플레이어들의 ID배열
extern PLAYERSNAME     PlayersName;
extern LOBBYMSG        LobbyMessage;
extern DWORD		   DPCheck[];

extern LPDIRECTPLAY3A		lpDP;
extern DPID					dpPlayerID;             // Local player's ID.
extern HANDLE				hPlayerEvent;
extern HANDLE				hKillEvent;
extern HANDLE				hReceiveThread;
extern DWORD				idReceiveThread;

extern	SHORT	MenuExpandStartX;
extern	SHORT	MenuExpandStartY;
extern	SHORT	InitPercent;
extern	SHORT	OriginalInitPercent;

extern	SHORT	MenuNum;
extern	SHORT	MiniMenuHeight;
extern	SHORT	MiniMenuWidth;
extern	SHORT	PrevMiniMenuHeight;
extern	SHORT	PrevMiniMenuWidth;
extern	SHORT	IncX;
extern	SHORT	IncY;
extern	SHORT	PrevOriginalInitPercent;
extern	BOOL	IsExpand;

extern	LPDIRECTDRAWSURFACE		lpTempMenuBuffer;
extern	LPDIRECTDRAWSURFACE		lpMainTempMenuBuffer;


BOOL	InitServiceProvider();
BOOL	InitEnumSessions();
BOOL	InitCreateSession();
SHORT	SelectServiceProvider();
GUID	SelectSession(BOOL& IsDoubleClicked);
GUID	GetSessionGUID(SHORT Index);
SHORT	GetSessionIndex(GUID Guid);
BOOL	IsValidGUID(GUID Guid);
void    EnumSessions();
void	EnumPlayers();
BOOL 	CreateSession();
BOOL	CreatePlayer();
BOOL	JoinSession(GUID Guid);
BOOL	InitInitEnumSessions();
BOOL	InitCreateSession();
//BOOL	InitLobby();

extern	RECT GetExpansionRect(RECT rcSource, SHORT nPercent);


//SetMulti()에서 혼자 하기 및 여럿이 하기중을 선택하기 위한 버튼 들이다.
static	_SelectButton		BMultiPlayer(SELECT_SINGLEORMULTI_MULTI_X, 
										 SELECT_SINGLEORMULTI_MULTI_Y, 
										 SELECT_SINGLEORMULTI_MULTI_WIDTH, 
										 SELECT_SINGLEORMULTI_MULTI_HEIGHT,
										 "여럿이하기", BUTTON_PUT_LEFT, TRUE);
static	_SelectButton		BSinglePlayer(SELECT_SINGLEORMULTI_SINGLE_X,
										  SELECT_SINGLEORMULTI_SINGLE_Y, 
										  SELECT_SINGLEORMULTI_SINGLE_WIDTH,
										  SELECT_SINGLEORMULTI_SINGLE_HEIGHT,
										  "혼자하기", BUTTON_PUT_LEFT, TRUE);


char	SetMultiMenuTitleName[255] = Y_TITLE_FILE_SELECTPROTOCOL;

_SelectNationButton		BNation[MAX_MULTI_PLAYER];
_SelectAllyButton		BAlly[MAX_MULTI_PLAYER];

BOOL WINAPI EnumSession( LPDPSESSIONDESC2 lpDPGameDesc, LPDWORD lpdwTimeOut,
                            DWORD dwFlags, LPVOID lpContext );
BOOL WINAPI EnumPlayer( DPID dpID, DWORD dwPlayerType, LPCDPNAME lpName,
                            DWORD dwFlags, LPVOID lpContext );

//컴퓨터 및 사용자 이름.
char	LocalComputerName[MAX_COMPUTERNAME_LENGTH + 1];
char	LocalUserName[MAX_COMPUTERNAME_LENGTH + 1];

static	_YServiceProviderListBox	YServiceProviderListBox;


/////////////////////////////////////////////////////////////////////////////////////////////////
/// BOOL InitSetMulti()
/// 목적 :  멀티를 설정하기 전에 초기화할 것들을 초기화한다. 
/////////////////////////////////////////////////////////////////////////////////////////////////
BOOL InitSetMulti()
{
	// 모든 구조체를 초기화한다.
	// 설정한 구조체에 형태를 지정한다.
	ZeroMemory(&StartGame,sizeof(GENERICMSG));
	StartGame.byType   = START_GAME ;

	ZeroMemory(&NoMessage,sizeof(NOMESSAGE)); 	
	NoMessage.byType   = NO_MESSAGE;            

	ZeroMemory(&NoPermit,sizeof(GENERICMSG));
	NoPermit.byType     = NO_PERMIT;   

	ZeroMemory(&ChatMessage,sizeof(CHATMESSAGE));
	ChatMessage.byType   = CHAT_MESSAGE;

	ZeroMemory(&LobbyMessage,sizeof(LOBBYMSG));
	LobbyMessage.byType = LOBBY_MESSAGE;
	
	ZeroMemory(&PlayersQue, sizeof(MYMESSAGE));
	PlayersQue.byType = MY_MESSAGE;

	ZeroMemory(&PlayersName,sizeof(PLAYERSNAME));
	ZeroMemory(DPCheck,sizeof(DWORD)*MAX_MULTI_PLAYER);
                	
	gbSessionLost    = FALSE;    // 세션을 잃어 버리지 않았음 
    gbIaminaLobby    = TRUE;     // 게임 시작시 Lobby에서 시작한다.

	// 리시브를 받을 배열을 초기화하고 잡는다.
	gdwReceiveBufferSize = sizeof(MYMESSAGE)*7;
	glpvReceiveBuffer = GlobalAllocPtr(GHND, gdwReceiveBufferSize);
	if(glpvReceiveBuffer == NULL) return FALSE;
	ZeroMemory(glpvReceiveBuffer, gdwReceiveBufferSize);

	ZeroMemory(&DPInfo, sizeof(DPLAYINFO));	
	
	hPlayerEvent = CreateEvent( NULL, FALSE, FALSE, NULL );	

	PlayMenuBackgroundMusic();

	//리스트 박스를 생성한다.
	//반드시 InitServiceProvider()전에 호출해 주어야 한다.
	YServiceProviderListBox.Create();
	
	if(InitServiceProvider() == TRUE)
	{
		//서비스 프로바이더의 초기화를 성공했다면 이제 부터 잡다한 것들을 초기화 시켜준다.

		nExpansionPercent = ((GMENU_START_WIDTH * GMENU_START_HEIGHT) * 100) / (ScreenXsize * ScreenYsize);

		rcSetMultiTitle.left	=	GMENU_MULTI_X;
		rcSetMultiTitle.top		=	GMENU_MULTI_Y;
		rcSetMultiTitle.right	=	GMENU_MULTI_X + GMENU_MULTI_WIDTH;
		rcSetMultiTitle.bottom	=	GMENU_MULTI_Y + GMENU_MULTI_HEIGHT;

		if(TitleSpr.Image == NULL)
		{
			if(LoadXspr(SetMultiMenuTitleName, TitleSpr)==FALSE)
			{
				Error("", "Y1312342");
			}
		}

		if(LockSurface(lpMainTempMenuBuffer) == TRUE)
		{
			PutImage32(0, 0, TitleSpr.Header.Xsize, TitleSpr.Header.Ysize, TitleSpr.Image);		
			UnlockSurface(lpMainTempMenuBuffer);
		}	

		if(YServiceProviderListBox.GetSellNum())
		{
			g_PrevServiceProvider = 0;
			YServiceProviderListBox.SetPosition(0);
		}	

		//처음에는 기본적으로 멀티가 디폴트 이다.
		BMultiPlayer.SetSelected(TRUE);
		BSinglePlayer.SetSelected(FALSE);

		return TRUE;
	}
	else
		return FALSE;
}

////////////////////////////////////////////////////////////////////////////////////////////////
/// SHORT SetMulti()
/// 목적 : 서비스 프로바이더를 선택하는 화면..
////////////////////////////////////////////////////////////////////////////////////////////////
SHORT SetMulti()
{	
	SHORT						ret;
	_ServiceProviderButton*		lpServiceProviderButton;
	SHORT						SProvider;

	if(nExpansionPercent <= 100)
	{	
		RECT	rcExpansionSetMulTitle;					//확대된 사각형.
		
		nExpansionPercent = (nExpansionPercent + MINI_MENU_DEFAULT_PERCENT) / MINI_MENU_DEFAULT_PERCENT *
							MINI_MENU_DEFAULT_PERCENT;

		rcExpansionSetMulTitle = GetExpansionRect(rcSetMultiTitle, nExpansionPercent);		

		lpDDSBack->Blt(&rcExpansionSetMulTitle , lpMainTempMenuBuffer, NULL, DDBLT_WAIT, NULL);		
	}
	else
	{
		ret=ServiceProvider(&SProvider);	
	}

	//마우스를 그려주고 화면을 갱신한다. 
	UpdateScreen();	

	if(LeftPressSwitch)	
		g_bPush=TRUE;	
	else	
		g_bPush=FALSE;			

	//서비스 프로바이더의 메뉴를 종료한다면 서비스 프로바이더 리스트 박스에서 할당 했던 메모리를
	//해제하기 위해 아래 함수를 호출해 준다.
	//그 전에 반드시 선택한 프로바이더는 백업해 주어야 한다.
	if(ret)
	{
		if(SProvider != -1)
		{
			lpServiceProviderButton = (_ServiceProviderButton*)YServiceProviderListBox.GetData(SProvider);

			g_SelectedServiceProvider = new BYTE[lpServiceProviderButton->m_dwSize];
			memcpy(g_SelectedServiceProvider, lpServiceProviderButton->m_lpConnection, 
					lpServiceProviderButton->m_dwSize);
		}

		YServiceProviderListBox.AllDestroyServiceProvider();
	}
	
	if(ret == GS_INITINITMENU)
	{		
		ShutdownConnection();	
	}

    return ret; 
}


//---------------------------	서비스 프로바이더의 메뉴 --------------------//

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/// BOOL InitServiceProvider()
/// 목적 : 서비스 프로바이더를 초기화 한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL	InitServiceProvider()
{
	int			i;
		
	if(lpDP)
	{
		lpDP->Release();
		lpDP=NULL;
	}		


	CoInitialize( NULL );   // Required by CoCreateInstance	

    if FAILED( CoCreateInstance( CLSID_DirectPlay,
                   NULL, CLSCTX_ALL, IID_IDirectPlay3A,
                  ( LPVOID* ) &lpDP ) )
    {
         Error("에러", "다이렉트 플레이 객체를 생성할 수 없습니다.");
		 return FALSE;
	}	

/*
	ZeroMemory(&EnumButtonInfo, sizeof(EnumButtonInfo));	

	for(i=0; i < SERVICE_PROVIDER_MAX; i++)
	{
		if(BServiceProvider[i].m_lpConnection)
		{
			delete [] BServiceProvider[i].m_lpConnection;
			BServiceProvider[i].m_lpConnection=NULL;	
		}
	}

	EnumButtonInfo.X=5;
	EnumButtonInfo.Y=10;	
*/
	if FAILED( lpDP->EnumConnections(NULL, 
		( LPDPENUMCONNECTIONSCALLBACK)EnumConnection,
        NULL, 0))
	{
		Error("에러", "서비스 프로바이더를 열거 할 수 없습니다.");
		return FALSE;
	}				

	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////////////////////////
/// BOOL WINAPI EnumConnection( LPCGUID lpguidSP, LPVOID lpConnection, DWORD dwSize,
///                         LPDPNAME lpName, DWORD dwFlags, LPVOID lpContext )
/// 목적 : 서비스 프로바이더를 열거 하기 위한 콜백 함수.
/////////////////////////////////////////////////////////////////////////////////////////////////
BOOL WINAPI EnumConnection( LPCGUID lpguidSP, LPVOID lpConnection, DWORD dwSize,
                            LPDPNAME lpName, DWORD dwFlags, LPVOID lpContext )
{
    LPDIRECTPLAY3   lpDPTemp;		
	BOOL			IsSuccess;

    // Check to see if a connection can be initialized
    if FAILED( CoCreateInstance( CLSID_DirectPlay,
                NULL, CLSCTX_ALL, IID_IDirectPlay3A,
                ( LPVOID* ) &lpDPTemp ) )
    {
        return( FALSE );
    }

    if FAILED( lpDPTemp->InitializeConnection( lpConnection, 0 ) )
    {
        lpDPTemp->Release();
        return( TRUE );
    }
    lpDPTemp->Release();	
	
	//BServiceProvider[EnumButtonInfo.Num].Create(EnumButtonInfo.X, EnumButtonInfo.Y, 
	//											250, 35, lpName->lpszShortNameA);

	IsSuccess = YServiceProviderListBox.AddSell(lpConnection,
												lpName->lpszShortNameA,
												dwSize);		

	if(IsSuccess == FALSE)
		return FALSE;

	/*
    // If it got added to the list box, create a copy of the connection
    // and store a pointer to it in the list box.
    if (IsSuccess)
    {
		BServiceProvider[EnumButtonInfo.Num].m_lpConnection=new BYTE[dwSize];
		
		if(!BServiceProvider[EnumButtonInfo.Num].m_lpConnection) return FALSE;        
		
        memcpy(BServiceProvider[EnumButtonInfo.Num].m_lpConnection, lpConnection, dwSize );       
    }
    else 
    {
        return FALSE;
    }

	EnumButtonInfo.Num++;
	EnumButtonInfo.Y+=40;
	*/

    return TRUE;	
}

//////////////////////////////////////////////////////////////////////////////////////////////////
/// SHORT	SelectServiceProvider(BOOL& IsDoubleClicked)
/// 목적 : 서비스 프로바이더를 선택한다.
/// 리턴 : 선택한 서비스 프로바이더를 리턴한다.
//////////////////////////////////////////////////////////////////////////////////////////////////
SHORT	SelectServiceProvider(BOOL& IsDoubleClicked)
{	
	SHORT i;

	for(i=0; i < (SHORT)EnumButtonInfo.Num; i++)
	{
		if(BServiceProvider[i].Process(g_bPush, IsDoubleClicked)==TRUE)
		{
			return i;
		}
	}  

	return -1;
}

///////////////////////////////////////////////////////////////////////////////////////////////
/// UINT ServiceProvider(SHORT* lpServiceProvier)
/// 목적 : 현 메뉴가 서비스 프로바이더에서 작업중이다.
///////////////////////////////////////////////////////////////////////////////////////////////
UINT ServiceProvider(SHORT* lpServiceProvider)
{		
	static	_Button				BOk		( 534, 428, 43, 14, "결정", BUTTON_PUT_LEFT);
	static	_Button				BCancel	(  53, 428, 88, 14, "되돌아가기", BUTTON_PUT_LEFT);	
	static	_Box				BoxProtocol( 73, 79, 73, 12, "프로토콜", BUTTON_PUT_LEFT);
	static	_Box				BoxTitleName(239, 33, 133, 16, "여럿이하기", BUTTON_PUT_CENTER);
	UINT	menuindex=	0;
	SHORT	ServiceProvider;
	HDC		hdc;
	int		i;
	RECT	rect, temprect;
	SHORT	TempWidth, TempHeight;
	SHORT	IncYUp, IncYDown;
	SHORT	TotalGap;
	BOOL	IsDoublceClicked = FALSE;
	BOOL	IsTempDoublieClicked;
	SHORT	HowGame;
		
	lpDDSBack->BltFast(0, 0, lpMainTempMenuBuffer, NULL, DDBLTFAST_WAIT);						

	//IsTempDoublieClicked 변수는 쓸모가 없다.
	if(BMultiPlayer.Process(g_bPush, IsTempDoublieClicked) == TRUE)		
	{
		BMultiPlayer.SetSelected(TRUE);
		YServiceProviderListBox.SetAction(TRUE);
		BSinglePlayer.SetSelected(FALSE);			
	}

	//IsTempDoublieClicked 변수는 쓸모가 없다.
	if(BSinglePlayer.Process(g_bPush, IsTempDoublieClicked) == TRUE)
	{
		BMultiPlayer.SetSelected(FALSE);
		YServiceProviderListBox.SetAction(FALSE);
		BSinglePlayer.SetSelected(TRUE);			
	}

	//어떤 게임의 형태인지를 지정한다.
	if(BMultiPlayer.IsSelected() == TRUE)		
		HowGame = SELECT_SINGLEORMULTI_MULTI;		
	else if(BSinglePlayer.IsSelected() == TRUE)		
		HowGame = SELECT_SINGLEORMULTI_SINGLE;
	

	//요청한 서비스 프로바이더의 값을 0으로 초기화 한다.
	*lpServiceProvider= 0;	

	//서비스 프로바이더를 선택하는지 본다.
//		ServiceProvider=SelectServiceProvider(IsDoublceClicked);		

	if(HowGame==SELECT_SINGLEORMULTI_MULTI)
	{
		YServiceProviderListBox.Action(IsDoublceClicked, ServiceProvider);

		//서비스 프로바이더가 -1 이면 선택 하지 않았다는 것이다.
		if(ServiceProvider!=-1)		//선택을 했다면.
		{
			//if(g_PrevServiceProvider != -1)
			//	BServiceProvider[g_PrevServiceProvider].SetSelected(FALSE);

			g_PrevServiceProvider = ServiceProvider;
			//BServiceProvider[g_PrevServiceProvider].SetSelected(TRUE);
		}			

		if(BOk.Process(g_bPush)==TRUE || (IsDoublceClicked == TRUE))
		{	
			*lpServiceProvider= g_PrevServiceProvider;
			menuindex=GS_INITSETSESSION;		
			IsExpand = FALSE;

			for(i=0; i<MAX_MULTI_PLAYER; i++)
			{
				PlayersdpId.Player[i].Init(i);			
				PlayersdpId.Player[i].PlayerNumber=(BYTE)i;			
			}

			//여럿하 하기 모드이다.			
			SoloPlaySwitch = FALSE;
		}		

		if(BCancel.Process(g_bPush)==TRUE)
		{	
			*lpServiceProvider= -1;
			menuindex=GS_INITINITMENU;
			IsExpand = FALSE;
		}
	}
	else
	{
		if(BOk.Process(g_bPush)==TRUE)
		{				
			*lpServiceProvider= -1;
			menuindex=GS_INITSETGAME;		
			IsExpand = FALSE;

			for(i=0; i<MAX_MULTI_PLAYER; i++)
			{
				PlayersdpId.Player[i].Init(i);			
				PlayersdpId.Player[i].PlayerNumber=(BYTE)i;			
			}

			//혼자 하기 모드이다.			
			SoloPlaySwitch = TRUE;
		}		

		if(BCancel.Process(g_bPush)==TRUE)
		{				
			*lpServiceProvider= -1;
			menuindex=GS_INITINITMENU;
			IsExpand = FALSE;
		}
	}		

	if(lpDDSBack->GetDC(&hdc)==DD_OK)
	{
		char	buffer[255];

		SetBkMode(hdc, TRANSPARENT );
		
		BoxProtocol.Put(hdc, BOX_PUT_NOBORDER, BOX_PUT_LEFT);
		BoxTitleName.Put(hdc, BOX_PUT_NOBORDER, BOX_PUT_LEFT);

		BSinglePlayer.Put(hdc, BUTTON_PUT_NOBORDER);
		BMultiPlayer.Put(hdc, BUTTON_PUT_NOBORDER);
		BOk.Put(hdc, BUTTON_PUT_NOBORDER);
		BCancel.Put(hdc, BUTTON_PUT_NOBORDER);				

		lpDDSBack->ReleaseDC(hdc);
	}		

	YServiceProviderListBox.Draw();			

	if(menuindex)
	{
		if(TitleSpr.Image)
		{
			FreeXspr(TitleSpr);
			TitleSpr.Image=NULL;
		}
	}
	
	return menuindex;
}


//---------------------------	세션의 메뉴 --------------------//

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/// BOOL InitInitEnumSessions()
/// 목적 : 세션 열거를 위한 초기화를 수행한다. 성공 여부를 알려준다.
/////////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL	InitInitEnumSessions()
{
	SHORT		i;
	
	if(lpDP)
	{
		lpDP->Release();
		lpDP=NULL;
	}

	// 다이렉트 플레이를 설정한다. 
    if FAILED( CoCreateInstance( CLSID_DirectPlay,NULL, CLSCTX_ALL, IID_IDirectPlay3A,
        ( LPVOID* ) &lpDP) )
    {		
		Error("에러", "다이렉트 플레이 객체를 얻는데 실패했습니다.");        
		return FALSE;
    }	
		

	if FAILED( lpDP->InitializeConnection(g_SelectedServiceProvider, 0 ) )
	{
		Error("에러", "요구한 프로바이더 서비스로 초기화 할 수 없습니다.");		
		return FALSE;
	}

	if(TitleSpr.Image == NULL)
	{
		if(LoadXspr("fnt\\title.spr", TitleSpr)==FALSE)
		{
			Error("", "Y1312342");
		}
	}

	g_PrevSessionGuid = GUID_NULL;
	for(i=0; i < ENUM_SESSIONS_MAX; i++)	
		BEnumSessions[i].SetSelected(FALSE);		

	return TRUE;
}

////////////////////////////////////////////////////////////////////////////////////////////////////
/// BOOL InitCreateSession()
/// 목적 : 세션을 만들기 위한 여러가지 변수들을 초기화 한다.
///////////////////////////////////////////////////////////////////////////////////////////////////
BOOL InitCreateSession()
{
	return TRUE;
}

//////////////////////////////////////////////////////////////////////////////////////////////////
/// GUID SelectSession(BOOL& IsDoubleClicked)
/// 목적 : 세션을 선택한다.
/// 리턴 : 선택한 세션을 리턴한다.
//////////////////////////////////////////////////////////////////////////////////////////////////
GUID	SelectSession(BOOL& IsDoubleClicked)
{
	SHORT i;

	for(i=0; i < (SHORT)EnumButtonInfoSessions.Num; i++)
	{
		if(BEnumSessions[i].Process(g_bPush, IsDoubleClicked)==TRUE)
		{			
			return *(BEnumSessions[i].m_lpGuid);			
		}
	}  
		
	return GUID_NULL;
}

//////////////////////////////////////////////////////////////////////////////////////////////////
/// GUID	GetSessionGUID(SHORT Index)
/// 목적 : 넘겨준 인자의 GUID 값을 얻어 온다.
//////////////////////////////////////////////////////////////////////////////////////////////////
GUID	GetSessionGUID(SHORT Index)
{	
	if((Index >= 0) && (Index < EnumButtonInfoSessions.Num))
		return *(BEnumSessions[Index].m_lpGuid);			
	else
		return GUID_NULL;
}

//////////////////////////////////////////////////////////////////////////////////////////////////
/// SHORT	GetSessionIndex(GUID Guid)
/// 목적 :	넘겨진 GUID 값의 인덱스를 가져 온다.
//////////////////////////////////////////////////////////////////////////////////////////////////
SHORT	GetSessionIndex(GUID Guid)
{
	SHORT	i;

	if(Guid == GUID_NULL)
	{
		return -1;
	}
	else
	{
		for(i=0; i < (SHORT)EnumButtonInfoSessions.Num; i++)
		{
			if((*(BEnumSessions[i].m_lpGuid)) == Guid)
				return i;
		}
	}

	return -1;
}

////////////////////////////////////////////////////////////////////////////////
/// void EnumSessions()
/// 목적 : 세션을 열거한다.
////////////////////////////////////////////////////////////////////////////////
void EnumSessions()
{
	DPSESSIONDESC2		dpDesc;
	DWORD				dwSessions;
	HRESULT				hr;

	ZeroMemory( &dpDesc, sizeof( dpDesc ) );
    dpDesc.dwSize = sizeof( dpDesc );
    dpDesc.guidApplication = IMJIN2_GUID;

    dwSessions = DPENUMSESSIONS_AVAILABLE | 
                 DPENUMSESSIONS_ASYNC;   

	InitEnumSessions();

	// 세션을 열거한다. 
    hr = lpDP->EnumSessions( &dpDesc, 0, 
        ( LPDPENUMSESSIONSCALLBACK2 )EnumSession, 
        (LPVOID)NULL, dwSessions );

	if(hr != DP_OK)
	{		
		switch(hr)
		{		
		case DPERR_CONNECTING:
			Error("에러", "세션 열거 에러입니다 1.");
			break;
		case DPERR_CONNECTIONLOST:
			Error("에러", "세션 열거 에러입니다 2.");
			break;
		case DPERR_EXCEPTION :
			Error("에러", "세션 열거 에러입니다 3.");
			break;
		case DPERR_GENERIC:
			Error("에러", "세션 열거 에러입니다 4.");
			break;
		case DPERR_INVALIDOBJECT:
			Error("에러", "세션 열거 에러입니다 5.");
			break;
		case DPERR_INVALIDPARAMS:
			Error("에러", "세션 열거 에러입니다 6.");
			break;
		case DPERR_NOCONNECTION:
			Error("에러", "세션 열거 에러입니다 7.");
			break;
		case DPERR_UNINITIALIZED:
			Error("에러", "세션 열거 에러입니다 8.");
			break;
		case DPERR_USERCANCEL :
			Error("에러", "세션 열거 에러입니다 9.");
			break;

		}
	}	
}

////////////////////////////////////////////////////////////////////////////////////////////////
/// BOOL WINAPI EnumSession( LPDPSESSIONDESC2 lpDPGameDesc, LPDWORD lpdwTimeOut,
///                           DWORD dwFlags, LPVOID lpContext )
/// 목적 : 세션을 열거하기 위한 콜백 함수.
////////////////////////////////////////////////////////////////////////////////////////////////								
BOOL WINAPI EnumSession( LPDPSESSIONDESC2 lpDPGameDesc, LPDWORD lpdwTimeOut,
                            DWORD dwFlags, LPVOID lpContext )
{ 
	char	temp[1024];

    // First check and see if the enumeration timed out.  If so, we
    // could reset it, but we'll just canel it instead.
    if( dwFlags & DPESC_TIMEDOUT )
    {
        return FALSE;
    }	

	wsprintf(temp, "%s %d", lpDPGameDesc->lpszSessionName, EnumButtonInfoSessions.Num);
	BEnumSessions[EnumButtonInfoSessions.Num].Create(EnumButtonInfoSessions.X, EnumButtonInfoSessions.Y,
												 100, 20, temp);

    if ( EnumButtonInfoSessions.Num !=  ENUM_SESSIONS_MAX)
    {
        BEnumSessions[EnumButtonInfoSessions.Num].m_lpGuid = ( LPGUID ) new BYTE[sizeof(GUID)];
        if ( !BEnumSessions[EnumButtonInfoSessions.Num].m_lpGuid) return FALSE;

        *(BEnumSessions[EnumButtonInfoSessions.Num].m_lpGuid) = lpDPGameDesc->guidInstance;        
    }

	EnumButtonInfoSessions.Num++;
	EnumButtonInfoSessions.Y+=20;
		
    return(TRUE);
}


////////////////////////////////////////////////////////////////////////////////////////////////
/// BOOL StartEnumSession()
/// 목적 : 세션 열거를 시작한다.
////////////////////////////////////////////////////////////////////////////////////////////////
BOOL	StartEnumSession()
{
	if(InitInitEnumSessions() == FALSE)
		return FALSE;

	StartTimer(SETMULTI_SELECT_SESSION);

	return TRUE;
}

////////////////////////////////////////////////////////////////////////////////////////////////
/// void StopEnumSession()
/// 목적 : 세션 열거를 중지한다.
////////////////////////////////////////////////////////////////////////////////////////////////
void	StopEnumSession()
{
	StopTimer();
}

///////////////////////////////////////////////////////////////////////////////////////////////
/// UINT Session(SHORT *Session)
/// 목적 : 현 메뉴가 세션 메뉴에 들어가 있다.
///////////////////////////////////////////////////////////////////////////////////////////////
UINT	Session(LPGUID lpGuid)
{	
	static	_Button	BCancel(480, 450, 70, 20, "Cancel", BUTTON_PUT_CENTER), BJoin(320, 450, 70, 20, "Join", BUTTON_PUT_CENTER), 
					BCreate(160, 450, 70, 20, "Create", BUTTON_PUT_CENTER);	
	GUID	SelectSessionGuid=GUID_NULL;
	UINT	menuindex=0;
	HDC		hdc;
	BOOL	IsDoubleClicked = FALSE;
	SHORT	i;

	if(LockSurface(lpDDSBack)==TRUE)
	{
		PutImage32(0, 0, TitleSpr.Header.Xsize, TitleSpr.Header.Ysize, TitleSpr.Image);
		UnlockSurface(lpDDSBack);
	}

	//세션이 있어야 조인 항목을 사용할 수 있다.
	if(EnumButtonInfoSessions.Num > 0)
	{
		for(i=0; i < (SHORT)EnumButtonInfoSessions.Num; i++)
			BEnumSessions[i].SetSelected(FALSE);

		BJoin.SetAction(TRUE);
	
		//만약 GUID를 가지고 있다면 그 구이드를 아직 유효한지 알아 본다. 세션을 없앴을 경우.
		if(g_PrevSessionGuid != GUID_NULL)
		{		
			if(IsValidGUID(g_PrevSessionGuid) == FALSE)
			{	
				//더 이상의 그 GUID는 유효하지 않다.							
				g_PrevSessionGuid = GUID_NULL;				
			}			
		}	

		if(g_PrevSessionGuid == GUID_NULL)
		{	
			g_PrevSessionGuid = GetSessionGUID(0);			
		}		

		BEnumSessions[GetSessionIndex(g_PrevSessionGuid)].SetSelected(TRUE);			
	}
	else
	{
		BJoin.SetAction(FALSE);
		g_PrevSessionGuid = GUID_NULL;		
	}		

	SelectSessionGuid=SelectSession(IsDoubleClicked);

	//GUID_NULL이면 아무것도 선택을 하지 않았다는 것이다.
	if(SelectSessionGuid!=GUID_NULL)
	{	
		if(g_PrevSessionGuid != GUID_NULL)
		{
			BEnumSessions[GetSessionIndex(g_PrevSessionGuid)].SetSelected(FALSE);
		}
			
		//선택했다면 다시 선택한 서비스 프로바이더의 값을 저장한다.
		g_PrevSessionGuid=SelectSessionGuid;		
		BEnumSessions[GetSessionIndex(g_PrevSessionGuid)].SetSelected(TRUE);				
	}
	
	if((BJoin.Process(g_bPush)==TRUE) || (IsDoubleClicked == TRUE))
	{			
		*lpGuid=g_PrevSessionGuid;		
		menuindex=SETMULTI_SESSION_INIT_JOIN;		
	}
	else if(BCreate.Process(g_bPush)==TRUE)
	{
		menuindex=SETMULTI_SESSION_INIT_CREATE;		
	}
	else if(BCancel.Process(g_bPush)==TRUE)
	{
		menuindex=GS_INITSETMULTI;		
	}
	
	
	if(lpDDSBack->GetDC(&hdc)==DD_OK)
	{
		//SetBkColor( hdc, RGB( 0, 0, 255 ) );    

		SetBkMode(hdc, TRANSPARENT );
		BCancel.Put(hdc);
		BJoin.Put(hdc);
		BCreate.Put(hdc);	  		

		for(i=0; i < (SHORT)EnumButtonInfoSessions.Num; i++)
		{		 
			BEnumSessions[i].Put(hdc);		 
		}  
		  
		lpDDSBack->ReleaseDC(hdc);
	}

	if(menuindex!=0)
	{
		StopEnumSession();

		if(TitleSpr.Image)
		{
			FreeXspr(TitleSpr);
			TitleSpr.Image=NULL;
		}
	}

	return menuindex;
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////
/// BOOL InitEnumSessions()
/// 목적 : 세션 열거를 위한 초기화를 수행한다.
/////////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL	InitEnumSessions()
{
	int i;

	EnumButtonInfoSessions.X=0;
	EnumButtonInfoSessions.Y=300;	
	EnumButtonInfoSessions.Num=0;

	for(i=0; i < ENUM_SESSIONS_MAX; i++)
	{
		if(BEnumSessions[i].m_lpGuid)
		{
			delete [] BEnumSessions[i].m_lpGuid;
			BEnumSessions[i].m_lpGuid=NULL;	
		}
	}


	return TRUE;
}

//--------------------------- 세션을 참여하는 곳 -------------------//
////////////////////////////////////////////////////////////////////////////////////////////////
/// BOOL JoinSession(GUID lpGuid)
/// 목적 : 세션에 들어간다. 들어갈 세션의 GUID값이 인자이다.
////////////////////////////////////////////////////////////////////////////////////////////////
BOOL JoinSession(GUID Guid)
{
	DPSESSIONDESC2	dpDesc;

    ZeroMemory( &dpDesc, sizeof( dpDesc ) );
    dpDesc.dwSize = sizeof( dpDesc );
	
    dpDesc.guidInstance = Guid;
    dpDesc.guidApplication = IMJIN2_GUID;

	if(lpDP->Open( &dpDesc, DPOPEN_JOIN )==DP_OK)
	{
		CreatePlayer();	
		return TRUE;
	}
	else
	{
		Error("Error", "Could not join session.");
        return FALSE;    
	}   
}


//--------------------------- 세션을 만드는 곳  --------------------//
////////////////////////////////////////////////////////////////////////////////////////////////
/// BOOL CreatePlayer()
/// 목적 : 플레이어를 만든다.
////////////////////////////////////////////////////////////////////////////////////////////////
BOOL CreatePlayer()
{	
	DPNAME              dpPlayerName;	
	DWORD				dwStrSize;	
	
	dwStrSize = MAX_COMPUTERNAME_LENGTH + 1;

	//컴퓨터의 이름을 얻어 온다.
	if(GetComputerName(LocalUserName, &dwStrSize) == FALSE)
	{
		strcpy(LocalUserName, "unknown");
	}	

	ZeroMemory( &dpPlayerName, sizeof( dpPlayerName ) );
	dpPlayerName.dwSize = sizeof( dpPlayerName );
	dpPlayerName.lpszShortNameA = LocalUserName;
	
	if ( FAILED( lpDP->CreatePlayer( &dpPlayerID, 
				 &dpPlayerName, hPlayerEvent, 
				 NULL, 0, 0 ) ) )
	{         
		Error("실패", "플레이어를 생성할 수 없습니다.");
		return FALSE;
	}	

	return TRUE;
}

////////////////////////////////////////////////////////////////////////////////////
/// BOOL CreateSession()
/// 목적 :  현 메뉴가 세션을 만드는 곳에 들어와 있다.
////////////////////////////////////////////////////////////////////////////////////
BOOL  CreateSession()
{	
	DPSESSIONDESC2	dpDesc;		
	DWORD			dwStrSize;	
	
	dwStrSize = MAX_COMPUTERNAME_LENGTH + 1;

	//컴퓨터의 이름을 얻어 온다.
	if(GetComputerName(LocalComputerName, &dwStrSize) == FALSE)
	{
		strcpy(LocalComputerName, "임진록2");
	}


	//방을 만든다.
	ZeroMemory(&dpDesc, sizeof(dpDesc));
	dpDesc.dwSize=sizeof(dpDesc);
	dpDesc.guidApplication=IMJIN2_GUID;
	dpDesc.dwFlags=DPSESSION_MIGRATEHOST | DPSESSION_KEEPALIVE;
	dpDesc.lpszSessionNameA=LocalComputerName;		

	if(lpDP->Open(&dpDesc, DPOPEN_CREATE)==DP_OK )
	{			
		if(CreatePlayer() == TRUE)
		{			
			return TRUE;
		}
		else
			return FALSE;
	}	
	else
	{
		return FALSE;
	}
}

//------------------------ 타이머 설정 및 구체적인 프로시저 ----------------------------///

//////////////////////////////////////////////////////////////////////////////////////////
/// void	StartTimer(DWORD dwFlag, DWORD Parameter=0)
/// 목적 : 타이머를 시작한다. 열거 하는 일을 한다. 참조 StopTimer();
//////////////////////////////////////////////////////////////////////////////////////////
void	StartTimer(DWORD dwFlag, DWORD Parameter)
{
	TIMECAPS	caps;

	timeGetDevCaps(&caps, sizeof(caps));
	timeBeginPeriod(caps.wPeriodMin);	

	switch(dwFlag)
	{
	case SETMULTI_SELECT_SESSION:		
		TimerID=timeSetEvent(2000 / caps.wPeriodMin, caps.wPeriodMin, TimerFuncEnumSessions, 0, 
						(UINT)TIME_PERIODIC);
		break;	
	}	
}

//////////////////////////////////////////////////////////////////////////////////////////
/// void	StopTimer()
/// 목적 : 타이머를 중지한다. 열거 하는 일을 한다. 참조 StartTimer();
//////////////////////////////////////////////////////////////////////////////////////////
void	StopTimer()
{
	if(TimerID != 0)
	{
		timeKillEvent(TimerID);
		TimerID=0;
	}
}
/*
//////////////////////////////////////////////////////////////////////////////////////////
/// void CALLBACK	TimerFuncEnumPlayers(UINT wID, UINT uiMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
/// 목적 : 사용자를 주기적으로 보여주기 위한 타이머 함수..
//////////////////////////////////////////////////////////////////////////////////////////
void CALLBACK TimerFuncEnumPlayers(UINT wID, UINT uiMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
	static	BOOL bEnumrate=FALSE;

	if(bEnumrate==FALSE)
	{
		bEnumrate=TRUE;
		MessageBeep((UINT)-1);
		EnumPlayers();
		bEnumrate=FALSE;
	}
}
*/
//////////////////////////////////////////////////////////////////////////////////////////
/// void CALLBACK	TimerFunc(UINT wID, UINT uiMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
/// 목적 : 세션을 주기적으로 보여주기 위한 타이머 함수..
//////////////////////////////////////////////////////////////////////////////////////////
void CALLBACK	TimerFuncEnumSessions(UINT wID, UINT uiMsg, DWORD dwUser, DWORD dw1, DWORD dw2)
{
	static	BOOL bEnumrate=FALSE;

	if(bEnumrate==FALSE)
	{
		bEnumrate=TRUE;
		MessageBeep((UINT)-1);	
		EnumSessions();
		bEnumrate=FALSE;
	}	
}





































/*
HRESULT SetupConnection(HINSTANCE hInstance, LPDPLAYINFO lpDPInfo)
{
	//LPDPNAME	lpName;
	//LPSTR		lpszPlayerName;
	HRESULT		hr;

	// DPLAYINFO를 0으로 초기화 한다. 
	ZeroMemory(lpDPInfo, sizeof(DPLAYINFO));

	// create event used by DirectPlay to signal a message has arrived
	// if there is no lobby connection, ask the user for settings
	hr = ConnectUsingDialog(hInstance, lpDPInfo);
d	if FAILED(hr)
			goto FAILURE;
	
	return (DP_OK);	

FAILURE:
	ShutdownConnection();

	return (hr);
}
*/

BOOL InitSetSession()
{
	int	i;

	PlayMenuBackgroundMusic();

	SessionMenuSwitch=SETMULTI_SELECT_SESSION;	

	ZeroMemory(&PlayersdpId,sizeof(PLAYERSDPIDMSG));
	PlayersdpId.byType = CURRENT_PLAYERS;

	for(i=0; i<MAX_MULTI_PLAYER;i++)
	{		
		PlayersdpId.Player[i].Init(i);		
	}

	for(i=0; i<MAX_MULTI_PLAYER; i++)
	{
		PlayersdpId.Player[i].PlayerNumber=(BYTE)i;
	}

	if(StartEnumSession()==TRUE)
		return TRUE;	
	else	
		return FALSE;		
}

	

SHORT SetSession()
{
	static	GUID	sessionguid;		

	switch(SessionMenuSwitch)
	{
	case SETMULTI_SELECT_SESSION:		
		SessionMenuSwitch=Session(&sessionguid);		

		if(SessionMenuSwitch == 0) SessionMenuSwitch = SETMULTI_SELECT_SESSION;
		break;
	case SETMULTI_SESSION_INIT_CREATE:
		if(InitCreateSession()==TRUE)		
			SessionMenuSwitch=SETMULTI_SESSION_CREATE;		
		else
			SessionMenuSwitch=GS_INITSETMULTI;
		break;
	case SETMULTI_SESSION_CREATE:
		if(CreateSession()==TRUE)
		{			
			SessionMenuSwitch=GS_INITSETGAME;			
		}		
		else
		{
			Error("방을 만들 수 없습니다.", "");
			SessionMenuSwitch=GS_INITSETMULTI;			
		}
		break;
	case SETMULTI_SESSION_INIT_JOIN:
		SessionMenuSwitch=SETMULTI_SESSION_JOIN;
		break; 
	case SETMULTI_SESSION_JOIN:
		if(JoinSession(sessionguid)==TRUE)
		{			
			SessionMenuSwitch=GS_INITSETGAME;			
		}
		else
		{
			Error("에러", "방에 참여할 수 없습니다.");			
			SessionMenuSwitch=GS_INITSETMULTI;			
		}
		break;			
	}

	// 마우스를 그려주고 화면을 갱신한다. 
	UpdateScreen();	

	if(LeftPressSwitch)	
		g_bPush=TRUE;	
	else	
		g_bPush=FALSE;			
	

	if(SessionMenuSwitch==GS_INITSETGAME)
	{				
		//세션열기 위해 사용했던 g_SelectedServiceProvider의 소유의 메모리를 없앤다.
		if(g_SelectedServiceProvider)
		{
			delete [] g_SelectedServiceProvider;
			g_SelectedServiceProvider = NULL;
		}
		
		return 1;
	}
	else if(SessionMenuSwitch==GS_INITSETMULTI)
	{
		if(g_SelectedServiceProvider)
		{
			delete [] g_SelectedServiceProvider;
			g_SelectedServiceProvider = NULL;
		}		

		return 2;
	}	
	
	return 0;
}

BOOL	IsValidGUID(GUID Guid)
{
	SHORT		i;

	if(Guid == GUID_NULL)
	{
		return FALSE;
	}
	else
	{
		for(i=0; i < EnumButtonInfoSessions.Num; i++)
		{
			if(Guid == (*(BEnumSessions[i].m_lpGuid)))
				return TRUE;
		}
	}

	return FALSE;
	
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
/// 함수 : _YServiceProviderListBox::_YServiceProviderListBox()
/// 목적 : 서비스 프로바이더 리스트 박스 클래스 생성자.
////////////////////////////////////////////////////////////////////////////////////////////////////////
_YServiceProviderListBox::_YServiceProviderListBox() : _YListBox()
{
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
/// 함수 : _YServiceProviderListBox::~_YServiceProviderListBox()
/// 목적 : 서비스 프로바이더 리스트 박스 클래스 소멸자.
////////////////////////////////////////////////////////////////////////////////////////////////////////
_YServiceProviderListBox::~_YServiceProviderListBox()
{	
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
/// 함수 : BOOL _YServiceProviderListBox::Create()
/// 목적 : 리스트 박스 클래스를 생성한다. 
////////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL _YServiceProviderListBox::Create()
{	
	_YListBox::Create(LISTBOX_SERVICEPROVIDER_X, 
					  LISTBOX_SERVICEPROVIDER_Y, 
					  LISTBOX_SERVICEPROVIDER_WIDTH, 
					  LISTBOX_SERVICEPROVIDER_HEIGHT, 
					  LISTBOX_SERVICEPROVIDER_SELLWIDTH, 
					  LISTBOX_SERVICEPROVIDER_SELLHEIGHT,
					  LISTBOX_SERVICEPROVIDER_UP_X,
					  LISTBOX_SERVICEPROVIDER_UP_Y,
					  LISTBOX_SERVICEPROVIDER_UP_WIDTH, 
					  LISTBOX_SERVICEPROVIDER_UP_HEIGHT);			

	return TRUE;
}


////////////////////////////////////////////////////////////////////////////////////////////////////////
/// 함수 : VOID _YServiceProviderListBox::Action(BOOL& IsDoubleClicked, SHORT& SelectedServiceProvider)
/// 목적 : 리스트 박스 클래스를 생성한다. 
////////////////////////////////////////////////////////////////////////////////////////////////////////
VOID _YServiceProviderListBox::Action(BOOL& IsDoubleClicked, SHORT& SelectedServiceProvider)
{	
	int		i, j;
	SHORT	ServiceProviderNum;	
	SHORT	VisibleSellNum;
	SHORT	StartSellNumber;
	SHORT	x, y;

	ServiceProviderNum	= _YListBox::GetSellNum();
	VisibleSellNum		= _YListBox::GetVisibleSellNum();
	StartSellNumber		= _YListBox::GetStartSellNumber();

	SelectedServiceProvider = -1;
	
	for(i=0; ((i+StartSellNumber) < ServiceProviderNum) && (i < VisibleSellNum); i++)
	{
		x = m_x;
		y = m_y + i * GetSellHeight();

		if(m_ServiceProviderButtons[i + StartSellNumber].Process(x, y, g_bPush, IsDoubleClicked)==TRUE)		
		{			
			SetPosition(i + StartSellNumber);				
			SelectedServiceProvider = i + StartSellNumber;		
		}			
	}

	_YListBox::Action(g_bPush);	
}

////////////////////////////////////////////////////////////////////////////////////////////////////////
/// 함수 : void _YServiceProviderListBox::AllDestroyServiceProvider()
/// 목적 : 서비스 프로바이더에서 할당 했던 메모리를 모두 해제 한다.
////////////////////////////////////////////////////////////////////////////////////////////////////////
void _YServiceProviderListBox::AllDestroyServiceProvider()
{
	int		i;
	SHORT	ServiceProviderNum;

	ServiceProviderNum = _YListBox::GetSellNum();

	for(i=0; i < ServiceProviderNum; i++)
	{		
		m_ServiceProviderButtons[i].m_dwSize = 0;

		if(m_ServiceProviderButtons[i].m_lpConnection)
		{
			delete [] m_ServiceProviderButtons[i].m_lpConnection;
			m_ServiceProviderButtons[i].m_lpConnection = NULL;
		}
	}	
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// 함수 : BOOL	_YServiceProviderListBox::AddSell(LPVOID lpData, char* MenuName, DWORD dwSize)
/// 목적 : 서비스 프로바이더를 리스트 박스에 추가한다.
////////////////////////////////////////////////////////////////////////////////////////////////////////////
BOOL	_YServiceProviderListBox::AddSell(LPVOID lpData, char* MenuName, DWORD dwSize)
{
	SHORT						ServiceProviderNum;
	_ServiceProviderButton		TempServiceProviderButton;
	BOOL						IsSuccess;		

	ServiceProviderNum = _YListBox::GetSellNum();

	m_ServiceProviderButtons[ServiceProviderNum].m_dwSize			= dwSize;
	m_ServiceProviderButtons[ServiceProviderNum].m_lpConnection		= new BYTE[dwSize];

	memcpy(m_ServiceProviderButtons[ServiceProviderNum].m_lpConnection, lpData, dwSize);
	
	m_ServiceProviderButtons[ServiceProviderNum].Create(0, 
														0, 
														GetSellWidth(), 
														GetSellHeight(), 
														MenuName, BUTTON_PUT_LEFT);
	

	IsSuccess = _YListBox::AddSell(&m_ServiceProviderButtons[ServiceProviderNum], MenuName);

	if(IsSuccess)
	{
		//버튼이 하나의 경우 활성화 시킨다.
		if(GetSellNum() == 1)					
			SetPosition(0);		
		
		return TRUE;
	}
	else
	{
		return FALSE;
	}	
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// 함수 : void	_YServiceProviderListBox::Draw()
/// 목적 : 화면에 그린다.
////////////////////////////////////////////////////////////////////////////////////////////////////////////
void	_YServiceProviderListBox::Draw()
{
	int		i;
	SHORT	ServiceProviderNum;
	SHORT	VisibleSellNum;
	SHORT	StartSellNumber;
	HDC		hdc;
	SHORT	x, y;

	ServiceProviderNum	= _YListBox::GetSellNum();		
	VisibleSellNum		= _YListBox::GetVisibleSellNum();
	StartSellNumber		= _YListBox::GetStartSellNumber();		

	if(lpDDSBack->GetDC(&hdc) == DD_OK)
	{
		for(i=0; ((i+StartSellNumber) < ServiceProviderNum) && (i < VisibleSellNum); i++)					
		{		
			x = m_x;
			y = m_y + i * GetSellHeight();
			m_ServiceProviderButtons[i + StartSellNumber].Put(x, y, hdc, BUTTON_PUT_NOBORDER, BUTTON_PUT_LEFT);	
		}

		lpDDSBack->ReleaseDC(hdc);
	}	

	_YListBox::DrawScroll();
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// 함수 : LPVOID	_YServiceProviderListBox::GetData(SHORT ServiceProvider)
/// 목적 : 데이타를 얻어 온다.
////////////////////////////////////////////////////////////////////////////////////////////////////////////
LPVOID	_YServiceProviderListBox::GetData(SHORT ServiceProvider)
{
	return (LPVOID)&m_ServiceProviderButtons[ServiceProvider];
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// 함수 : VOID	_YServiceProviderListBox::SetPosition(SHORT NewPosition)
/// 목적 : 새로운 위치를 정한다.
////////////////////////////////////////////////////////////////////////////////////////////////////////////
VOID	_YServiceProviderListBox::SetPosition(SHORT NewPosition)
{	
	if(IsValidIndex(_YListBox::GetCurrentPosition())==TRUE)
		m_ServiceProviderButtons[_YListBox::GetCurrentPosition()].SetSelected(FALSE);

	_YListBox::SetPosition(NewPosition);

	if(IsValidIndex(_YListBox::GetCurrentPosition())==TRUE)
		m_ServiceProviderButtons[_YListBox::GetCurrentPosition()].SetSelected(TRUE);
}


////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// 함수 : SHORT _YServiceProviderListBox::NextSell()
/// 목적 : 다음의 셀로 이동한다.
////////////////////////////////////////////////////////////////////////////////////////////////////////////
SHORT _YServiceProviderListBox::NextSell()
{
	SHORT	ServiceProviderIndex;

	ServiceProviderIndex = _YListBox::GetCurrentPosition();

	if(IsValidIndex(ServiceProviderIndex) == TRUE)	
		m_ServiceProviderButtons[ServiceProviderIndex].SetSelected(FALSE);
	
	ServiceProviderIndex = _YListBox::NextSell();

	if(IsValidIndex(ServiceProviderIndex) == TRUE)	
		m_ServiceProviderButtons[ServiceProviderIndex].SetSelected(TRUE);

	return ServiceProviderIndex;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// 함수 : SHORT _YServiceProviderListBox::PrevSell()
/// 목적 : 다음의 셀로 이동한다.
////////////////////////////////////////////////////////////////////////////////////////////////////////////
SHORT _YServiceProviderListBox::PrevSell()
{
	SHORT	ServiceProviderIndex;

	ServiceProviderIndex = _YListBox::GetCurrentPosition();

	if(IsValidIndex(ServiceProviderIndex) == TRUE)	
		m_ServiceProviderButtons[ServiceProviderIndex].SetSelected(FALSE);
	
	ServiceProviderIndex = _YListBox::PrevSell();

	if(IsValidIndex(ServiceProviderIndex) == TRUE)	
		m_ServiceProviderButtons[ServiceProviderIndex].SetSelected(TRUE);

	return ServiceProviderIndex;
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// 함수 : void  _YServiceProviderListBox::SetAction(BOOL	bAction)
/// 목적 : 활동을 할 것인지 안 할것인지를 지정한다.
////////////////////////////////////////////////////////////////////////////////////////////////////////////	
void  _YServiceProviderListBox::SetAction(BOOL	bAction)
{
	int		i;

	for(i=0; i < SERVICE_PROVIDER_MAX; i++)
	{
		m_ServiceProviderButtons[i].SetAction(bAction);
	}
}



