/*
  car.c: C equivalent of:

  implementation class Car;
  void method addfuel( double fuel ) { // add fuel litres to the fuel tank.
      assert fuel >= 0;
      assert fuel_cur >= 0 && fuel_cur <= fuel_max;
      fuel_cur += fuel;
      fuel_cur = fuel_max if fuel_cur > fuel_max;
  }
  void method print() {             // redefine how to display this car
      printf( "Car( " );
      printf( "%s: pos:%OBJ, dir:%OBJ", name, pos, dir );
      printf( ", speed:%g, people: %d (max:%d)", speed, people_cur, people_max );
      printf( ", wheels:%d, fuel:%g (max %g)", wheels, fuel_cur, fuel_max );
      printf( " )" );
  }
*/

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

#include "vector2.h"
#include "vehicle.h"
#include "car.h"

// methods

static void addfuel( Car this, double fuel ) { // add fuel litres to the fuel tank.
        assert( fuel >= 0 );
        double max = this->fuel_max;
        assert( this->fuel_cur >= 0 && this->fuel_cur <= max );
        this->fuel_cur += fuel;
        if( this->fuel_cur > max ) this->fuel_cur = max;
}

static void print( Car this ) {               // redefine how to display this car
	printf( "Car( " );
	printf( "%s: pos:", this->name );
	OM0( this->pos, print );
	printf( ", dir:" );
	OM0( this->dir, print );
	printf( ", speed:%g, people: %d (max:%d)",
		this->speed, this->people_cur, this->people_max );
        printf( ", wheels:%d, fuel:%g (max %g)",
		this->wheels, this->fuel_cur, this->fuel_max );
	printf( " )" );
}

Car new_Car( char * name, Vector2 pos, Vector2 dir, double speed, int people_cur, int people_max, int wheels, double fuel_cur, double fuel_max ) {
	Car  c = alloc_Car();
	init_Car( c, name, pos, dir, speed, people_cur, people_max, wheels, fuel_cur, fuel_max );
	return c;
}

void init_Car( Car c, char * name, Vector2 pos, Vector2 dir, double speed, int people_cur, int people_max, int wheels, double fuel_cur, double fuel_max ) {
	// set "vehicly" bits up
	init_Vehicle( (Vehicle)c, name, pos, dir, speed, people_cur, people_max );
	// now set "car"ry bits up (overriding the print method)
	c->isa       = "Car";
	c->wheels    = wheels==-1 ? 4 : wheels;
	c->fuel_cur  = fuel_cur==-1 ? 0 : fuel_cur;
	c->fuel_max  = fuel_max;
	c->addfuel   = &addfuel;
	c->print     = &print;
}

Car alloc_Car( void ) {
	Car c = (Car) malloc( sizeof(struct Car) );
	assert( c != NULL );
	return c;
}
