/*------------------------------------------------------------------------------*
 * File Name: binfile.c															*
 * Creation: CPY 1/26/2002														*
 * Purpose: Binary File Import/Export Example for Origin C						*
 * All Rights Reserved															*
 * 																				*
 * Modification Log:															*
 *------------------------------------------------------------------------------*/
 
////////////////////////////////////////////////////////////////////////////////////
// you can include just this typical header file for most Origin built-in functions and classes
// and it takes a reasonable amount of time to compile, 
#include <origin.h>
// this file include most of the other header files except the NAG header, which takes longer to compile
// NAG routines
//#include <OC_nag.h> // this contains all the NAG headers, 

// you should put definitions specific to your needs in a separate header file for
// easier maintenance and sharing later on
#include "binfile.h" // our header for this example

////////////////////////////////////////////////////////////////////////////////////


////////////////////////////////////////////////////////////////////////////////////
// start your functions here

//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// in this example, we design a binary file with the a simple structure, namely
// a file header (see struct MyMainHeader) followed by each column of data 
// stored as 2byte(short) integers with the 1st four byte(long) for the number
//  of points in that column
// Data in Origin worksheet are double values, so a calibration factor is used
// to convert these integers (MyMainHeader.factor)
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++


// copy data from given column to a short vector by dividing each point by a factor
// return number of points
UINT ColumnDataToIntVector(Column& cc, vector<short>& vv, float factor)
{
	Dataset aa(cc);
	UINT		nSize = aa.GetSize();
	vv.SetSize(nSize);
	for(int ii = 0; ii < nSize; ii ++)
		vv[ii] = nint(aa[ii]/factor);
	
	return nSize;
}

// copy data from a short vector to a column
// return number of 
BOOL IntVectorToColumnData(Column& cc, vector<short>& vv, float factor)
{
	Dataset aa(cc);
	UINT	nSize = vv.GetSize();
	aa.SetSize(nSize);
	for(int ii = 0; ii < nSize; ii ++)
		aa[ii] = factor * vv[ii];
	
	return TRUE;// worry about error checking later
}

// strFileName must be supplied, strWksName = "" to use the current window
// return TRUE for success, FALSE for error and error messages are printed to script window
BOOL myImport(string strFileName, string strWksName)
{
	Worksheet wks;
	
	if(strWksName.IsEmpty())
		wks = (Worksheet)Application.ActiveLayer();
	else
		wks.Attach(strWksName);
	if(wks==NULL)
	{
		out_str("invalid worksheet");
		return FALSE;
	}
	file	myFile;
	
	if(myFile.Open(strFileName, file::modeRead) == FALSE)
	{
		printf("Cannot open file %f for reading\n", strFileName);
		return FALSE;
	}
	MyMainHeader	myHeader;
	// we will read our file header and do some simple minded test for validity
	if(myFile.Read(&myHeader, sizeof(MyMainHeader)) != sizeof(MyMainHeader) ||
		myHeader.nColumns <=0 || myHeader.nColumns > 100) // assuming that we don't usually play with more than 100 columns in this example
	{
		printf("File %s is empty or not created by the myExport function\n", strFileName);
		return FALSE;
	}
	//------------------------------------------------------
	// we will remove all current columns and create new ones
	while(wks.DeleteCol(0))	 // remove all columns in worksheet
		;
	int ii;
	for(ii = 0; ii < myHeader.nColumns; ii++)
		wks.AddCol();
	//------------------------------------------------------
	vector<short> vTemp;
	UINT		nSize;
	Column		cc;			
	for(ii = 0; ii < myHeader.nColumns; ii++)
	{
		cc = wks.Columns(ii);
		if(myFile.Read(&nSize, sizeof(nSize)) != sizeof(nSize))
			return FALSE;
		vTemp.SetSize(nSize);
		if(myFile.Read(vTemp, sizeof(short)*nSize) != sizeof(short)*nSize)
			return FALSE;
		IntVectorToColumnData(cc, vTemp, myHeader.factor);
	}
	return TRUE;
}


// strFileName must be supplied, strWksName = "" to use the current window
// return TRUE for success, FALSE for error and error messages are printed to script window
BOOL myExport(string strFileName, string strWksName)
{
	Worksheet wks;
	
	if(strWksName.IsEmpty())
		wks = (Worksheet)Application.ActiveLayer();
	else
		wks.Attach(strWksName);
	if(wks==NULL)
	{
		out_str("invalid worksheet");
		return FALSE;
	}
	
	file	myFile;
	
	if(myFile.Open(strFileName,	file::modeCreate | file::modeWrite) == FALSE)
	{
		printf("Cannot create file %f for writing\n", strFileName);
		return FALSE;
	}
	
	MyMainHeader	myHeader;
	lstrcpyn(myHeader.szTitle, wks.GetPage().Label, MY_TEXT_SIZE); 
	myHeader.factor = 3.0 / 2048.0;// example for 11bit to map to 3 volts
	myHeader.nColumns = wks.GetNumCols();
	
	myFile.Write(&myHeader, sizeof(MyMainHeader));
	
	vector<short> vTemp;
	UINT		nSize;
	Column		cc;			
	for(int ii = 0; ii < myHeader.nColumns; ii++)
	{
		cc = wks.Columns(ii);
		nSize = ColumnDataToIntVector(cc, vTemp, myHeader.factor);
		myFile.Write(&nSize, sizeof(UINT));
		myFile.Write(vTemp, sizeof(short)*nSize);
	}
	return TRUE;
}

 
