/*
 * Rubik's clock.
 *
 * This file is public domain, I just hate copy[left/right]s.
 *-------------
 * the load/save handling stuff include file
 */

#include "save.h"

#include <stdio.h>
#include <ctype.h>

#include "clock.h"
#include "version.h"

/* a void line begins with # or is really void (ie only '\n' or full of space chars), EOF ends the function */
static void remove_void_lines(FILE *f)
{
  while (1) {
    int d=getc(f);
    if (d==EOF)
      return;
    if (isspace(d))
      continue;
    if (d=='#') {
      while ((d=getc(f))!='\n' && d!=EOF);
      continue;
    }
    ungetc(d, f);
    return;
  }
}

/* return -1 on error 0 otherwise */
int load(char *file, CLOCK *c)
{
  int new[2][3][3];
  int i, j;

  FILE *f=fopen(file, "r");

  if (!f) {
    /* this perror is wrong, because we might have no file to load the first time we run rubiclox */
    /* perror("load.c : load error 1 "); */
    return -1;
  }

  for (i=0; i<3; i++)
    for (j=0; j<3; j++) {
      remove_void_lines(f);
      if (fscanf(f, "%d", &new[0][j][i])!=1) {
	fprintf(stderr, "load.c : load error 2, sorry but your saved file seems wrong\n");
	return -1;
      }
      if (new[0][j][i]<0 || new[0][j][i]>11) {
	fprintf(stderr, "load.c : bad clock 1 value (%d)\n", new[0][j][i]);
	return -1;
      }
    }

  for (i=0; i<3; i++)
    for (j=0; j<3; j++) {
      remove_void_lines(f);
      if (fscanf(f, "%d", &new[1][j][i])!=1) {
	fprintf(stderr, "load.c : load error 3, sorry but your saved file seems wrong\n");
	return -1;
      }
      if (new[1][j][i]<0 || new[1][j][i]>11) {
	fprintf(stderr, "load.c : bad clock 2 value (%d)\n", new[1][j][i]);
	return -1;
      }
    }

  /* check clock corner */
  if (new[1][0][2] != (12-new[0][2][2])%12 ||
      new[1][2][2] != (12-new[0][0][2])%12 ||
      new[1][0][0] != (12-new[0][2][0])%12 ||
      new[1][2][0] != (12-new[0][0][0])%12) {
    fprintf(stderr, "load.c : bad clock corner value\n");
    return -1;
  }

  /* we modify the clocks only if no bugs in the file, isn't it clever, huh ? (no, it's logic) well, hum... ok */
  /* I could do a memcpy, but I prefer this way, the types are not sure to be the same */
  for (i=0; i<3; i++)
    for (j=0; j<3; j++)
      c->face[0][i][j]=new[0][i][j];
  for (i=0; i<3; i++)
    for (j=0; j<3; j++)
      c->face[1][i][j]=new[1][i][j];

  return 0;
}

/* return -1 on error 0 otherwise */
int save(char *file, CLOCK *c)
{
  /* should check the fprintf return values, but it's a bit tricky, I don't know how to do, anyway does someone
   * do that ? */
  int i, j;

  FILE *f=fopen(file, "w");

  if (!f) {
    perror("save.c : save error 1 ");
    return -1;
  }

  fprintf(f, "#" NAME " " VERSION " data file\n" "#the face one\n");

  for (i=0; i<3; i++) {
    for (j=0; j<3; j++)
      fprintf(f, "%2d ", c->face[0][j][i]);
    fprintf(f, "\n");
  }

  fprintf(f, "#the face two\n");
  for (i=0; i<3; i++) {
    for (j=0; j<3; j++)
      fprintf(f, "%2d ", c->face[1][j][i]);
    fprintf(f, "\n");
  }

  if (fclose(f)==EOF) {
    perror("save.c : save error 2 ");
    return -1;
  }

  return 0;
}
