#include "stdafx.h"
#include "InventoryWindow.h"
#include "UIImage.h"

#include "../Common/Item_Common.h"
#include "GameUIManager.h"
#include "PushButton.h"
#include "ItemIcon.h"
#include "ItemManager.h"
#include "InvenSheetWindow.h"
#include "InvenEquipWindow.h"
#include "ObjectManager.h"
#include "Hero.h"
#include "Gauge.h"
#include "NumberEditBox.h"
#include "BagWindow.h"
#include "ChatWindow.h"

cInventoryWindow::cInventoryWindow()
: mWeightGauge(0)
, mSelectIcon(0)
, mpMoney(0)
, mShowBit(0)
, mpSelectImage(0)
, mShowSelect( false )
{
	mBagButton[0] = 0;
	mBagButton[1] = 0;
	mBagButton[2] = 0;
}

cInventoryWindow::~cInventoryWindow()
{
	SAFE_DELETE( mpSelectImage );
}

void cInventoryWindow::OnShow()
{
	cUIWindow::OnShow();

	BYTE byte = mShowBit;
	for( int i = 0; i < 3; ++i )
	{
		cUIWindow* b = (cUIWindow*)GAMEUI->GetBagWindow(i);
		if( b && (byte & 1) )
			b->ShowTop();

		byte = byte >> 1;
	}
}

void cInventoryWindow::OnHide()
{
	cUIWindow::OnHide();

	for( int i = 0; i < 3; ++i )
	{
		cUIWindow* b = (cUIWindow*)GAMEUI->GetBagWindow(i);
		if( b )
			b->Hide( false );
	}

	UIMAN->HideTip();
	UIMAN->HideDrag( this );

	mSelectIcon = 0;
	mShowSelect = false;

	/// npc 상점창이 열려있으면 닫기
	if( UIMAN->IsShowNpcBack() == true )
		UIMAN->HideNpcBack();
}

/// ESC 로 인해 닫힐때 가방도 같이닫는다
void cInventoryWindow::HideESC( bool onsound )
{
	cUIWindow::HideESC( onsound );

	for( unsigned int i = 0; i < 3; ++i )
	{
		cUIWindow* b = (cUIWindow*)GAMEUI->GetBagWindow(i);
		if( b )
			b->Hide( false );
	}
}

/// 주의사항 : 시트 윈도우나, 특별한 자식윈도우들을 따로 Init을 해주어야한다.
/// 그래야 맵체인지 등에 초기화 할수 있다.
void cInventoryWindow::UIStageIn()
{
	cInvenEquipWindow*	pEquip = (cInvenEquipWindow*)GetChild( eUIID_INVENTORY_EQUIPWINDOW );
	if( pEquip )
	{
		pEquip->UIStageIn();
	}
	else
	{
		assert(0);
	}

	/// 돈 초기 설정
	SetMoney( HERO->GetMoney() );
}

void cInventoryWindow::SetBagButtonPressed( unsigned int i, bool pressed )
{
	assert( i >= 0 && i <= 2 && "index out of range" );

	if( mBagButton[i] )
		mBagButton[i]->SetPress( pressed );

	//특정비트를 1로 지정하는 공식은 a | (a<<(n-1)) 가 되고
	//특정비트를 0으로 지정하는 공식은 (a&~(1<<n-1)) 가 되고
	//원하는 특정 비트를 반대로 하려면 (a^(1<<n-1)) 가 된다.

	BYTE byte = 0;
	BYTE end = 1;
	if( pressed )
	{
		byte = (1 << i);
	}

	end = (1 << i);
	BYTE mask = (0xFF ^ end);

	/// 마스크 씌워서 해당 위치의 비트만 세팅하기
	mShowBit = ( mShowBit & mask ) | byte;
}

bool cInventoryWindow::OnCreate( cUINodeProperty* property )
{
	if( cTabWindow::OnCreate( property ) == false )
		return false;

	/// 탭윈도우 세팅 
	cInvenSheetWindow* p = 0;
	for( unsigned int i = 0; i < 3; ++i )
	{
		p = (cInvenSheetWindow*)GetChild( eUIID_INVEN_SHEET1 + i );
		if( p )
		{
			p->BindSlot( i );
			p->Hide();
		}
	}

	SetCurrent( 0 );

	/// 장착 윈도우를 생성
	cUIWindow* pEquipWindow = (cUIWindow*)GetChild( eUIID_INVENTORY_EQUIPWINDOW );
	if( pEquipWindow )
	{
		pEquipWindow->Show( false );
	}
	else
	{
		assert(0);
	}

	/// 무게 게이지
	mWeightGauge = (cGauge*)GetChild( eUIID_INVENTORY_WEIGHT );
	mpMoney = (cNumberEditBox*)GetChild( eUIID_INVENTORY_MONEY );

	if( mWeightGauge )
	{
		ITEMMAN->SetWeightGauge( mWeightGauge );
	}
	else
	{
		assert(0);
	}
	
	/// 가방 버튼
	mBagButton[0] = (cPushButton*)GetChild( eUIID_INVENTORY_BAG0 );
	mBagButton[1] = (cPushButton*)GetChild( eUIID_INVENTORY_BAG1 );
	mBagButton[2] = (cPushButton*)GetChild( eUIID_INVENTORY_BAG2 );

	/// 무게게이지 뚜껑이미지
	cUISkin* pSkin = UIMAN->GetSkin();
	if( !pSkin )
	{
		assert(0);
		return false;
	}

	/// 선택 이미지 생성
	cUINodeSkin* selectSkin = pSkin->GetNodeSkin( "Inventory_SelectImage" );
	if( selectSkin )
	{
		mpSelectImage = new cUIImage( selectSkin->mpTexture );
		unsigned int tx = selectSkin->mSkinInfo->mTexX;
		unsigned int ty = selectSkin->mSkinInfo->mTexY;
		unsigned int w = selectSkin->mSkinInfo->mWidth;
		unsigned int h = selectSkin->mSkinInfo->mHeight;
		unsigned int x = selectSkin->mSkinInfo->mX;
		unsigned int y = selectSkin->mSkinInfo->mY;
		mpSelectImage->SetTextureRect( tx, ty, tx + w, ty + h );
		mpSelectImage->SetScreenRect( cUIRect( x, y, x + w, y + h ) );
	}
	return true;
}

void cInventoryWindow::UpdateRect()
{
	cTabWindow::UpdateRect();

	if( mSelectIcon && mpSelectImage )
	{
		cUIRect rc = mSelectIcon->GetAbsoluteRect();
		mpSelectImage->SetPos( rc.mLeft-2, rc.mTop-2 );
	}
}	

void cInventoryWindow::OnRender(cUIFontItemKeeper* pKeeper )
{
	cTabWindow::OnRender( pKeeper );

	if( mShowSelect && mpSelectImage )
		mpSelectImage->Draw();
}

void cInventoryWindow::OnCommand( cUINode* /*node*/, unsigned int id )
{
	if( id == eUIID_INVENTORY_CLOSE )
		Hide();
}

void cInventoryWindow::OnTabButtonPressed( cUINode* caller, unsigned int id )
{
	cTabWindow::OnTabButtonPressed( caller, id );
	mShowSelect = false;
	//mShowSelect = ( id == eUIID_INVENTORY_GENERIC && mSelectIcon ) ? true : false;
}

void cInventoryWindow::OnPushButtonPressed( cUINode* /*caller*/, unsigned int id )
{
	switch( id )
	{
	case eUIID_INVENTORY_BAG0:
		{
			cBagWindow* bag = GAMEUI->GetBagWindow( 0 );
			if( bag )
			{
				bag->Toggle();
				SetBagButtonPressed( 0, bag->IsVisible() );
			}
		}
		break;

	case eUIID_INVENTORY_BAG1:
		{
			cBagWindow* bag = GAMEUI->GetBagWindow( 1 );
			if( bag )
			{
				bag->Toggle();
				SetBagButtonPressed( 1, bag->IsVisible() );
			}
		}
		break;

	case eUIID_INVENTORY_BAG2:
		{
			cBagWindow* bag = GAMEUI->GetBagWindow( 2 );
			if( bag )
			{
				bag->Toggle();
				SetBagButtonPressed( 2, bag->IsVisible() );
			}
		}
		break;
	}
}

///
void cInventoryWindow::OnIconClicked( cUINode* caller, unsigned int )
{
	UpdateSelect( (cItemIcon*)caller );
}

void cInventoryWindow::OnIconRightClicked( cUINode* caller, unsigned int id, bool shift )
{
	/// shift + 우클릭 = 아이템 링크
	cItemIcon* itemIcon = (cItemIcon*)caller;
	if( itemIcon && shift == true )
	{
		cChatWindow* chatWin = GAMEUI->GetChatWindow();
		if( chatWin )
			chatWin->AddLinkItem( itemIcon->GetSlotIndex() );
	}
}

/// 새로운 슬롯으로 선택 갱신
void cInventoryWindow::ChangeSelect( unsigned int slotIndex )
{
	cItem& item = ITEMMAN->GetItem( slotIndex );
	cItemIcon* newIcon = item.GetIcon();
	UpdateSelect( newIcon );

	/// 일반 쉬트 아니면 보이지 않게 하기
	cUIWindow* sheet = GetCurrentSheet();
	if( sheet && sheet->GetID() != eUIID_INVEN_SHEET1 )
		mShowSelect = false;
}

/// 눌린아이콘을 선택된 아이콘으로 저장.
void cInventoryWindow::UpdateSelect( cItemIcon* icon )
{
	if( icon ==0 )
	{
		assert(0);
		return;
	}

	unsigned int itemIdex = icon->GetItemIndex();
	if( mpSelectImage && itemIdex > 0 )
	{
		/// 새 선택 아이콘 눌림효과
		cUIRect rc = icon->GetAbsoluteRect();
		mpSelectImage->SetPos( rc.mLeft-2, rc.mTop-2 );
		mSelectIcon = icon;
		mShowSelect = true;

		ITEMMAN->SetInvenSelect( this );
	}
	else
		mShowSelect = false;
}

void cInventoryWindow::UpdateMaxWeight()
{
	if( mWeightGauge )
	{
        mWeightGauge->SetMaxValue( (float)HERO->GetMaxWeight() );
	}
	else
	{
		assert(0);
	}
}

void cInventoryWindow::SetMoney( unsigned long money )
{
	if( mpMoney )
	{
		mpMoney->SetValue( money );
	}
	else
	{
		assert(0);
	}
}

unsigned long cInventoryWindow::GetMoney()
{
	if( mpMoney )
	{
		return mpMoney->GetValue();
	}
	else
	{
		assert(0);
		return 0;
	}
}
