/*************************************/
/*TELEPHONE BOOK APPLICATION FOR SEAL*/
/*************************************/

/* by Kostas Michalopoulos aka Bad Sector */
/* this is a part from "Creating a SEAL application Step-by-Step" tutorial */

/* include some needed headers */
#include "allegro.h"
#include "seal.h" 
#include "app.h" 
#include "dialogs.h" 
#include "button.h"
#include "helpsys.h"
#include <io.h>

/* fsize(f) returns size of f (type FILE) in bytes */
#define fsize(f) filelength(fileno(f))

/* define messages */
#define MSG_PREV 10001
#define MSG_NEXT 10002
#define MSG_SAVE 10003
#define MSG_NEW 10004
#define MSG_ABOUT 90001

static DATAFILE *dat = NULL;

/* define record type */
typedef struct t_record {
  char name[101];   /* 101=100 maximum characters plus \0 for end-of-string mark */
  char phone[33];   /* 32 maximum characters */
} t_record;

p_appwin win;
p_button btPrev, btNext, btSave, btNew;
p_textline tlName, tlPhone;

l_int idx, cnt; /* record index and count of records in file */

/* This function returns the amount of records in file filename */
l_int get_record_count(const l_text filename)
{
  FILE *f = fopen(filename, "rb"); /* Binary file */
  l_int size = 0;
  if (!f) {    /* if file doesn't exists, create one new with one record */
    t_record r;
    f = fopen(filename, "wb");
    strcpy(r.name, "Bad Sector");
    strcpy(r.phone, "unknown");
    fwrite(&r, sizeof(t_record), 1, f);
    fclose(f);
    f = fopen(filename, "rb");
  };
  size = fsize(f) / sizeof(t_record);
  fclose(f);

  return size;
};

/* This function saves current record to file filename */
void save_record(const l_text filename)
{
  FILE *f = fopen(filename, "rb+");
  t_record r;

  fseek(f, idx*sizeof(t_record), SEEK_SET);
  strcpy(r.name, tlName->text);
  strcpy(r.phone, tlPhone->text);
  fwrite(&r, sizeof(t_record), 1, f);
  fclose(f);
};

/* This function loads a record from the file */
void load_record(const l_text filename, l_int rec)
{
  FILE *f = fopen(filename, "rb");
  t_record r;
  fseek(f, rec*sizeof(t_record), SEEK_SET); /* move to record's position */
  fread(&r, sizeof(t_record), 1, f);
  fclose(f);
  /* change text in Name and Phone fields */
  tlName->set_text(tlName, r.name);
  tlPhone->set_text(tlPhone, r.phone);
  idx = rec;
};

static void translate_event(p_object o, p_event event)
{
  if (event->type == EV_MESSAGE)
  {
    switch (event->message)
    {
      case MSG_PREV: {
        if (idx > 0) load_record("telebook.tbf", idx-1);
        clear_event(event);
      } break;
      case MSG_NEXT: {
        if (idx < cnt-1) load_record("telebook.tbf", idx+1);
        clear_event(event);
      } break;
      case MSG_SAVE: {
        save_record("telebook.tbf");
        clear_event(event);
      } break;
      case MSG_NEW: {
        idx = cnt;
        tlName->set_text(tlName, "name");
        tlPhone->set_text(tlPhone, "-");
        save_record("telebook.tbf");
        cnt++;
        clear_event(event);
      } break;
      case MSG_ABOUT: {
        msgbox(MW_INFO, MB_OK, "TeleBOOK 1.0 (C) 2000,2001 by Bad Sector\n\ne-mail: michalopoylos@hotmail.com\nvisit SEAL/BadSeal Resources page at:\n  http://www.badseal.org");
        clear_event(event);
      }; break;
      case MSG_HELP: {  /* MSG_HELP is defined in SEAL.H */
        open_help("telebook.hlp");
        clear_event(event);
      }; break;
    };
  }
}

void testapp_init() 
{ 
  t_rect r = rect_assign(100, 100, 300, 200);
  p_stattext st1;

  /* Let's create main window */
  win = appwin_init(malloc(sizeof(t_appwin)), r, "TeleBOOK for SEAL", WF_MINIMIZE, ap_id, &translate_event);
#ifdef WANT_OLD_STUFF
  win->icon16 = (BITMAP*)GET_DATA(dat, 0);
#else
{
              p_appwin_extension ext;
              if( OBJECT(win)->find_extension && 
                  (ext=(p_appwin_extension)OBJECT(win)->find_extension(OBJECT(win), BS_APPWIN_NAME, BS_APPWIN_VERSION)))
                 ext->icon16= (BITMAP*)GET_DATA(dat, 0);
}
#endif
  /* Define our system menu */
  win->menu = standard_system_menu_items(win, // standard menu items (Maximize, Minimize, etc
              new_menu_line(
              new_menu_item("Help...", 0, 0, MSG_HELP, NULL,
              new_menu_item("About TeleBOOK...", 0, 0, MSG_ABOUT, NULL,
  NULL))));
  OBJECT(desktop)->insert(OBJECT(desktop), OBJECT(win));

  /* And insert the controls */
  r = rect_assign(5, 25, 45, 45);
  btPrev = button_init(malloc(sizeof(t_button)), r, "<-", MSG_PREV, BF_NORMAL);
  OBJECT(win)->insert(OBJECT(win), OBJECT(btPrev));

  r = rect_assign(50, 25, 90, 45);
  btNext = button_init(malloc(sizeof(t_button)), r, "->", MSG_NEXT, BF_NORMAL);
  OBJECT(win)->insert(OBJECT(win), OBJECT(btNext));

  r = rect_assign(95, 25, 135, 45);
  btSave = button_init(malloc(sizeof(t_button)), r, "Save", MSG_SAVE, BF_NORMAL);
  OBJECT(win)->insert(OBJECT(win), OBJECT(btSave));

  r = rect_assign(140, 25, 180, 45);
  btNew = button_init(malloc(sizeof(t_button)), r, "New", MSG_NEW, BF_NORMAL);
  OBJECT(win)->insert(OBJECT(win), OBJECT(btNew));

  r = rect_assign(5, 50, 69, 65);
  st1 = stattext_init(malloc(sizeof(t_stattext)), r, TX_ALIGN_LEFT, "Name:");
  OBJECT(win)->insert(OBJECT(win), OBJECT(st1));

  r = rect_assign(5, 70, 69, 85);
  st1 = stattext_init(malloc(sizeof(t_stattext)), r, TX_ALIGN_LEFT, "Phone:");
  OBJECT(win)->insert(OBJECT(win), OBJECT(st1));

  r =rect_assign(70, 48, 210, 67);
  tlName = textline_init(malloc(sizeof(t_textline)), r, 100, TF_NONE);
  OBJECT(win)->insert(OBJECT(win), OBJECT(tlName));

  r =rect_assign(70, 68, 210, 87);
  tlPhone = textline_init(malloc(sizeof(t_textline)), r, 32, TF_NONE);
  OBJECT(win)->insert(OBJECT(win), OBJECT(tlPhone));

  /* Initialize non-visual things */

  cnt = get_record_count("telebook.tbf");
  idx = 0;
  load_record("telebook.tbf", idx);
}

app_begin(void) 
{ 
  if (ap_process == AP_INIT) { 
    dat = conv_to_skipcolor_data(DLXGetFileData(ap_id), CO_SKIP_RED, CO_SKIP_GREEN, CO_SKIP_BLUE);
    testapp_init();
  }; 
} app_end;

