#include "Help.as";

#define CLIENT_ONLY

ConfigFile done;
bool loaded = false;

const f32 HELP_DISTANCE = 20.0f;

void onInit( CSprite@ this )
{
	this.getCurrentScript().runFlags |= Script::tick_myplayer;
	this.getCurrentScript().removeIfTag = "dead";
}

void Done( const string &in name, const string &in prefix )
{
	const string name2 = prefix + " " + name;
	if (done.exists(name2)) 
	{
		int amount = 1 + done.read_u32( name2 );
		done.add_u32( name2, amount );
	}
	else
		done.add_u32( name2, 1 );
}

void onTick( CSprite@ this )
{
	CBlob@ blob = this.getBlob();
	{	
		if (!loaded)
		{
			if (!done.loadFile("../Cache/HelpDone.cfg"))
				done.saveFile("../Cache/HelpDone.cfg");		
			else
				loaded = true;
		}

		// near 

		CBlob@[] blobsInRadius;
		CMap@ map = blob.getMap();
		if (map !is null && map.getBlobsInRadius( blob.getPosition(), blob.getRadius() + HELP_DISTANCE, @blobsInRadius )) 
		{
			for (uint i = 0; i < blobsInRadius.length; i++)
			{
				CBlob @b = blobsInRadius[i]; 
				if (b !is blob) 
				{	 
					if (blob.isKeyJustPressed( key_use ) && isRecipientOfHelp( blob, b, "help use" )) {
						Done( "done use", b.getName() );
					}

					if (blob.isKeyPressed( key_action1 ) && isRecipientOfHelp( blob, b, "help action" )) {
						Done( "done action", b.getName() );
					}

					if (blob.isKeyPressed( key_action2 ) && isRecipientOfHelp( blob, b, "help action2" )) {
						Done( "done action2", b.getName() );
					}

					if (blob.isKeyJustPressed( key_down ) && isRecipientOfHelp( blob, b, "help hop" )) {
						Done( "done hop", b.getName() );
					}

				}
			}
		}

		// carried

		CBlob@ carried = blob.getCarriedBlob();
		if (carried !is null)
		{	 
			if (isRecipientOfHelp( blob, carried, "help pickup" )) {
			   Done( "done pickup", carried.getName() );
			}

			if (blob.isKeyJustPressed( key_action3 ) && isRecipientOfHelp( blob, carried, "help activate" )) {
				  Done( "done activate", carried.getName() );
			}

			if (blob.isKeyJustPressed( key_action3 ) && isRecipientOfHelp( blob, carried, "help rotate" )) {
				Done( "done rotate", carried.getName() );
			}

			if (blob.isKeyJustPressed( key_action3 ) && isRecipientOfHelp( blob, carried, "help throw" ) && carried.hasTag("activated")) {
				 Done( "done throw", carried.getName() );
				printf(" carried.getName()  " +  carried.getName()  );
				// hack:
				if (carried.getName() == "bomb") {
					Done( "done activate", "mat_bombs" );
				}			
			}

		}

		// inventory

		CInventory@ inv = blob.getInventory();
		for (int i = 0; i < inv.getItemsCount(); i++)
		{
			CBlob @b = inv.getItem(i);	
			
			if (blob.isKeyJustPressed( key_inventory ) && isRecipientOfHelp( blob, b, "help switch" )) {
				Done( "done switch", b.getName() );
			}

			//if (blob.isKeyJustPressed( key_action3 ) && isRecipientOfHelp( blob, b, "help activate" )) {	// wont work
			//	Done( "done activate", b.getName() );
			//}
		}

		// general - self

		if (blob.isKeyJustPressed( key_action2 ) && isRecipientOfHelp( blob, blob, "help self action2" )) {
			Done( "done self action2", blob.getName() );
		}

		if (blob.isKeyJustPressed( key_action1 ) && isRecipientOfHelp( blob, blob, "help self action" )) {
			Done( "done self action", blob.getName() );
		}

		if (blob.isKeyJustPressed( key_up ) && isRecipientOfHelp( blob, blob, "help jump" )) {
			Done( "done jump", blob.getName() ); 
		}

		if (blob.isKeyJustPressed( key_left ) && isRecipientOfHelp( blob, blob, "help left" )) {
			Done( "done left", blob.getName() ); 
		}

		if (blob.isKeyJustPressed( key_right ) && isRecipientOfHelp( blob, blob, "help right" )) {
			Done( "done right", blob.getName() ); 
		}

		//

		if (getGameTime() % 300 == 0)
		{
			done.saveFile("../Cache/HelpDone.cfg");		
		}
	}
}

bool wasAlreadyInList( CBlob@[] blobs, uint index, CBlob@ blob )
{
	const string name = blob.getName();
	for (uint i = 0; i < index; i++)
	{
		CBlob @b = blobs[i]; 
		if (b.getName() == name)
			return true;
	}
	return false;
}

void onRender( CSprite@ this )
{			
	CBlob@ blob = this.getBlob();
	if (u_showtutorial)
	{
		// general - self

		if (shouldDraw( blob, blob, "help left", blob.getName() + " done left" ) ) {
			if (DrawHelp( blob, blob, "help left" ))
				return;
		}

		if (shouldDraw( blob, blob, "help right", blob.getName() + " done right" ) ) {
			if (DrawHelp( blob, blob, "help right" ))
				return;
		}

		if (shouldDraw( blob, blob, "help jump", blob.getName() + " done jump" ) ) {
			if (DrawHelp( blob, blob, "help jump" ))
				return;
		}

		if (shouldDraw( blob, blob, "help self action", blob.getName() + " done self action" ) ) {
			if (DrawHelp( blob, blob, "help self action" ))
				return;
		}

		if (shouldDraw( blob, blob, "help self action2", blob.getName() + " done self action2" ) ) {
			if (DrawHelp( blob, blob, "help self action2" ))
				return;
		}


		// near

		CBlob@[] blobsInRadius;	 
		CMap@ map = blob.getMap();
		if (map !is null && map.getBlobsInRadius( blob.getPosition(), blob.getRadius() + HELP_DISTANCE, @blobsInRadius )) 
		{
			for (uint i = 0; i < blobsInRadius.length; i++)
			{
				CBlob @b = blobsInRadius[i]; 
				if (b !is blob && !b.isAttached() && !wasAlreadyInList(blobsInRadius, i, b) ) 
				{
					if (shouldDraw( blob, b, "help pickup", b.getName() + " done pickup" ) ) {
						DrawHelp( blob, b, "help pickup" );
					}

					if (shouldDraw( blob, b, "help use", b.getName() + " done use" ) ) {
						DrawHelp( blob, b, "help use" );
					}

					if (shouldDraw( blob, b, "help action",  b.getName() + " done action" ) ) {
						DrawHelp( blob, b, "help action" );
					}

					if (shouldDraw( blob, b, "help action2",  b.getName() + " done action2" ) ) {
						DrawHelp( blob, b, "help action2" );
					}

					if (shouldDraw( blob, b, "help hop", b.getName() + " done hop" ) ) {
						DrawHelp( blob, b, "help hop" );
					}
				}
			}
		}

		//carry 

		CBlob@ carried = blob.getCarriedBlob();
		if (carried !is null)
		{
			if (shouldDraw( blob, carried, "help activate", carried.getName() + " done activate" ) ) {
				DrawHelp( blob, carried, "help activate" );
			}

			if (shouldDraw( blob, carried, "help throw", carried.getName() + " done throw" ) && carried.hasTag("activated")) {
				DrawHelp( blob, carried, "help throw" );
			}

			if (shouldDraw( blob, carried, "help rotate", carried.getName() + " done rotate" ) ) {
				DrawHelp( blob, carried, "help rotate" );
			}
		}

		// inventory

		CInventory@ inv = blob.getInventory();
		for (int i = 0; i < inv.getItemsCount(); i++)
		{
			CBlob @b = inv.getItem(i);	
			if (shouldDraw( blob, b, "help activate", b.getName() + " done activate" ) ) {
				DrawHelp( blob, b, "help activate" );
			}

			if (shouldDraw( blob, b, "help switch", b.getName() + " done switch" ) ) {
				DrawHelp( blob, b, "help switch" );
			}
		}

		// draw item captions

		{						 
			if (!getHUD().hasButtons() && !getHUD().hasMenus() &&
				!blob.isKeyPressed(key_left) && !blob.isKeyPressed(key_right) &&
				!blob.isKeyPressed(key_up) && !blob.isKeyPressed(key_action1) &&
				!blob.isKeyPressed(key_down) && !blob.isKeyPressed(key_action2) &&
				!blob.isKeyPressed(key_pickup) && !blob.isKeyPressed(key_inventory)
				)
			{
				CBlob@ mouseBlob = getMap().getBlobAtPosition( blob.getAimPos() );
				if (mouseBlob !is null && !mouseBlob.hasTag("player"))
				{
					GUI::DrawText( mouseBlob.getInventoryName(), mouseBlob.getScreenPos() + Vec2f(-mouseBlob.getWidth(), mouseBlob.getHeight() + 16.0f), color_white );
					//	mouseBlob.RenderForHUD( RenderStyle::outline_front );
				}
			}
		}  
			 
	}
}

void DrawHelpText( CBlob@ this, const string &in text, const bool drawBackground = false )
{
	if (text.size() == 0)
		return;
	Vec2f pos = this.getScreenPos();
	f32 h = 150.0f;
	f32 y = Maths::Max( 200, int(pos.y - h) );
	GUI::DrawText( text, Vec2f(pos.x - 50, y - 15.0f), Vec2f(pos.x + 50, y + 15.0f), color_black, false, false, drawBackground );
}

bool DrawHelp( CBlob@ this, CBlob@ blob, const string &in name )
{
	HelpText @ht;
	blob.get( name, @ht );
	if (ht !is null) {
		DrawHelpText( blob, isRecipientOfHelp( this, ht ) ? ht.text : ht.altText, true );
		return true;
	}	 
	return false;
}

bool isRecipientOfHelp( CBlob@ this, HelpText@ ht )
{
	if (ht is null)
		return false;
	const string name = this.getName();
	return (ht.recipient.size() == 0 || ht.recipient == name);
}

bool isRecipientOfHelp( CBlob@ this, CBlob@ b, const string &in name )
{
	HelpText @ht;
	b.get( name, @ht );
	return isRecipientOfHelp( this, ht );
}


bool shouldDraw( CBlob@ this, CBlob@ blob, const string &in helpName, const string &in doneName )
{
	if (blob.exists( helpName ) && done.exists(doneName) )
	{
		HelpText @ht;
		blob.get( helpName, @ht );
		if (ht !is null)
		{
			if ( done.read_u32( doneName ) < ht.reduceAfterTimes) {
				return true;
			}
		}
		return false;
	}
	return true;
}
