// SGDIRender.cpp: implementation of the SGDIRender class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "Simulator.h"
#include "SGDIRender.h"
#include "ChildView.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

SGDIRender::SGDIRender()
{
    ModelPtr = NULL; 

    SensorRenderingScale = REALRENDERINGSCALE;

    RCResetView();

}

SGDIRender::~SGDIRender()
{

}

// converts the window point into real cooridates
CPoint SGDIRender::ScreentoReal(CPoint Coord)
{
     CPoint temp;
     // translate the mouse point into a real point
    temp.x = (int)((float)(Coord.x-RectDrawingArea.left)/(float)(RectDrawingArea.Width())*RectCurrentView.Width() + RectCurrentView.left);//CurrentView.Width());
    temp.y = (int)((float)(Coord.y-RectDrawingArea.top)/(float)(RectDrawingArea.Height())*RectCurrentView.Height() + RectCurrentView.top);//CurrentView.Height());

    return temp;

}

/************************************************************************
* Function Render(CDC &MemDC)
* 
* PURPOSE
* Function used by window to render the screen
*************************************************************************/
void SGDIRender::Render(CDC &MemDC)
{
    MapPtr->Render(MemDC,RectCurrentView,RectDrawingArea);
    if (ModelPtr != NULL)
    {      
        ModelPtr->RenderGDI(MemDC,RectCurrentView,RectDrawingArea,SensorRenderingScale,RenderControl.ModelLockPoint);

        // draw the collision rect, for debugging I guess
        if (ModelPtr->TheModel.CollisionPoint.x != NOCOLLISION)
        {
            CRect Rect;
            int size = 3;
            CPoint Point = RealToScreen(ModelPtr->TheModel.CollisionPoint);
            Rect.left = Point.x - size;
            Rect.right = Rect.left + 2*size;
            Rect.top = Point.y - size;
            Rect.bottom = Rect.top + 2*size;
            MemDC.Rectangle(&Rect);
        }
    }
    

}

/************************************************************************
* Function RCZoom(float ratio)
* 
* PURPOSE
* To Zoom in/out the view
* USAGE
* Called by the window class
*************************************************************************/
void SGDIRender::RCZoom(float ZoomFactor)
{
     // make the mouse the center of the screen.
    float newWidth = (RectCurrentView.Width()/ZoomFactor);
    float newHeight = (RectCurrentView.Height()/ZoomFactor);   

    if (newWidth > MINZOOM && newHeight > MINZOOM)
    {

         // zoom into the area where the mouse cursor is, (that is why there is the extra math
        RectCurrentView.left = RenderControl.ZoomMousePos.x - newWidth/2;
        RectCurrentView.right = RectCurrentView.left + newWidth;
        RectCurrentView.top =  RenderControl.ZoomMousePos.y - newWidth/2;
        RectCurrentView.bottom = RectCurrentView.top + newHeight;
        // if statements to make sure the user does't pan off the screen
        if (RectCurrentView.left < XMin)
        {
            RectCurrentView.left = 0;
            RectCurrentView.right = newWidth;
        }
        else if (RectCurrentView.right > XMax)
        {
            RectCurrentView.right = XMax;
            RectCurrentView.left = XMax-newWidth;
        }
        if (RectCurrentView.top < YMin)
        {
            RectCurrentView.top = 0;
            RectCurrentView.bottom = newHeight;
        }
        else if (RectCurrentView.bottom > YMax)
        {
            RectCurrentView.bottom = YMax;
            RectCurrentView.top = YMax-newHeight;
        }
    }

}

/************************************************************************
* Function RCSetZoomPoint(CPoint Point
* 
* PURPOSE
* To set the center point at which to zoom
* USAGE
* Called by the window class
*************************************************************************/
void SGDIRender::RCSetZoomPoint(CPoint Point)
{
    RenderControl.ZoomPoint = Point;
    RenderControl.PrevZoomedPoint = Point;
    RenderControl.ZoomMousePos = ScreentoReal(RenderControl.ZoomPoint);

}

/************************************************************************
* Function RCSetFollowModel()
* 
* PURPOSE
* To have the view always follow the model
* INPUT
* ToFollow, if true follow model is true
* USAGE
* Called by the window class
*************************************************************************/
void SGDIRender::RCSetFollowModel(BOOL ToFollow)
{
    RenderControl.LockonModel = ToFollow;

}

/************************************************************************
* Function RCZoom(CPoint Point)
* 
* PURPOSE
* To Zoom in/out the view, when the mouse moves
* USAGE
* Called by the window class
*************************************************************************/
void SGDIRender::RCZoom(CPoint Point)
{
    float ZoomFactor = (float)(1-(float)((Point.y-RenderControl.PrevZoomedPoint.y))*ZOOMPIXELPERCENT);

    RenderControl.PrevZoomedPoint = Point;

    RCZoom(ZoomFactor);
    

}

/************************************************************************
* Function RCResetView()
* 
* PURPOSE
* Reset the view to the default one
* USAGE
* Called by the window class
*************************************************************************/
void SGDIRender::RCResetView()
{
    RectDrawingArea.top=0;
    RectDrawingArea.bottom=500;
    RectDrawingArea.left=0;
    RectDrawingArea.right=500;

    RectCurrentView.top=0;
    RectCurrentView.bottom=12800;
    RectCurrentView.left=0;
    RectCurrentView.right=12800;

    RenderControl.LockonModel = true;

}

// converts real coordinates to screen coordinates
CPoint SGDIRender::RealToScreen(FPoint Coord)
{
    CPoint temp;

    // translate the real point into a screen point
    temp.x = (long)((Coord.x - RectCurrentView.left) * (float)RectDrawingArea.Width() /(float)RectCurrentView.Width() +  RectDrawingArea.left);
    temp.y = (long)((Coord.y - RectCurrentView.top) * (float)RectDrawingArea.Height() / (float)RectCurrentView.Height() + RectDrawingArea.top);
    
    return temp;


}

// called by the main window before a paint
void SGDIRender::RCSetModelCoord(FPoint Point)
{
	RenderControl.ModelLockPoint = Point;

    if (RenderControl.LockonModel)
    {       

        // now center the current view around this point;

        FRect NewView;

        float Height = RectCurrentView.Height()/(float)2.0;
        float Width =  RectCurrentView.Width()/(float)2.0;

        NewView.left = (RenderControl.ModelLockPoint.x - Width);
        NewView.right =  (RenderControl.ModelLockPoint.x + Width);    
        NewView.top = (RenderControl.ModelLockPoint.y - Height);
        NewView.bottom = (RenderControl.ModelLockPoint.y +Height);

        RectCurrentView = NewView;

    }

}
