/**************************************************************
This program reads a binary files to manipulate customer records
creates new data to be placed in the file, and deletes data
already in the file.
***************************************************************/

#include <stdio.h>
#include <string.h>

/***************************************************************
Define structure for customer records.
***************************************************************/

struct customer
{
   char   name[30];
   char   account[10];
   float  balance;
   float  credits;
};

typedef struct customer Customer;

int   enterChoice   (void);
long  search        (FILE *,char[]);
int   insert        (FILE *,Customer *);
int   delete        (FILE *,char[]);
void  clean         (FILE *);
void  List_Customer (FILE *);


int main()
{
   FILE *fptr;      /* file pointer to data45.dat */
   Customer x;
   int choice;
   long k;
   char id[10];

   if ((fptr=fopen("data.dat","rb+"))==NULL)
      printf("File could not be opened.\n" );
   else {

      while ((choice=enterChoice())!=6)
      {
	 switch ( choice ) {
	    case 1:
	    {
	      printf("\nEnter account to find offset account : \n");
	      scanf("%s",id);
	      k=search(fptr,id);
	      if (k!=-1)
		printf("\nThe the offset of account you entred = %ld \n",k);
	      else
		printf("\nThe account not found in file. \n");
	     }
	       break;
	    case 2:
	    {
	      printf("\nEnter record to add at end of file : \n");
	      printf("\nEnter name \n");
	      scanf("%s",x.name);
	      printf("Enter account \n");
	      scanf("%s",x.account);
	      printf("Enter balance \n");
	      scanf("%f",&x.balance);
	      printf("Enter credits \n");
	      scanf("%f",&x.credits);

	      k=insert(fptr,&x);
	      if (k==0)
		printf("\nThe the record add to end of file. \n");
	      else
		printf("\nThe record not add at end of file. \n");
	    }
	       break;
	    case 3:
	    {
	      printf("\nEnter account to marked as unused : \n");
	      scanf("%s",id);
	      k=delete(fptr,id);
	      if (k==1)
		printf("\nThe the account you entred has marked by ''X''. \n");
	      else
		printf("\nThe account not found in file. \n");
	     }
	       break;
	    case 4:
	       clean(fptr);
	       break;
	    case 5:
	       List_Customer(fptr);
	       break;
	 }
      }
      fclose(fptr);
   }
   return 0;
}

/***************************************************************
This function menu of program.
***************************************************************/

int enterChoice( void )
{
   int menuChoice;

   printf( "\nEnter your choice : \n"
      "1 - To search offset of any record. \n"
      "2 - To add record to end of file. \n"
      "3 - To mark unused record. \n"
      "4 - To delete unused record. \n"
      "5 - To print all customer record. \n"
      "6 - To end program.\n? " );

   scanf("%d",&menuChoice);

   return menuChoice;
}

/***************************************************************
This function retur offset of record entered by user.
***************************************************************/

long search (FILE *fptr,char cID[10])
{
  Customer x;
  long k,flag=0,i=0;

  rewind(fptr);
  while (!feof(fptr)&&!flag)
  {
    fread(&x,sizeof(Customer),1,fptr);
    if (strcmp(cID,x.account)==0)
    {
      flag=1;
      i++;
      k=(i-1)*sizeof(Customer);
    }
    i++;
  }

  if (flag)
    return k;
  else
    return -1;
}

/***************************************************************
This function insert record at end of file if not found in file.
***************************************************************/

int insert (FILE *fptr,Customer *s)
{
  Customer x;
  int flag=0,i=0;

  rewind(fptr);

  while (!feof(fptr)&&!flag)
  {
    fread(&x,sizeof(Customer),1,fptr);
    if (strcmp(x.account,s->account)==0)
      flag=1;
    i++;
  }
  if (flag==0)
  {
    fseek(fptr,(i-1)*sizeof(Customer),SEEK_SET);
    fwrite(s,sizeof(Customer),1,fptr);
    return 0;
  }
  else
    return 1;
}

/*******************************************************************
This function mark any records "X" entred by user if found in file.
*******************************************************************/

int delete (FILE *fptr,char sID[10])
{
  Customer x;
  int flag=0,i=0;

  rewind(fptr);

  while (!feof(fptr)&&!flag)
  {
    fread(&x,sizeof(Customer),1,fptr);
    if (strcmp(sID,x.account)==0)
    {
      strcpy(x.account,"X");
      flag=1;
    }
    i++;
  }
  if (flag==1)
  {
    fseek(fptr,(i-1)*sizeof(Customer),SEEK_SET);
    fwrite(&x,sizeof(Customer),1,fptr);
    return 1;
  }
  else
    return 0;
}

/**********************************************************************************
This function delete all customer records marks "X" as unused from function delete
************************************************************************************/

void clean (FILE *fptr)
{
   FILE *newPtr;
   Customer x,y;

   if ((newPtr=fopen("copy.dat", "wb"))==NULL)
      printf( "File could not be opened.\n" );
   else
   {
      rewind(fptr);
      while (!feof(fptr))
      {
    /* Copy to another file with out record marked by "X" */
	fread(&x,sizeof(Customer),1,fptr);
	if (strcmp(x.account,"X")!=0 && (!feof(fptr)))
	fwrite(&x,sizeof(Customer),1,newPtr);
      }
      fclose(newPtr);
      fclose(fptr);
   }

   if ((fptr=fopen( "data.dat", "wb" ))==NULL)
     printf("File could not be opened.\n");
   else
   {
     if ((newPtr=fopen("copy.dat","rb"))==NULL)
       printf("File could not be opened.\n");
     else
     {
       fread(&y,sizeof(Customer),1,newPtr);
       while (!feof(newPtr))
       {
	 fwrite(&y,sizeof(Customer),1,fptr);
	 fread(&y,sizeof(Customer),1,newPtr);
       }
       fclose(newPtr);
       fclose(fptr);
     }
   }
   if ((fptr=fopen("data.dat","rb+"))==NULL)
   printf("File could not be opened.\n" );
}

/***************************************************************
This function prints all customer records.
***************************************************************/

void List_Customer (FILE *fptr)
{
  Customer x;

  printf("\n             The Records in FILE  \n");
  printf("           ========================== \n\n");
  printf("%-10s%-15s%-16s%s\n","name","account","balance","credit");
  printf("%-10s%-15s%-16s%s\n","====","=======","=======","======");
  rewind(fptr);
  fread(&x,sizeof(Customer),1,fptr);
  while (!feof(fptr))
  {
    printf("%-10s%-15s%-16.2f%.2f\n",x.name,x.account,x.balance,x.credits);
    fread(&x,sizeof(Customer),1,fptr);
  }
}










