/* !FormText.settings.c */

#include <string.h>

#include "event.h"
#include "gadgets.h"
#include "saveas.h"
#include "window.h"

#include "err.h"
#include "msgtrans.h"
#include "settings.h"
#include "tbchunks.h"
#include "textfile.h"

#define FileType_Data 0xffd

#define MINWIDTH 12
#define MINHEIGHT 4

typedef enum {
  TotalHeight = 2,
  TotalWidth,
  LeftMargin,
  RightMargin,
  TopMargin,
  HeaderLines,
  FooterLines,
  BottomMargin,
  Header = 0xb,
  Footer = 0xd,
  UnderlineChar = 0xe,
  HeadingFlag = 0x10,
  GenContents = 0x11,
  Leadering,
  ContentsTitle
} SettingsGadgets;

typedef enum {
  CancelEvent = TBC_WindowAction,
  FormatEvent,
  SaveSettingsEvent,
  ContentsOptionEvent
} SettingsEvents;

Settings settings;
static ObjectId settings_window;
static ObjectId saveas_id;

static const char SettingsFile[] = "<FormText$Dir>.Settings";

/* Fades appropriate contents gadgets if contents aren't to be generated */
static void set_fades()
{
  int contents;
  unsigned int flags;
  E(optionbutton_get_state(0, settings_window, GenContents, &contents));
  E(gadget_get_flags(0, settings_window, ContentsTitle, &flags));
  flags = (flags & ~Gadget_Faded) | (Gadget_Faded * !contents);
  E(gadget_set_flags(0, settings_window, ContentsTitle, flags));
  E(gadget_get_flags(0, settings_window, Leadering, &flags));
  flags = (flags & ~Gadget_Faded) | (Gadget_Faded * !contents);
  E(gadget_set_flags(0, settings_window, Leadering, flags));
}

static int read_window()
{
  Settings lsettings;
  char read_char[2];
  int ok = 1;
  E(numberrange_get_value(0, settings_window, TotalHeight,
  	&lsettings.text_height));
  E(numberrange_get_value(0, settings_window, TotalWidth,
  	&lsettings.text_width));
  E(numberrange_get_value(0, settings_window, LeftMargin,
  	&lsettings.left_margin));
  E(numberrange_get_value(0, settings_window, RightMargin,
  	&lsettings.right_margin));
  E(numberrange_get_value(0, settings_window, TopMargin,
  	&lsettings.top_margin));
  E(numberrange_get_value(0, settings_window, BottomMargin,
  	&lsettings.bottom_margin));
  E(numberrange_get_value(0, settings_window, HeaderLines,
  	&lsettings.header_height));
  E(numberrange_get_value(0, settings_window, FooterLines,
  	&lsettings.footer_height));
  /* Using 0 for number of bytes read safely ignores it
     (well Acorn's examples do so) */
  E(writablefield_get_value(0, settings_window, Header,
  	lsettings.header, 256, 0));
  E(writablefield_get_value(0, settings_window, Footer,
  	lsettings.footer, 256, 0));
  E(writablefield_get_value(0, settings_window, HeadingFlag,
  	read_char, 2, 0));
  lsettings.heading_flag = read_char[0];
  E(writablefield_get_value(0, settings_window, UnderlineChar,
  	read_char, 2, 0));
  lsettings.underline_char = read_char[0];
  E(optionbutton_get_state(0, settings_window, GenContents,
  	&lsettings.generate_contents));
  E(writablefield_get_value(0, settings_window, ContentsTitle,
  	lsettings.contents_title, 256, 0));
  E(writablefield_get_value(0, settings_window, Leadering,
  	read_char, 2, 0));
  lsettings.contents_leader = read_char[0];
  /* Now calculate net body text width and height */
  lsettings.text_height -= (lsettings.top_margin + lsettings.header_height +
  	lsettings.footer_height + lsettings.bottom_margin);
  lsettings.text_width -= (lsettings.left_margin + lsettings.right_margin);
  if (lsettings.text_width < MINWIDTH)
  {
    err_report(0, msgs_lookup("Narrow"));
    ok = 0;
  }
  if (lsettings.text_height < MINHEIGHT)
  {
    err_report(0, msgs_lookup("Short"));
    ok = 0;
  }
  if (lsettings.heading_flag < 128)
  {
    err_report(0, msgs_lookup("Flag"));
    ok = 0;
  }
  if (lsettings.heading_flag == lsettings.underline_char)
  {
    err_report(0, msgs_lookup("LineFlag"));
    ok = 0;
  }
  if (!lsettings.contents_leader)
    lsettings.contents_leader = ' ';
  if (!lsettings.header[0])
  {
    lsettings.header[0] = ' ';
    lsettings.header[1] = 0;
  }
  if (!lsettings.footer[0])
  {
    lsettings.footer[0] = ' ';
    lsettings.footer[1] = 0;
  }
  if (!lsettings.contents_title[0])
  {
    lsettings.contents_title[0] = ' ';
    lsettings.contents_title[1] = 0;
  }
  if (ok)
    settings = lsettings;
  return ok;
}

static void write_window()
{
  char write_char[2];
  write_char[1] = 0;
  E(numberrange_set_value(0, settings_window, TotalHeight,
  	settings.text_height +
  	settings.top_margin + settings.header_height +
  	settings.footer_height + settings.bottom_margin));
  E(numberrange_set_value(0, settings_window, TotalWidth,
  	settings.text_width +
  	settings.left_margin + settings.right_margin));
  E(numberrange_set_value(0, settings_window, LeftMargin,
  	settings.left_margin));
  E(numberrange_set_value(0, settings_window, RightMargin,
  	settings.right_margin));
  E(numberrange_set_value(0, settings_window, TopMargin,
  	settings.top_margin));
  E(numberrange_set_value(0, settings_window, BottomMargin,
  	settings.bottom_margin));
  E(numberrange_set_value(0, settings_window, HeaderLines,
  	settings.header_height));
  E(numberrange_set_value(0, settings_window, FooterLines,
  	settings.footer_height));
  E(writablefield_set_value(0, settings_window, Header,
  	settings.header));
  E(writablefield_set_value(0, settings_window, Footer,
  	settings.footer));
  write_char[0] = settings.heading_flag;
  E(writablefield_set_value(0, settings_window, HeadingFlag,
  	write_char));
  write_char[0] = settings.underline_char;
  E(writablefield_set_value(0, settings_window, UnderlineChar,
  	write_char));
  E(optionbutton_set_state(0, settings_window, GenContents,
  	settings.generate_contents));
  E(writablefield_set_value(0, settings_window, ContentsTitle,
  	settings.contents_title));
  write_char[0] = settings.contents_leader;
  E(writablefield_set_value(0, settings_window, Leadering,
  	write_char));
  set_fades();
}

static int settings_created(int c, ToolboxEvent *event, IdBlock *id_block,
	void *h)
{
  _kernel_osfile_block kob;
  ToolboxObjectAutoCreatedEvent *toace =
  	(ToolboxObjectAutoCreatedEvent *) event;
  if (strcmp(toace->template_name, "Window"))
    return 0;
  /* Don't need this handler any more */
  event_deregister_toolbox_handler(-1, Toolbox_ObjectAutoCreated,
  	settings_created, h);
  settings_window = id_block->self_id;
  kob.load = (int) &settings;
  kob.exec = 0;
  /* If can't load settings file use defaults from window */
  if (_kernel_osfile(16, SettingsFile, &kob) != 1)
    read_window();
  return 1;
}

static int saveas_created(int c, ToolboxEvent *event, IdBlock *id_block,
	void *h)
{
  ToolboxObjectAutoCreatedEvent *toace =
  	(ToolboxObjectAutoCreatedEvent *) event;
  if (strcmp(toace->template_name, "SaveAs"))
    return 0;
  /* Don't need this handler any more */
  event_deregister_toolbox_handler(-1, Toolbox_ObjectAutoCreated,
  	saveas_created, h);
  saveas_id = id_block->self_id;
  return 1;
}

static int contents_click(int c, ToolboxEvent *e, IdBlock *i, void *h)
{
  set_fades();
  return 1;
}

static int save_clicked(int c, ToolboxEvent *e, IdBlock *i, void *h)
{
  _kernel_osfile_block kob;
  if (!read_window())
    return 1;
  kob.load = FileType_Data;
  kob.start = (int) &settings;
  kob.end = kob.start + sizeof(Settings);
  if (_kernel_osfile(10, SettingsFile, &kob) != 10)
    err_complain(0, msgs_lookup("SaveOpts"));
  return 1;
}

static int cancel_clicked(int c, ToolboxEvent *e, IdBlock *i, void *h)
{
  textfile_clear();
  return 1;
}

static int format_clicked(int c, ToolboxEvent *e, IdBlock *id_block, void *h)
{
  if (!read_window())
    return 1;
  if (textfile_process(saveas_id))
  {
    E(toolbox_hide_object(0, settings_window));
    E(toolbox_show_object(0, saveas_id,
    	Toolbox_ShowObject_Default, 0,
    	id_block->self_id, id_block->self_component));
  }
  return 1;
}

static int saveas_done(int c, ToolboxEvent *e, IdBlock *i, void *h)
{
  textfile_clear();
  return 1;
}

void settings_initialise()
{
  /* Can't do much until we know window handle, so leave it to
     Toolbox_ObjectAutoCreated handler */
  event_register_toolbox_handler(-1, Toolbox_ObjectAutoCreated,
  	settings_created, 0);
  event_register_toolbox_handler(-1, Toolbox_ObjectAutoCreated,
  	saveas_created, 0);
  event_register_toolbox_handler(-1, CancelEvent, cancel_clicked, 0);
  event_register_toolbox_handler(-1, FormatEvent, format_clicked, 0);
  event_register_toolbox_handler(-1, SaveSettingsEvent, save_clicked, 0);
  event_register_toolbox_handler(-1, ContentsOptionEvent, contents_click, 0);
  event_register_toolbox_handler(-1, SaveAs_DialogueCompleted, saveas_done, 0);
}

void settings_show()
{
  write_window();
  E(toolbox_show_object(0 /* static dbox */, settings_window,
  	Toolbox_ShowObject_Default, 0, 0, 0));
}
