/* ------------------------- forms2.h ---------------------------------------- *
 * Version 1.0  18.01.2023                                                     *
 *                                                                             *
 * Formularbibliothek forms2.                                                  *
 * --------------------------------------------------------------------------- */

#ifndef __FORMS2_H__
#define __FORMS2_H__

#include "mytypes.h"
#include "input2.h"

typedef enum {feField, feButton} formElementType;
typedef enum {ftText, ftNumNatural, ftInteger, ftReal, ftDate, ftFileName} fieldType;
typedef enum {ok, cancel, other} buttonType;

typedef struct {
    fieldType kind;
    int length;
    const char *caption;
    int xCaption, yCaption;
    int xInput, yInput;
    char *txt;
    bool mandatory;
} Field;

typedef struct {
    buttonType kind;
    int x, y;
    uint8_t width;
    const char *caption;
    bool activated;
} Button;

typedef struct tagFormElement {
    struct tagFormElement *next;
    struct tagFormElement *prev;
    formElementType elementType;
    union {
        Field *field;
        Button *button;
    };
} FormElement;

/* TEST >>>
void printField(Field *f);
void printButton(Button *b);
void printFormElement(FormElement * e);
void printFormElements();
<<< TEST */

// External function, must be implemented in client code.
extern void initFormElements(uint8_t formIdx);

// Sets the position of the message line (Y coordinate).
void setMessageLine(uint8_t line);

// Was form processing finished by a cancel button?
bool formCancelled();

// Clears the message line.
void clearMessageLine();
  
// Displays the form.
void displayForm();

// Processes the form.
void processForm();

/* Gets the nth form element from the element list.
   Returns a pointer to element n if found or nil if not found. */
FormElement *getFormElement(uint8_t n);

/* Gets the nth field from the element list.
   Returns a pointer to the field n if found or nil if not found. */
Field *getField(uint8_t n);

/* Gets the nth button from the element list.
   Returns a pointer to the button n if found or nil if not found. */
Button *getButton(uint8_t n);

// Is the button activated?
bool isActivated(uint8_t n);

// Adds a field to the form.
void addField(fieldType pKind,
              int pFieldLength, const char *pCaption,
              int pXCaption, int pYCaption,
              int pXInput, int pYInput,
              bool pMandatory);

// Adds a button to the form.
void addButton(buttonType pKind, int pX, int pY, int pWidth, const char *pCaption);

// Creates a new form element and links it with the previous one.
void newAndLinkWithPrevElement();

/* Initializes the form. Calls InitFormElements, a procedure to be
   implemented in the main application. */
void initForm(uint8_t formIdx);

/* Destroys the form and releases allocated memory. */
void destroyForm(uint8_t formIdx);

// Sets the text of field n.
void setFieldText(uint8_t n, char *s);

// Gets the first element of the form.
FormElement *getFormFirstElement();

#endif
