#include "stdafx.h"
#include "MonsterDialog.h"

#include "RegenToolView.h"
#include "MonsterSceneNode.h"

IMPLEMENT_DYNAMIC(cMonsterDialog, CDialog)

BEGIN_MESSAGE_MAP(cMonsterDialog, CDialog)
	ON_BN_CLICKED(IDC_BUTTON_MONSTER_SAVE, OnClickedSave)
	ON_BN_CLICKED(IDC_BUTTON_MONGROUP_CREATE, OnClickedGroupCreate)
	ON_BN_CLICKED(IDC_BUTTON_MONGROUP_DELETE, OnClickedGroupDelete)
	ON_LBN_SELCHANGE(IDC_LIST_MONGROUP, OnSelchangeGroup)
	ON_LBN_SELCHANGE(IDC_COMBO_MONGROUP_REGEN_INDEX, OnSelchangeGroupRegenIndex)
	ON_BN_CLICKED(IDC_CHECK_MONGROUP_FIRST_REGEN, OnCheckedGroupFirstRegen)
	ON_BN_CLICKED(IDC_CHECK_MONGROUP_CHANNEL_CHECK, OnCheckedChannelCheck)
	ON_BN_CLICKED(IDC_BUTTON_MONSTER_CREATE, OnClickedCreate)
	ON_BN_CLICKED(IDC_BUTTON_MONSTER_CHANGE, OnClickedChange)
	ON_BN_CLICKED(IDC_BUTTON_MONSTER_DELETE, OnClickedDelete)
	ON_LBN_SELCHANGE(IDC_LIST_MONSTER, OnSelchangeNode)
	ON_REGISTERED_MESSAGE(NEN_CHANGED, OnChangedNumber)
END_MESSAGE_MAP()

cMonsterDialog::cMonsterDialog()
: mSelMonsterGroup( 0 )
, mSelMonster( 0 )
{
}

cMonsterDialog::~cMonsterDialog()
{
}

void cMonsterDialog::Clear()
{
	CListBox* list = (CListBox*)GetDlgItem(IDC_LIST_MONGROUP);
	list->ResetContent();

	CComboBox* combo = (CComboBox*)GetDlgItem(IDC_COMBO_MONGROUP_REGEN_INDEX);
	combo->ResetContent();

	list = (CListBox*)GetDlgItem(IDC_LIST_MONSTER);
	list->ResetContent();
}

void cMonsterDialog::SelectGroup( cMonsterGroup* group )
{
	mSelMonsterGroup = group;
	CListBox* list = (CListBox*)GetDlgItem(IDC_LIST_MONGROUP);
	list->SetCurSel( -1 );

	if( group == 0 )
	{
		SetGroupEnabled( false );
		SelectNode( 0 );
		return;
	}
	else
	{
		SetGroupEnabled( true );
	}

	/// 리스트
	for( unsigned int i = 0, iend = list->GetCount(); i < iend; ++i )
	{
		if( (cMonsterGroup*)list->GetItemData( i ) == group )
		{
			list->SetCurSel( i );
			break;
		}
	}

	/// 그룹 데이타를 갱신
	{
		/// 최초 리젠 여부
		CButton* check = (CButton*)GetDlgItem( IDC_CHECK_MONGROUP_FIRST_REGEN );
		check->SetCheck( group->mFirstRegen ? 1 : 0 );

		/// 채널간 공유 체크
		check = (CButton*)GetDlgItem( IDC_CHECK_MONGROUP_CHANNEL_CHECK );
		check->SetCheck( group->mChannelCheck ? 1 : 0 );

		/// 리젠 인덱스
		CComboBox* combo = (CComboBox*)GetDlgItem(IDC_COMBO_MONGROUP_REGEN_INDEX);
		unsigned int i = 0, iend = combo->GetCount();

		for( ; i < iend; ++i )
		{
			if( (unsigned int)combo->GetItemData(i) == group->mRegenGroupIndex )
			{
				combo->SetCurSel( i );
				break;
			}
		}
		if( i == iend )
		{
			combo->SetCurSel( -1 );
			group->mRegenGroupIndex = 0;
		}

		/// 맵 그룹 인덱스
		mMapGroupIndex.SetValue( (float)group->mMapGroupIndex );

		/// 리젠 퍼센트
		mGroupRegenPercentNum.SetValue( (float)group->mRegenPercent );

		/// 리젠 범위
		mGroupRegenRangeNum.SetValue( (float)group->mRegenRange );

		/// 리젠 대기 시간
		mGroupRegenWaitTimeNum.SetValue( (float)group->mRegenWaitTime );
	}

	/// 몬스터 리스트를 갱신
	UpdateList( group->mNodeList );
}

void cMonsterDialog::SelectNode( cMonsterSceneNode* node )
{
	mSelMonster = node;
	CListBox* list = (CListBox*)GetDlgItem(IDC_LIST_MONSTER);
	list->SetCurSel( -1 );

	if( node == 0 )
	{
		SetEnabled( false );
		return;
	}
	else
	{
		SetEnabled( true );
	}

	/// 리스트
	for( unsigned int i = 0, iend = list->GetCount(); i < iend; ++i )
	{
		if( (cMonsterSceneNode*)list->GetItemData( i ) == node )
		{
			list->SetCurSel( i );
			break;
		}
	}

	/// 인덱스
	unsigned int index = node->GetUserData0();
	const cMonsterInfo* info = VIEW->GetMonsterInfo( index );
	assert( info );

	cString str;
	str.Format( "%d", index );
	GetDlgItem(IDC_EDIT_MONSTER_INDEX)->SetWindowText( str.Cstr() );

	/// 이름
	GetDlgItem(IDC_EDIT_MONSTER_NAME)->SetWindowText( VIEW->GetMonsterNameByNameIndex(info->mNameIndex).Cstr() );

	/// 모델
	GetDlgItem(IDC_EDIT_MONSTER_MODEL)->SetWindowText( VIEW->GetModelFile(info->mModelIndex).Cstr() );

	/// 리젠 대기 시간
	mRegenWaitTimeNum.SetValue( (float)node->GetUserData1() );

	/// 리젠 유지 시간
	mRegenLifeTimeNum.SetValue( (float)node->GetUserData3() );

	/// 이동, 회전
	UpdateNodeTransform( node );
}

void cMonsterDialog::UpdateCombo( const tMap<unsigned int, cMonsterInfo*>& infoMap )
{
	CComboBox* combo = (CComboBox*)GetDlgItem(IDC_COMBO_MONSTER_INDEX);
	combo->ResetContent();
	cString str;

	typedef tMap<unsigned int, cMonsterInfo*> cInfoMap;
	cInfoMap::cConstIterator ii = infoMap.Begin();
	cInfoMap::cConstIterator iiend = infoMap.End();

	for( unsigned int c = 0; ii != iiend; ++ii, ++c )
	{
		unsigned int monIndex = ii->mFirst;
		cMonsterInfo* info = ii->mSecond;

		str.Format( "%d %s", monIndex, VIEW->GetMonsterNameByNameIndex(info->mNameIndex).Cstr() );

		combo->AddString( str.Cstr() );
		combo->SetItemData( c, (DWORD)monIndex );
	}

	combo->SetCurSel( 0 );
}

void cMonsterDialog::UpdateGroupList( const tMap<unsigned int, cMonsterGroup*>& groupMap )
{
	CListBox* list = (CListBox*)GetDlgItem(IDC_LIST_MONGROUP);
	list->ResetContent();
	CComboBox* combo = (CComboBox*)GetDlgItem(IDC_COMBO_MONGROUP_REGEN_INDEX);
	combo->ResetContent();
	cString str;

	typedef tMap<unsigned int, cMonsterGroup*> cGroupMap;
	cGroupMap::cConstIterator ii = groupMap.Begin();
	cGroupMap::cConstIterator iiend = groupMap.End();

	for( unsigned int c = 0; ii != iiend; ++ii, ++c )
	{
		unsigned int groupIndex = ii->mFirst;
		cMonsterGroup* group = ii->mSecond;

		str.Format( "%d {...}", groupIndex );

		list->AddString( str.Cstr() );
		list->SetItemData( c, (DWORD)group );

		combo->AddString( str.Cstr() );
		combo->SetItemData( c, (DWORD)groupIndex );
	}
}

void cMonsterDialog::UpdateList( const tList<cMonsterSceneNode*>& nodeList )
{
	CListBox* list = (CListBox*)GetDlgItem(IDC_LIST_MONSTER);
	list->ResetContent();
	cString str;

	typedef tList<cMonsterSceneNode*> cMonsterList;
	cMonsterList::cConstIterator i = nodeList.Begin();
	cMonsterList::cConstIterator iend = nodeList.End();

	for( unsigned int c = 0; i != iend; ++i, ++c )
	{
		cMonsterSceneNode* n = *i;
		unsigned int monIndex = n->GetUserData0();

		str.Format( "%d %s", monIndex, VIEW->GetMonsterNameByMonIndex(monIndex).Cstr() );

		list->AddString( str.Cstr() );
		list->SetItemData( c, (DWORD)n );
	}
}

void cMonsterDialog::UpdateNodeTransform( const cMonsterSceneNode* node )
{
	assert( node );

	/// 이동
	const NiPoint3& t = node->GetTranslate();
	mTxNum.SetValue( t.x / 100.0f );
	mTyNum.SetValue( t.y / 100.0f );

	/// 회전
	const NiMatrix3& r = node->GetRotate();
	float xangle = 0.0f, yangle = 0.0f, zangle = 0.0f;
	r.ToEulerAnglesXYZ( xangle, yangle, zangle );
	mRzNum.SetValue( D3DXToDegree( zangle ) );
}

void cMonsterDialog::DoDataExchange( CDataExchange* dx )
{
	CDialog::DoDataExchange( dx );

	DDX_Control( dx, IDC_BUTTON_MONSTER_SAVE, mSaveButton );
	DDX_Control( dx, IDC_BUTTON_MONGROUP_CREATE, mGroupCreateButton );
	DDX_Control( dx, IDC_BUTTON_MONGROUP_DELETE, mGroupDeleteButton );
	DDX_Control( dx, IDC_BUTTON_MONSTER_CREATE, mCreateButton );
	DDX_Control( dx, IDC_BUTTON_MONSTER_CHANGE, mChangeButton );
	DDX_Control( dx, IDC_BUTTON_MONSTER_DELETE, mDeleteButton );
}

BOOL cMonsterDialog::OnInitDialog()
{
	CDialog::OnInitDialog();

	mGroupIndexNum.Create( 1.0f, 1000.0f, 1.0f, 1.0f, this, IDC_NUM_MONGROUP_INDEX );
	mMapGroupIndex.Create( 0.0f, 1000.0f, 0.0f, 1.0f, this, IDC_NUM_MONGROUP_MAPGROUP_INDEX );
	mGroupRegenPercentNum.Create( 0.0f, 100.0f, 50.0f, 5.0f, this, IDC_NUM_MONGROUP_REGEN_PERCENT );
	mGroupRegenRangeNum.Create( 10.0f, 1000.0f, 100.0f, 10.0f, this, IDC_NUM_MONGROUP_REGEN_RANGE );
	mGroupRegenWaitTimeNum.Create( 100.0f, 1000000.0f, 10000.0f, 1000.0f, this, IDC_NUM_MONGROUP_REGEN_WAIT_TIME );
	mTxNum.Create( -100000.0f, 100000.0f, 0.0f, 0.1f, this, IDC_NUM_MONSTER_TX );
	mTyNum.Create( -100000.0f, 100000.0f, 0.0f, 0.1f, this, IDC_NUM_MONSTER_TY );
	mRzNum.Create( -179.0f, 179.0f, 0.0f, 1.0f, this, IDC_NUM_MONSTER_RZ );
	mRegenWaitTimeNum.Create( 100.0f, 1000000.0f, 100000.0f, 1000.0f, this, IDC_NUM_MONSTER_REGEN_WAIT_TIME );
	mRegenLifeTimeNum.Create( 100.0f, 1000000.0f, 0.0f, 1000.0f, this, IDC_NUM_MONSTER_REGEN_LIFE_TIME );

	SetGroupEnabled( false );
	SetEnabled( false );
	return TRUE;
}

void cMonsterDialog::OnClickedSave()
{
	VIEW->SaveMonsterRegen();
}

void cMonsterDialog::OnClickedGroupCreate()
{
	unsigned int index = (unsigned int)mGroupIndexNum.GetValue();
	int ret = VIEW->CreateMonsterGroup( index );

	switch( ret )
	{
	case 0:
		MessageBox( "Failed to create monster group.", "Monster Group" );
		break;
	case -1:
		MessageBox( "Same group exists.", "Monster Group" );
		break;
	}
}

void cMonsterDialog::OnClickedGroupDelete()
{
	CListBox* list = (CListBox*)GetDlgItem(IDC_LIST_MONSTER);
	list->ResetContent();

	///
	list = (CListBox*)GetDlgItem(IDC_LIST_MONGROUP);
	int i = list->GetCurSel();

	if( i == LB_ERR )
		return;

	cMonsterGroup* group = (cMonsterGroup*)list->GetItemData( i );
	assert( group );

	VIEW->DeleteMonsterGroup( group->mIndex );
}

void cMonsterDialog::OnSelchangeGroup()
{
	CListBox* list = (CListBox*)GetDlgItem( IDC_LIST_MONGROUP );

	int i = list->GetCurSel();
	if( i == LB_ERR )
		return;

	cMonsterGroup* group = (cMonsterGroup*)list->GetItemData( i );

    VIEW->SelectMonsterGroup( group );
}

void cMonsterDialog::OnSelchangeGroupRegenIndex()
{
	if( mSelMonsterGroup == 0 )
		return;

	CComboBox* combo = (CComboBox*)GetDlgItem( IDC_COMBO_MONGROUP_REGEN_INDEX );

	int i = combo->GetCurSel();
	if( i == LB_ERR )
		return;

	unsigned int groupIndex = (unsigned int)combo->GetItemData( i );
	mSelMonsterGroup->mRegenGroupIndex = groupIndex;
}

void cMonsterDialog::OnCheckedGroupFirstRegen()
{
	if( mSelMonsterGroup == 0 )
		return;

	CButton* check = (CButton*)GetDlgItem( IDC_CHECK_MONGROUP_FIRST_REGEN );

	mSelMonsterGroup->mFirstRegen = check->GetCheck() != 0;
}

void cMonsterDialog::OnCheckedChannelCheck()
{
	if( mSelMonsterGroup == 0 )
		return;

	CButton* check = (CButton*)GetDlgItem( IDC_CHECK_MONGROUP_CHANNEL_CHECK );

	mSelMonsterGroup->mChannelCheck = check->GetCheck() != 0;
}


void cMonsterDialog::OnClickedCreate()
{
	CComboBox* combo = (CComboBox*)GetDlgItem(IDC_COMBO_MONSTER_INDEX);
	unsigned int monIndex = (unsigned int)combo->GetItemData( combo->GetCurSel() );

	///
	unsigned int regenWaitTime = (unsigned int)mRegenWaitTimeNum.GetValue();
	unsigned int regenLifeTime = (unsigned int)mRegenLifeTimeNum.GetValue();
	int ret = VIEW->CreateMonster( monIndex, 0, 0, 0, regenWaitTime, regenLifeTime, true, true );

	switch( ret )
	{
	case -1:
		MessageBox( "Failed to create monster scene node.", "Monster" );
		break;
	}
}

void cMonsterDialog::OnClickedChange()
{
	CComboBox* combo = (CComboBox*)GetDlgItem(IDC_COMBO_MONSTER_INDEX);
	unsigned int monIndex = (unsigned int)combo->GetItemData( combo->GetCurSel() );

	///
	int ret = VIEW->ChangeMonster( monIndex );

	switch( ret )
	{
	case -1:
		MessageBox( "Select monster.", "Monster" );
		break;
	case -2:
		MessageBox( "Same monster exists.", "Monster" );
		break;
	}
}

void cMonsterDialog::OnClickedDelete()
{
	CListBox* list = (CListBox*)GetDlgItem( IDC_LIST_MONSTER );

	int i = list->GetCurSel();
	if( i == LB_ERR )
		return;

	cMonsterSceneNode* node = (cMonsterSceneNode*)list->GetItemData( i );
	int ret = VIEW->DeleteMonster( node );

	switch( ret )
	{
	case -1:
		MessageBox( "Select monster.", "Monster" );
		break;
	}
}

void cMonsterDialog::OnSelchangeNode()
{
	CListBox* list = (CListBox*)GetDlgItem( IDC_LIST_MONSTER );

	int i = list->GetCurSel();
	if( i == LB_ERR )
		return;

	cMonsterSceneNode* node = (cMonsterSceneNode*)list->GetItemData( i );
	VIEW->SelectMonster( node );
}

LRESULT cMonsterDialog::OnChangedNumber( WPARAM id, LPARAM )
{
	if( mSelMonsterGroup == 0 )
		return 0;

	switch( id )
	{
	case IDC_NUM_MONGROUP_MAPGROUP_INDEX:
		{
			mSelMonsterGroup->mMapGroupIndex = (unsigned int)mMapGroupIndex.GetValue();
			break;
		}
	case IDC_NUM_MONGROUP_REGEN_PERCENT:
		{
			mSelMonsterGroup->mRegenPercent = (unsigned int)mGroupRegenPercentNum.GetValue();
			break;
		}
	case IDC_NUM_MONGROUP_REGEN_RANGE:
		{
			mSelMonsterGroup->mRegenRange = (unsigned int)mGroupRegenRangeNum.GetValue();
			break;
		}
	case IDC_NUM_MONGROUP_REGEN_WAIT_TIME:
		{
			mSelMonsterGroup->mRegenWaitTime = (unsigned int)mGroupRegenWaitTimeNum.GetValue();
			break;
		}
	case IDC_NUM_MONSTER_TX:
	case IDC_NUM_MONSTER_TY:
		{
			float x = mTxNum.GetValue() * 100;
			float y = mTyNum.GetValue() * 100;
			VIEW->SetSelTranslate( NiPoint3(x, y, 0.0f), false );
			break;
		}
	case IDC_NUM_MONSTER_RZ:
		{
			float zangle = D3DXToRadian( mRzNum.GetValue() );
			VIEW->SetSelRotate( zangle, false );
			break;
		}
	case IDC_NUM_MONSTER_REGEN_WAIT_TIME:
		{
			if( mSelMonster )
				mSelMonster->SetUserData1( (unsigned int)mRegenWaitTimeNum.GetValue() );
			break;
		}
	case IDC_NUM_MONSTER_REGEN_LIFE_TIME:
		{
			if( mSelMonster )
				mSelMonster->SetUserData3( (unsigned int)mRegenLifeTimeNum.GetValue() );
			break;
		}
	}
	return 0;
}
