/*
	TEST.C Copyright 1993, 1999 Microcal Software, Inc.
	Revised 23 September 1994 for Origin v3.5
	Revised 18 March 1999 for Origin v6.0
*/

#include <windows.h>

#include "Test.h"

/*
	Function prototypes for LABUTIL_next_token and etc.
	these functions are from the LABUTIL.DLL
	that comes with Origin. You don't need to
	include this if you do not need to use
	these functions, in which case, you will not
	need to link the library.
*/
#include "..\..\include\labstr.h"

/*
	DLL related messages like WM_DLL_OPEN_DATA
*/
#include "..\..\include\orgdll.h"


/*
	The following are entry and exit codes related to Windows.
	Libentry.obj that comes with the Microsoft SDK is assumed.
	We do not need to do anything special in these area.
*/
#ifdef _WIN32

	BOOL WINAPI DllMain (HANDLE hModule, DWORD fdwReason, LPVOID lpReserved)
	{
		 
		/* 
			Return value only used for DLL_PROCESS_ATTACH;
			all other conditions are ignored.
		*/
		return TRUE; /* successful DLL_PROCESS_ATTACH */
	}

#else  /* !_WIN32 */

	int FAR PASCAL LibMain(HANDLE hModule, WORD wDataSeg, WORD cbHeapSize, LPSTR lpszCmdLine)
	{
		return 1; /* Nothing is done, but it is necessary */
	}

#endif /* !_WIN32 */


/* Your DLL code start here */

/*
	Function names have to be upper case so that origin can
	recognize the functions.
*/
int FAR PASCAL TEST1(HWND hWnd, LPSTR lpString);
int FAR PASCAL TEST2(HWND hWnd, LPSTR lpString);


/***************************************************************************
The function Test1 expects it's lpString to contain three arguments when
called from LabTalk.

<source_dataset> <add_value> <destination_dataset>

The data in <source_dataset> will be incremented by the value in <add_value>
and the results will put put into <destination_dataset>.

The LabTalk command "DLL test test1 data1_a 5 data1_b" will add 5 to
Data1_A and put the results into Data1_B.
***************************************************************************/
/*5/20/99 IV: For this function to work the columns have to be set to Numeric */
int FAR PASCAL TEST1(HWND hWnd, LPSTR lpString)
{
	double		FAR *lpSource;
	double		FAR *lpDestination;
	DWORD		dw;
	short		i, i1, i2;
	double		add_amount;

	/* MAXLINE and NAMESIZE are defined in orgdll.h */
	char		temp[MAXLINE];
	char		source_name[NAME_SIZE];
	

	/*
		lpString should contain three arguments.
		We will use the LABUTIL_next_token to get inidividual arguemnts.
		This function is declared in labstr.h and defined in Origin's
		OUtl DLL.  Other useful funtions exist or you may of course
		use your own.
	*/
	lpString = LABUTIL_next_token(source_name, lpString);
	/*
		The first argument should be the source dataset name and is copied
		into source_name.  lpString will now point to the second argument.
	*/

	
	/*
		WM_DLL_OPEN_DATA will find "data1_a" and lock the data
		handle and return the far pointer to the data.
		Origin's worksheet by default holds double numerics
	*/
	dw = SendMessage(hWnd, WM_DLL_OPEN_DATA, 0, (LONG)(LPSTR)source_name);
	if( 0L == dw )
		return 1;

	/* lpSource is now a pointer to the beginning of the given data. */
	lpSource =  (double FAR *)dw;

	///IV 5/21/99 t6096 CHECK_FOR_COLUMN_TYPE_NOT_NUMERIC
	if(LOWORD(SendMessage(hWnd,WM_DLL_GET_SIZE,0,0L)) != sizeof(double))
		return(1);
	///end CHECK_FOR_COLUMN_TYPE_NOT_NUMERIC

	/* next we need to find out the range, which maybe reflect
	 * the DataSelector markers, or the selected worksheet
	 * range in Origin
	 */
	dw = SendMessage(hWnd, WM_DLL_GET_RANGE, 0, 0L);
	/* you must call this immediately after OPEN_DATA
	 * since OPEN_DATA finds the range and store it
	 * in a static location in Origin, which may change
	 * by the next OPEN_DATA
	 */

	i1=LOWORD(dw);
	i2=HIWORD(dw);

	/* now we are ready to read the next token which should be
	 * the number 5
	 */
	lpString = LABUTIL_next_token(temp, lpString);

	///ANU 8/14/95.  Borland compiler can only make large memory model applications for the 
	// for the windows platform.  As a result we have to use functions compatible with 
	// the memory model. Use cvtstr2real instead of str2real. No double returns.
	//add_amount = LABUTIL_str2real(temp);
	LABUTIL_cvtstr2real((LPSTR)temp, &add_amount);
		/* lpString now points to "data1_b".
		 * before we open the data, we want to set the
		 * active range of the destination data to be the
		 * same as the source, incase they are not.
		 * To do that, we send a message to Origin with a
		 * LabTalk command string.
		 */

	wsprintf(temp, "set %s -end %d", lpString, i2);
		/* eg. "set data1_b -end 7"
		 * we may need to set the beginning but
		 * assume it is ok for now
		 */

	SendMessage(hWnd, WM_USER, 0, (LONG)(LPSTR)temp);
		/* Origin will process the lParam as a
		 * command string if WM_USER message is
		 * sent
		 */

	dw =SendMessage(hWnd, WM_DLL_OPEN_DATA, 0, (LONG)lpString);
	if( 0L == dw )
		return 1;
	/* in general, any modification to the property of a data set
	 * must be made before the data is open
	 */

	lpDestination = (double FAR *)dw;

	/* for this demo, we just add add_amount to every point */
	for( i = i1; i < i2; i++ )
		lpDestination[i] = lpSource[i] + add_amount;

	/* now we are all done, we can
	 * close the data, which unlock the
	 * the handle for the data set
	 */
	SendMessage(hWnd, WM_DLL_CLOSE_DATA, 0, (LONG)(LPSTR)source_name);
	SendMessage(hWnd, WM_DLL_CLOSE_DATA, 1, (LONG)lpString);
	/* lpString still points to "data1_b" 
	 * the wparam has the value of 1 to tell Origin
	 * that the data has been changed.
	 * otherwise, you should pass a 0 if the data
	 * are merely used, like in source_name.
	 */

	return 0; /* 1 for error, 0 for success */
}


/* In this example, we will use the worksheet related
 * messages to Origin and also send a LabTalk command
 * back to Origin. Again, lets consider the Data1 worksheet.
 * We want to expend the size of the worksheet to a size
 * specified in the argument string and fill
 * column 1 with 1,2,3.. and column 2 with 10,20,30,...
 */
/*5/20/99 IV: For this function to work the columns have to be set to Numeric */
 int FAR PASCAL TEST2(hWnd,lpString)
	HWND		hWnd;
	LPSTR		lpString;
	/* argument: worksheetName size */
{
	double FAR 	*lpColumn1;
	double FAR	*lpColumn2;
	char 		szNameWorkSheet[NAME_SIZE];
	char		szTemp[MAXLINE];
	WORD		wSizeWorkSheet;
	DWORD  		dwTemp;
	WORD		i;
	
	/* a worksheet in Origin is created from a template
	 * so we assume our worksheet contain doubles.
	 */
	lpString = LABUTIL_next_token(szNameWorkSheet,lpString);
	
	lpString = LABUTIL_next_token(szTemp,lpString);

	wSizeWorkSheet = LABUTIL_str2int(szTemp);
	/* now we have the name of the worksheet and the size
	 * to increase the worksheet into. We will send a command
	 * to set the worksheet size.
	 */
	wsprintf(szTemp,"set %s -e %d",(LPSTR)szNameWorkSheet,wSizeWorkSheet);
	
	if(SendMessage(hWnd,WM_USER,0,(LPSTR)szTemp))
		return(1L);
		/* Please note that WM_USER will always return 0L before
		 * to Origin version 1.11.
		 */
	
	/* Now the worksheet has the correct size, we can start
	 * putting data into it
	 */

	if(SendMessage(hWnd,WM_DLL_OPEN_WKSHEET,0,(LPSTR)szNameWorkSheet))
		return(1L);
	
	/* Now the worksheet opens sucessfully, we can open the columns
	 * This is similar to the OPEN_DATA message, except you don't
	 * need to know the column/dataset names
	 */
	
	if((dwTemp=SendMessage(hWnd,WM_DLL_WKS_OPEN_COL,1,0L))==0L)
		return(1L);
		
		/* open columu 1 and get a DWORD, which is the pointer */
	lpColumn1 = (double FAR *)dwTemp;
	
		/* you may want to do a 	
		 * dwTemp = SendMessage(hWnd,WM_DLL_GET_RANGE,0,0L);
		 * to convince yourself that LOWORD(dwTemp) == 0 
		 * and HIWORD(dwTemp) == wSizeWorkSheet
		 */


		/* But we do need to check that the columns are double
		 * since they can be anything
		 */
	if(LOWORD(SendMessage(hWnd,WM_DLL_GET_SIZE,0,0L)) != sizeof(double))
		return(1);
		/* might want to close the worksheet before returning
		 * but Origin does the house keeping on every screen
		 * refresh. So ...
		 */

	if((dwTemp=SendMessage(hWnd,WM_DLL_WKS_OPEN_COL,2,0L))==0L)
		return(1L);
		/* We assume everything is fine for the second column
		 *
		 * open columu 2 and get a DWORD, which is the pointer 
		 */
	lpColumn2 = (double FAR *)dwTemp;

		/* Now we are ready to put values into these columns
		 */
	for(i = 0; i < wSizeWorkSheet; i++)
	{
		lpColumn1[i] = i;
		lpColumn2[i] = lpColumn1[i] * 10;
	}
		/* Now we are done and we need to close the datasets
		 * or we can simply close the worksheet and Origin
		 * will close all columns.
		 */
	SendMessage(hWnd,WM_DLL_CLOSE_WKSHEET,1,0L);
		/* the parameter 1 tells Origin that the
		 * worksheet has changed.
		 */
	
	return(0);/* no error */
}
