// GenericModel.h: interface for the GenericModel class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_GENERICMODEL_H__0CB82D43_65B6_4F3E_AA45_D6E24E4ED571__INCLUDED_)
#define AFX_GENERICMODEL_H__0CB82D43_65B6_4F3E_AA45_D6E24E4ED571__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "ULinearAlgebra.h"	// Added by ClassView
#include "SQuadTree.h"	// Added by ClassView
#include "SBumpSensor.h"
#include "SIRSensor.h"
#include "SSonarSensor.h"
#include "SOpticalMouse.h"
#include "SShaftEncoders.h"

#include <D3D8.h>


#define REALCENTER

#define NOTQUITEONE 1.05

#define MAXSPEEDTABLE 10

/************************************************************************
* class SGenericModel  
*
* PURPOSE
* This class is the basis of the logic model and graphic model.
*************************************************************************/



class SGenericModel  
{
    


    struct MODELSTATE
    {
        #ifdef USEFLOAT
            float x,y; // position
            float dx,dy; // velocity
            float CurrAngle; // Current Angle
            float DAngle; // Angular velocity 
        #else
            double x,y; // position
            double dx,dy; // velocity
            double CurrAngle; // Current Angle
            double DAngle; // Angular velocity
        #endif  

        
    };

    struct OBJECT;

    typedef OBJECT *ObjectPtr;

    // for exlusive use in the physicalmodel to store the bounds to the model
    struct OBJECT
    {
        FPoint start,end;
        int renderflag;
        int objectID;
        int objectColor;
        ObjectPtr Next;
        ObjectPtr RealObject; // used to link a tranformed object to the real one.
    };

    struct PHYSICALMODEL
    {
        FPoint Center;
        ObjectPtr ObjectBounds;
    };

    struct SENSORSUITE
    {
        SBumpSensor BumpSensors;
        SIRSensor IRSensors;
        SSonarSensor SonarSensor;
        SOpticalMouse OpticalMouse;
        SShaftEncoders ShaftEncoders;
    };

    struct THEMODEL
    {
        PHYSICALMODEL PhysicalModel;
        MODELSTATE ModelState;
        SENSORSUITE Sensors;
        FPoint CollisionPoint; // debug
    };

    struct MVSTRUCT
    {
        BOOL MVBlocking; // blocking state?
        BOOL TurningState; // turning state?
        BOOL FowardState; // foward state?
        int TurningTicksLeft; // how many ticks left to turn
        int FowardTicksLeft; // how many ticks left to go straight
        short KRNLTicks; // had to put it somewhere        
    };

  
public:
	float SimMultiplier;


    struct DFPoint
    {
        FPoint Point1;
        FPoint Point2;
    };
    // directX rendering functions
	ObjectPtr DirectXEnumPtr;
	BOOL DirectXEnum(DFPoint &TwoPoints);
	void DirectXSetupEnum(FPoint RenderModelCenter);

    // debug what else
	int Debug1;

    // part of the robot API
	MVSTRUCT MVStruct;
	BOOL MVIsBlocking();
    int AngleTable[MAXSPEEDTABLE];
	void MVGoFowardWA(char speed, char angle);
	short KRNLGetTicks();
	void MVReset();
    void MVTurn(short Ticks);
	void MVAllStop();
    void MVGoFoward(char Speed);	
	void MVGoFowardT(char Speed ,short Ticks);

	LARGE_INTEGER StartTime;
	LARGE_INTEGER Frequency;
	unsigned long KRNLGetTicksL();

    // to synconize with the real robot
    int SpeedTable[MAXSPEEDTABLE];

    // when the user tries to move the robot to make sure it is moved in a valid location
	BOOL UDoSafetyCheck(CPoint NewCoords);
	
	
    // updates the sensors and position
	void RSUpdateSonarSensor(float TimeElapse);
	void RSUpdateBumpSensors();
    void RSUpdateIRSensors();
	void RSUpdatePosition(float TimeElapse);

    // pointer to the map
	SQuadTree *MapPtr;

    // manuall movement
	void InputfromKeyboard(UINT nChar);
    // called to run the simulation
	void RunSimulation(float TimeElapse);

    // standard linear algebra class
	ULinearAlgebra LAUtils;

    // utitlity functions
	ObjectPtr UGetRotatedBounds(); // performs rotation/translation of an objects
    ObjectPtr UGetRotatedBounds(FPoint RenderModelCenter); // performs rotation/translation of an objects
    void UAdjustforCenter(); // used to center a model when first loaded

    // the function that renders the model on the screen
	void RenderGDI(CDC &MemDC, FRect Quad, CRect Screen, float SRScale, FPoint RenderModelCenter);

    // the one and only model
	THEMODEL TheModel;

    // used to load a model from a mapper file
	void FileChartoLong(long &toRecieve, unsigned char *&ptr);
	void FileLoadModel(CString FileName);

	SGenericModel();
	virtual ~SGenericModel();

    void _Destruct();
	void _Construct();

};

#endif // !defined(AFX_GENERICMODEL_H__0CB82D43_65B6_4F3E_AA45_D6E24E4ED571__INCLUDED_)
