#include "StdAfx.h"
#include <time.h>

#include <atlstr.h>
#include "OpenGraph.h"


using namespace NSOpenGraphLib;
extern COpenGraph m_openGraph;
extern int m_nCx;
extern int m_nCy;

#include "Helper.h"


//////////////////////////////////////////////////////////////////////
void BoxPts(CPointf pt[8], CPointf ptCenter, double fDeltaX, double fDeltaY, double fDeltaZ)
{
    pt[0].xyz[X] = ptCenter.xyz[X] + fDeltaX / 2.;
    pt[0].xyz[Y] = ptCenter.xyz[Y] + fDeltaY / 2.;
    pt[0].xyz[Z] = ptCenter.xyz[Z] + fDeltaZ / 2.;
    pt[1] = pt[0];
    pt[1].xyz[X] = ptCenter.xyz[X] - fDeltaX / 2.;
    pt[2] = pt[1];
    pt[2].xyz[Y] = ptCenter.xyz[Y] - fDeltaY / 2.;
    pt[3] = pt[2];
    pt[3].xyz[X] = pt[0].xyz[X];

    for(int i = 0; i < 4; i++)
    {
        pt[i + 4] = pt[i];
        pt[i + 4].xyz[Z] = ptCenter.xyz[Z] - fDeltaZ / 2.;
    }

}


void OnViewSelectall()
{
    m_openGraph.SelectAll();
    m_openGraph.Render();
}   

void OnViewUnselectall()
{
    m_openGraph.UnSelectAll();
    m_openGraph.Render();
}   

void OnViewReverseselect()
{
    m_openGraph.ReverseSelectAll();
    m_openGraph.Render();
}

void OnViewShowselected()
{
    CIdentity* pIdentity;
    int nCount;
    m_openGraph.GetSelected(pIdentity, nCount);
    CString msg = _T("The following entities are selected:\n");
    for(int i = 0; i < nCount; i++)
    {
        CString temp;
        temp.Format(_T("[%s, %d]"), pIdentity[i].uid, pIdentity[i].id);
        msg +=temp;
        msg += _T(",");
    }
    MessageBox(NULL, msg, _T("Info"), MB_OK);
    delete []pIdentity;
}

void OnViewViewfront()
{
    m_openGraph.SetFrontView();
}

void OnViewViewisometric()
{
    m_openGraph.SetIsometricView();
}

void OnViewResetview()
{
    m_openGraph.ZoomExtentView();
}

void OnViewProjectpoint()
{
    CPointf pt(0, 0, 0);
    CPointf ptProjected = m_openGraph.GetProjectedPoint(pt);
    CString msg;
    msg.Format(_T("projected point for (0, 0, 0) is: x = %.1f, y = %.1f, z = %.1f"), ptProjected.xyz[X], ptProjected.xyz[Y], ptProjected.xyz[Z]);
    MessageBox(NULL, msg, _T("Info"), MB_OK);
}

void OnDrawDrawnodes()
{
    int fontId = m_openGraph.AddFont(_T("Times New Roman"), 30, 0, 0);

    srand((unsigned)time(NULL));
    const int nNodes = 400;
    const int nBatches = 10;
    const int nNodesPerBatch = nNodes / nBatches;
    for(int j = 0; j < nBatches; j++)
    {
        COLORREF color = RGB(rand() % 256, rand() % 256, rand() % 256);
        COLORREF colorSelected = RGB(255, 0, 0);
        CPointf* pPt = new CPointf[nNodesPerBatch];
        int* pId = new int[nNodesPerBatch];
        int nSize = (rand() % 8);
        CString strTag;
        strTag.Format(_T("Tag_%d"), j);
        for(int i = 0; i < nNodesPerBatch; i++)
        {
            double x = ((double) rand() / RAND_MAX - 0.5) * 4;
            double y = ((double) rand() / RAND_MAX - 0.5) * 4;
            double z = ((double) rand() / RAND_MAX - 0.5) * 4;
            CString strText;
            int id = j * nNodesPerBatch + i + 1;
            strText.Format(_T("%d"), id);
            if(i%2 == 0)
            {
                m_openGraph.AddText(id, 0, CPointf(x, y, z), strText, RGB(125, 123, 0), colorSelected);
            }else
            {
                m_openGraph.AddText(id, fontId, CPointf(x, y, z), strText, RGB(0, 123, 123), colorSelected);
            }
            pId[i] = id;
            pPt[i] = CPointf(x, y, z);
        }
        CIdentity* pIdentity = new CIdentity[nNodesPerBatch];
        // for performance reason, you should send in your data in batches
        m_openGraph.AddNodes(pIdentity, pId, pPt, nNodesPerBatch, nSize, color, colorSelected, 0, strTag, NULL);
        delete []pIdentity;
        delete []pId;
        delete []pPt;
    }

    m_openGraph.AddNode(99999, CPointf(), 15, RGB(255, 255, 0), RGB(0, 255, 255), 0, NULL, NULL);
    m_openGraph.AddText(99999, 0, CPointf(), _T("99999"), RGB(125, 123, 0), RGB(0, 255, 255));


    m_openGraph.Render();
}

void OnDrawDrawlines()
{
    srand((unsigned)time(NULL));
    const int nNodes = 300;
    const int nBatches = 30;
    const int nLinesPerBatch = nNodes / nBatches;
    for(int j = 0; j < nBatches; j++)
    {
        COLORREF color = RGB(rand() % 256, rand() % 256, rand() % 256);
        COLORREF colorSelected = RGB(255, 0, 0);
        CPointf* pPt1 = new CPointf[nLinesPerBatch];
        CPointf* pPt2 = new CPointf[nLinesPerBatch];
        int* pId = new int[nLinesPerBatch];
        int nSize = (rand() % 8);
        CString strTag;
        strTag.Format(_T("Tag_%d"), j);
        for(int i = 0; i < nLinesPerBatch; i++)
        {
            double x1 = ((double) rand() / RAND_MAX - 0.5) * 4;
            double y1 = ((double) rand() / RAND_MAX - 0.5) * 4;
            double z1 = ((double) rand() / RAND_MAX - 0.5) * 4;
            double x2 = ((double) rand() / RAND_MAX - 0.3) * 4;
            double y2 = ((double) rand() / RAND_MAX - 0.2) * 4;
            double z2 = ((double) rand() / RAND_MAX - 0.4) * 4;
            int id = j * nLinesPerBatch + i + 1;
            pId[i] = id;
            pPt1[i] = CPointf(x1, y1, z1);
            pPt2[i] = CPointf(x2, y2, z2);

            CString strText;
            strText.Format(_T("%d"), id);
            m_openGraph.AddText(id, 0, (pPt1[i] + pPt2[i]) / 2.0, strText, RGB(255, 0, 0), colorSelected);
        }
        CIdentity* pIdentity = new CIdentity[nLinesPerBatch];
        // for performance reason, you should send in your data in batches
        m_openGraph.AddLines(pIdentity, pId, pPt1, pPt2, nLinesPerBatch, nSize, color, colorSelected, 0, strTag, NULL);
        delete []pIdentity;
        delete []pId;
        delete []pPt1;
        delete []pPt2;
    }

    m_openGraph.AddLine(99999, CPointf(-2, 0, 0), CPointf(2, 0, 0), 15, RGB(255, 255, 0), RGB(0, 255, 255), 0, NULL, 0);
    m_openGraph.AddText(99999, 0, (CPointf(-2, 0, 0) + CPointf(2, 0, 0)) / 2.0, _T("99999"), RGB(125, 123, 0), RGB(0, 123, 0));

    m_openGraph.Render();
}

void OnDrawDrawtriangles()
{
    CPointf pt[4] = {CPointf(0.5, 0, -0.5), CPointf(0.5, 0, 0.5), CPointf(-0.5, 0, 0.5), CPointf(0, 2, 0)};
    COLORREF colorSelected = RGB(255, 255, 0);
    CString strTag;

    m_openGraph.AddTriangle(1, pt[0], pt[1], pt[2], RGB(123, 0, 123), colorSelected,1, 0, strTag, NULL);
    m_openGraph.AddTriangle(2, pt[0], pt[1], pt[3], RGB(65, 0, 0), colorSelected,1, 0, strTag, NULL);
    m_openGraph.AddTriangle(3, pt[0], pt[3], pt[2], RGB(123, 0, 0), colorSelected,1, 0, strTag, NULL);
    m_openGraph.AddTriangle(4, pt[2], pt[3], pt[1], RGB(225, 0, 0), colorSelected,1, 0, strTag, NULL);

    // two transparent triangle
    CPointf pt1[2] = {CPointf(-1.5, -1.5, 1), CPointf(-1.5, -1.5, 1)};
    CPointf pt2[2] = {CPointf(1.2, 1.5, 1), CPointf(1.2, 1.5, 1)};
    CPointf pt3[2] = {CPointf(-2, 2.2, 1), CPointf(2, 0.2, 1)};
    int ids[2] = {5, 6};
    CIdentity identity[2];
    m_openGraph.AddTriangles(identity, ids, pt1, pt2, pt3, 2, RGB(0, 0, 255), colorSelected,0.5f, 0, strTag, NULL);
    m_openGraph.AddText(5, 0, CPointf((-1.5 + 1.2 + -2), (-1.5 + 1.5 + 2.2), (1 + 1 + 1)) / 3.0, _T("5"), RGB(125, 123, 0), colorSelected);
    m_openGraph.AddText(6, 0, CPointf((-1.5 + 1.2 + 2), (-1.5 + 1.5 + 0.2), (1 + 1 + 1)) / 3.0, _T("6"), RGB(125, 123, 0), colorSelected);

    m_openGraph.Render();
}

void OnDrawDrawquads()
{
    COLORREF colorSelected = RGB(123, 0, 255);
    CString strTag;
    CPointf pt[8];
    COLORREF color = RGB(int(0.8 * 255), 0, 0);
    BoxPts(pt, CPointf(0, 0, 0), 0.5, 2, 1);
    m_openGraph.AddQuad(1, pt[1], pt[0], pt[4], pt[5], RGB(65, 0, 0), colorSelected,1, 0, strTag, NULL);
    m_openGraph.AddQuad(2, pt[3], pt[2], pt[6], pt[7], RGB(65, 0, 0), colorSelected,1, 0, strTag, NULL);
    m_openGraph.AddQuad(3, pt[2], pt[1], pt[5], pt[6], RGB(123, 0, 0), colorSelected,1, 0, strTag, NULL);
    m_openGraph.AddQuad(4, pt[0], pt[3], pt[7], pt[4], RGB(123, 0, 0), colorSelected,1, 0, strTag, NULL);
    m_openGraph.AddQuad(5, pt[0], pt[1], pt[2], pt[3], RGB(225, 0, 0), colorSelected,1, 0, strTag, NULL);
    m_openGraph.AddQuad(6, pt[7], pt[6], pt[5], pt[4], RGB(225, 0, 0), colorSelected,1, 0, strTag, NULL);

    CPointf pt1[2] = {CPointf(-1.5, -1.5, 10), CPointf(0, -1.5, 10)};
    CPointf pt2[2] = {CPointf(0, -1.5, 10), CPointf(1.5, -1.5, 10)};
    CPointf pt3[2] = {CPointf(0, 1.5, 10), CPointf(1.5, 1.5, 10)};
    CPointf pt4[2] = {CPointf(-1.5, 1.5, 10), CPointf(0, 1.5, 10)};
    int ids[2] = {7, 8};
    CIdentity identity[2];
    m_openGraph.AddQuads(identity, ids, pt1, pt2, pt3, pt4, 2, RGB(0, 0, 255), colorSelected,0.5f, 0, strTag, NULL);
    m_openGraph.AddText(5, 0, CPointf(-0.75, 0, 10), _T("7"), RGB(125, 123, 0), colorSelected);
    m_openGraph.AddText(5, 0, CPointf(0.75, 0, 10), _T("8"), RGB(125, 123, 0), colorSelected);

    m_openGraph.Render();
}

void OnDrawDrawwindownodes()
{
    int fontId = m_openGraph.AddFont(_T("Times New Roman"), 30, 0, 0);
    srand((unsigned)time(NULL));
    const int nNodes = 40;
    const int nBatches = 4;
    const int nNodesPerBatch = nNodes / nBatches;
    for(int j = 0; j < nBatches; j++)
    {
        COLORREF color = RGB(rand() % 256, rand() % 256, rand() % 256);
        COLORREF colorSelected = RGB(255, 0, 0);
        CPointf* pPt = new CPointf[nNodesPerBatch];
        int* pId = new int[nNodesPerBatch];
        int nSize = (rand() % 8);
        CString strTag;
        strTag.Format(_T("Tag_%d"), j);
        for(int i = 0; i < nNodesPerBatch; i++)
        {
            double x = rand() % m_nCx;
            double y = rand() % m_nCy;
            double z = 0;
            CString strText;
            int id = j * nNodesPerBatch + i + 1;
            strText.Format(_T("%d"), id);

            if(i%2 == 0)
            {
                m_openGraph.AddWindowText(id, 0, CPointf(x, y, z), strText, RGB(125, 123, 0), colorSelected);
            }else
            {
                m_openGraph.AddWindowText(id, fontId, CPointf(x, y, z), strText, RGB(0, 123, 123), colorSelected);
            }
            pId[i] = j * nNodesPerBatch + i + 1;
            pPt[i] = CPointf(x, y, z);
        }
        CIdentity* pIdentity = new CIdentity[nNodesPerBatch];
        // for performance reason, you should send in your data in batches
        m_openGraph.AddWindowNodes(pIdentity, pId, pPt, nNodesPerBatch, nSize, color, colorSelected, 0, strTag, NULL);
        delete []pIdentity;
        delete []pId;
        delete []pPt;
    }

    m_openGraph.AddWindowNode(99999, CPointf(m_nCx/2, m_nCy/2, 0), 10, RGB(255, 255, 0), RGB(0, 255, 255), 0, 0, 0);
    m_openGraph.AddWindowText(99999, 0, CPointf(m_nCx/2, m_nCy/2, 0), _T("99999"), RGB(255, 0, 0), RGB(0, 255, 0));

    m_openGraph.Render();
}

void OnDrawDrawwindowlines()
{
    int fontId = m_openGraph.AddFont(_T("Times New Roman"), 30, 0, 0);

    srand((unsigned)time(NULL));
    const int nNodes = 20;
    const int nBatches = 10;
    const int nLinesPerBatch = nNodes / nBatches;
    for(int j = 0; j < nBatches; j++)
    {
        COLORREF color = RGB(rand() % 256, rand() % 256, rand() % 256);
        COLORREF colorSelected = RGB(255, 0, 0);
        CPointf* pPt1 = new CPointf[nLinesPerBatch];
        CPointf* pPt2 = new CPointf[nLinesPerBatch];
        int* pId = new int[nLinesPerBatch];
        int nSize = (rand() % 8);
        CString strTag;
        strTag.Format(_T("Tag_%d"), j);
        for(int i = 0; i < nLinesPerBatch; i++)
        {
            double x1 = rand() % m_nCx;
            double y1 = rand() % m_nCy;
            double z1 = 0;
            double x2 = abs(rand() % m_nCx - 300);
            double y2 = abs(rand() % m_nCy - 20);;
            double z2 = 0;
            int id = j * nLinesPerBatch + i + 1;
            pId[i] = id;
            pPt1[i] = CPointf(x1, y1, z1);
            pPt2[i] = CPointf(x2, y2, z2);
            CString strText;
            strText.Format(_T("%d"), id);
            m_openGraph.AddWindowText(id, 0, (pPt1[i] + pPt2[i]) / 2, strText, RGB(125, 123, 0), colorSelected);
        }
        CIdentity* pIdentity = new CIdentity[nLinesPerBatch];
        // for performance reason, you should send in your data in batches
        m_openGraph.AddWindowLines(pIdentity, pId, pPt1, pPt2, nLinesPerBatch, nSize, color, colorSelected, 0, strTag, NULL);
        delete []pIdentity;
        delete []pId;
        delete []pPt1;
        delete []pPt2;
    }

    // draw the boundary line
    CPointf pt[4] = {CPointf(5, 5, 0), CPointf(m_nCx - 10, 5, 0), CPointf(m_nCx - 10, m_nCy - 10, 0), CPointf(5, m_nCy - 10, 0)};
    m_openGraph.AddWindowLine(1, pt[0], pt[1], 3, RGB(255, 0, 0), RGB(255, 255, 0), 0, _T(""), NULL);
    m_openGraph.AddWindowLine(2, pt[1], pt[2], 3, RGB(255, 0, 0), RGB(255, 255, 0), 0, _T(""), NULL);
    m_openGraph.AddWindowLine(3, pt[2], pt[3], 3, RGB(255, 0, 0), RGB(255, 255, 0), 0, _T(""), NULL);
    m_openGraph.AddWindowLine(4, pt[3], pt[0], 3, RGB(255, 0, 0), RGB(255, 255, 0), 0, _T(""), NULL);

    m_openGraph.Render();
}

void OnDrawDrawwindowtriangles()
{
    CPointf pt[3] = {CPointf(m_nCx / 8, m_nCy / 8, 0), CPointf(m_nCx / 1.5, m_nCy / 8, 0), CPointf(m_nCx /2, m_nCy / 2, 0)};
    COLORREF colorSelected = RGB(255, 255, 0);
    CString strTag;
    m_openGraph.AddWindowTriangle(1, pt[0], pt[1], pt[2], RGB(123, 0, 123), colorSelected,1, 0, strTag, NULL);

    CPointf pt1[2] = {CPointf(m_nCx / 4, m_nCy / 1.1, 0), CPointf(m_nCx / 1.5, m_nCy / 1.1, 0)};
    CPointf pt2[2] = {CPointf(m_nCx / 2, m_nCy / 5, 0), CPointf(m_nCx / 4, m_nCy / 4, 0)};
    CPointf pt3[2] = {CPointf(10, 10, 0), CPointf(m_nCx / 3, m_nCy / 8, 0)};
    CIdentity pIdentity[2];
    int pId[2] = {2, 3};
    m_openGraph.AddWindowTriangles(pIdentity, pId, pt1, pt2, pt3, 2, RGB(123, 123, 123), colorSelected,0.5, 0, strTag, NULL);
    m_openGraph.Render();
}

void OnDrawDrawwindowquads()
{
    CPointf pt[4] = {CPointf(25, 25, 0), CPointf(m_nCx - 25, 25, 0), CPointf(m_nCx - 25, m_nCy - 25, 0), CPointf(25, m_nCy - 25, 0)};
    COLORREF colorSelected = RGB(255, 255, 0);
    CString strTag;
    m_openGraph.AddWindowQuad(1, pt[0], pt[1], pt[2], pt[3], RGB(123, 0, 123), colorSelected,0.5, 0, strTag, NULL);

    CPointf pt1[2] = {CPointf(50, 50, 0), CPointf(m_nCx*2 / 3, 50, 0)};
    CPointf pt2[2] = {CPointf(m_nCx / 3,50, 0), CPointf(m_nCx -50, 50, 0)};
    CPointf pt3[2] = {CPointf(m_nCx / 3,m_nCy - 50, 0), CPointf(m_nCx -50, m_nCy - 50, 0)};
    CPointf pt4[2] = {CPointf(50,m_nCy - 50, 0), CPointf(m_nCx*2 / 3, m_nCy - 50, 0)};
    CIdentity pIdentity[2];
    int pId[2] = {2, 3};
    m_openGraph.AddWindowQuads(pIdentity, pId, pt1, pt2, pt3, pt4,2, RGB(123, 123, 123), colorSelected,0.5, 0, strTag, NULL);
    m_openGraph.Render();
}

void OnDrawClear()
{
    m_openGraph.Clear();
    m_openGraph.Render();
}

void OnDrawSaveimage()
{
    bool bUseWhiteBackground = false;
    // use bmp for highest quality of picture
    const TCHAR* fileName = _T("c:\\temp\\test.bmp");
    m_openGraph.SaveImage(fileName, bUseWhiteBackground);
    MessageBox(NULL, fileName, _T("Info"), MB_OK);
}

void OnModeDefault()
{
    m_openGraph.SetMode(COpenGraph::modeNONE);
}

void OnModeTrack()
{
    m_openGraph.SetMode(COpenGraph::modeTRACK);
}

void OnModeSelect()
{
    m_openGraph.SetMode(COpenGraph::modeSELECT);
}

void OnModePan()
{
    m_openGraph.SetMode(COpenGraph::modeREALPAN);
}

void OnModeRotate()
{
    m_openGraph.SetMode(COpenGraph::modeROTATE);
}

void OnModeWindowzoom()
{
    m_openGraph.SetMode(COpenGraph::modeZOOM);
}

void OnModePixelpan()
{
    m_openGraph.Pan(20, 5); // change steps here to suit your needs
}
