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

struct contato {
    char *nome;
    char endereco[50];
    int telefone;
    char email[30];
};
typedef struct contato Contato;

void listar_contatos(Contato *v, int q) {
    int i;
    for (i=0; i<q; i++) {
        printf("\nContato %d => %s|%s|%d|%s \n", i+1,
               v[i].nome,v[i].endereco,v[i].telefone,v[i].email);
    }
}

int pesquisar_nome(Contato *v, int q, char *nome) {
    int i;
    for (i=0; i<q; i++) {
        if (strcmp(v[i].nome,nome)==0) {
            printf("\nEncontrado: Contato %d => %s|%s|%d|%s \n", i+1,
                   v[i].nome,v[i].endereco,v[i].telefone,v[i].email);
            return 0;
        }
    }
    printf("\nContato nao encontrado!\n");
    return 1;
}

int pesquisar_telefone(Contato *v, int q, int telefone) {
    int i;
    for (i=0; i<q; i++) {
        if (v[i].telefone == telefone) {
            printf("\nEncontrado: Contato %d => %s|%s|%d|%s \n", i+1,
                   v[i].nome,v[i].endereco,v[i].telefone,v[i].email);
            return 0;
        }
    }
    printf("\nContato nao encontrado!\n");
    return 1;
}

int conta_linhas(char *filename) {
    FILE *fp = fopen(filename,"rt");
    int ch = 0, nLinhas = 0;

    if (fp == NULL) return 0;

    nLinhas++;
    while ((ch = fgetc(fp)) != EOF) {
        if (ch == '\n')
            nLinhas++;
    }
    fclose(fp);
    return nLinhas;
}

int carregar_do_arquivo(Contato *v, char *nomeArq) {
    FILE *fp = fopen(nomeArq, "r");
    if (fp == NULL) return 0;
    int q = conta_linhas(nomeArq);
    printf("\nArquivo tem %d linhas.", q);
    int i;
    for (i=0; i<(q-1)/4; i++) {
        v[i].nome =  (char *) malloc(sizeof(char)*50);
        fscanf(fp, " %50[^\n]%*c", v[i].nome);

        fscanf(fp, " %50[^\n]%*c", v[i].endereco);

        fscanf(fp, "%d\n", &(v[i].telefone));

        fscanf(fp, " %30[^\n]%*c", v[i].email);
    }

    fclose(fp);
    return ((q-1)/4);
}

void cadastrar_novo_contato(Contato *v, int *q) {
    if (*q >= 50)
        printf("\nNao eh possivel cadastrar novo contato. Lista ja atingiu limite.\n");
    else {
        printf("\nNovo contato - digite nome: ");
        // alocacao dinamica do nome
        v[*q].nome = (char *) malloc(sizeof(char)*50);
        scanf(" %50[^\n]%*c", v[*q].nome);

        printf("\nNovo contato - digite endereco: ");
        scanf(" %50[^\n]%*c", v[*q].endereco);

        printf("\nNovo contato - digite telefone: ");
        scanf("%d", &(v[*q].telefone));

        printf("\nNovo contato - digite email: ");
        scanf(" %30[^\n]%*c", v[*q].email);

        (*q)++;
    }
}

void remover_contato(Contato *v, int *q, char *nome) {
    int i, achou = 0;
    for (i=0; i<(*q); i++) {
        if (strcmp(v[i].nome,nome) == 0 && achou == 0) {
            achou = 1;
        } else if (achou == 1 && i > 0) { // move todos que vem depois uma posicao antes
            v[i-1].nome = v[i].nome;
            strcpy(v[i-1].endereco, v[i].endereco);
            v[i-1].telefone = v[i].telefone;
            strcpy(v[i-1].email, v[i].email);
        }
    }
    if (achou == 1) {
        printf("\nContato removido com sucesso!\n");
        (*q)--;
    } else {
        printf("\nContato nao encontrado!\n");
    }
}

void salvar_em_arquivo(Contato *v, int q, char *nomeArq) {
    FILE *fp = fopen(nomeArq, "w");
    if (fp == NULL) return;
    int i;
    for (i=0; i<q; i++) {
        fprintf(fp, "%s\n", v[i].nome);
        fprintf(fp, "%s\n", v[i].endereco);
        fprintf(fp, "%d\n", v[i].telefone);
        fprintf(fp, "%s\n", v[i].email);
    }
    fclose(fp);
}

int main(void) {
    Contato vContatos[50]; // vetor de contatos
    int quant = 0; // tamanho do vetor de contatos (inicialmente 0)

    int opcao;
    char nome[50];
    int telefone;
    char nomeArq[50];
    do {
        printf("\nEscolha uma opcao:");
        printf("\n1 - Listar contatos");
        printf("\n2 - Pesquisar por nome");
        printf("\n3 - Pesquisar por telefone");
        printf("\n4 - Carregar contatos de arquivo");
        printf("\n5 - Adicionar novo contato");
        printf("\n6 - Remover um contato existente");
        printf("\n7 - Salvar em arquivo");
        printf("\n8 - Sair\n=> ");
        scanf("%d", &opcao);
        switch (opcao) {
        case 1:
            listar_contatos(vContatos, quant);
            break;
        case 2:
            printf("\nDigite o nome desejado: ");
            scanf(" %50[^\n]%*c", nome);
            pesquisar_nome(vContatos, quant, nome);
            break;
        case 3:
            printf("\nDigite o telefone desejado: ");
            scanf("%d", &telefone);
            pesquisar_telefone(vContatos, quant, telefone);
            break;
        case 4:
            printf("\nNome do arquivo: ");
            scanf(" %50[^\n]%*c", nomeArq);
            quant = carregar_do_arquivo(vContatos, nomeArq);
            break;
        case 5:
            cadastrar_novo_contato(vContatos, &quant);
            break;
        case 6:
            printf("\nDigite o nome desejado: ");
            scanf(" %50[^\n]%*c", nome);
            remover_contato(vContatos, &quant, nome);
            break;
        case 7:
            printf("\nNome do arquivo: ");
            scanf(" %50[^\n]%*c", nomeArq);
            salvar_em_arquivo(vContatos, quant, nomeArq);
            break;
        case 8:
            printf("\nTchau!\n");
            break;
        default:
            printf("\nOpcao invalida. Tente novamente.\n");
        }
    } while (opcao != 8);

    system("pause");
    return 0;
}