#include "stdafx.h"
#include "GMTool.h"
#include "resource.h"
#include "Richedit.h"
#include "CheatManager.h"
#include "Cheat_Common.h"
#include "Protocol_Cheat.h"

cGMTool* cGMTool::mInstance = 0;

cGMTool::cGMTool()
: mMainDlg( 0 )
, mRichMod( 0 )
, mIsfileOpen( false )
, mTimeInterval( 2000 )
, mSpeed( 0 )
, mIsInOn( false )
, mExpPercent( 0 )
, mSxpPercent( 0 )
, mDropPercent( 0 )
{
	assert( mInstance == 0 && "bad singleton" );
	mInstance = this;

	::memset( mSubDlg, 0, sizeof(HWND)*MAX_GMTOOL_SUBDLG );

	GetCurrentDirectoryA( MAX_PATH, mCurrentPath);
}

cGMTool::~cGMTool()
{
	FreeLibrary( mRichMod );

	assert( mInstance );
	mInstance = 0;
}

BOOL cGMTool::SetDlgItemTextEx( eGMTOOL_SUBDLG_INDEX hwndIndex, int nControlID, int nStringID )
{
	TCHAR str[MAX_LOADSTRING];
	if( LoadString( mInst, nStringID, str, MAX_LOADSTRING ) == 0 )
		return FALSE;

	return SetDlgItemText( mSubDlg[hwndIndex], nControlID, str );
}

bool cGMTool::Init( HINSTANCE hinst, HWND hwnd )
{
	mInst      = hinst;
	mParentWnd = hwnd;
	
	mRichMod = LoadLibrary( _T("Riched20.dll") );

	/// dialog 생성
	mMainDlg = CreateDialog( hinst, MAKEINTRESOURCE(IDD_DIALOG_GMTOOL), mParentWnd, DlgProc );
	mSubDlg[GMTOOL_SUBDLG_ITEM]		= CreateDialog( hinst, MAKEINTRESOURCE(IDD_DIALOG_GMTOOL_ITEM),		mMainDlg, DlgItemProc );
	mSubDlg[GMTOOL_SUBDLG_SKILL]	= CreateDialog( hinst, MAKEINTRESOURCE(IDD_DIALOG_GMTOOL_SKILL),	mMainDlg, DlgSkillProc );
	mSubDlg[GMTOOL_SUBDLG_PK]		= CreateDialog( hinst, MAKEINTRESOURCE(IDD_DIALOG_GMTOOL_PK),		mMainDlg, DlgPKProc );
	mSubDlg[GMTOOL_SUBDLG_MONSTER]	= CreateDialog( hinst, MAKEINTRESOURCE(IDD_DIALOG_GMTOOL_MONSTER),	mMainDlg, DlgMonsterProc );
	mSubDlg[GMTOOL_SUBDLG_NOTE]		= CreateDialog( hinst, MAKEINTRESOURCE(IDD_DIALOG_GMTOOL_NOTE),		mMainDlg, DlgNoteProc );
	mSubDlg[GMTOOL_SUBDLG_NOTICE]	= CreateDialog( hinst, MAKEINTRESOURCE(IDD_DIALOG_GMTOOL_NOTICE),	mMainDlg, DlgNoticeProc );
	mSubDlg[GMTOOL_SUBDLG_CHAT]		= CreateDialog( hinst, MAKEINTRESOURCE(IDD_DIALOG_GMTOOL_CHAT),		mMainDlg, DlgChatProc );
	mSubDlg[GMTOOL_SUBDLG_EVENT]	= CreateDialog( hinst, MAKEINTRESOURCE(IDD_DIALOG_GMTOOL_EVENT),	mMainDlg, DlgEventProc );
	mSubDlg[GMTOOL_SUBDLG_WEBSITE]	= CreateDialog( hinst, MAKEINTRESOURCE(IDD_DIALOG_GMTOOL_WEBSITE),	mMainDlg, DlgWebSiteProc );
	mSubDlg[GMTOOL_SUBDLG_MAP]	    = CreateDialog( hinst, MAKEINTRESOURCE(IDD_DIALOG_GMTOOL_MAP),	    mMainDlg, DlgMapProc );
	mSubDlg[GMTOOL_SUBDLG_SPEED]    = CreateDialog( hinst, MAKEINTRESOURCE(IDD_DIALOG_GMTOOL_SPEED),	mMainDlg, DlgSpeedProc );
	mSubDlg[GMTOOL_SUBDLG_CALL]	    = CreateDialog( hinst, MAKEINTRESOURCE(IDD_DIALOG_GMTOOL_CALL),	    mMainDlg, DlgCallProc );
 	mSubDlg[GMTOOL_SUBDLG_STOP]	    = CreateDialog( hinst, MAKEINTRESOURCE(IDD_DIALOG_GMTOOL_STOP),	    mMainDlg, DlgStopProc );
 	mSubDlg[GMTOOL_SUBDLG_KICK]	    = CreateDialog( hinst, MAKEINTRESOURCE(IDD_DIALOG_GMTOOL_KICK),	    mMainDlg, DlgKickProc );
	mSubDlg[GMTOOL_SUBDLG_EXPDROP]	= CreateDialog( hinst, MAKEINTRESOURCE(IDD_DIALOG_GMTOOL_EXPDROP),	mMainDlg, DlgExpDropProc );

	/// enable 걸기
	EnableWindow( GetDlgItem( mMainDlg, IDC_BUTTON_GMT_SKILL ), false );
	EnableWindow( GetDlgItem( mMainDlg, IDC_BUTTON_GMT_CHAT ), false );
	EnableWindow( GetDlgItem( mMainDlg, IDC_BUTTON_GMT_PK ), false );
	EnableWindow( GetDlgItem( mMainDlg, IDC_BUTTON_GMT_NOTE ), false );
	EnableWindow( GetDlgItem( mMainDlg, IDC_BUTTON_GMT_EVENT ), false );
	EnableWindow( GetDlgItem( mMainDlg, IDC_BUTTON_GMT_STOP ), false );
	EnableWindow( GetDlgItem( mMainDlg, IDC_BUTTON_GMT_EXPDROP ), false );

	return true;
}

void cGMTool::Exit()
{
	DestroyWindow( mSubDlg[GMTOOL_SUBDLG_EVENT] );
	DestroyWindow( mSubDlg[GMTOOL_SUBDLG_CHAT] );
	DestroyWindow( mSubDlg[GMTOOL_SUBDLG_NOTICE] );
	DestroyWindow( mSubDlg[GMTOOL_SUBDLG_NOTE] );
	DestroyWindow( mSubDlg[GMTOOL_SUBDLG_MONSTER] );
	DestroyWindow( mSubDlg[GMTOOL_SUBDLG_PK] );
	DestroyWindow( mSubDlg[GMTOOL_SUBDLG_SKILL] );
	DestroyWindow( mSubDlg[GMTOOL_SUBDLG_ITEM] );
	DestroyWindow( mSubDlg[GMTOOL_SUBDLG_WEBSITE] );
	DestroyWindow( mSubDlg[GMTOOL_SUBDLG_MAP] );
	DestroyWindow( mSubDlg[GMTOOL_SUBDLG_SPEED] );
	DestroyWindow( mSubDlg[GMTOOL_SUBDLG_CALL] );
 	DestroyWindow( mSubDlg[GMTOOL_SUBDLG_STOP] );
 	DestroyWindow( mSubDlg[GMTOOL_SUBDLG_KICK] );
	DestroyWindow( mSubDlg[GMTOOL_SUBDLG_EXPDROP] );
	DestroyWindow( mMainDlg );
}

bool cGMTool::LoadData()
{
	/// 아이템 데이터 로딩
	if( LoadItemData() == false )
	{
		assert(0);
		return false;
	}

	/// 몬스터 데이터 로딩
	if( LoadMonsterData() == false )
	{
		assert(0);
		return false;
	}
	
	/// 공지 데이터 로딩
	if( LoadNoticeData() == false )
	{
		assert(0);
		return false;
	}

	/// 스킬 데이터 로딩
	if( LoadSkillData() == false )
	{
		assert(0);
		return false;
	}

	/// 스킬 데이터 로딩
	if( LoadMapData() == false )
	{
		assert(0);
		return false;
	}

	//::ShowWindow( mMainDlg, SW_SHOW );
	::SetActiveWindow( mParentWnd );

	return true;
}

void cGMTool::OnMove()
{
	RECT rc0, rc1;
	::GetWindowRect( mParentWnd, &rc0 );
	::GetWindowRect( mMainDlg, &rc1 );
	int width = rc1.right - rc1.left;
	int x = rc0.left - width;
	if( x < 0 )
		x = 0;
	int y = rc0.top;// + GetSystemMetrics(SM_CYSIZEFRAME) + GetSystemMetrics(SM_CYCAPTION);

	::SetWindowPos( mMainDlg, 0, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );

	for( int cnt = 0; cnt < MAX_GMTOOL_SUBDLG; ++cnt )
	{
		if ( ::IsWindowVisible( mSubDlg[cnt] ) == TRUE )
		{
			int screenWid   = GetSystemMetrics( SM_CXSCREEN );;
			int ScreenHeight= GetSystemMetrics( SM_CYSCREEN );;
			
			RECT childWndPos;
			::GetWindowRect( mSubDlg[cnt], &childWndPos );
			
			int posX      = rc0.left + mSubDlgPos[cnt].x;
			int posY      = rc0.top  + mSubDlgPos[cnt].y;;
			int wndWidth  = childWndPos.right - childWndPos.left;
			int wndHeight = childWndPos.bottom- childWndPos.top;

// 			if( posX < 0 )
// 				posX = 0;
// 			if( posX + wndWidth > screenWid ) 
// 				posX = screenWid - wndWidth;
// 			if( posY < 0 )
// 				posY = 0;
// 			if( posY + wndHeight > ScreenHeight ) 
// 				posY = ScreenHeight - wndHeight;

			::SetWindowPos( mSubDlg[cnt], 0, posX, posY, 0, 0, SWP_NOSIZE | SWP_NOZORDER | SWP_NOACTIVATE );
		}
	}
}

void cGMTool::OnCommand( int id )
{
	HWND hwnd = NULL;
	switch( id )
	{
	case IDC_BUTTON_GMT_ITEM:	hwnd = mSubDlg[GMTOOL_SUBDLG_ITEM];		break;
	case IDC_BUTTON_GMT_SKILL:	hwnd = mSubDlg[GMTOOL_SUBDLG_SKILL];	break;
	case IDC_BUTTON_GMT_CHAT:	hwnd = mSubDlg[GMTOOL_SUBDLG_CHAT];		break;
	case IDC_BUTTON_GMT_PK:		hwnd = mSubDlg[GMTOOL_SUBDLG_PK];		break;
	case IDC_BUTTON_GMT_MONSTER:hwnd = mSubDlg[GMTOOL_SUBDLG_MONSTER];	break;
	case IDC_BUTTON_GMT_NOTE:	hwnd = mSubDlg[GMTOOL_SUBDLG_NOTE];		break;
	case IDC_BUTTON_GMT_NOTICE:	hwnd = mSubDlg[GMTOOL_SUBDLG_NOTICE];	break;
	case IDC_BUTTON_GMT_EVENT:	hwnd = mSubDlg[GMTOOL_SUBDLG_EVENT];	break;
    case IDC_BUTTON_GMT_WEBSITE:hwnd = mSubDlg[GMTOOL_SUBDLG_WEBSITE];	break;
	case IDC_BUTTON_GMT_MAP    :hwnd = mSubDlg[GMTOOL_SUBDLG_MAP];   	break;
	case IDC_BUTTON_GMT_SPEED  :hwnd = mSubDlg[GMTOOL_SUBDLG_SPEED];   	break;
	case IDC_BUTTON_GMT_CALL   :hwnd = mSubDlg[GMTOOL_SUBDLG_CALL];   	break;
 	case IDC_BUTTON_GMT_STOP   :hwnd = mSubDlg[GMTOOL_SUBDLG_STOP];   	break;	
 	case IDC_BUTTON_GMT_KICK   :hwnd = mSubDlg[GMTOOL_SUBDLG_KICK];   	break;
	case IDC_BUTTON_GMT_EXPDROP:hwnd = mSubDlg[GMTOOL_SUBDLG_EXPDROP];	break;
	case IDC_BUTTON_GMT_IN     :
#ifdef _GMTOOL
		/// 메시지 전송
		if( NETWORK->IsConnected() )
		{
			TCHAR str[MAX_LOADSTRING];

			if( mIsInOn == false )
			{
				MSG_REQ_CHEAT_IN msg;
				::memset( &msg, 0, sizeof(msg) );
				msg.Category = NM_CHEAT;
				msg.Protocol = NM_CHEAT_IN_REQ;
 
				NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );
				CHEATMAN->SetHideMode( true );
				CHEATMAN->SetUndeadMode( true );
				
				if( LoadString( mInst, IDS_GMTOOL_IN_ON, str, MAX_LOADSTRING ) == 0 )
					return;
				SetDlgItemText( mMainDlg, IDC_BUTTON_GMT_IN, str );
				
				mIsInOn = true;
			}
			else
			{
				if( CHEATMAN->GetHideMode() == true )
					SendMessage( mMainDlg, WM_COMMAND, MAKEWPARAM( IDC_BUTTON_GMT_HIDE, BN_CLICKED ), 0 );
				if( CHEATMAN->GetUndeadMode() == true )
				{
					MSG_REQ_CHEAT_UNDEAD msg;
					::memset( &msg, 0, sizeof(msg) );
					msg.Category = NM_CHEAT;
					msg.Protocol = NM_CHEAT_UNDEAD_REQ;
					msg.mMode = false;

					NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );
					mIsInOn = false;
				}
				if( LoadString( mInst, IDS_GMTOOL_IN, str, MAX_LOADSTRING ) == 0 )
					return;
				SetDlgItemText( mMainDlg, IDC_BUTTON_GMT_IN, str );
			}
		}
		return;
	
	case IDC_BUTTON_GMT_HIDE   :
		/// 메시지 전송
		if( NETWORK->IsConnected() )
		{
			CHEATMAN->SetHideMode( !CHEATMAN->GetHideMode() );

			MSG_REQ_CHEAT_HIDE msg;
			::memset( &msg, 0, sizeof(msg) );
			msg.Category = NM_CHEAT;
			msg.Protocol = NM_CHEAT_HIDE_REQ;
			msg.mMode = CHEATMAN->GetHideMode();

			NETWORK->SendNetworkMsg( (char*)&msg, sizeof(msg) );
		}
		return;
#endif
	
	default:					assert( 0 && "error gmtool button" );	return;
	}

	::ShowWindow( hwnd, IsWindowVisible( hwnd ) ? SW_HIDE : SW_SHOW );
}

INT_PTR CALLBACK cGMTool::DlgProc( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
	switch( msg )
	{
	case WM_INITDIALOG:
		break;
	case WM_MOVE:
		{
			GMTOOL->OnMove();
		}
		break;
	case WM_COMMAND:
		{
			GMTOOL->OnCommand( LOWORD( wparam ) );
		}
		break;
	case WM_SYSCOMMAND:
		{
			if( wparam == SC_CLOSE ) 
			{
				PostMessage( ::GetParent( wnd ), msg, wparam, lparam );
			}
			break;
		}

	}
	return FALSE;
}

/// 아이템 
INT_PTR CALLBACK cGMTool::DlgItemProc( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
	switch( msg )
	{
	case WM_MOVE:
		{
		    GMTOOL->OnChildMove( GMTOOL_SUBDLG_ITEM );	
		}
		break;
	case WM_SHOWWINDOW:
		{
			GMTOOL->InitDlgItem();
		}
		break;
	case WM_COMMAND:
		{
			GMTOOL->OnCommandItem( LOWORD( wparam ), HIWORD( wparam ) );
		}
		break;
	}
	return FALSE;
}

/// 스킬
INT_PTR CALLBACK cGMTool::DlgSkillProc( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
	switch( msg )
	{
	case WM_MOVE:
		{
			GMTOOL->OnChildMove( GMTOOL_SUBDLG_SKILL );	
		}
		break;
	case WM_SHOWWINDOW:
		{
			GMTOOL->InitDlgSkill();
		}
		break;
	case WM_COMMAND:
		{
			GMTOOL->OnCommandSkill( LOWORD( wparam ), HIWORD( wparam ) );
		}
		break;
	}
	return FALSE;
}

/// PK
INT_PTR CALLBACK cGMTool::DlgPKProc( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
	switch( msg )
	{
	case WM_MOVE:
		{
			GMTOOL->OnChildMove( GMTOOL_SUBDLG_PK );	
		}
		break;
	case WM_SHOWWINDOW:
		break;
	case WM_COMMAND:
		break;
	}
	return FALSE;
}

/// 몬스터
INT_PTR CALLBACK cGMTool::DlgMonsterProc( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
	switch( msg )
	{
	case WM_MOVE:
		{
			GMTOOL->OnChildMove( GMTOOL_SUBDLG_MONSTER );	
		}
		break;
	case WM_SHOWWINDOW:
		{
			GMTOOL->InitDlgMonster();
		}
		break;
	case WM_COMMAND:
		{
			GMTOOL->OnCommandMonster( LOWORD( wparam ), HIWORD( wparam ) );
		}
		break;
	}
	return FALSE;
}

/// 1:1채팅
INT_PTR CALLBACK cGMTool::DlgChatProc( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
	switch( msg )
	{
	case WM_MOVE:
		{
			GMTOOL->OnChildMove( GMTOOL_SUBDLG_CHAT );	
		}
		break;
	case WM_SHOWWINDOW:
		break;
	case WM_COMMAND:
		break;
	}
	return FALSE;
}

/// 쪽지보내기
INT_PTR CALLBACK cGMTool::DlgNoteProc( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
	switch( msg )
	{
	case WM_MOVE:
		{
			GMTOOL->OnChildMove( GMTOOL_SUBDLG_NOTE );	
		}
		break;
	case WM_INITDIALOG:
		break;
	case WM_COMMAND:
		break;
	}
	return FALSE;
}

/// 공지
INT_PTR CALLBACK cGMTool::DlgNoticeProc( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
	switch( msg )
	{
	case WM_MOVE:
		{
			GMTOOL->OnChildMove( GMTOOL_SUBDLG_NOTICE );	
		}
		break;
	case WM_INITDIALOG:
		break;
	case WM_SHOWWINDOW:
		{
			GMTOOL->InitDlgNotice();
		}
		break;
	case WM_COMMAND:
		{
			GMTOOL->OnCommandNotice( LOWORD( wparam ), HIWORD( wparam ) );
		}
		break;
	case WM_TIMER:
		{
			GMTOOL->OnTimer();	
		}
		break;
	}
	return FALSE;
}

/// 이벤트
INT_PTR CALLBACK cGMTool::DlgEventProc( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
	switch( msg )
	{
	case WM_MOVE:
		{
			GMTOOL->OnChildMove( GMTOOL_SUBDLG_EVENT );	
		}
		break;
	case WM_SHOWWINDOW:
		break;
	case WM_COMMAND:
		break;
	}
	return FALSE;
}

/// 웹 사이트
INT_PTR CALLBACK cGMTool::DlgWebSiteProc( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
	switch( msg )
	{
	case WM_MOVE:
		{
			GMTOOL->OnChildMove( GMTOOL_SUBDLG_WEBSITE );	
		}
		break;
	case WM_SHOWWINDOW:
		{
			GMTOOL->InitDlgWebSite();
		}
		break;
	case WM_COMMAND:
		{
			GMTOOL->OnCommandWebSite( LOWORD( wparam ), HIWORD( wparam ) );
		}
		break;
	}
	return FALSE;
}

/// 맵 이동 
INT_PTR CALLBACK cGMTool::DlgMapProc( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
	switch( msg )
	{
	case WM_MOVE:
		{
			GMTOOL->OnChildMove( GMTOOL_SUBDLG_MAP );	
		}
		break;
	case WM_SHOWWINDOW:
		{
			GMTOOL->InitDlgMap();
		}
		break;
	case WM_COMMAND:
		{
			GMTOOL->OnCommandMap( LOWORD( wparam ), HIWORD( wparam ) );
		}
		break;
	}
	return FALSE;
}

/// 이동 속도
INT_PTR CALLBACK cGMTool::DlgSpeedProc( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
	switch( msg )
	{
	case WM_MOVE:
		{
			GMTOOL->OnChildMove( GMTOOL_SUBDLG_SPEED );	
		}
		break;
	case WM_SHOWWINDOW:
		{
			GMTOOL->InitDlgSpeed();
		}
		break;
	case WM_HSCROLL:
		{
			GMTOOL->OnCommandSpeed( IDC_SLIDER_SPEED_MOVESPEED, LOWORD( wparam ));
		}
		break;
	case WM_COMMAND:
		{
			GMTOOL->OnCommandSpeed( LOWORD( wparam ), HIWORD( wparam ) );
		}
		break;
	}
	return FALSE;
}

/// 유저 소환 
INT_PTR CALLBACK cGMTool::DlgCallProc( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
	switch( msg )
	{
	case WM_MOVE:
		{
			GMTOOL->OnChildMove( GMTOOL_SUBDLG_CALL );	
		}
		break;
	case WM_SHOWWINDOW:
		{
			GMTOOL->InitDlgCall();
		}
		break;
	case WM_COMMAND:
		{
			GMTOOL->OnCommandCall( LOWORD( wparam ), HIWORD( wparam ) );
		}
		break;
	}
	return FALSE;
}

/// 유저 이동, 스킬 사용, 공격, 거래, 아이템 습득, 창고 이용 금지
INT_PTR CALLBACK cGMTool::DlgStopProc( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
	switch( msg )
	{
	case WM_MOVE:
		{
			GMTOOL->OnChildMove( GMTOOL_SUBDLG_STOP );	
		}
		break;
	case WM_SHOWWINDOW:
		{
			GMTOOL->InitDlgStop();
		}
		break;
	case WM_COMMAND:
		{
			GMTOOL->OnCommandStop( LOWORD( wparam ), HIWORD( wparam ) );
		}
		break;
	}
	return FALSE;
}

/// 유저 강제 퇴장
INT_PTR CALLBACK cGMTool::DlgKickProc( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
	switch( msg )
	{
	case WM_MOVE:
		{
			GMTOOL->OnChildMove( GMTOOL_SUBDLG_KICK );	
		}
		break;
	case WM_SHOWWINDOW:
		{
			GMTOOL->InitDlgKick();
		}
		break;
	case WM_COMMAND:
		{
			GMTOOL->OnCommandKick( LOWORD( wparam ), HIWORD( wparam ) );
		}
		break;
	}
	return FALSE;
}

/// 드롭율 / 경험치 증가율 조정
INT_PTR CALLBACK cGMTool::DlgExpDropProc( HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam )
{
	switch( msg )
	{
	case WM_MOVE:
		{
			GMTOOL->OnChildMove( GMTOOL_SUBDLG_EXPDROP );	
		}
		break;
	case WM_SHOWWINDOW:
		{
			GMTOOL->InitDlgExpDrop();
		}
		break;
	case WM_COMMAND:
		{
			GMTOOL->OnCommandExpDrop( LOWORD( wparam ), HIWORD( wparam ) );
		}
		break;
	}
	return FALSE;
}
