/***************************************************************************
 *  Columbia University Introduction to Computer Programming in C COMS 1003
 *  A car reservation system to demonstrate the use of malloc() and free()
 *
 *  Copyright (C) 2005 Michael E. Locasto
 *
 *  All rights reserved.
 *
 * $Id: carorder.c,v 1.1 2005/11/15 00:49:33 locasto Exp $
 **************************************************************************/

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


#define   MAX_CARS   100

/* import errno from the standard library errno.h */
extern int errno;

/* define a car type */
enum cartype {SUV, COMPACT, SEDAN, SPORTSCAR, F1, JEEP, MINIVAN};

/**
 * Define a template for a car type. 
 */
struct car
{
   long         id;
   char         *make;
   char         *model;
   int          year;
   int          seats;
   enum cartype category;
   long         mileage;
   float        price_per_day;
   int          is_rented;
};

/* define a pointer to the struct car type as car_t */
typedef struct car *car_t;

/* The global array of cars that are in existence. Note that this is
 * an array of pointers to the 'struct car' type.
 */
car_t car_pool[MAX_CARS];

/* Define some strings to be placed in the make member of struct car*/
char* makes[] = {"Honda", "Chevrolet", "GM", "Ford", "Toyota", "Porsche"};


/* Function Prototypes */

//------------------------------------ agency actions

car_t    createcar(char*, char*, int, int, enum cartype, long, float);
long     destroycar(car_t);
car_t    lookupcar(long);
void     savecarlist();
void     printcar(car_t);

//------------------------------------ customer actions

car_t    rentcar(long);
car_t    reservecar(enum cartype);
long     returncar(car_t);

car_t
createcar(char* make, char* model, int year, int seats, enum cartype category, 
          long mileage, float price_per_day)
{
   car_t temp_car = NULL;
   temp_car = (car_t)malloc(sizeof(struct car));
   if(NULL==temp_car)
   {
      //print diagnostic error
      perror("createcar()");
      fprintf(stderr,"could not create car, out of memory");
      return NULL;
   }
   temp_car->make = make;
   temp_car->model = model;
   temp_car->year = year;
   temp_car->seats = seats;
   //XXX do sanity checking on category !!!
   //switch(category){}
   temp_car->category = category;
   temp_car->mileage = mileage;
   temp_car->price_per_day = price_per_day;
   temp_car->is_rented = 0; //FALSE
   return temp_car;
}

/**
 * Free the memory associated with a car.
 * This routine, as written, potentially leaks memory. Why?
 * Think about the object that is passed in.
 */
long destroycar(car_t target_car)
{
   long id = 0L;
   if(NULL==target_car)
      return id;
   id = target_car->id;
   free(target_car);
   target_car = NULL;
   return id;
}

/**
 * A program for dealing with car orders.
 * Expects that all existing cars are stored in
 * cars.dat in the local directory.
 */
int main(int argc, char* argv[])
{
   car_t mycar = NULL;
   //struct car *some_car = NULL;

   char* command = NULL;

   command = (char*)malloc(80*sizeof(char)+1);
   if(NULL==command)
   {
      fprintf(stderr,"could not allocate memory for command");
      perror("allocating command");
      free(command);
      command=NULL;
   }else{
      printf("sizeof(char) = %d\n",sizeof(char));
      printf("sizeof(*char) = %d\n",sizeof(char*));
      printf("sizeof(command) = %d\n",sizeof(command));
      printf("sizeof(*command) = %d\n",sizeof(*command));
      printf("strlen(command) = %d\n",strlen(command));
      free(command);
      command=NULL;
   }

   printf("\n ---\n");

   //why is this statement wrong?
   //mycar = (car_t)malloc(sizeof(car_t));
   mycar = (car_t)malloc(sizeof(struct car));
   if(NULL==mycar)
   {
      // errno should be set to ENOMEM by malloc() for us already...
      fprintf(stderr,"could not allocate memory for car instance.\n");
      perror("allocating car instance");
      exit(-1);
   }

   mycar->id = 56689;
   mycar->category = SPORTSCAR;
   mycar->make = makes[1];
   mycar->model = "Corvette Z06";
   mycar->year = 2006;
   mycar->seats = 2;
   mycar->mileage = 6000;
   mycar->price_per_day = 199.95;
   mycar->is_rented = 1; //true

   car_pool[0] = mycar;
   
   printf("sizeof(car_pool) = %d\n", sizeof(car_pool));
   printf("sizeof(car_t) = %d\n", sizeof(car_t));
   printf("sizeof(struct car) = %d\n", sizeof(struct car));
   printf("sizeof(mycar) = %d\n", sizeof(mycar));
   printf("sizeof(*mycar) = %d\n", sizeof(*mycar));

   free(mycar);
   mycar = NULL;

   exit(0);
}
