/**
 * Initialisation code
 * (C) Nettle developers 2000-2001
 *
 * $Id: init,v 1.59 2003/06/15 20:51:58 archifishal Exp $
 */

#include "generic.h"
#include "globals.h"

#include "choices.h"
#include "hotlist.h"
#include "init.h"
#include "messages.h"
#include "misc.h"
#include "nettle.h"
#include "scripts.h"
#include "quit.h"
#include "sockwatch.h"
#include "templ.h"
#include "url.h"
#include "wimp.h"
#include "wimputil.h"
#include "zapredraw.h"

#define MAX_TEMPLATES 14
#define LOAD_TEMPLATE_NO_FONTS          (int *)(-1)
#define LOAD_TEMPLATE_WIMP_SPRITE_AREA  (struct os_spriteop_area *)(1)

static int zapredraw_block[128];
static int maxindirected=0;
static int *indirected[MAX_TEMPLATES];

static void initialise_wimp(void)
{
  static const int messages[] =
  {
    WIMP_MESSAGE_DATASAVE,
    WIMP_MESSAGE_DATASAVEACK,
    WIMP_MESSAGE_DATALOAD,
    WIMP_MESSAGE_DATALOADACK,
    WIMP_MESSAGE_PREQUIT,
    WIMP_MESSAGE_CLIP_CLAIMENTITY,
    WIMP_MESSAGE_CLIP_DATAREQUEST,
    WIMP_MESSAGE_MENUWARNING,
    WIMP_MESSAGE_MODECHANGE,
    WIMP_MESSAGE_MENUSDELETED,
    WIMP_MESSAGE_WINDOWINFO,
    COLOURPICKER_COLOUR_CHOICE,
    COLOURPICKER_CLOSE_REQUEST,
    WIMP_MESSAGE_TASKWINDOW_OUTPUT,
    WIMP_MESSAGE_TASKWINDOW_EGO,
    WIMP_MESSAGE_TASKWINDOW_MORIO,
    URI_MProcess,
    URI_MReturnResult,
    Wimp_MOpenUrl,
    WIMP_MESSAGE_QUIT /* must be last! */
  };

  _swi(Wimp_Initialise, _INR(0,3)|_OUTR(0,1), 310, 0x4b534154,
    application_name, messages, &wimp_version, &task_handle);
}

static void open_template(void)
{
  char country[16];
  char template_filename[1024];
  FILE *file_handle;

  /* Again, set country to UK if we don't know */
  if (strlen(get_country(country, sizeof(country)))==0)
    strcpy(country,"UK");

  /* Put together filename */
  sprintf(template_filename,"<%s$Dir>.Resources.%s.Templates",application_name,country);

  file_handle=fopen(template_filename,"r");

  /* If we fail to open, change to UK */
  if (file_handle==0)
  {
    strcpy(country,"UK");
  }
  else
  {
    fclose(file_handle);
  }

  /* Put together filename */
  sprintf(template_filename,"<%s$Dir>.Resources.%s.Templates",application_name,country);

  file_handle=fopen(template_filename,"r");

  /* this time, if we fail to open, moan about lack of templates and quit */
  if (file_handle==0)
  {
    generror("NoTemplates", true);
    closedown_application();
  }
  else
  {
    fclose(file_handle);
  }

  _swi(Wimp_OpenTemplate, _IN(1), template_filename);
}


static int load_template(int *font_array, const char *window_name, struct os_spriteop_area *templ_sprite, int furniture)
{
  char window_name_copy[12];
  struct wimp_createwindow_block *template_data;
  int *indirected_data;
  int size_of_template_data;
  int size_of_indirected_data;
  int window_handle;

  assert(maxindirected<MAX_TEMPLATES);

  /* template name must be in a writable 12-byte buffer */
  strcpy(window_name_copy, window_name);

  /* get sizes of template data and indirected_data */
  _swi(Wimp_LoadTemplate, _IN(1)|_INR(5,6)|_OUTR(1,2), 0, window_name_copy,
    0, &size_of_template_data, &size_of_indirected_data);

  /* alloc this amount, indirected first to be heap friendly */
  indirected_data=malloc(size_of_indirected_data);
  assert(size_of_indirected_data == 0 || indirected_data != NULL);

  template_data=malloc(size_of_template_data);
  assert(size_of_template_data == 0 || template_data != NULL);

  indirected[maxindirected++]=indirected_data;

  /* load the template */
  _swi(Wimp_LoadTemplate, _INR(1,6), template_data, indirected_data,
    indirected_data+size_of_indirected_data, font_array, window_name_copy,
    0);

  /* set the sprite area pointer */
  template_data->sprite_area=templ_sprite;

  /* Need to set a bit to mark a window as furniture */
  /* This might not be preserved by a template editor, so do it here! */
  if (furniture)
    template_data->window_flags |= (1<<23);

  window_handle = _swi(Wimp_CreateWindow, _IN(1)|_RETURN(0), template_data);

  /* free the template data (indirected is still needed) */
  free(template_data);

  return window_handle;
}


static void close_template(void)
{
  _swi(Wimp_CloseTemplate, 0);
}


void lose_templates(void)
{
  int i;
  for(i=0; i<maxindirected; i++)
    free(indirected[i]);
}

static void load_templates(void)
{
  char info_data[60];

  /* open the templates file */
  open_template();

  /* read template definitions */
  win_info=load_template(LOAD_TEMPLATE_NO_FONTS,"info",LOAD_TEMPLATE_WIMP_SPRITE_AREA, 0);
  set_icon_data(win_info,icon_info_name,lookup("AppName", info_data, sizeof(info_data)));
  set_icon_data(win_info,icon_info_purpose,lookup("AppPurpose", info_data, sizeof(info_data)));
  set_icon_data(win_info,icon_info_author,lookup("AppAuthor", info_data, sizeof(info_data)));
#ifdef BETA_VERSION
  sprintf(info_data, "Development (%s)", __DATE__);
  set_icon_data(win_info,icon_info_version, info_data);
#else
  set_icon_data(win_info,icon_info_version,lookup("AppVersion", info_data, sizeof(info_data)));
#endif

  win_choices=load_template(LOAD_TEMPLATE_NO_FONTS,"choices",LOAD_TEMPLATE_WIMP_SPRITE_AREA, 0);
  win_paneterm=load_template(LOAD_TEMPLATE_NO_FONTS,"paneterm",LOAD_TEMPLATE_WIMP_SPRITE_AREA, 0);
  win_panecols=load_template(LOAD_TEMPLATE_NO_FONTS,"panecols",LOAD_TEMPLATE_WIMP_SPRITE_AREA, 0);
  win_panehot=load_template(LOAD_TEMPLATE_NO_FONTS,"panehot",LOAD_TEMPLATE_WIMP_SPRITE_AREA, 0);
  win_hotpane=load_template(LOAD_TEMPLATE_NO_FONTS,"hotpane",LOAD_TEMPLATE_WIMP_SPRITE_AREA, 0);
  win_hotedit=load_template(LOAD_TEMPLATE_NO_FONTS,"hotedit",LOAD_TEMPLATE_WIMP_SPRITE_AREA, 0);
  win_panemisc=load_template(LOAD_TEMPLATE_NO_FONTS,"panemisc",LOAD_TEMPLATE_WIMP_SPRITE_AREA, 0);

  win_open=load_template(LOAD_TEMPLATE_NO_FONTS,"open",LOAD_TEMPLATE_WIMP_SPRITE_AREA, 0);
  set_icon_data(win_open,icon_open_contype,lookup("Telnet", info_data, sizeof(info_data)));

  win_resize=load_template(LOAD_TEMPLATE_NO_FONTS,"resize",LOAD_TEMPLATE_WIMP_SPRITE_AREA, 0);
  win_sizebar=load_template(LOAD_TEMPLATE_NO_FONTS,"sizebar",LOAD_TEMPLATE_WIMP_SPRITE_AREA, 1);

  win_save=load_template(LOAD_TEMPLATE_NO_FONTS,"save",LOAD_TEMPLATE_WIMP_SPRITE_AREA, 0);
  win_spoolsave=load_template(LOAD_TEMPLATE_NO_FONTS,"spoolsave",LOAD_TEMPLATE_WIMP_SPRITE_AREA, 0);

  win_termterm=load_template(LOAD_TEMPLATE_NO_FONTS,"termterm",LOAD_TEMPLATE_WIMP_SPRITE_AREA, 0);

  /* close the templates file */
  close_template();
}


static void load_zap_fonts(void)
{
  redraw.r_workarea=zapredraw_block;

  /* load in hires and lores zap fonts */
  zap_font_area=load_font(zap_font);
  zap_lowres_font_area=load_font(zap_lowres_font);

  /* do mode_change to set things up */
  mode_change();
}


static void create_icon_bar_icon(void)
{
  struct wimp_createicon_block block;

  block.window_handle=-1; /* window handle */
  block.min.x         =0;  /* min x */
  block.min.y         =0;  /* min y */
  block.max.x         =68; /* max x */
  block.max.y         =68; /* max y */
  block.icon_flags   =WIMP_ICON_BGCOL(1) | WIMP_ICON_FGCOL(7) | WIMP_ICON_TYPE(3) | \
                      WIMP_ICON_VCENT_BIT | WIMP_ICON_HCENT_BIT | WIMP_ICON_SPRITE_BIT ;

  strcpy(block.contents.t.text, application_icon_name);

  iconbar_handle=_swi(Wimp_CreateIcon, _IN(1)|_RETURN(0), &block);
}


void initialise_application(void)
{
#ifdef FORTIFY
  Fortify_EnterScope();
#endif

  /* Turn on hourglass */
  _swi(Hourglass_On, 0);

  /* Initialise application */
  initialise_wimp();

  /* load things in */
  load_messages();
  load_choices();
  load_hotlist();
  load_scripts();
  load_templates();
  load_zap_fonts();

  create_log();

  /* create the iconbar icon */
  create_icon_bar_icon();

  socketwatch_initialise();

  /* Turn off hourglass */
  _swi(Hourglass_Off, 0);

}
