#include "StdAfx.h"
#include "uitransformimage.h"
#include "RenderSystem.h"

cUITransformImage::cUITransformImage()
: mpScreenElement( 0 )
, mpTextureProp( 0 )
, mpAlphaProp( 0 )
{
	mTextureWidth = 1;
	mTextureHeight = 1;

	mTexRect.Set( 0, 0, 1, 1);

	mScreenX = 0;
	mScreenY = 0;

	mAngle = 0.0f;
	mCenter = NiPoint2::ZERO;
}

cUITransformImage::~cUITransformImage()
{
	mpTextureProp = 0;
	mpAlphaProp = 0;

	SAFE_NIDELETE(mpScreenElement);
}

/// 주의사항 : 
void cUITransformImage::SetTexture( NiTexture* ptex )
{
	assert( ptex );
	SAFE_NIDELETE(mpScreenElement);

	mTextureWidth = ptex->GetWidth();
	mTextureHeight = ptex->GetHeight();

	/// 관리용 스크린 객체를 생성한다.
	mpScreenElement = NiNew NiScreenElements( NiNew NiScreenElementsData(false, true, 1) );
	if( !mpScreenElement ) 
	{
		assert(0);
		return;
	}

	for( unsigned int i=0; i<4; i++ )
	{
		mVertex[i].x = i/2? 1.0f:-1.0f;
		mVertex[i].y = i%3? 1.0f:-1.0f;
	}

	mAngle = 0.0f;
	mCenter = NiPoint2::ZERO;

	/// 4점을 생성한다.
	mpScreenElement->Insert( 4 );

	/// 컬러 정보를 셋팅한다.
	mpScreenElement->SetColors( 0, NiColorA::WHITE );
	mColor = NiColorA::WHITE;

	/// 관리 Property정보를 생성한다.
	mpTextureProp = NiNew NiTexturingProperty();
	mpTextureProp->SetBaseTexture( ptex );
	mpTextureProp->SetApplyMode( NiTexturingProperty::APPLY_MODULATE );
	mpScreenElement->AttachProperty( mpTextureProp );

	/// use vertex colors
	NiVertexColorProperty* pVertex = NiNew NiVertexColorProperty;
	pVertex->SetSourceMode( NiVertexColorProperty::SOURCE_EMISSIVE );
	pVertex->SetLightingMode( NiVertexColorProperty::LIGHTING_E );
	mpScreenElement->AttachProperty( pVertex );

	NiZBufferProperty* pZ = NiNew NiZBufferProperty;
	pZ->SetZBufferTest( false );
	pZ->SetZBufferWrite( false );
	mpScreenElement->AttachProperty( pZ );

	mpAlphaProp = NiNew NiAlphaProperty();
	mpAlphaProp->SetAlphaBlending( true );
	mpScreenElement->AttachProperty( mpAlphaProp );

	mpScreenElement->UpdateProperties();
	mpScreenElement->Update( 0.0f );
}

void cUITransformImage::SetPos( int x, int y )
{
	/// 위치 정보를 셋팅한다.
	/// 주의 : 스크린상의 상대 좌표를 사용한다.
	mScreenX = (short)x;
	mScreenY = (short)y;

	SetTranslate( mScreenX, mScreenY );
}

void cUITransformImage::SetScreenWH( unsigned short screenW, unsigned short screenH )
{
	/// 위치 정보를 셋팅한다.
	/// 주의 : 스크린상의 상대 좌표를 사용한다.
	mWidthOnScreen = screenW;
	mHeightOnScreen = screenH;

	mScaleX = (float)mWidthOnScreen * 0.5f;
	mScaleY = (float)mHeightOnScreen * 0.5f;

	SetTranslate( mScreenX, mScreenY );
}

void cUITransformImage::SetScreenRect( const cUIRect& rect )
{
	/// 위치 정보를 셋팅한다.
	/// 주의 : 스크린상의 상대 좌표를 사용한다.
	mScreenX = rect.mLeft;
	mScreenY = rect.mTop;
	mWidthOnScreen = rect.GetWidth();
	mHeightOnScreen = rect.GetHeight();

	mScaleX = (float)mWidthOnScreen * 0.5f;
	mScaleY = (float)mHeightOnScreen * 0.5f;

	SetTranslate( mScreenX, mScreenY );

}

void cUITransformImage::SetTextureRect( unsigned int tl, unsigned int tt, unsigned int tr, unsigned int tb )
{
	mTexRect.Set( tl, tt, tr, tb );

	/// 텍스쳐 UV셋팅
//	float localTexL = (float)(tl+0.5f) / (float)mTextureWidth;
	float localTexL = (float)tl / (float)mTextureWidth;
	float localTexT = (float)tt / (float)mTextureHeight;
	float localTexR = (float)tr / (float)mTextureWidth;
	float localTexB = (float)tb / (float)mTextureHeight;

	mpScreenElement->SetTextures( 0, 0, localTexL, localTexT, localTexR, localTexB );
}

void cUITransformImage::SetColor( float r, float g, float b, float a )
{
	SetColor( NiColorA(r, g, b, a) );
}

void cUITransformImage::SetColor( const NiColorA& color )
{
	mpScreenElement->SetColors( 0, color );

	mColor = color;
}

const NiColorA& cUITransformImage::GetColor() const
{
	return mColor;
}

void cUITransformImage::SetAlpha( float a )
{
	SetColor( mColor.r, mColor.g, mColor.b, a );
}

void cUITransformImage::Draw()
{
	NiRenderer* pkRenderer = NiRenderer::GetRenderer();
	mpScreenElement->Draw( pkRenderer );
}

void cUITransformImage::UpdateImage()
{
	SetRotate( mAngle );
}

///
void cUITransformImage::SetTranslate( short x, short y )
{
	float cx = (float)x + mScaleX;
	float cy = (float)y + mScaleY;

	mScreenX = x;
	mScreenY = y;

	/// 중앙을 기준으로 한다.
//	if( mCenter.x != cx || mCenter.y != cy )
	{
		mCenter.x = cx;
		mCenter.y = cy;
		SetRotate( mAngle );
	}
}

void cUITransformImage::SetRotate(float angle )
{
	float width = (float)RENDERSYS->GetScreenWidth();
	float height = (float)RENDERSYS->GetScreenHeight();

	mAngle = angle;

	if( mAngle != 0.f )
	{
		float cos = NiCos( angle );
		float sin = NiSin( angle );

		NiPoint2 p;
		for( unsigned int i = 0; i < 4; ++i )
		{
			p.x = ( mVertex[i].x * cos * mScaleX + mVertex[i].y * sin * mScaleY );
			p.y = ( mVertex[i].y * cos * mScaleY - mVertex[i].x * sin * mScaleX );

			p += mCenter;

			p.x /= width;
			p.y /= height;

			mpScreenElement->SetVertex( 0, i, NiPoint2( p.x, p.y ) );
		}
	}
	else
	{
		NiPoint2 p;

		for( unsigned int i = 0; i < 4; ++i )
		{
			p.x = mVertex[i].x * mScaleX + mCenter.x;
			p.y = mVertex[i].y * mScaleY + mCenter.y;

			p.x /= width;
			p.y /= height;

			mpScreenElement->SetVertex( 0, i, p );
		}
	}
}


/*
/// 주의사항 : 
void cUITransformImage::SetPos( unsigned int x, unsigned int y )
{
	SetTranslate( (float)x, (float)y );
}

/// 주의사항 : 
void cUITransformImage::SetSize( double w, double h )
{
	float fLeft, fTop, fWidth, fHeight;
	if( mpScreenElement->GetRectangle( 0, fLeft, fTop, fWidth, fHeight ) == false )
	{
		assert(0);
		return;
	}

	mpScreenElement->SetRectangle( 0, fLeft, fTop, (float)w, (float)h );
	SetRotate( mAngle );
}

/// 주의사항 : 
void cUITransformImage::SetScreenRect( const cUIRect& rect )
{
	mWidthOnScreen = rect.mRight - rect.mLeft;
	mHeightOnScreen = rect.mBottom - rect.mTop;

	float hw = (float)rect.GetWidth()/(float)RENDERSYS->GetScreenWidth() * 0.5f;
	float hh = (float)rect.GetHeight()/(float)RENDERSYS->GetScreenHeight() * 0.5f;
	mVertex[0].x = -hw;
	mVertex[0].y = -hh;
	mVertex[1].x = -hw;
	mVertex[1].y = +hh;
	mVertex[2].x = +hw;
	mVertex[2].y = +hh;
	mVertex[3].x = +hw;
	mVertex[3].y = -hh;
	SetTranslate( (float)rect.mLeft/(float)RENDERSYS->GetScreenWidth() + hw, (float)rect.mTop/RENDERSYS->GetScreenHeight() + hh );
}

/// 주의사항 : 
void cUITransformImage::SetTextureRect( unsigned int tl, unsigned int tt, unsigned int tr, unsigned int tb )
{
	mTexRect.Set( tl, tt, tr, tb );

	/// 텍스쳐 UV셋팅
	float l = (float)tl / (float)mTextureWidth;
	float t = (float)tt / (float)mTextureHeight;
	float r = (float)tr / (float)mTextureWidth;
	float b = (float)tb / (float)mTextureHeight;

	mpScreenElement->SetTextures( 0, 0, l, t, r, b );
}

/// 주의사항 : 
void cUITransformImage::SetTextureRect( const cUIRect& rect )
{
	mTexRect = rect;

	/// 텍스쳐 UV셋팅
	float l = (float)mTexRect.mLeft / (float)mTextureWidth;
	float t = (float)mTexRect.mTop / (float)mTextureHeight;
	float r = (float)mTexRect.mRight / (float)mTextureWidth;
	float b = (float)mTexRect.mBottom / (float)mTextureHeight;

	mpScreenElement->SetTextures( 0, 0, l, t, r, b );
}

/// 주의사항 : 
void cUITransformImage::SetColor( const NiColorA& color )
{
	mpScreenElement->SetColors( 0, color );
}

const NiColorA& cUITransformImage::GetColor() const
{
	NiColorA* pColors = mpScreenElement->GetColors( 0 );
	if( pColors == 0 )
		return NiColorA::BLACK;
	return pColors[0];
}

/// 주의사항 : 
void cUITransformImage::SetAlpha( float a )
{
	NiColorA color;
	if( mpScreenElement->GetColor(0, 0, color) == false )
	{
		assert(0);
		return;
	}

	color.a = a;
	mpScreenElement->SetColors( 0, color );
}

void cUITransformImage::SetTranslate( float x, float y )
{
	if( mCenter.x != x || mCenter.y != y )
	{
		mCenter.x = x;
		mCenter.y = y;
		SetRotate( mAngle );
	}
}

void cUITransformImage::SetRotate( float angle )
{
	mAngle = angle;

	if( mAngle != 0.f )
	{
		float cos = NiCos( angle );
		float sin = NiSin( angle );
		NiPoint2 p;

		for( unsigned int i = 0; i < 4; ++i )
		{
			p.x = mVertex[i].x * cos + mVertex[i].y * sin;
			p.y = mVertex[i].y * cos - mVertex[i].x * sin;
			p += mCenter;

			mpScreenElement->SetVertex( 0, i, p );
		}
	}
	else
	{
		NiPoint2 p;

		for( unsigned int i = 0; i < 4; ++i )
		{
			p = mVertex[i] + mCenter;

			mpScreenElement->SetVertex( 0, i, p );
		}
	}
}
*/
