/*
 beats.c:
   Adds an expando to the timestamp display, namely '%1' to show Swatch
	 Interneat Time. Look at http://www.swatch.com/alu_beat/fs_itime.html
	 for more information.

 compile:
   export IRSSI=~/src/irssi-0.8.5
	 gcc beats.c -Wall -g -o ~/.irssi/modules/libbeats.so -shared -I$IRSSI/src -I$IRSSI/src/fe-common/core -I$IRSSI/src/core -I$IRSSI/src/fe-text $(glib-config --cflags)

 usage:
   /LOAD beats
	 /SET timestamp_format %1
     -or somehing like-
	 /SET timestamp_format %1 %H:%M

*/

#define MODULE_NAME "fe-text/beats"

#include "common.h" // some base includes we need to compile
#include "modules.h"
#include "signals.h"
#include "levels.h"

#include "expandos.h" // here the expandos are defined
#include "misc.h" // replace_chars
#include "settings.h" // settings_get_str

#include <string.h> // strstr

EXPANDO_FUNC pfExpandoTime; // will hold the address of the old method

/** \brief will replace every 'replace' in 'hay' with 'with'
 * \param src pointer to the source string
 * \param dest pointer to a buffer, where the replaced string will be stored in
 * \param iSize maximum number of chars to be stored, without the \0
 * \param replace string to replace
 * \param with replacement of every occurance of 'replace'
 * \return retuns dest
*/
const char* strnreplace(const char *src, char *dest, int iSize,
                       const char *replace, const char *with)
{
	const char *s;
	char *at,*d;
	int iLenWith,iLenReplace,iCount,iLenLeft;

	--iSize;
	d = dest;
	s = src;
	iLenWith = strlen(with);
	iLenReplace = strlen(replace);

	while ((at = strstr(s,replace)) && iSize)
	{
		iCount = at-s;
		if (iCount > iSize)
			iCount = iSize;

		memcpy(d,s,iCount);
		d += iCount;
		iSize -= iCount;

		if (iLenWith > iSize)
			iLenWith = iSize;

		memcpy(d,with,iLenWith);
		d += iLenWith;
		iSize -= iLenWith;

		s = at +iLenReplace;
	}

	iLenLeft = strlen(s);
	if (iLenLeft < iSize)
	{
		memcpy(d,s,iLenLeft);
		d += iLenLeft;
	}

	*d = 0;
	return dest;
}

// the wrapper method
static char *beats_time(SERVER_REC *server, void *item, int *free_ret)
{
	const int SIZE = 256;
	const int BEATS = 4; // beats range from 000-999

	int iBeats;
	time_t now;
	struct tm *tm;
	char str[SIZE],replaced[SIZE],beats[BEATS];

	const char *timestamp_format = settings_get_str("timestamp_format");

	*free_ret = TRUE;
	now = time(NULL);

	// create the std expands
	tm = localtime(&now);

	if (strftime(str, SIZE, timestamp_format, tm) == 0)
		return g_strdup("");

	// calculate beats and put them into a char[]
	tm->tm_hour += settings_get_int("beat_distance");

	iBeats = ( tm->tm_hour *3600 +tm->tm_min *60 +tm->tm_sec ) /86.4;

	while (iBeats < 0)
		iBeats += 1000;
	while (iBeats > 1000-1)
		iBeats -= 1000;

	snprintf(beats,BEATS,"%03d",iBeats);

	// replace all %1 with BEATS
	strnreplace(str,replaced,SIZE,"%1",beats);

	return g_strdup(replaced);
}

void beats_init(void)
{
	// our setting
	settings_add_int("misc", "beat_distance", 0);

	// remember the old method
	pfExpandoTime = expando_find_char('Z');

	// we can use expando_find_char, cras said we are internal enough :)
	expando_destroy("Z",pfExpandoTime);
	expando_create("Z",beats_time,"time changed", EXPANDO_ARG_NONE, NULL);

	// before of after we are ready?	
	module_register("beats", "core");
}

void beats_deinit(void)
{
	// revert back to original settings
	expando_destroy("Z",beats_time);
	expando_create("Z",pfExpandoTime,"time changed", EXPANDO_ARG_NONE, NULL);
}
