/* -*- objective-c -*- */

/*

    Webster Access, a program to use NeXT online Webster dictionary.
    Copyright (C) 1994 Benoit Grange, ben@fizz.fdn.org

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.

*/

#import <libc.h>

#import "daemon.h"
#import "utils.h"
#import "commands.h"
#import "search.h"
#import "config.h"

#import "WebsterVolume.h"
#import "WebsterWord.h"

static WebsterDictionary* dico = NULL;
static WebsterThesaurus* thesaurus = NULL;
static WebsterVolume* currentVolume = NULL;

short whichVolume = useDictionary;

int initSearch()
{
  WebsterVolume** v = (whichVolume == useThesaurus)?
    (WebsterVolume**)&thesaurus:
    (WebsterVolume**)&dico;

  currentVolume = *v;

  if (!currentVolume) {
    if (whichVolume == useThesaurus) 
      currentVolume = [[WebsterThesaurus alloc]
		       initFromFile: (dictionaryFileName)?thesaurusFileName:
		       "/NextLibrary/References/Webster-Thesaurus/Thesaurus"];
    else
      currentVolume = [[WebsterDictionary alloc]
		       initFromFile: (dictionaryFileName)?dictionaryFileName:
		       "/NextLibrary/References/Webster-Dictionary/Dictionary"];
    if (!currentVolume) return -1;
    *v = currentVolume;
  }
  return 0;
}

void processDefine(char* args)
/* Define the following word */
{
  WebsterWord* word;

  initSearch();
  
  word = [currentVolume defineWord: args];
  if (word) {
    char* text;
    int length;
    if ([word outputDefinitionAs: "ascii" result: &text length: &length]) {
      fprintf(clientW, "DEFINITION 0\n");
      fwrite(text, 1, length, clientW);
      vm_deallocate(task_self(), (vm_address_t)text, (vm_size_t)length);
      fputc(0200, clientW);
    } else {
      fprintf(clientW, "%sDEFINE FAILED\n", (mode==normalMode)?"":"590 ");
    }
    [word free];
  } else {
    fprintf(clientW, "%sSPELLING 0\n", (mode==normalMode)?"":"590 ");
  }
}

void processSpell(char* args)
/* Define the following word */
{
  WebsterWord* word;

  initSearch();
  
  word = [currentVolume defineWord: args];
  fprintf(clientW, "SPELLING %d\n", (word)?1:0);
  [word free];
}

void processComplete(char* args)
{
  List* l;
  initSearch();

  // A maxCount is included for speed sake
  // This avoids going thru the most of the index to complete 'e'
  if (l = [currentVolume completeWord: args maxCount: 16]) {
    if ([l count] == 1) fprintf(clientW, "COMPLETION %s\n", [[l objectAt: 0] word]);
    else fprintf(clientW, "AMBIGUOUS %d\n", [l count]);
    [l freeObjects];
    [l free];
  } else fprintf(clientW, "AMBIGUOUS 0\n");
}

void processEndings(char *args)
{
  List* l;
  initSearch();

  if (l = [currentVolume completeWord: args]) {
    int i;
    fprintf(clientW, "MATCHS %d\n", [l count]);
    for(i=0; i<[l count]; i++) {
      fprintf(clientW, "%s\n", [[l objectAt: i] word]);
    }
    fputc(0200, clientW);
    [l freeObjects];
    [l free];
  } else fprintf(clientW, "MATCHS 0\n");
}
