namespace HLWanted_Telegram
{

class item_telegram : ScriptBasePlayerItemEntity
{
	private string strNoteImage;
	private float flReadTime = 20.0f;
	private HUDSpriteParams hspNote, hspNull;
	private EHandle hReader;
	private CScheduledFunction@ m_pStopReadSched = null;

	bool KeyValue( const string& in szKey, const string& in szValue )
	{
        if( szKey == "useimage" ) 
            strNoteImage = szValue;
        else if( szKey == "readdelay" ) 
            flReadTime = atof( szValue );
        else
		    return BaseClass.KeyValue( szKey, szValue );

		return true;
	}

	void Precache()
	{
		BaseClass.Precache();

		if( ( "" + string( self.pev.model ) ).Length() > 0 ) // hack to get rid of the warns and/or crashes -R4to0
			g_Game.PrecacheModel( self.pev.model );

		if( strNoteImage.Length() > 0 ) // hack to get rid of the warns and/or crashes -R4to0
		{
			g_Game.PrecacheModel( "sprites/" + strNoteImage ); // not really needed for HUD sprites, they're late precached -R4to0
			g_Game.PrecacheGeneric( "sprites/" + strNoteImage ); // will make users download twice if precached by PrecacheModel function due to engine weirdness :shrug: -R4to0
		}

/*		int iMdlIndex = g_ModelFuncs.ModelIndex( self.pev.model );
		int iSprIndex = g_ModelFuncs.ModelIndex( strNoteImage );

		g_EngineFuncs.ServerPrint( "Mdl Index: " + iMdlIndex + " | Spr Index: " + iSprIndex + "\n" ); */
		
		g_SoundSystem.PrecacheSound( "extended/papers.wav" ); // Precaches for playing, won't make users download unless used with precache_generic or added to a res file
	}

	void Spawn()
	{
		//g_EngineFuncs.ServerPrint( "ENTITY item_telegram SPAWNED!\n" );

		Precache();

		g_EntityFuncs.SetModel( self, self.pev.model );
		
		hspNote.spritename	= "" + strNoteImage;
		hspNote.x			= 0.0f;
		hspNote.y			= 0.40f;
		hspNote.frame		= 0;
		hspNote.numframes	= 1;
		hspNote.framerate	= 1;
		hspNote.fadeinTime	= 0.0f;
		hspNote.fadeoutTime	= 0;
		hspNote.color1		= RGBA_WHITE;
		hspNote.channel 	= hspNull.channel = 4;
		hspNote.flags		= HUD_ELEM_SCR_CENTER_X | HUD_SPR_MASKED;

		SetTouch( TouchFunction( this.Read ) );

		BaseClass.Spawn();
	}

	void Use( CBaseEntity@ pActivator, CBaseEntity@ pCaller, USE_TYPE useType, float value )
	{
		if( self.pev.SpawnFlagBitSet( 256 ) )
			return;
	
		Read( pActivator );
	}

	void Read( CBaseEntity@ pOther )
	{
		if( pOther is null || !pOther.IsPlayer() || !pOther.IsAlive() )
			return;

		CBasePlayer@ pPlayer = cast<CBasePlayer@>( pOther );

        if( pPlayer is null || hReader )
            return;
        
		SetTouch( null );
		self.pev.effects |= EF_NODRAW;

		g_SoundSystem.EmitSound( self.edict(), CHAN_ITEM, "extended/papers.wav", 1.0f, 1.0f );
		g_PlayerFuncs.HudCustomSprite( pPlayer, hspNote );
		pPlayer.SetMaxSpeedOverride( 0 );
		pPlayer.pev.velocity = g_vecZero;
		g_PlayerFuncs.ScreenFade( pPlayer, Vector( 0, 0, 0 ), 0.0f, 0.0f, 165, FFADE_STAYOUT );

		g_EntityFuncs.FireTargets( "" + self.pev.target, pPlayer, self, USE_TOGGLE, 0.0f, self.m_flDelay );

		hReader = pPlayer;

		@m_pStopReadSched = g_Scheduler.SetTimeout( this, "StopReading", flReadTime );
		self.pev.nextthink = g_Engine.time + 0.01f;
	}

	void StopReading()
	{
		if( !hReader )
			return;
		
		CBasePlayer@ pPlayer = cast<CBasePlayer@>( hReader.GetEntity() );
		
		if( pPlayer is null )
			return;

		pPlayer.SetMaxSpeedOverride( -1 );
		g_PlayerFuncs.HudCustomSprite( pPlayer, hspNull );
		g_PlayerFuncs.ScreenFade( pPlayer, Vector( 0, 0, 0 ), 0.0f, 0.0f, 0, FFADE_IN );

		hReader = null;

		if( m_pStopReadSched !is null )
			g_Scheduler.RemoveTimer( m_pStopReadSched ); // Remove scheduler because it still running even when the entity is killed - R4to0
		
		@m_pStopReadSched = null;

		g_EntityFuncs.Remove( self );
	}

	void Think()
	{
		if( !hReader )
			return;

		if( !hReader.GetEntity().IsAlive() || 
			!cast<CBasePlayer@>( hReader.GetEntity() ).IsConnected() || 
			FlagSet( hReader.GetEntity().pev.button, IN_DUCK | IN_JUMP | IN_USE | IN_ATTACK | IN_ATTACK2 | IN_ALT1 ) )
		{
			StopReading();
		}

		self.pev.nextthink = g_Engine.time + 0.01f;
	}

	bool FlagSet(uint iTargetBits, uint iFlags)
    {
        return( ( iTargetBits & iFlags ) != 0 );
    }
}

string GetTelegramName()
{
	return "item_telegram";
}

void Register()
{
	g_CustomEntityFuncs.RegisterCustomEntity( "HLWanted_Telegram::item_telegram", GetTelegramName() );
	g_ItemRegistry.RegisterItem( GetTelegramName(), "" );
}

} //namespace HLWanted_Telegram END
