/* nfchoices.c */

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

#include "event.h"
#include "gadgets.h"

#include "err.h"
#include "fade.h"
#include "msgtrans.h"
#include "newsbase.h"
#include "newsfind.h"
#include "nfchoices.h"
#include "nfstr.h"
#include "nftcodes.h"
#include "workdir.h"

NFChoices nfchoices;

enum ChoicesGadgets {
  Choices_Folder,
  Choices_User = 5,
  Choices_LogFile = 0xb
};

static MessagesFD nfchoices_fd;

static void nfchoices_save()
{
  FILE *fp;
  int scope;
  workdir_create("<NewsFind$ChoicesDir>");
  fp = fopen("<NewsFind$ChoicesDir>.NewsFind.Choices", "w");
  if (!fp)
  {
    err_complain(0, msgs_lookup("OpenChoices"));
    return;
  }
  fprintf(fp, "FoundFolder:%s\n", nfchoices.foundfolder);
  fprintf(fp, "User:%s\n", nfchoices.user);
  fprintf(fp, "Log:%d\n", nfchoices.log);
  fprintf(fp, "LogFile:%s\n", nfchoices.logfile);
  fprintf(fp, "XPos:%d\n", nfchoices.xpos);
  fprintf(fp, "YPos:%d\n", nfchoices.ypos);
  fprintf(fp, "Status:%c\n", nfchoices.status ? 'Y' : 'N');
  if (nfchoices.status)
  {
    fprintf(fp, "StatusX:%d\n", nfchoices.statusx);
    fprintf(fp, "StatusY:%d\n", nfchoices.statusy);
  }
  if (newsfind_info.ctrl_group[0])
    fprintf(fp, "Group:%s\n", newsfind_info.ctrl_group);
  if (newsfind_info.scope < FB_SearchBody)
    scope = newsfind_info.header;
  else
    scope = 256 + newsfind_info.scope - FB_SearchBody;
  fprintf(fp, "Scope:%d\n", scope);
  fprintf(fp, "Case:%c\n", newsfind_info.casesensve ? 'Y' : 'N');
  fprintf(fp, "Strict:%c\n", newsfind_info.strict ? 'Y' : 'N');
  fprintf(fp, "Reverse:%c\n", newsfind_info.reverse ? 'Y' : 'N');
  fprintf(fp, "Delete:%c\n", newsfind_info.del ? 'Y' : 'N');
  fclose(fp);
}

static int nfchoices_folderopen(int c, ToolboxEvent *e, IdBlock *id, void *h)
{
  E(writablefield_set_value(0, id->self_id, Choices_Folder,
  	nfchoices.foundfolder));
  E(writablefield_set_value(0, id->self_id, Choices_User,
  	nfchoices.user));
  E(radiobutton_set_state(0, id->self_id, nfchoices.log, 1));
  E(writablefield_set_value(0, id->self_id, Choices_LogFile,
  	nfchoices.logfile));
  return 1;
}

static int nfchoices_folderok(int c, ToolboxEvent *e, IdBlock *id, void *h)
{
  char foldername[256];
  E(writablefield_get_value(0, id->self_id, Choices_Folder,
  	foldername, 256, 0));
  if (strincmp(foldername, "Folder.", 7))
  {
    err_report(0, msgs_lookup("BadFolder"));
    return 1;
  }
  writablefield_get_value(0, id->self_id, Choices_Folder,
  	nfchoices.foundfolder, 256, 0);
  E(writablefield_get_value(0, id->self_id, Choices_User,
  	nfchoices.user, 32, 0));
  E(radiobutton_get_state(0, id->self_id, NoLog, 0, (int *) &nfchoices.log));
  E(writablefield_get_value(0, id->self_id, Choices_LogFile,
  	nfchoices.logfile, 256, 0));
  nfchoices_setuser();
  if (c == NFT_ChoicesSave)
    nfchoices_save();
  return 1;
}

static int nfchoices_radio(int c, ToolboxEvent *e, IdBlock *id, void *h)
{
  int state;
  E(radiobutton_get_state(0, id->self_id, NoLog, &state, 0));
  if (state)
    E(gadget_fade(0, id->self_id, Choices_LogFile));
  else
    E(gadget_unfade(0, id->self_id, Choices_LogFile));
  return 1;
}

void nfchoices_initialise(const char *filename)
{
  char *buffer;
  _kernel_oserror *mtlr;
  if (filename)
    nfchoices.transient = 1;
  else
  {
    nfchoices.transient = 0;
    filename = "<NewsFind$ChoicesDir>.NewsFind.Choices";
  }
  mtlr = msgtrans_load(filename, &nfchoices_fd, &buffer);
  if (mtlr)
  {
    if (nfchoices.transient)
      EF(mtlr);
    strcpy(nfchoices.foundfolder, "Folder.NewsFind");
    strcpy(nfchoices.user, "root");
    nfchoices.log = AppendLog;
    strcpy(nfchoices.logfile, "<NewsDir$Dir>.NewsFind.Log");
    nfchoices.resultfile[0] = 0;
    nfchoices.foundfile[0] = 0;
    nfchoices.copy = 'Y';
    nfchoices.xpos = nfchoices.ypos = 0;
    nfchoices.status = 1;
    nfchoices.statusx = nfchoices.statusy = 0;
  }
  else
  {
    const char *scope;
    strncpyC(nfchoices.foundfolder,
    	msgtrans_lookup(&nfchoices_fd, "FoundFolder:Folder.NewsFind"),
    	256);
    strncpyC(nfchoices.user, msgtrans_lookup(&nfchoices_fd, "User:root"), 32);
    strncpyC(nfchoices.password,
    	msgtrans_lookup(&nfchoices_fd, "Password:"), 32);
    nfchoices.log = (LogType) atoi(msgtrans_lookup(&nfchoices_fd, "Log:9"));
    strncpyC(nfchoices.logfile,
    	msgtrans_lookup(&nfchoices_fd,
    		"LogFile:<NewsDir$Dir>.NewsFind.Log"), 256);
    strncpyC(nfchoices.resultfile,
    	msgtrans_lookup(&nfchoices_fd, "ResultFile:"), 256);
    strncpyC(nfchoices.foundfile,
    	msgtrans_lookup(&nfchoices_fd, "FoundFile:"), 256);
    nfchoices.copy = msgtrans_lookup(&nfchoices_fd, "Copy:Y")[0];
    nfchoices.xpos = atoi(msgtrans_lookup(&nfchoices_fd, "XPos:0"));
    nfchoices.ypos = atoi(msgtrans_lookup(&nfchoices_fd, "YPos:0"));
    nfchoices.status =
    	(toupper(msgtrans_lookup(&nfchoices_fd, "Status:Y")[0])=='Y');
    if (nfchoices.status)
    {
      nfchoices.statusx = atoi(msgtrans_lookup(&nfchoices_fd, "StatusX:0"));
      nfchoices.statusy = atoi(msgtrans_lookup(&nfchoices_fd, "StatusY:0"));
    }
    strncpyC(newsfind_info.expression,
    	msgtrans_lookup(&nfchoices_fd, "Expression:"), 256);
    nfchoices.extctrl = (newsfind_info.expression[0] != 0);
    newsfind_info.ctrl_group = strdupC(
    	msgtrans_lookup(&nfchoices_fd, nfchoices.extctrl ? "Group" : "Group:"));
    if (nfchoices.extctrl && !newsfind_info.ctrl_group[0])
      exit(0);
    scope = msgtrans_lookup(&nfchoices_fd,
    	nfchoices.extctrl ? "Scope" : "Scope:");
    if (nfchoices.extctrl && !scope)
      exit(0);
    newsfind_info.header = (FB_WhichHeader) atoi(scope);
    switch (newsfind_info.header)
    {
      case FB_WholeArticle:
        newsfind_info.scope = FB_SearchBody;
        break;
      case FB_BodyOnly:
        newsfind_info.scope = FB_SearchBodyOnly;
        break;
      case FB_AllHeaders:
        newsfind_info.scope = FB_SearchAllHeaders;
        break;
      default:
        newsfind_info.scope = FB_SearchHeader;
        break;
    }
    newsfind_info.casesensve =
    	(toupper(msgtrans_lookup(&nfchoices_fd, "Case:N")[0])=='Y');
    newsfind_info.strict =
    	(toupper(msgtrans_lookup(&nfchoices_fd, "Strict:N")[0])=='Y');
    newsfind_info.reverse =
    	(toupper(msgtrans_lookup(&nfchoices_fd, "Reverse:N")[0])=='Y');
    newsfind_info.del =
    	(toupper(msgtrans_lookup(&nfchoices_fd, "Delete:N")[0])=='Y');
    EF(msgtrans_close(&nfchoices_fd));
    free(buffer);
  }
  EF(event_register_toolbox_handler(-1,
  	NFT_ChoicesOpen, nfchoices_folderopen, 0));
  EF(event_register_toolbox_handler(-1,
  	NFT_ChoicesOK, nfchoices_folderok, 0));
  EF(event_register_toolbox_handler(-1,
  	NFT_ChoicesSave, nfchoices_folderok, 0));
  EF(event_register_toolbox_handler(-1,
  	NFT_ChoicesRadio, nfchoices_radio, 0));
}

static int nfchoices_userreply(WimpMessage *m, void *h)
{
  if (m->data.words[0] < NewsBase_SetUser ||
  	m->data.words[0] > NewsBase_SetUser+9)
    return 0;
  if (m->data.words[0] > NewsBase_SetUser || m->data.bytes[12] < 32)
    err_report(0, msgs_lookup("User"));
  E(event_deregister_message_handler(Wimp_MNewsBaseReply, nfchoices_userreply,
  	0));
  return 1;
}

void nfchoices_setuser()
{
  NewsBaseSetUser nbsu;
  nbsu.encryption = 0;
  strcpy(nbsu.username, nfchoices.user);
  if (nfchoices.password[0])
    strcpy(nbsu.username + strlen(nfchoices.user)+1, nfchoices.password);
  E(event_register_message_handler(Wimp_MNewsBaseReply, nfchoices_userreply,
  	0));
  newsbase_send(NewsBase_SetUser, &nbsu);
}
