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

#if !defined(AFX_UQUADTREE_H__3E7EA700_44AA_438A_8727_6AFA29D404EC__INCLUDED_)
#define AFX_UQUADTREE_H__3E7EA700_44AA_438A_8727_6AFA29D404EC__INCLUDED_

#include "uIDList.h"	// Added by ClassView
#include "math.h"
#include "ULinearAlgebra.h"	// Added by ClassView

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

#define WM_SAVE_STATE (WM_USER + 10)

// bounds
#define  QUADYSTART 1
#define  QUADXSTART 1
#define  QUADXBOUND 128 // 128
#define  QUADYBOUND 128 // 128
#define QUAD 4
// object types
#define LINE 1
#define ARCLINE 2

// sensor types
#define BUMPSENSOR 3
// the bump sensor consists of
// the display point (the middle point)
// the start and end bounds of it range (start and end point)
#define IRSENSOR 4
// the IR sensor consists of
// the display/originating beam point (the middle point)
// the range minimum and maximum (start.x and start.y)
// the angle (end.x)
#define SONARSENSOR 5
// the sonar simply consists of the display point (middle)
#define ROOF3D 6 // Create a line that is for the rendering version of a 3D triangle
#define TRIANGLE3D 7 // non 2D renderable roof, this is the on used for the 3D port
// Notes on Roof3D and Triangle3D.  In order to get roofs for walls that had depth added to them, so it looks
// good in 3D, two extra objects were created.  The triangle3D is what the 3D engine uses to generate the 2 roof triangles
// the Roof3D is for the mapper, in given the user something to looks at and delete, because the triangle 3D isn't visible.
#define ROBOTPLACEMENT 8 // the robot inital placement

//#define SENSORSCALE (float)0.03 // used to display the sensors at varouis sizes scale = 1/0.03 etc.

// color types
#define SELECTRECTSIZE 3
#define SELECTCOLOR 1
#define NEUTRALCOLOR 0
#define SNAPCOLOR 2

// file defines
#define MAXGROUPS 32768 // that how many id could exist, so that many array spaces have to exist
#define OBJECTSIZE 30
#define MAXFILESIZE 200000 // should be enough for 6666 objects, less if there are groups
#define SEPERATOR -1



/* note the wierd skewing, quad 1,1 represents 0-99, 0-99 in cms, 2,2 is 100-199, 100-199 etc. */

/* the full grid is from 0 to 12799 both x and y */



// used for the duplicate function
enum DUPLICATESTATE {Copy,Move,Paste};

class UQuadTree  
{
public:

    struct RENDERINGSTATS
    {
        int RenderCycle;
        int NRendered;
        int NQuadRendered;
        int XQuadEnd;
        int XQuadStart;
        int YQuadEnd;
        int YQuadStart;
        BOOL doNotRender;
        BOOL IsRendering;
        float OldBumperScaleX;
        float OldBumperScaleY;

    };

    
    struct GROUPSTRUCT;

    typedef GROUPSTRUCT *LGroupPtr, GroupStruct;

    struct OBJECTLIST;

    typedef OBJECTLIST *ObjectListPtr;

     // the object structer, this is where information on features such as lines are stored.
    struct OBJECT
    {
        int objecttype; //1 for line
        CPoint start,middle,end;
        int renderflag;
        int SimFlag;
        int objectID;
        int objectColor;
        LGroupPtr GroupPtr;
    };
    
    typedef OBJECT Object, *ObjectPtr;

    // an object list.  This is for the quick recall of objects inside of a quadrent.
    // and also for other types of lists
    struct OBJECTLIST
    {
        ObjectListPtr Next,Prev;
        ObjectPtr Data;
    };

    /* the actual quad tree structure.
    *  Each lower level quadrant could represent 1 meter squared.  There will be up to 7 levels
    *  for a total of 16384 meters squared or 128*128 meter grid. 
    *  The individual quadrants are 1 meter squared, and they at the lowest level represent 1 cm,
    *  e.g 100x100 centmenteres */
    struct TREESTRUCT;

    typedef TREESTRUCT *TreePtr,TreeStruct;

    struct TREESTRUCT
    {
        CRect QuadRect;
        ObjectListPtr Objects;
        TreePtr NextQuad[4];
        TreePtr PrevQuad;
    };

    
    struct DRAFTINGSTRUCT
    {
        ObjectPtr theObject;
        int WhatPoint; // 0 for start 1 for end and 2 for middle
        BOOL valid;
        BOOL changed;
        BOOL selected; // used to see if the user is clicking on an end point, not on a new line;
        BOOL isMoving; // used to check if the user is currently manipulating an object
    };

    enum GROUPTYPE {Seperable,NonSeperable};

    // stores the state of current drafting commands.
    struct DRAFTINGSTATE
    {
        BOOL Line1; // one point placed down
        BOOL Arc1; // one point place down
        BOOL Arc2; // two points placed down.
        BOOL Move1; // starting point for the move already happened
        BOOL Bump1; // when the first point is down
        BOOL Bump2; // when the second point is down
        CPoint PrevPos; // used when moving a object
        CPoint BumpStart;
        CPoint BumpEnd;
    };


    struct GROUPSTRUCT
    {
        LGroupPtr ParentPtr; // pointer to a higher level group
        LGroupPtr Child; // pointer to a lowel level group
        LGroupPtr Sibling; // simular to Next
        ObjectListPtr Next; // in case it is the first group
        int NumofObjects;
        long GroupID;
        GROUPTYPE GroupType;
    };

    struct SELECTSTRUCT;

    typedef SELECTSTRUCT *SelectPtr,SelectStruct;

    struct SELECTSTRUCT
    {
        LGroupPtr data; // pointer to a higher level group
        SelectPtr Next,Prev;
    };

    // the grouplist is used during saving and loading to construct the group links

    struct GROUPLIST;

    typedef GROUPLIST *GroupListPtr,GroupListStruct;

    struct GROUPLIST
    {
        long ID;
        GroupListPtr Next;
    };

public: 

    // extra functionality for the 3D roofs suport. All of these functions
    // are needed because the roofs stretch the architecture to the limit
    // only create the roof 3d
	LGroupPtr AddRoof3D3(CPoint Point1, CPoint Point2);
    // only create the triangle 3d
	LGroupPtr AddRoof3D2(CPoint Point1, CPoint Point2, CPoint Point3);
    // only duplicate the triangle 3d
    LGroupPtr DuplicateAddRoof3D(CPoint Point1, CPoint Point2, CPoint Point3);
    // only duplicate the roof 3d
	LGroupPtr DuplicateAddRoof3D2(CPoint Start, CPoint End);
    // add the roof3d and triangle 3d, used in the create depth
    LGroupPtr AddRoof3D(CPoint Point1, CPoint Point2, CPoint Point3);

	HWND ParentHandle;



	
    // adding sensor functionality     
	float SensorRenderingScale; // to possible scales
	uIDList IRSensorIDList;	
    void DraftingEditProperties();
    LGroupPtr DuplicateAddSonarSensor(CPoint DisplayPoint);
    LGroupPtr AddSonarSensor(CPoint DisplayPoint);
    LGroupPtr DuplicateAddIRSensor(CPoint DisplayPoint, long MinRange, long MaxRange, long Angle);
    LGroupPtr AddIRSensor(CPoint DisplayPoint, long MinRange, long MaxRange, long Angle);
    uIDList BumpSensorIDList;
	LGroupPtr AddBumpSensor(CPoint Start, CPoint End, CPoint Display);
    LGroupPtr DuplicateAddBumpSensor(CPoint Start, CPoint End, CPoint Display);
	void DraftingAddBumpSensor(CPoint thePoint);
    void DraftingAddSonarSensor(CPoint thePoint);
    void DraftingAddIRSensor(CPoint thePoint, long MinRange, long MaxRange, long Angle);
    void RenderBumpSensor(CDC &MemDC, float XScale, float YScale, int XTransform, int YTransform, CPoint Center, int color, BOOL isVertical);
    void RenderIRSensor(CDC &MemDC, float XScale, float YScale, int XTransform, int YTransform, CPoint Center, long angle, int color);
    void RenderSonarSensor(CDC &MemDC, float XScale, float YScale, int XTransform, int YTransform, CPoint Center, int color);



    // creating depth functionality
	void DraftingCreateDepth(int depth, BOOL Reverse);
	void DepthReturnPointList(LGroupPtr GroupPtr, ObjectListPtr &ObjectList);
	BOOL DepthFindEndPoints(CPoint &Start, CPoint &End, int Tolerance);

    SelectPtr CopyPtr;
    void DraftingRotate(CPoint CenterPoint, int Angle); // really a duplicate function
	void DuplicateTraverseList(LGroupPtr OldList, LGroupPtr &NewList, CPoint RotateCenter, int angle);
	void DuplicatePasteGroup(CPoint Point);
	void DuplicateDeleteGroup(LGroupPtr GroupPtr);	
	void DuplicateFlushCopyList();
	void DuplicateCopyGroup(BOOL toCut);
	LGroupPtr DuplicateAddArc(CPoint Start, CPoint Middle, CPoint End);
	LGroupPtr DuplicateAddLine(CPoint Start, CPoint End);
	void DuplicateMoveGroup(CPoint Delta);
    void DuplicateTraverseList(LGroupPtr OldList, LGroupPtr &NewList, DUPLICATESTATE Command, CPoint Delta);
	
    // drafting features.  This are the ones called externally.
    DRAFTINGSTATE DraftingState;
    DRAFTINGSTRUCT DraftingObject;
    CPoint DraftingGetStartPoint();
    int DefaultLinesinArc;
    void DraftingCutGroup();
	void DraftingPasteGroup(CPoint Point);
	void DraftingCopyGroup();
    void DraftingCancelCommand();
    void DraftingMoveGroup(CPoint Point);
	void DraftingAddArc(CPoint Point);
    void DraftingFlushAll();
	void DraftingAddLine(CPoint Point);
    CPoint DraftingSnaptoEndpoint(CPoint Point, int range);
    BOOL DraftingCheckifPrevSelEndPoint(CPoint Point, float range, BOOL select);
	void DraftingOnMouseUp();
	void DraftingOnMouseMoved(CPoint Point);	
	void SelectCheckIfDraftPoint(ObjectPtr theObject, CPoint thePoint, float range);
	
	// saving/loading functions
    void FileSaveMap(CFile &theFile, CRect CurrView, BOOL AllLine);
	CRect FileOpenMap(CFile &theFile);
	void FileAddLinkstoArray(LGroupPtr toAdd, GroupListPtr theArray[]);
	void FileChartoLong(long &toRecieve, unsigned char *&ptr);
	CRect FileOpenMap(CString FileName);
	void FileLongtoChar(long &toCopy, unsigned char *&ptr);
	int FileIsInTable(LGroupPtr Table[], LGroupPtr Key);
	void FileSaveMap(CString FileName, CRect CurrView, BOOL AllLine);
	

    // grouping and selection functions
    uIDList GroupIDList;
	void SelectDeleteAll();
	void SelectPrintStats(CDC &MemDC, int x, int );
	void SelectAddGrouptoList(LGroupPtr theGroup);
	void SelectDeleteGroup();
	void SelectCreateGroup();

    // deletion functionality
    // used to ungroup groups
	void DeleteGroup1(LGroupPtr GroupPtr);
	void DeleteGroupList1(LGroupPtr GroupPtr);
    // delete groups
	void DeleteGroup(LGroupPtr &GroupPtr);
	void DeleteGroupList(LGroupPtr &GroupPtr);
    // Does the real work
    void DeleteObjectReal(ObjectPtr theObject);
	void DeleteFromObjectList(TreePtr tTreePtr,ObjectPtr theObject);
    // is the user call function
	void DeleteObject(ObjectPtr theObject);


    // basic linear algebra routines
	ULinearAlgebra LAUtils;

    // select object stuff
    SelectPtr SelectedObjectPtr; // stores objects that are selected.
    CPen ColorPens[5];
    CBrush ColorBrush[5];
    COLORREF Colors[5];
    void SelectArea(CRect Area, BOOL AllIn);
    void SelectCancelList();
    void SelectAddtoList(ObjectPtr theObject);
    void SelectChangeSelectStatus(LGroupPtr GroupPtr, bool Select);
	void SelectChangeSelectStatus1(LGroupPtr GroupPtr, bool Select);
    void SelectDeleteList();
	void SelectRemovefromList(ObjectPtr theObject);
	void SelectGetAllQuadrants(CPoint Point, int Range, CRect &Rect);
	BOOL SelectObject(CPoint Point, float Range, BOOL Select);

    // Rendering stats
    RENDERINGSTATS RenderingStats;    

    // rendering functions and variables
    int RenderApetureSize;
	CPoint RenderApeture;
    ObjectListPtr RenderObjectListPtr;
	void RenderCreateList(CRect RenderingBound, TreePtr toRender);
	void RenderCreateList(CRect RenderingBound);
	void RenderAddtoList(TreePtr toRender);
    void RenderDrawRectangle(CRect Rectangle, CDC &MemDC);
	BOOL RenderEnumObjects(ObjectPtr &object);
	void Render(CDC &DBufferDC, FRect Quad, CRect Screen);
	
    // main object list functions and variables
    ObjectListPtr BigObjectList;
    void AddToBigObjectList(ObjectPtr tObjectPtr);
    void DeleteObjectList(TreePtr temp);	
	
    // add objects functionality
    uIDList IDList; // The ID class.
    BOOL AddArcLine(CPoint Start, CPoint End, LGroupPtr GroupPtr, int ArcID);
	BOOL AddCheckifPointValid(CPoint thePoint);
	LGroupPtr AddArc(CPoint Start, CPoint Middle, CPoint End);
	TreePtr AddFindQuad(CPoint point, TreePtr Level);
    CPoint AddFindPoint(CPoint Start, CPoint End);
	void AddToObjectList(TreePtr tTreePtr, ObjectPtr tObjectPtr);
	int AddFindQuad(CRect quad, CPoint point);
    TreePtr AddFindQuad(int x, int y);
	TreePtr AddFindQuad(CPoint point);
    LGroupPtr AddLine(CPoint Start, CPoint End);
	void AddBox(CPoint start, int Size);

    // memory allocation debug stuff
	int DebugDeleteCount;
	int DebugNewCount;

    int DeleteFindNonNull(TreePtr temp);
	void DeleteQuadTree();
	void DeleteQuadTree(TreePtr Head);
    void DeleteObjects();
	
    // initialization functions
	TreePtr HeadQuadPtr;// the one and only root node of the quad tree
    void InitializeQuadTree();
    void InitializeQuadTree(TreePtr Head);
	CRect InitGetQuad(CRect toSplit, int index);
    int InitFindNull(TreePtr temp);

    // constructers, destructers
    void _Destruct();
	void _Construct();
    UQuadTree();
	virtual ~UQuadTree();

};

#endif // !defined(AFX_UQUADTREE_H__3E7EA700_44AA_438A_8727_6AFA29D404EC__INCLUDED_)
