#include "Lib.h"

#define APPEND_BINARY "a+b"
#define FILE_NAME "starship.dat"
#define PRINT "print"
#define EXIT "exit"
#define CREATE "create"
#define UPDATE "update"

typedef struct
{
    int id;
    char name[8];
    char star_name[15];
    int age;
} alien;


// -------------------------------------------------------

/* close file */
int CloseFile(FILE * fp)
{
    return (fclose(fp));
}

/* print alien */
void PrintAlien(alien * aln)
{
    printf("ID : %d\nName : %s\nStar Name : %s\nAlien age : %d\n\n", 
            aln->id, aln->name, aln->star_name, aln->age);
}

/* get all data from file */
void GetAllDataFromFile(alien ** aln_arr)
{
    alien * aln_data;
    FILE * fp = fopen(FILE_NAME , APPEND_BINARY);
    *aln_arr = (alien *)malloc((ftell(fp) / sizeof(alien)) + (TWO * sizeof(alien)));
    aln_data = *aln_arr;
    rewind(fp);
    while (!feof(fp));
    {
        fread(aln_data, sizeof(alien), ONE, fp);
        aln_data++;
    }
    aln_data->id = ZERO;
    fclose(fp); // fix
}

/* print aliens in arr */
void PrintArrayAliens(alien * arr_alien)
{
    while (arr_alien->id != ZERO)
    {
        PrintAlien(arr_alien);
        arr_alien++;
    }
}

/* print data */
void PrintAllAlienData()
{
    alien * aliens_data;
    GetAllDataFromFile(&aliens_data);
    PrintArrayAliens(aliens_data);
    free(aliens_data);
    OutputErrorOpenReadFile();
    
}

/* write in file */
void WriteInFile(alien * aln, unsigned int location)
{
    FILE * fp = fopen(FILE_NAME , APPEND_BINARY);
    fseek(fp, (sizeof(alien) * location), SEEK_SET);
    fwrite(aln, sizeof(alien), ONE, fp);
    CloseFile(fp);
}

/* check if the alien is exists in file */
BOOLEAN ValueExistsInFile(alien * aln)
{
    alien * temp_aln = (alien *)malloc(sizeof(alien));
    FILE * fp = fopen(FILE_NAME , APPEND_BINARY);
    fseek(fp, ZERO, SEEK_SET);
    while (fread(temp_aln, sizeof(alien), ONE, fp) > ZERO && temp_aln->id != aln->id);
    CloseFile(fp);
    return (temp_aln->id == aln->id);
}

/* Get the pointer of alien in file */
unsigned int GetLocationValueInFile(alien * aln)
{
    FILE * fp;
    unsigned int count = -ONE;
    alien * temp_aln = (alien *)malloc(sizeof(alien));;
    fp = fopen(FILE_NAME , APPEND_BINARY);
    fseek(fp, ZERO, SEEK_SET);
    while (fread(temp_aln, sizeof(alien), ONE, fp) > ZERO && temp_aln->id != aln->id)
    {
        count++;
    }
    CloseFile(fp);
    return count;
}

void GetInputIdAlien(alien * aln)
{
    int id;
    printf("Enter ID: ");
    scanf("%d", &id);
    aln->id = id;
}

void GetInputNameAlien(alien * aln)
{
    printf("Enter name: ");
    scanf("%s", (aln->name));
}

void GetInputStarNameAlien(alien * aln)
{
    printf("Enter star name: ");
    scanf("%s", (aln->star_name));
}

void GetInputAgeAlien(alien * aln)
{
    int age;
    printf("Enter age: ");
    scanf("%d", &age);
    aln->age = age;
}

void GetInputUpdateAlien(alien * aln)
{
    GetInputNameAlien(aln);
    GetInputStarNameAlien(aln);
    GetInputAgeAlien(aln);
}

void GetInputAlien(alien * aln)
{
    GetInputIdAlien(aln);
    GetInputUpdateAlien(aln);
}

/* create data */
void CreateData(alien * aln)
{
    unsigned int location;
    alien temp = *aln;
    if (!ValueExistsInFile(&temp))
    {
        location = GetLocationValueInFile(aln) + ONE;
        WriteInFile(aln, location);
    }
    else
    {
        printf("The alien is exists already!\n");
    }
}

/* update data */
void UpdateData(alien * aln)
{
    if (ValueExistsInFile(aln))
    {   
        GetInputUpdateAlien(aln);
        WriteInFile(aln, GetLocationValueInFile(aln));
    }
    else
    {
        printf("The alien is not exists!\n");
    }
}


//---------------------------------------------------------------------------------------
//                                        Project
//                                        -------
//
//---------------------------------------------------------------------------------------
// Programmer : Cohen Idan
// Student No : 211675038
// Date       : 19.12.2019
//---------------------------------------------------------------------------------------
void main(void)
{
    string command = " ";
    alien aln;
    int id = ZERO;
    string exit_command = EXIT;
    string print_command = PRINT;
    string create_command = CREATE;
    string update_command = UPDATE;

    while (!StringCompare(command, exit_command))
    {
        // print request for command
        printf("Enter command (\"print\", \"create\", \"update\" and \"exit\"): ");

        // Input command
        scanf("%s", command);
        if (StringCompare(command, print_command))
        {
            PrintAllAlienData();
        }
        else if (StringCompare(command, create_command))
        {
            /* get input from user about new alien */
            /* if alien is not exists create new alien else output error */
            GetInputAlien(&aln);
            CreateData(&aln);
        }
        else if (StringCompare(command, update_command))
        {
            GetInputIdAlien(&aln);
            UpdateData(&aln);  
        }
    }
    
}