/*
 * status.h
 * 
 * Copyright (C) 2005-2007  Josef Kufner <jk@myserver.cz>
 * 
 * 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.
 *
 */
#ifndef NETBOARD_STATUS_H
#define NETBOARD_STATUS_H

#include <glib.h>

struct s_status_table;

typedef struct s_status {
	/* state machine properties */
	char *name;				/* state machine name -- for debug only */
	int max_st;				/* maximal state id */
	struct s_status_table *table;		/* status table (and callbacks) */

	/* current state */
	long time;				/* current time */
	int current_st;				/* current state */
	char *current_sub_state;		/* current sub-state (string parameter) */
	gchar *current_desc;			/* description of current state */

	/* history */
	int last_st;				/* previous state */

	/* future */
	int after_st;				/* change to this state after current transition */
	char *after_sub_st;			/*  ... and it's parameter */

	/* callbacks */
	void (*cb_before_switch)(struct s_status *st); /* call this before state transition */
	void (*cb_between_switch)(struct s_status *st); /* call this inside state transition (after leave, before enter) */
	void (*cb_after_switch)(struct s_status *st); /* call this after state transition */
	
	/* calculated data and internal flags -- do not change outside status.c */
	int is_status_switch_in_progress;	/* lock for status_switch */
	int switch_queue_full;			/* status_switch can be called only twice */
	void *trie_abbr_to_id;			/* trie containing state id by it's abbrevation */
} STATUS;

struct s_status_table {
	char *status_name, *status_abbr;	/* state long name and abbrevation */
	void (*cb_enter)(STATUS *st);		/* callback on enter */
	void (*cb_leave)(STATUS *st);		/* callback on leave */
	char *allowed_st;			/* string contaning '1' at position of allowed next state */
	char *comparsion;			/* +/- (by pos.) for greather/lesser state than this state */
};


STATUS *status_create (char *name, struct s_status_table *table, int table_lines);
int status_destroy(STATUS *st);

int status_switch (STATUS *st, int new_state, const char *new_sub_state);
int status_get(STATUS *st);

long status_get_time (STATUS *st);

char *status_get_name (STATUS *st);
char *status_get_name_by_id (STATUS *st, int id);

char *status_get_abbr (STATUS *st);
char *status_get_abbr_by_id (STATUS *st, int id);
int status_get_id_by_abbr (STATUS *st, const char *abbr);
	
void status_set_description(STATUS *st, char *fmt, ...);
int status_validate_trans(STATUS *st, int old_st, int new_st);
int status_compare_states(STATUS *st, int a, int b);

#endif
