/***************************************************************************
 *   Copyright (C) 2007 by Michael Schlagmueller   *
 *   snubnose@amd4200   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/

/*
 * sunnylog.c
 *
 * To compile sample use:
 *
 *    g++ sunnylog.cpp -I../../include/ -I../../smalib -I../../libs -o sunnylog -lyasdimaster
 */
#undef DEBUG
#include "libyasdimaster.h"
#undef DEBUG
#include <stdio.h>
#include <time.h>
#include <cstring>
#include <unistd.h>
#include <iostream>
#include <iomanip>
#include <string>
using namespace std;
#undef DEBUG

string trim ( string s )
{
	static const char ws[] = " \f\n\r\t\v";
	using namespace std;
	string::size_type i = s.find_first_not_of ( ws );
	return i != string::npos ? s.substr ( i, s.find_last_not_of ( ws ) + 1 - i ) : "";
}


FILE *fileHandle;
bool firstRow = true;
bool skipheader = false;
bool first = true;

void myTime ( char* string )
{
	struct tm *l_time;
	time_t now;
	time ( &now );
	l_time = localtime ( &now );
	strftime ( string, 40, "%d.%m.%Y %H:%M:%S", l_time );
}

void openFile()
{
	struct tm *l_time;
	char string[20];
	time_t now;
	time ( &now );
	l_time = localtime ( &now );
	strftime ( string, sizeof string, "%Y-%m-%d", l_time );
	char fileString[50];
	sprintf ( fileString, "/home/stefan/SunnyData/%s.txt", string );
	FILE *filep;
	if (filep = fopen(fileString, "r")) {
		skipheader = true;
		fclose(filep);
	}
	
	cout << "open file: " << fileString << endl;
	fileHandle = fopen ( fileString,"a+" );
	firstRow = true;
	first = true;
}

void fileNewLine()
{
	firstRow = true;
	fputs ( "\r\n",fileHandle );
	fflush ( fileHandle );
}

void fileNewPar ( char *c )
{
	string s = c;

	s = trim ( s );

	int i = 0;
	while ( c[i] != '\0' )
	{
		if ( c[i] == '.' )
		{
			c[i] = ',';
		}
		i++;
	}
	if ( firstRow == true )
	{
		firstRow = false;
		char string[40];
		myTime ( string );
		fputs ( string,fileHandle );
		fputs ( "\t",fileHandle );
	}
	else
	{
		fputs ( "\t",fileHandle );
	}

	fputs ( c,fileHandle );
}
void closeFile()
{
	fclose ( fileHandle );
}


/**************************************************************************
   Description   : print out all channels of a device
   Parameter     : ChanMask: the filter mask (see SMA-Data-Description)
   Return-Value  : (none)
   Changes       : Author, Date, Version, Reason
                   ********************************************************
                   PRUESSING, 02.07.2001, 1.0, Created
**************************************************************************/
int PrintChannelValues ( TChanType chanType )
{
	int cnt = 0;
	int res;
	//lets say that we expect 300 channels in max
#define EXPECT_CHAN_CNT 300
	DWORD ChanHandle[EXPECT_CHAN_CNT];
	char ChanName[50];
	char DevName[50];
	char cUnit[17];
	int i;
	int ChanCount;
	DWORD DevHandle;
	double Value;
	char TextValue[30];
	DWORD MaxValueAge = 5; /* maximum age of the channel value in seconds...*/

	cout << "Device handle: ";
	//scanf("%ld",&DevHandle);
	DevHandle = 1;

	if ((ChanCount = GetChannelHandlesEx ( DevHandle, ChanHandle, EXPECT_CHAN_CNT, chanType )) == 0) {
		cout << "Error reading ChanCount" << endl;
		return 0;
	}

	if (GetDeviceName ( DevHandle, DevName, sizeof ( DevName )-1 ) != 0) {
		cout << "Error reading DeviceName" << endl;
		return 0;
	}

	cout << "Device " << DevName << " has " << ChanCount << " channels:" << endl,
/*	         
 ( chanType == TESTCHANNELS ) ? "(Test)" : "",
	         ( chanType == PARAMCHANNELS ) ? "Parameter" : "Spot" );
*/
	cout << "Reading channel values, please wait..." << endl;

	cout << "------------------------------------------------------------" << endl;
	cout << "Channel handle |    Channel name    | Channel value (Unit) |" << endl;
	cout << "------------------------------------------------------------" << endl;
	
	if ( ( first == true) && (!skipheader) )
	{
		first = false;
		cout << " FIRST " << endl;
		for ( i=0;i<ChanCount;i++ )
		{
			GetChannelName ( ChanHandle[i],ChanName, sizeof ( ChanName )-1 );

			//get the channel unit?
			cUnit[0]=0;
			GetChannelUnit ( ChanHandle[i], cUnit, sizeof ( cUnit )-1 );

			/* Get channel value... */
			res = GetChannelValue ( ChanHandle[i], DevHandle, &Value, TextValue,
			                        sizeof ( TextValue )-1, MaxValueAge );
			if ( res==0 )
			{
				/* Status texts?*/
				if ( strlen ( TextValue ) ==0 )
					sprintf ( TextValue,"%f", Value );
			}
			else
			{
				cout << "Error reading channel value....error code=" << res << endl;
				return 0;
			}
			printf ( "     %3ld       | '%16s' | '%s' %c%s%c \n", ChanHandle[i], ChanName,
			         TextValue,
			         strlen ( cUnit ) > 0 ? '(' : ' ',
			         cUnit,
			         strlen ( cUnit ) > 0 ? ')' : ' ' );
			fileNewPar ( ChanName );


		}
		fileNewLine();
	}
	for ( i=0;i<ChanCount;i++ )
	{
		if (res = GetChannelName ( ChanHandle[i],ChanName, sizeof ( ChanName )-1 ) != 0) {
			cout << "Error reading channel name....error code=" << res << endl;
			return 0;
		}

		//get the channel unit?
		cUnit[0]=0;
		if (res = GetChannelUnit ( ChanHandle[i], cUnit, sizeof ( cUnit )-1 ) != 0) {
			cout << "Error reading channel unit....error code=" << res << endl;
			return 0;
		}

		/* Get channel value... */
		res = GetChannelValue ( ChanHandle[i], DevHandle, &Value, TextValue,
		                        sizeof ( TextValue )-1, MaxValueAge );
		if ( res==0 )
		{
			/* Status texts?*/
			if ( strlen ( TextValue ) == 0 )
				sprintf ( TextValue,"%f", Value );
		}
		else
		{
			cout << "Error reading channel value....error code=" << res << endl;
			return 0;
		}
		printf ( "     %3ld       | '%16s' | '%s' %c%s%c \n", ChanHandle[i], ChanName,
		         TextValue,
		         strlen ( cUnit ) > 0 ? '(' : ' ',
		         cUnit,
		         strlen ( cUnit ) > 0 ? ')' : ' ' );
		fileNewPar ( TextValue );


	}
	fileNewLine();
	if ( ChanCount <= 0 )
	{
		cout << "Error: no channel found" << res << endl;
		return 0;
	}
	return 1;
}


int main ( void )
{
	int i;
	DWORD channelHandle=0;  /* channel handle             */
	DWORD SerNr=0;          /* Serial number of 1. Device */
	DWORD DeviceHandle[10]; /* place for 10 device ID's   */
	int ires=0;             /* result code                */
	DWORD dwBDC=0;          /* BusDriverCount             */
	double value;           /* Channel value              */
	char valuetext[17];     /* channel text value         */

	cout << "Init yasdi master..." << endl;
	yasdiMasterInitialize ( "/etc/yasdi.ini",&dwBDC );

	cout << "Set all available YASDI Bus Driver online..." << endl;
	for ( i=0; i < dwBDC; i++ )
		yasdiMasterSetDriverOnline ( i );
	
	do 
	{
		DWORD DevCount=0;
		do
		{
			cout << "Start an device detection (searching 1 device)..." << endl;
			ires = yasdiDoMasterCmdEx ( "detection", 1, 0, 0 );
	
			/* get all device handles...*/
			cout << "Get all available devices..." << endl;
			DevCount = GetDeviceHandles ( DeviceHandle, 10 );
			if ( DevCount == 0 )
			{
				char string[40];
				myTime ( string );
				cout << string << "no Devices found - waiting 1 Minute" << endl;
				sleep ( 60 );
			}
		}
		while ( DevCount==0 );
		
		openFile();
	
	
		while ( PrintChannelValues ( SPOTCHANNELS ) == 1 )
		{
			char string[40];
			myTime ( string );
			cout << "Time:" << string << endl;
			sleep ( 10 );
		}
	
		closeFile();
	} while (true);

	cout << "Shutting down YASDI..." << endl;
	yasdiMasterShutdown( );

	closeFile();

	return ( 0 );
} /* main */