/****************************************************************/
/*                                                              */
/*                          hstudio.c                           */
/*                     Bad Seal help studio                     */
/*                             v0.1                             */
/*                                                              */
/*        (c) 2001 Kostas Michalopoulos aka Bad Sector          */
/*                                                              */
/****************************************************************/

#include <process.h>
#include "allegro.h"
#include "seal.h"
#include "app.h"
#include "beditor.h"
#include "iodlg.h"
#include "menus.h"
#include "helpsys.h"

#define MSG_NEW 100001
#define MSG_OPEN 100002
#define MSG_SAVE 100003
#define MSG_SAVEAS 100004

#define MSG_NEW_BLANK_HLS 200001
#define MSG_COMPILE 200002
#define MSG_VIEW 200003

#define MSG_HELP_MAKE 300002
#define MSG_HSHELP 300003
#define MSG_ABOUT 300010

static l_text current_path = NULL;
static l_text current_file = NULL;

p_appwin main = NULL;
p_beditor edit = NULL;
p_stattext status = NULL;

static p_list get_file_items()
{
  p_list p = list_init(malloc(sizeof(t_list)), &free_filehistory_item, 0);

  if (p) {
     p->insert(p, new_filehistory_item("HELP Source files (*.hls)", "*.hls"));
     p->insert(p, new_filehistory_item("All files (*.*)", "*.*"));
  };

  return p;
}

l_bool compile(l_text fname)
{
  l_bool ok;
  l_text args[] = {
    "helpc",
    fname,
    "-q",
    0
  };
  if (!fname) return 0;

  ok = spawnvp(P_WAIT, "helpc", args);

  if (((char) ok) != 0) {
    switch ((char) ok) {
      case 1: {
        seal_error(ERR_INFO, "Cannot open source file");
        return 0;
      }; break;
      case 2: {
        seal_error(ERR_INFO, "Cannot create help file");
        return 0;
      }; break;
      default: {
        seal_error(ERR_INFO, "Uknown error");
        return 0;
      }; break;
    };
  };

  return TRUE;
}

static p_menu hstudio_menu()
{
  p_menu menu = new_menu(
    new_sub_menu("File", new_menu(
      new_menu_item("New document", "", 0, MSG_NEW, NULL,
      new_menu_item("Open document...", "", 0, MSG_OPEN, NULL,
      new_menu_item("Save document", "", 0, MSG_SAVE, NULL,
      new_menu_item("Save document as...", "", 0, MSG_SAVEAS, NULL,
      new_menu_line(
      new_menu_item("Quit Help Studio...", "ALT+F4", TO_ALT(KB_F4), MSG_CLOSE, NULL,
    NULL))))))),
    new_sub_menu("Studio", new_menu(
      new_menu_item("New blank help file", "", 0, MSG_NEW_BLANK_HLS, NULL,
      new_menu_line(
      new_menu_item("Compile", "F9", TO_KEY(KB_F9), MSG_COMPILE, NULL,
      new_menu_item("View", "Ctrl+F9", TO_ALT(KB_F9), MSG_VIEW, NULL,
    NULL))))),
    new_sub_menu("Help", new_menu(
      new_menu_item("Help Studio help", "", 0, MSG_HSHELP, NULL,
      new_menu_line(
      new_menu_item("Help System documentation", "", 0, MSG_HELP, NULL,
      new_menu_item("Creating HLP files", "", 0, MSG_HELP_MAKE, NULL,
      new_menu_line(
      new_menu_item("About Help Studio...", "", 0, MSG_ABOUT, NULL,
    NULL))))))),
  NULL))));

  return menu;
};

void redraw_title()
{
  if (main) {
    free(WINDOW(main)->caption);
    if (current_file)
      WINDOW(main)->caption = set_format_text(NULL, "Help Studio 1.0 - [%s]", current_file);
    else
      WINDOW(main)->caption = strdup("Help Studio 1.0");

    TEST_SUB_VIEWS(VIEW(main), WINDOW(main)->draw_title(WINDOW(main)));
  };
};

l_bool ask_if_modified()
{
  if (!edit->modified) return TRUE;
  return (l_bool)(msgbox(MW_INFO, MB_YES|MB_NO, "Do you want to discard changes?") != MSG_NO);
}

static void trans_ev(p_object o, p_event event)
{
  if (event->type == EV_MESSAGE) {
    switch (event->message) {
      case MSG_CLOSE: {
        t_event oldev = *event;
        if (o->phase == PH_PREPROCESS)
        if (ask_if_modified()) {
          *event = oldev;
        } else clear_event(event);
      }; break;
      case MSG_NEW: {
        clear_event(event);
        if (ask_if_modified()) {
          edit->modified = FALSE;
          free(current_file);
          current_file = NULL;
          edit->set_text(edit, "");
          redraw_title();
        };
      }; break;
      case MSG_OPEN: {
        l_text file;
        clear_event(event);

        file = open_dialog(current_path, "*.hls", get_file_items());
        if (file && ask_if_modified()) {
          l_text t = file_gettext(file);
          l_text p = io_path(file);
          edit->modified = FALSE;
          free(current_file);
          free(current_path);
          current_file = strdup(file);
          current_path = p;
          edit->set_text(edit, t);
          redraw_title();
          free(t);
        };
        free(file);
      }; break;
      case MSG_SAVE: {
        clear_event(event);

        if (!current_file)
          current_file = save_dialog(current_path, "*.hls", get_file_items());
        if (current_file) {
          edit->modified = FALSE;
          if (!file_puttext(current_file, edit->text))
            seal_error(ERR_INFO, "Cannot save - %s", current_file);
          redraw_title();
        };
      }; break;
      case MSG_SAVEAS: {
        clear_event(event);

        current_file = save_dialog(current_path, "*.hls", get_file_items());
        if (current_file && ask_if_modified()) {
          if (!file_puttext(current_file, edit->text))
            seal_error(ERR_INFO, "Cannot save - %s", current_file);
          else
            edit->modified = FALSE;
          redraw_title();
        };
      }; break;
      case MSG_NEW_BLANK_HLS: {
        clear_event(event);
        if (ask_if_modified()) {
          edit->modified = FALSE;
          free(current_file);
          current_file = NULL;
          edit->set_text(edit, "; ***************************************
;  myfile.hls
;  Help for myprogram
;  (C) 2001 myname_goes_here
; ***************************************

.topic main
<b>My Program's Help file</b>

.end
");

          redraw_title();
        };
      }; break;
      case MSG_COMPILE: {
        clear_event(event);
        if (edit->modified) {
          msgbox(MW_WARNING, MB_OK, "Please save your code first");
          return;
        };
        if (!compile(current_file)) msgbox(MW_ERROR, MB_OK, "Compile failed");
      }; break;
      case MSG_VIEW: {
        l_text hlpfile = NULL;
        clear_event(event);
        if (edit->modified || !current_file) {
          msgbox(MW_WARNING, MB_OK, "Please save your code first");
          return;
        };
        hlpfile = strdup(current_file);
        hlpfile[strlen(hlpfile)-1] = 'p';
        open_help(hlpfile);
        free(hlpfile);
      }; break;
      case MSG_HELP: {
        open_help("help.hlp");
        clear_event(event);
      }; break;
      case MSG_HELP_MAKE: {
        open_help_topic("help.hlp", "make");
        clear_event(event);
      }; break;
      case MSG_HSHELP: {
        open_help("hstudio.hlp");
        clear_event(event);
      }; break;
      case MSG_ABOUT: {
        msgbox(MW_INFO, MB_OK, "Help Studio 1.0 (C) 2001 Kostas Michalopoulos aka Bad Sector\n\ne-mail: michalopoylos@hotmail.com\nwww: http://www.badseal.org/");
        clear_event(event);
      }; break;
    };
  };
}

static t_point app_min_size(p_view o)
{
  return point_assign(250, 200);
}

void app_init()
{
  p_menuview menu;

  t_rect r = rect_assign(0, 0, 450, 400);
  main = appwin_init(malloc(sizeof(t_appwin)), r, "Help Studio 1.0", WF_MINIMIZE|WF_MAXIMIZE, ap_id, &trans_ev);
  VIEW(main)->align |= TX_ALIGN_CENTER;
  #ifdef Bad_Seal
//  main->icon16 = (BITMAP*)GET_DATA(dat, 0);
  main->menu = standard_system_menu_items(main,
               new_menu_line(
               new_menu_item("About Help Studio...", 0, 0, MSG_ABOUT, NULL,
  NULL)));
  #endif
  VIEW(main)->size_minimum = &app_min_size;
  OBJECT(desktop)->insert(OBJECT(desktop), OBJECT(main));

  r = rect_assign(2, 20, 448, 40);
  menu = hormenu_init(malloc(sizeof(t_menuview)), r, hstudio_menu());
  OBJECT(main)->insert(OBJECT(main), OBJECT(menu));

  r = rect_assign(2, 45, 448, 383);
  edit = beditor_init(malloc(sizeof(t_beditor)), r, 0);
  VIEW(edit)->align |= TX_ALIGN_BOTTOM+TX_ALIGN_RIGHT;
  OBJECT(main)->insert(OBJECT(main), OBJECT(edit));

  r = rect_assign(2, 385, 448, 398);
  status = stattext_init(malloc(sizeof(t_stattext)), r, TX_ALIGN_LEFT, "Welcome to Help Studio by Bad Sector");
  VIEW(status)->align |= TX_ALIGN_BOTTOM+TX_ALIGN_RIGHT;
  OBJECT(main)->insert(OBJECT(main), OBJECT(status));
}

app_begin(void)
{
  if (ap_process == AP_INIT) {
    l_text t;

    #ifdef Bad_Seal
    #endif

    current_path = strdup("c:/");
    app_init();

    t = file_gettext(ap_args);
    if (t) {
      current_file = strdup(ap_args);
      edit->set_text(edit, t);
      redraw_title();
      free(t);
    };
  };
} app_end;

