
/*

 DIRU v1.0 (March 30th, 2001) -- a Russian <-> English electronic dictionary
 Copyright (c)2001 Daniel Mealha Cabrita (dancab@iname.com)
 This program is under the terms of GNU General Public License (read documentation for details).

 */

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

#include "di_tools.h"
#include "txt_filter.h"

#include "config.h"

/* #define USER_CHAR_KOI8R */
/* #define USER_CHAR_TRANSLITERATED */
/* #define USER_CHAR_WIN1251 */

/* checks if there are chars > ASCII 0x7f
   returns !=0 if there are cyrillic chars, ==0 if not */
int are_there_cyrillic_chars(const char *given_string)
{
    const unsigned char *my_pos;

    my_pos=given_string;
    while(*my_pos){
        if(*my_pos++ > '\x7f')
            return(1);
    }
    return(0);
}

/* creates a copy of given string in a self-allocated mem space */
char *replicate_string(const char *given_string)
{
    char *new_buff;

    if(new_buff=malloc((strlen(given_string)+1)*sizeof(char)))
        strcpy(new_buff, given_string);
    return(new_buff);
}

/* auxiliary function which converts a given text
   (source standard defined at compilation time) to koi8
   returns: NULL, given_string or pointer to elsewhere
   (!!!) you don't need to free() given_string anymore, just
   the returned pointer, if != NULL */
/* if do_not_free!=0 do not free given_string
   (for the case given_string reflects a argv[], por example) */
const char *convert_to_koi8(const char *given_string, int do_not_free)
{
    const char *new_buff=NULL;

    if(!given_string)
        return(NULL);
#ifdef USER_CHAR_TRANSLITERATED
    new_buff=detransliterate_to_koi8(given_string);
#endif
#ifdef USER_CHAR_KOI8R
    new_buff=replicate_string(given_string);
#endif
#ifdef USER_CHAR_WIN1251
    new_buff=convert_between_koi8_win1251(replicate_string(given_string), 1);
#endif
    if(!do_not_free)
        free_text(given_string);
    return(new_buff);
}

/* auxiliary function which converts a given text
   (source standard defined at compilation time) from koi8
   returns: NULL, given_string or pointer to elsewhere
   (!!!) you don't need to free() given_string anymore, just
   the returned pointer, if != NULL */
/* if do_not_free!=0 do not free given_string
   (for the case given_string reflects a argv[], por example) */
const char *convert_from_koi8(const char *given_string, int do_not_free)
{
    const char *new_buff=NULL;

    if(!given_string)
        return(NULL);
#ifdef USER_CHAR_TRANSLITERATED
    new_buff=transliterate_from_koi8(given_string);
#endif
#ifdef USER_CHAR_KOI8R
    new_buff=replicate_string(given_string);
#endif
#ifdef USER_CHAR_WIN1251
    new_buff=convert_between_koi8_win1251(replicate_string(given_string), 0);
#endif
    if(!do_not_free)
        free_text(given_string);
    return(new_buff);
}

/* this is just an example on how a dictionary code can be implemented
   using these routines */
int main(int argc, const char *argv[])
{
    struct t_dictionary *my_dictionary;
    const char *query_word; /* the word which the user provided */
    int source_lang=0; /* 0-()unknown 1-(r)ussian 2-(e)nglish */
    int word_found_already=0; /* used when no lang specified (tries first en then ru) */

    if((argc!=2)&&(argc!=3)){
        printf("DIRU v1.0 (March 30th, 2001) -- a Russian <-> English electronic dictionary\nCopyright (c)2001 Daniel Mealha Cabrita (dancab@iname.com)\nThis program is under the terms of GNU General Public License (read documentation for details).\n\n");
        printf("Invalid/missing parameter.\n\nUsage: diru [r|e] <word_to_find>\n\n");
        return(1);
    }

#ifdef DICTIONARY_LOCATION
    if(!(my_dictionary=load_dictionary(DICTIONARY_LOCATION))){
#else
    if(!(my_dictionary=load_dictionary("Mueller24.koi"))){
#endif
        printf("Unable to load dictionary to memory!\n(out of memory or I/O error)\n\n");
        return(2);
    }

    if(argc==2){
        query_word=argv[1];
    }else{
        query_word=argv[2];

        if(*argv[1]=='r'){
            printf("Russian -> English\n");
            source_lang=1;
        }else{
            printf("English -> Russian\n");
            source_lang=2;
        }
    }

    /* EN */
    /* if source language is undefined, tries english only if no cyrillic
       chars present for speedup */
    if((source_lang==2)||((!source_lang) && (!are_there_cyrillic_chars(query_word)))){
        const char *found_definition;

        if(found_definition=convert_from_koi8(query_english_word(my_dictionary, query_word), 0)){
            if(!source_lang)
                printf("English -> Russian\n");
            printf("Word found.\n\n%s\n%s\n\n", query_word, found_definition);
            word_found_already=1;
            free_text(found_definition);
        }else{ /* word not found. try to find close words, if the user specified 'english' */
            if(source_lang){
                const char *possible_words;

                if(possible_words=find_possible_words_en(my_dictionary, query_word)){
                    if(*possible_words){
                        printf("Word not found.\n\nPossible matches for \"%s\":\n%s\n\n", query_word, possible_words);
                    }else{
                        printf("Word not found.\n\nNo possible matches found.\n\n");
                    }
                    free_text(possible_words);
                }
            }
        }
    }

    /* RU */
    if(((source_lang==1)||(!source_lang))&&!word_found_already){
        const char *found_definition;
        const char *query_word_converted;

        query_word_converted=convert_to_koi8(query_word, 1);
        if(found_definition=convert_from_koi8(query_russian_word(my_dictionary, query_word_converted), 0)){
            if(!source_lang)
                printf("Russian -> English\n");
            printf("Word found.\n\n%s\n%s\n\n", query_word, found_definition);
            free_text(found_definition);
        }else{ /* word not found. try to find close words */
            const char *possible_words;

            if(possible_words=convert_from_koi8(find_possible_words_ru(my_dictionary, query_word_converted), 0)){
                if(*possible_words){
                    printf("Word not found.\n\nPossible matches for \"%s\":\n%s\n\n", query_word, possible_words);
                }else{
                    printf("Word not found.\n\nNo possible matches found.\n\n");
                }
                free_text(possible_words);
            }
        }
        free_text(query_word_converted);
    }

    unload_dictionary(my_dictionary);
    return(0);
}
