#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#define NOMEFILE "c:\\windows\\desktop\\pippo.txt"

typedef struct lista
  {
  char nome[11];
  int valore;
  struct lista *next;
  } lista;

lista *testa=0;

void recupera ();
void inserisciintesta (char*, int);
void inserisciincoda (char*, int);
void visualizza ();
int conta ();
void salva ();
void ribalta ();
void spaccalista ();
void eliminapernumero (int);
void ordinapernumero ();
void ordinapernome ();

void main ()
  {
  char scelta=' ', stringa[11];
  int num,c;

  recupera();

  while (scelta!='X' && scelta!='x')
    {
    clrscr();
    c=conta();
    printf ("Elementi in lista: %d\n\n",c);
    visualizza();

    printf ("\nT - Inserisci in testa.              ");
    printf ("O - Ordina per nome.");
    printf ("\nC - Inserisci in coda.               ");
    printf ("N - Ordina per numero.");
    printf ("\nE - Elimina per numero.              ");
    printf ("\nR - Ribalta la lista.                ");
    printf ("\nD - Distruggi la lista.              ");
    printf ("\nX - Uscita.\n");

    scanf ("%c*c",&scelta);
    switch (scelta)
      {
      case 'o': case 'O':
      ordinapernome();
      break;
      case 'n': case 'N':
      ordinapernumero();
      break;
      case 'e': case 'E':
      printf ("Valore: ");
      scanf ("%d", &num);
      eliminapernumero(num);
      break;
      case 'D': case 'd':
      spaccalista();
      break;
      case 'r': case 'R':
      ribalta();
      break;
      case 't': case 'T': case 'c': case 'C':
      printf ("\nNome: ");
      scanf ("%10s", stringa);
      printf ("Valore: ");
      scanf ("%d", &num);
      if (scelta=='t' || scelta=='T')
	inserisciintesta (stringa, num);
      else
	inserisciincoda (stringa, num);
      break;
      case 'x': case 'X':
      salva();
      }
    }
  }

void recupera ()
  {
  FILE *fp;
  char s[11];
  int n,c,i;

  if (fp=fopen(NOMEFILE, "r"))
    {
    fscanf (fp,"%d",&c);
    for (i=1;i<=c;i++)
      {
      fscanf (fp, "%s", s);
      fscanf (fp, "%d", &n);
      inserisciincoda (s,n);
      }
    }
  }

void inserisciintesta (char *s, int n)
  {
  int j;
  lista *punta;

  if (!(punta=(lista*)malloc(sizeof(lista))))
    exit (1);

  punta->next=testa;
  testa=punta;
  punta->valore=n;
  for (j=0;j<=10;j++)
    *(punta->nome+j)=*(s+j);
  }

void inserisciincoda (char *s, int n)
  {
  int j;
  lista *punta, *p;

  if (!(punta=(lista*)malloc(sizeof(lista))))
    exit (1);
  punta->valore=n;
  for (j=0;j<=10;j++)
    *(punta->nome+j)=*(s+j);
  punta->next=0;
  if (!testa)
    testa=punta;
  else
    {
    for (p=testa;p->next;p=p->next);
    p->next=punta;
    }
  }

void visualizza ()
  {
  lista *punta=testa;
  int c=(int)(conta()/14)+1, i;

  for (i=1;punta;i++)
    {
    printf ("%-10s\t %d\t\t",punta->nome,punta->valore);
    if (!(i % c))
      printf ("\n");
    punta=punta->next;
    }
  printf ("\n");
  }

int conta ()
  {
  lista *punta=testa;
  int j=0;

  while (punta)
    {
    j++;
    punta=punta->next;
    }
  return j;
  }

void salva()
  {
  FILE *fp;
  lista *punta=testa, *p;

  if (fp=fopen(NOMEFILE, "w"))
    {
    fprintf (fp,"%d\n",conta());
    while (punta)
      {
      fprintf (fp, "%s\n", punta->nome);
      fprintf (fp, "%d\n", punta->valore);
      p=punta;
      punta=punta->next;
      free (p);
      }
    fclose (fp);
    }
  }

void ribalta ()
  {
  lista *p=testa, *p1;
  char c=1;

  while (p)
    {
    if (c)
      {
      p=testa->next;
      testa->next=0;
      c=0;
      }
    else
      {
      p1=p->next;
      p->next=testa;
      testa=p;
      p=p1;
      }
    }
  }

void spaccalista ()
  {
  lista *p;

  while (testa)
    {
    p=testa->next;
    free(testa);
    testa=p;
    }
  }

void eliminapernumero (int n)
  {
  lista *p=testa, *prec;
  while (p)
    {
    if (p->valore==n)
      if (p==testa)
	{
	testa=testa->next;
	free (p);
	p=testa;
	}
      else
	{
	prec->next=p->next;
	free(p);
	p=prec->next;
	}
    else
      {
      prec=p;
      p=p->next;
      }
    }
  }

void ordinapernumero ()
  {
  char s;
  lista *p1, *p2;
  int n,i;

  if (testa)
    for (p1=testa;p1->next;p1=p1->next)
      for (p2=p1->next;p2;p2=p2->next)
	{
	if (p1->valore>p2->valore)
	  {
	  n=p1->valore;
	  p1->valore=p2->valore;
	  p2->valore=n;
	  for (i=0;i<=10;i++)
	    {
	    s=p1->nome[i];
	    p1->nome[i]=p2->nome[i];
	    p2->nome[i]=s;
	    }
	  }
	}
  }

void ordinapernome ()
  {
  char s;
  lista *p1, *p2;
  int n,i;

  if (testa)
    for (p1=testa;p1->next;p1=p1->next)
      for (p2=p1->next;p2;p2=p2->next)
	{
	if (strcmp(p1->nome,p2->nome)==1)
	  {
	  n=p1->valore;
	  p1->valore=p2->valore;
	  p2->valore=n;
	  for (i=0;i<=10;i++)
	    {
	    s=p1->nome[i];
	    p1->nome[i]=p2->nome[i];
	    p2->nome[i]=s;
	    }
	  }
	}
  }