#ifndef __dew_cgi_lib
#define __dew_cgi_lib

#include "php_tmpl_prefix.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <utime.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <stdio.h>
#include <sys/timeb.h>
#include <sys/time.h>
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <ctype.h>	// for tolower(char)

#include <string.h>

#include <sqltypes.h>

#include "config.h"
#include "clog.h"
#include "list.h"
#include "cvariables.h"


#define CGI_FLAG_CLEAR (char*)-1

#define EMAIL_PREFIX TMPL_PREFIX

enum { METHOD_NONE, METHOD_GET, METHOD_POST };
enum { SEQ_NONE, SEQ_REVERSE };

int Min0(int a, int b, bool & EOS);		// Returns the smaller of the two; if it's < 0, returns 0
				// a = how many to copy; b = limit;

void strncpy_(char * dst, char * src, int n);

int GetParam(char * params, char _name[], char value[], int valuelen, char ** end = NULL);

void CatFile( char * fname, FILE * fout );

/************************************************************************
*									*
* 				Classes					*
*									*
* - Class CVariables defines a set of routines for handling internal 	*
*	variables, which are stored by using a linked list		*
*									*
* - Class CGIList implements the functionality in template rendering	*
*	by which one can define lists of unknown length from within 	*
*	a template.							*
*									*
* - Class C_CGI_Form is the most essential class for the CGI interface.	*
*	It enables to obtain variables passed from the browser		*
*	and renders complex templates using CVariables and CGIList	*
*									*
*************************************************************************/



// The following deals with getting variables from forms


typedef struct
	{
		char * mask, * explanation;

	} pattern_t;


typedef
	enum { CGI_STRING, CGI_RADIO,
		CGI_SELECT,
		CGI_SELECT_LOOKUP,
		CGI_CHECKBOX,
		CGI_CHECKBOXLIST, 	// bit-encoded ULONG
		CGI_LONG,
		CGI_FLOAT,
		CGI_CHECKBOXLIST_ARRAY, 	// array of ULONGs
		CGI_RADIO_INT,
		CGI_SELECT_MUL,		// multiple select box
		CGI_RADIO_INT2,		// CGI_RADIO_INT that uses first two letters of the variable name for referencing values
		CGI_AMOUNT,		// currency amount, converts to unsigned long
	}
	CGI_VAR_TYPE;

typedef struct
{
	char		*name;
	CGI_VAR_TYPE	type;

	// Matching

	int		minlen, maxlen;
	pattern_t	*pattern;	// ext regular expression; NULL for skip

	char		**radio;	// for radio buttons, NULL otherwise
	unsigned char	nradio;		// number of elements

	// return portion

	void		*target;	// Where the result should be stored
	int		size;		// Don't exceed this !

	// corresponding SQL type
	int		sql_type;

	// more return data
	bool		match;


} CGI_Variable;

//





class CGIList;


typedef struct
{
	char * pre, * post;
	int pre_n, post_n;
} Tprepost;


class C_CGI_Form : public CVariables {
public:
	friend	class CGIList;

	C_CGI_Form( char * _dir, char * _template_file, char * _global_template=NULL, int _argc=0, char **_argv = NULL );
		// Instantiates a C_CGI_Form object.
		//	_dir - template directory
		//	_template_file - initial/default template file
		//	_global_template - used to encapsulate templates in a global template
		//	_arc - argc from main()
		//	_argv - argv from main()



	~C_CGI_Form( );

	void Email( char * fname, char * from=NULL );
	
	bool	Form( FILE * fout );	// Render output from current template into opened file 'fout'
	bool	Form( FILE * fout, char * template_file );

	char	* FormFile( char * fname );	// Render output from current template into 'fname'

	char *  FormBuffer( char * buf );

/*	bool	FormBuffer( char * buf, FILE * fout, char * listname = NULL, int listi = 0  );
					// Render output from current template into buffer*/
	char 	* RFormBuffer( char * buf, char * listname = NULL, int listi = 0 );
					// Render output from current template into buffer using recursion

#ifdef WITH_LANGUAGE
	char    *translate( char * buf, const char *template_file );
#endif

//	int 	GetParam( char name[], char value[], int valuelen );
					// Scan 'params' for 'name' and return its value in 'value'
	int 	GetParam( char name[], char value[], int valuelen, char ** end = NULL, char *start = NULL );
	int	GetParamMul( char name[], TList ** list );

	int 	GetScreen( char * screens[], int n, const char * scrs = NULL );
					// Returns current screen index as passed by the browser
					// and looked up in screens[]
	int	GetCommand( char * commands[], int n );
					// Returns current command index as passed by the browser
					// and looked up in commands[]

	void	Template( char * _template_file )
					// Sets the default template to '_template_file'
	{
		free( template_file );
		template_file = (char*)malloc( strlen(TMPL_PREFIX)+1+strlen(_template_file)+1 );
		sprintf( template_file, "%s/%s", TMPL_PREFIX, _template_file );
	}

	void	GlobalTemplate( char * _template_file )
					// Sets the global template to '_template_file'
	{
		if ( global_template ) free( global_template );
		global_template = strdup(_template_file);
	}
//	void	ParseGlobalTemplate(); // Parse the global template file and set 'sectionX' variables
	void ParseGlobalTemplate( char * fname = NULL );
	bool ParseNewTemplate( char * fname = NULL );

	void	MatchVariable( CGI_Variable * var, bool optional = false, bool flag_if_mismatch = true );
					// Provides CGI variable mapping and matching functionality
					//  can match against regular expressions etc
	void	SetVariable( CGI_Variable * var );
					// Sets a variable that may be used in a template
	void	Flag( CGI_Variable * var );
					// Mark variable as invalid input
	void	Flag( char * var, char * explanation = NULL );
					// Mark variable as invalid input

	void    ClearVariable( CGI_Variable var );

	void	GetNextVariable( TList * &cur, char * &c1, char * &c, char * listname, int listi  );
	CGIList * lists[50];
	int	nlists;

	char * params;

	char * template_file;
	char * global_template;

	unsigned char	 method, sequence;

private:
	char * dir;
	char * form;

#ifdef WITH_LANGUAGE
	char language[10];
#endif
	int	argc;
	char**	argv;

};

class CGIList
{
public:
	friend class C_CGI_Form;

	CGIList( C_CGI_Form * _form, char * name );

		// Instantiates a CGI_List object
		//	_form points to the parent form object
		//	name - name of the list as used in template

	~CGIList() { free( listname ); if (form) form->lists[listn] = 0; };

	int CloseElement() { return ++n; };
		// Move on to the next element in the list.

	void LetStr( char * var, char * value );
		// Set a CGI list variable using the list name and element number as part of the name

	void	LetStrf( char * var, const char * format, ... );

	void LetInt16( char * var, int value );
		// Set a CGI list variable using the list name and element number as part of the name

	char 	* GetVariable( char * var, char * result, int size );
		// Obtain a CGI list variable value using the list name and element number as part of the name

	void LetStr( char * var, const char * format, ... );

	int	n;
private:
	C_CGI_Form * form;
	int listn;
	char * listname;
};



class CInputError : public CVariables {
public:

	void Add( bool text, const char * name, const char * explanation, ... );
	char * Get( const char * name, bool *text );
	void Log();
};

#endif
