/* bin.tiedosto.esim.c */

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

#define MAXINLKM 50
#define INFLAG "-i"
#define OUTFLAG "-o"

struct hlo_hattu_rakenne {
	int hatunnumero;
	char nimi[30];
};
typedef struct hlo_hattu_rakenne *hlo_hattu;
/* hlo_hattu on siis osoitin rakenteeseen */

int lue_hlo_hattu(hlo_hattu hh);
char *suuripaisin(hlo_hattu taulu, int lkm);
int tallennahatut(char *filename, hlo_hattu taulu,
				  int lkm);
int luehatut(char *filename, hlo_hattu *taulu,
			 int *lkm);


/* luetaan tietoja joko -i tiedostosta tai
   käyttäjältä, tallennetaan -o tiedostoon,
   ei sekä -i että -o */

int main(int argc, char *argv[])
{
  int ok, n;
  hlo_hattu hhtaulu = NULL;

  if (argc == 3 && !strcmp(argv[1], INFLAG)) {

	  /* luetaan tiedot tiedostosta */

	  ok = luehatut(argv[2], &hhtaulu, &n);
	  if (! ok) {
		  printf("Luku ei onnistunut\n");
		  if (hhtaulu)
			  free(hhtaulu);
		  exit(1);
	  } else
		  printf("%d tietoa luettu.\n", n);

  } else {

	  /* luetaan käyttäjältä */

	  hhtaulu = (hlo_hattu)malloc(MAXINLKM * 
				sizeof(struct hlo_hattu_rakenne));
	  if (! hhtaulu) {
		  fprintf(stderr, "Tilanvarausvirhe\n");
		  exit(1);
	  }

	  printf("Anna hattu-henkilö -pareja, \
pienipäinen lopuksi\n");
	  for (n = 0 ; n < MAXINLKM ; n++)
		  if (! lue_hlo_hattu(&hhtaulu[n]))
			  break;
			  
  } /* if-else */

  if (argc == 3 && !strcmp(argv[1], OUTFLAG)) {

	  ok = tallennahatut(argv[2], hhtaulu, n);
	  if (! ok)
		  printf("Tallennus ei onnistunut\n");
	  else
		  printf("Tallennettu!\n");
  }

  printf("Suuripäisin on %s!\n",
		 suuripaisin(hhtaulu, n));

  free(hhtaulu);
  exit(0);
   
} /* main() */

/* Tallennetaan hatut tiedostoon, palautetaan 0
   jollei onnistunut */

int tallennahatut(char *filename, hlo_hattu taulu,
				  int lkm)
{
  FILE *htiedosto;
  int ok;

  if (! (htiedosto = fopen(filename, "wb")) )
	  return 0;

  /* kirjoitetaan tietueiden määrä */
  ok = fwrite(&lkm, sizeof(int), 1, htiedosto);

  /* kirjoitetaan tietueet */
  ok += fwrite(taulu, sizeof(struct hlo_hattu_rakenne),
			   lkm, htiedosto);

  fclose(htiedosto);

  return ok == lkm+1;
} /* tallennahatut() */
  

/* Luetaan hatut tiedostosta
   jollei onnistunut, palautetaan 0
   varataan&palautetaan tila, palautetaan lkm */

int luehatut(char *filename, hlo_hattu *taulu,
			 int *lkm)
{
  FILE *htiedosto;
  int ok, inlkm;
  hlo_hattu uusit;

  if (! (htiedosto = fopen(filename, "rb")) )
	  return 0;

  /* luetaan tietueiden määrä */
  ok = fread(&inlkm, sizeof(int), 1, htiedosto);

  if (! ok) {
	  fclose(htiedosto);
	  return 0;
  }

  uusit = (hlo_hattu)malloc(inlkm * 
				sizeof(struct hlo_hattu_rakenne));

  if (! uusit) {
	  fclose(htiedosto);
	  return 0;
  }

  ok += fread(uusit, sizeof(struct hlo_hattu_rakenne),
			  inlkm, htiedosto);

  *taulu = uusit;
  *lkm = inlkm;

  fclose(htiedosto);
  return ok == inlkm+1;
} /* luehatut() */



/* demo 24 */
char *suuripaisin(hlo_hattu taulu, int lkm)
{
  char *snimi = NULL;
  int i, suurin = 0;

  for (i = 0; i < lkm; i++)
	  if (taulu[i].hatunnumero > suurin) {
		  suurin = taulu[i].hatunnumero;
		  snimi = taulu[i].nimi;
	  }

  return snimi;
}

int lue_hlo_hattu(hlo_hattu hh)
{
  printf("Anna \"hatunnro nimi\" (esim \"57 \
Matti Meikäläinen\") : ");
  scanf("%d %29[^\n]", &hh->hatunnumero, hh->nimi);

  /* "%29[^\n]" tarkoittaa: enintään 29 merkkiä
	 kaikkia muita merkkejä paitsi rivinvaihtoa
	 (\n), ts. "rivinvaihtoon asti" */

  if (hh->hatunnumero <= 10)
	  return 0;
  else
	  return hh->hatunnumero;
} /* lue_hlo_hattu() */

/* Tiedoston sisältö:
00000002 00000039 4D617474 69204D65  .......9Matti Me
696BE46C E4696E65 6E000000 00000000  ik.l.inen.......
00000000 00000000 00000037 54657274  ...........7Tert
74752054 65696BE4 6CE4696E 656E0000  tu Teik.l.inen..
00000000 00000000 00000000           ............    
*/
