/***************************************************************************

    file                 : driver.h
    created              : Sun Jul 28 11:04:45 CET 2003
    copyright            : (C) 2003 Paul Bain

 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#ifndef _DRIVER_H_
#define _DRIVER_H_

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

#include <tgf.h>
#include <track.h>
#include <car.h>
#include <raceman.h>
#include <robottools.h>
#include <robot.h>

#include "linalg.h"
#include "opponent.h"
#include "pit.h"

class Opponents;
class Opponent;
class Pit;

class Driver {
    public:
        Driver(int index);
	~Driver();

        /* callback functions called from TORCS */
        void initTrack(tTrack* t, void *carHandle,
                       void **carParmHandle, tSituation *s);
        void newRace(tCarElt* car, tSituation *s);
        void drive(tSituation *s);
        int pitCommand(tSituation *s);
        void endRace(tSituation *s);
        
	tCarElt *getCarPtr() { return car; }
        tTrack *getTrackPtr() { return track; }
        float getSpeed() { return speed; }

	float fuelperlap;  /* fuel consumption per lap */
	float stops;       /* Number of pitstops to be taken this race */

 private:
        /* utility functions */
        bool isStuck();
        void update(tSituation *s);
	float getAllowedSpeed(tTrackSeg *segment);
	float getAccel();
	float getBrake();
	float getDistToSegEnd();
	int getGear();
	float critDistance(float higherspeed, float lowerspeed, float friction);
	void initCa();
	void initCw();
	float filterABS(float brake);
	float filterTCL(float accel);
	float filterTCL_RWD();
	float filterTCL_FWD();
	float filterTCL_4WD();
	void initTCLfilter();
	float getSteer();
        v2d getTargetPoint();
	float filterTrk(float accel);
	float FrontCollisionFilter(float brake);
	float GetSpeedOnTrack();
	float SideCollisionFilter(float steer);
	float getOvertakeOffset();
        float filterBPit(float brake);

        /* per robot global data */
        int stuck;
        float trackangle;
        float angle;
	float brake;
	float accel;
	float mass;        /* mass of car + fuel */
	tCarElt *car;      /* pointer to tCarElt struct */
	float CARMASS;     /* mass of the car only */
	float CA;          /* aerodynamic downforce coefficient */
	float CW;          /* aerodynamic drag coefficient */
	float speed;       /* speed in track direction */
	float myoffset;    /* overtake offset sideways */
	float currentspeedsqr;
	/*float fuellevel;
	int lapno;
	float fuelused[50];*/
	Opponents *opponents;
        Opponent *opponent;
        Pit *pit;

        /* data that should stay constant after first initialization */
        int MAX_UNSTUCK_COUNT;
        int INDEX;
	float (Driver::*GET_DRIVEN_WHEEL_SPEED)();
	float TCL_SLIP_VALUE;
	float ABS_SLIP_VALUE;

        /* class constants */
        static const float MAX_UNSTUCK_ANGLE;
        static const float UNSTUCK_TIME_LIMIT;
	static const float G;
	static const float FULL_ACCEL_MARGIN;
	static const float BRAKE_INCREMENT;
	static const float ACCEL_INCREMENT;
	static const float SHIFT;
        static const float SHIFT_MARGIN;
	static const float ABS_MINSPEED;
	static const float TCL_MINSPEED;
	static const float LOOKAHEAD_CONST;
        static const float LOOKAHEAD_FACTOR;
	static const float WIDTHDIV;
	static const float MAX_UNSTUCK_SPEED;
	static const float MIN_UNSTUCK_DIST;
	static const float SIDECOLL_MARGIN;
	static const float BORDER_OVERTAKE_MARGIN;
	static const float OVERTAKE_OFFSET_INC;
	static const float FUEL_PER_LAP;
        static const float PIT_LOOKAHEAD;
        static const float PIT_BRAKE_AHEAD;
        static const float PIT_MU;
	static const float MIN_SIDE_CLEARANCE;

        /* track variables */
        tTrack* track;
};

#endif // _DRIVER_H_
