// testcpp.cpp : Defines the entry point for the DLL application.
//

//this usually goes in stdafx.h
#define WIN32_LEAN_AND_MEAN		// Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>


//This simple pinHEAD plugin increments a variable 
//named "counter" with the value on pin0 "IPin1"
//IPin2 is not used and is shown purely to illustrate the dll
//It draws onto the Module canvas in the pulse function

//in Visual Studio create a Win32 Project 
//and select DLL in the project options.
//create a Module.def file that looks like this:
/*
LIBRARY   testcpp
EXPORTS
   DllMain   @1
   TestProbe @2
   GetName	 @3
   GetInputPinCount @4
   GetInputPinName @5
   GetOutputPinCount @6
   GetOutputPinName @7
   InputPinData @8
   Pulse	@9
   GetOutputPinData @10
*/ 

//and select it in the Linker->Input section of the project properties.

//build, and copy the dll to the pinHead/plugins folder
//or specify your output file to that location, in the Linker->General properties.


//our code
#include <stdio.h>

//These variables are shared between all instances, so you can transfer data
//if you want unique values per instance you can create a new class
char Name[] = "TestCPP";
char ip1[] = "IPin1";
char ip2[] = "IPin2";

double Pin1Data = 0;
double counter = 0;
bool bNewData = false;
HWND MyWnd = NULL;

__declspec(dllexport) BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
					 )
{
	printf( "dllMain %i\n", ul_reason_for_call );
	switch (ul_reason_for_call)
	{
	case DLL_PROCESS_ATTACH:
	case DLL_THREAD_ATTACH:
	case DLL_THREAD_DETACH:
	case DLL_PROCESS_DETACH:
		break;
	}
    return TRUE;	
}

//The host calls this to test the plugin during installation 
extern "C" __declspec(dllexport) int TestProbe( )
{
	
	counter = 0;
	printf( "Test\n" );
	return 1;
}

//return our name
extern "C" __declspec(dllexport) const char* GetName( )
{
	printf( "getname\n" );	
	return Name;
}

//return the number of input pins we want
extern "C" __declspec(dllexport) int GetInputPinCount( )
{
	return 2;
}

//return the name we want for the input pin #i
extern "C" __declspec(dllexport) const char* GetInputPinName( int i )
{
	if ( i==0 ) return ip1 ;
	if ( i==1 ) return ip2;
	return NULL;
}



//return the number of output pins we want
extern "C" __declspec(dllexport) int GetOutputPinCount( )
{
	return 1;
}

//the host wants our output pin name for pin #i
extern "C" __declspec(dllexport) const char* GetOutputPinName( int i )
{
	if ( i==0 ) return "OPin2" ;	
	return NULL;
//	return NULL;
}

//data was sent to one of our pins
extern "C" __declspec(dllexport) void InputPinData( int Pin, double Data )
{
	if ( Pin == 0 )
		Pin1Data = Data;
	bNewData = true; //the next time Pulse is called we tell the host we have new data

}

//this gets called roughly every 40ms
//if we have new data for the host then return true, otherwise return false
extern "C" __declspec(dllexport) bool Pulse( )
{
	if ( bNewData == true ) //we only want to update our value when something happened on an input pin
		counter += Pin1Data;
	if ( counter> 99 ) counter = 0;

	//draw something on our output window
	if ( MyWnd != NULL )
	{
		HDC hdc = GetDC( MyWnd );
	
		HPEN old = NULL;
		HPEN pen = CreatePen( PS_SOLID, 2, RGB( 0,0,0 ) );
		old = (HPEN)SelectObject( hdc, pen );
		MoveToEx( hdc, 0, 80, NULL );
		LineTo( hdc, 100, 80 );		
		SelectObject( hdc, old );
		DeleteObject( pen );
		
		HPEN pen2 = CreatePen( PS_SOLID, 2, RGB( 255,0,0 ) );
		old = (HPEN)SelectObject( hdc, pen2 );

		MoveToEx( hdc, 0, 80, NULL );
		LineTo( hdc, (int)counter, 80 );		
		SelectObject( hdc, old );
		DeleteObject( pen2 );
		ReleaseDC( MyWnd, hdc );
	}
	return bNewData;	
}

//the host wants any output pin data we have
//will only be called if Pulse returned true
extern "C" __declspec(dllexport) double GetOutputPinData( int Pin )
{
	bNewData = false; //we can clear this flag because the host now has the data
	return counter;
}

//The host gives us a window to draw in
extern "C" __declspec(dllexport) void SetWindow( HWND hwnd )
{
	MyWnd = hwnd;
}
