// function_pointer_test.c - a tiny demo of function pointers

#include <stdio.h>
#include <stdlib.h>

typedef struct _Displayer_ Displayer;

char *cloneString(char* str);
void exitOnFatalErrorOutOfMemory();

void displayVariantOne(char *text);
void displayVariantTwo(char *text);

Displayer *newDisplayer(void (*display_function)(char *text));
void deleteDisplayer(Displayer *displayer);
void changeDisplayFunctionInDisplayer(Displayer *displayer,
                      void (*display_function)(char *text));

//----------------------------------------------------------------------
struct _Displayer_
{
  void (*show)(char *text);
};

//----------------------------------------------------------------------
Displayer *newDisplayer(void (*display_function)(char *text))
{
  Displayer *ret = malloc(sizeof(Displayer));
  if (!ret)
    exitOnFatalErrorOutOfMemory();
  ret->show = display_function;
  return(ret);
}

//----------------------------------------------------------------------
void deleteDisplayer(Displayer *displayer)
{
  if (!displayer)
    return;
  free(displayer);
}

//----------------------------------------------------------------------
void changeDisplayFunctionInDisplayer(Displayer *displayer,
                      void (*display_function)(char *text))
{
  if (!displayer)
    return;
  displayer->show = display_function;
}

//----------------------------------------------------------------------
int main(int argc,char *argv[])
{
  Displayer *displayer = newDisplayer(displayVariantOne);
  displayer->show("a text");
  changeDisplayFunctionInDisplayer(displayer,displayVariantTwo);
  displayer->show("a text");
  return(0);
}

//----------------------------------------------------------------------
void displayVariantOne(char *text)
{
  printf("First Display Variant...\n%s\n",text);
}

//----------------------------------------------------------------------
void displayVariantTwo(char *text)
{
  printf("Second Display Variant\n******\n%s\n******\n",text);
}


//----------------------------------------------------------------------
// helper function if the program runs out of memory
void exitOnFatalErrorOutOfMemory()
{
  printf("Fatal Error: Out of Memory\n");
  exit(-1);
}
