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

// define a estrutura do no
struct _no {
  char nome[40];
  float preco;
  struct _no *proximo;
};
typedef struct _no No;

// define um ponteiro para o no raiz
No *Raiz=NULL;

void InsereNo(char *nomeitem, float precoitem) {
  No *Atual;
  No *Proximo;
  No *Inserido;

  // verifica se o nó raiz é nulo. Se for, cria nó raiz com os dados fornecidos
  if (Raiz==NULL) {
    Raiz = (No *)malloc(sizeof(No));
    strcpy (Raiz->nome,nomeitem);
    Raiz->preco = precoitem;
    Raiz->proximo = NULL;
  }
  else {  // se já houver raiz

    // percorre a lista encadeada, comecando da raiz
    Atual = Raiz;
    while (Atual->proximo!=NULL) {
      Proximo = Atual->proximo;
      Atual = Proximo;
    }

    // aloca memória para o novo nó
    Inserido = (No *)malloc(sizeof(No));
    
    // coloca o nó na lista encadeada, mudando o ponteiro para o próximo no
    // do último nó
    Atual->proximo = Inserido;
    
    // coloca dados no nó Inserido
    strcpy (Inserido->nome,nomeitem);
    Inserido->preco = precoitem;

    // indica que o nó inserido é agora o último nó
    Inserido->proximo = NULL;
  }
}

No *BuscaNo(char *nome) {
  No *Atual;
  No *Proximo;
  char *nomeatual;
 
  if (Raiz!=NULL) {  

    // percorre a lista encadeada desde a raiz
    Atual = Raiz;
    while (Atual->proximo!=NULL) {
      
      // verifica se o no atual é o nó que procuramos
      nomeatual = Atual->nome;
      if (strcmp(nomeatual,nome)==0) return Atual; // se for, retorna o no atual

      // se não for, continua
      Proximo = Atual->proximo;
      Atual = Proximo;
    }

    // se chegou ao ultimo nó e ainda não encontrou, verifica se ele é o nó
    // que procuramos
    nomeatual = Atual->nome;
    if (strcmp(nomeatual,nome)==0)
    return Atual;
  }
  
  printf ("Nao achei!\n");
  return NULL; // se não encontrou de jeito nenhum, retorna um ponteiro nulo
}

No *ApagaNo (char *nome) {
  No *Atual;
  No *Proximo;
  No *Anterior=NULL;
  char *nomeatual;

  // primeiro, efetuamos uma busca na lista encadeada
  if (Raiz!=NULL) {  

    // percorre a lista encadeada desde a raiz
    Atual = Raiz;
    while (Atual->proximo!=NULL) {
      
      // verifica se o no atual é o nó que procuramos
      nomeatual = Atual->nome;
      if (strcmp(nomeatual,nome)==0) break; // se for, pára

      // se não for, continua
      Proximo = Atual->proximo;
      // o nó Atual será o nó Anterior agora, pois vou avançar
      Anterior = Atual;
      // avança para o próximo nó
      Atual = Proximo;
    }

    // se chegou ao ultimo nó e ainda não encontrou, verifica se ele é o nó
    // que procuramos
    nomeatual = Atual->nome;
    // se não for, coloco NULL em Atual
    if (strcmp(nomeatual,nome)!=0) Atual = NULL;

    // se for o nó raiz, faço a raiz apontar para o próximo nó
    if (Atual==Raiz) {
      printf ("%s e no raiz.\n",Atual->nome);
      Raiz = Raiz->proximo;
      free(Atual);
    }
    // se não for o nó raiz, testa para ver se é o nó encontrado
    else if (Atual!=NULL) {
      Anterior->proximo = Atual->proximo;
      free(Atual);
    }
    // se não encontrou, emite mensagem de erro
    else {
      printf ("Nao achei!\n");
    }
  }
}
void ImprimeNo (No *no) {
  if (no!=NULL) {
    printf ("Nome: %s\n",no->nome);
    printf ("Preco: %.2f\n",no->preco);
  }
  else {
    printf ("No inexistente!\n");
  }
}

main () {
  No *buscado;

  printf ("Insere Banana\n");
  InsereNo ("Banana",0.85);
  printf ("Insere Laranja\n");
  InsereNo ("Laranja",1.09);
  printf ("Insere Melancia\n\n");
  InsereNo ("Melancia",1.15);

  printf ("Busca Laranja\n");
  buscado = BuscaNo ("Laranja");
  ImprimeNo (buscado);

  printf ("\nBusca Morango\n");
  buscado = BuscaNo ("Morango");

  printf ("\nApagando Banana\n");
  ApagaNo("Banana");
  printf ("Buscando Banana\n");
  buscado = BuscaNo ("Banana");

  printf ("\nApagando Melancia\n");
  ApagaNo("Melancia");
  buscado = BuscaNo ("Melancia");
  printf ("Apagando Laranja\n");
  ApagaNo("Laranja");

  printf ("\nA lista esta vazia. Sera que a variavel Raiz e NULL?\n",Raiz);
  // verifica se a Raiz é um ponteiro nulo. Se for, imprime sim, caso
  // contrário, imprime nao.
  if (Raiz==NULL)
    printf ("Sim!\n");
  else
    printf ("Nao!\n");
} 
