#include "cbase.h"
// identifier was truncated to '255' characters in the debug information
#pragma warning(disable: 4786)

#include "hl2wars/fow/tex_fogofwar.h"
#include "hl2wars/hl2wars_convars.h"
#include "materialsystem/IMaterialVar.h"
#include "bitmap/TGALoader.h"
#include "view.h"
#include "datacache/idatacache.h"
#include "materialsystem/IMaterial.h"
#include "vtf/vtf.h"

#include "hl2wars/c_rts_globalresource.h"
#include "PixelWriter.h"

// memdbgon must be the last include file in a .cpp file!!!
#include "tier0/memdbgon.h"

// convars
ConVar	cl_fowcolor_red( "cl_fowcolor_red", "50", FCVAR_CLIENTDLL|FCVAR_ARCHIVE );
ConVar	cl_fowcolor_green( "cl_fowcolor_green", "50", FCVAR_CLIENTDLL|FCVAR_ARCHIVE );
ConVar	cl_fowcolor_blue( "cl_fowcolor_blue", "50", FCVAR_CLIENTDLL|FCVAR_ARCHIVE );
ConVar	cl_fowcolor_alpha( "cl_fowcolor_alpha", "90", FCVAR_CLIENTDLL|FCVAR_ARCHIVE );

//-----------------------------------------------------------------------------
// Regenerate the texture
//-----------------------------------------------------------------------------
void CFOWTextureRegen::RegenerateTextureBits( ITexture *pTexture, IVTFTexture *pVTFTexture, Rect_t *pSubRect )
{
	if( !g_RTSR || !sv_fogofwar.GetBool() )
		return;

	// HACK: Other forces are calling this thing too it seems, and only the global resource should update this.
	// FIXME: Find a different way to retrieve the array with pixel data
	//g_RTSR->pVTFTexture = pVTFTexture;
	//return;

	
	//CPixelWriter pixelWriter;
	//pixelWriter.SetPixelMemory( pVTFTexture->Format(), 
		//pVTFTexture->ImageData( 0, 0, 0 ), pVTFTexture->RowSizeInBytes( 0 ) );
	unsigned char *imageData = pVTFTexture->ImageData( 0, 0, 0 );
	int width = pVTFTexture->Width();
	int height = pVTFTexture->Height();
	

	int x, y;//, xmax, ymax;
	//xmax = pSubRect->x + pSubRect->width;
	//ymax = pSubRect->y + pSubRect->height;

	//for( x = 0; x < width; x++ )
	for( x = 0; x < width; x++ )
	{
		//for( y = 0; y < height; y++ )
		for( y = 0; y < height; y++ )
		{	
			int offset = 4 * ( x + y * width );
			//pixelWriter.Seek( x, y );
			if( g_RTSR->m_pFogOfWar[x][y] )
			{
				imageData[offset + 3] = 0;
				imageData[offset + 0] = 0;
				imageData[offset + 1] = 0;
				imageData[offset + 2] = 0;
				//pixelWriter.WritePixel( 0, 0, 0, 0 );
			}
			else
			{
				imageData[offset + 3] = cl_fowcolor_alpha.GetInt();
				imageData[offset + 0] = cl_fowcolor_red.GetInt();
				imageData[offset + 1] = cl_fowcolor_green.GetInt();
				imageData[offset + 2] = cl_fowcolor_blue.GetInt();
				//pixelWriter.WritePixel( cl_fowcolor_red.GetFloat(), cl_fowcolor_green.GetFloat(),
					//cl_fowcolor_blue.GetFloat(),  cl_fowcolor_alpha.GetFloat() );
			}
		}
	}
}


#pragma warning (disable:4355)

CFOWMaterialProxy::CFOWMaterialProxy()// : m_TextureRegen(this)
{
	m_pMaterial = NULL;
	m_pFOWTextureVar = NULL;
	m_pTexture = NULL;
	m_pTextureRegen = NULL;

}

#pragma warning (default:4355)

CFOWMaterialProxy::~CFOWMaterialProxy()
{
	// Disconnect the texture regenerator...
	if (m_pFOWTextureVar)
	{
		ITexture *pFOWTexture = m_pFOWTextureVar->GetTextureValue();
		if (pFOWTexture)
			pFOWTexture->SetTextureRegenerator( NULL );
	}
}

bool CFOWMaterialProxy::Init( IMaterial *pMaterial, KeyValues *pKeyValues )
{
	bool found;
	m_pFOWTextureVar = pMaterial->FindVar("$basetexture", &found, false);  // Get a reference to our base texture variable
	if( !found )
	{
		m_pFOWTextureVar = NULL;
		return false;
	}

	m_pTexture = m_pFOWTextureVar->GetTextureValue();  // Now grab a ref to the actual texture
	if (m_pTexture != NULL)
	{
		m_pTextureRegen = new CFOWTextureRegen( this );  // Here we create our regenerator
		m_pTexture->SetTextureRegenerator(m_pTextureRegen); // And here we attach it to the texture.
	}

	return true;
}

//-----------------------------------------------------------------------------
// Called when the texture is bound...
//-----------------------------------------------------------------------------
void CFOWMaterialProxy::OnBind( C_BaseEntity *pEntity )
{
	if( !m_pTexture )  // Make sure we have a texture
		return;

	if(!m_pFOWTextureVar->IsTexture())  // Make sure it is a texture
		return;

	m_pTexture->Download(); // Force the regenerator to redraw

}

IMaterial *CFOWMaterialProxy::GetMaterial()
{
	if ( !m_pFOWTextureVar )
		return NULL;

	return m_pFOWTextureVar->GetOwningMaterial();
}

EXPOSE_INTERFACE( CFOWMaterialProxy, IMaterialProxy, "fow" IMATERIAL_PROXY_INTERFACE_VERSION );

//------------------------------------------------------------------------------
void CC_FOW_ChangeColor( const CCommand &args )
{
	if ( args.ArgC() < 4 )
	{
		
		Msg("Usage:\n   fow_changecolor <red> <green> <blue> <alpha>\n Current values: %d %d %d %d\n",
			cl_fowcolor_red.GetInt(), cl_fowcolor_green.GetInt(), cl_fowcolor_blue.GetInt(), cl_fowcolor_alpha.GetInt() );
		return;
	}

	cl_fowcolor_red.SetValue( args[1] );
	cl_fowcolor_green.SetValue( args[2] );
	cl_fowcolor_blue.SetValue( args[3] );

	if( args.ArgC() > 4 )
		cl_fowcolor_alpha.SetValue( args[4] );
}
static ConCommand fow_changecolor("fow_changecolor", CC_FOW_ChangeColor, "Change fog of war color");

