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

#define TAM_MAX_PALAVRA 256
#define TAM_MAX_INDICE 256
#define MAX_PALAVRAS 256
#define TAM_MAX_LINHA 256

struct palavra_indice{char palavra[TAM_MAX_PALAVRA];
                      int lin;
                      int col;};

struct indice{int num_elem;
              struct palavra_indice entrada[TAM_MAX_INDICE];
             };

struct lista_palavras{
                      int num_elem;
                      char palavras[MAX_PALAVRAS][TAM_MAX_PALAVRA];
                     };

int le_linha(FILE *f, char *linha, int n){
    char c;
    int i;

    for (i=0; (i<n) && ((c=fgetc(f))!=EOF) && (c!='\n');i++){
        linha[i] = c;
    }

    if (c=='\n'){
        linha[i] = '\n';
        i++;
    }

    linha[i] = '\0';

    return i;

}


void ler_arq_palavras(char *nome_arq, struct lista_palavras *lst){
    FILE *f = fopen(nome_arq,"r");

    if (!f){return;}

    lst->num_elem = 0;

    while (le_linha(f,lst->palavras[lst->num_elem],TAM_MAX_PALAVRA))
    {
        int tam = strlen(lst->palavras[lst->num_elem]);

        // remove os \n
        if (lst->palavras[lst->num_elem][tam-1]=='\n'){
            lst->palavras[lst->num_elem][tam-1]='\0';
        }

        lst->num_elem++;


    }
    fclose(f);
}

int busca_palavra(const char *palavra, struct lista_palavras lst){
    int pos = -1;

    for (int i=0;i<lst.num_elem;i++){
        if (strcmp(palavra,lst.palavras[i])==0){
            return i;
        }
    }
    return pos;
}

void insere_indice_palavras(struct indice *indice, char *palavra, int lin, int col){

    int i = 0;
    int cmp ;

    for (i=0; i<indice->num_elem && (cmp = strcmp(indice->entrada[i].palavra,palavra)<0);i++);

    if (cmp==0){return;}

    for (int j = indice->num_elem;j>i;j--){
            indice->entrada[j] = indice->entrada[j-1];
        }

    indice->num_elem++;

}


int eh_caracter_valido(char c){
    return c!=' ' && c!='.' && c!='\n';
}

int get_palavra(char *linha, char *palavra, int *col, int *pos){
    int i = 0;

    //pula espaços e pontuação
    while (linha[*pos]!='\0' && !eh_caracter_valido(linha[*pos])){
        (*pos)++;
    }
    *col = *pos;

    // copia os caracteres validos para uma palavra
    while (linha[*pos]!='\0'){
        if (eh_caracter_valido(linha[*pos])){
            palavra[i] = linha[*pos];
            (*pos)++;
            i++;
        }
        else{
            break;
        }
    }

    if(i>0){
        palavra[i] = '\0';
    }

    return i;
}

void criar_indice(char *nome_arq, struct indice *indice_palavras, struct lista_palavras palavras){
    FILE *f;
    char linha[TAM_MAX_LINHA];
    char palavra[TAM_MAX_PALAVRA];

    f = fopen(nome_arq,"r");

    if (!f){return;}

    int lin = 0;

    while(le_linha(f,linha,TAM_MAX_LINHA)>0){

        printf("%d %s",lin,linha);

        int pos=0;
        int col=0;
        
        while(get_palavra(linha,palavra,&col,&pos)){
            if (busca_palavra(palavra,palavras)!=-1){
                //printf("%s %d %d\n",palavra,lin+1,col+1);
                insere_indice_palavras(indice_palavras,palavra,lin,col);
            }
        }
        lin++;
    }

    fclose(f);
}

void imprimir_indices(struct indice *indice_palavras){

    for (int i=0;i<indice_palavras->num_elem;i++){
        printf("%s lin:%d col:%d\n",indice_palavras->entrada[i].palavra,indice_palavras->entrada[i].lin,indice_palavras->entrada[i].col);
    }


}

int main()
{

    struct lista_palavras palavras;
    struct indice indice_palavras;

    ler_arq_palavras("palavras.txt",&palavras);
    criar_indice("texto.txt",&indice_palavras,palavras);

    return 0;
}
