// OpenGraphDialogClientDlg.cpp : implementation file
//

#include "stdafx.h"
#include "OpenGraphDialogClient.h"
#include "OpenGraphDialogClientDlg.h"

// jxu
#include "OpenGraph.h"
#include "OpenGLWnd.h"

using namespace NSOpenGraphLib;

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.;
    }

}



#ifdef _DEBUG
#define new DEBUG_NEW
#endif


// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	CAboutDlg();

// Dialog Data
	enum { IDD = IDD_ABOUTBOX };

	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

// Implementation
protected:
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
END_MESSAGE_MAP()


// COpenGraphDialogClientDlg dialog




COpenGraphDialogClientDlg::COpenGraphDialogClientDlg(CWnd* pParent /*=NULL*/)
	: CDialog(COpenGraphDialogClientDlg::IDD, pParent)
{
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
    // jxu
    m_openglWnd = new COpenGLWnd();
}

void COpenGraphDialogClientDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
}

BEGIN_MESSAGE_MAP(COpenGraphDialogClientDlg, CDialog)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	//}}AFX_MSG_MAP
    ON_BN_CLICKED(IDC_DEFAULT, &COpenGraphDialogClientDlg::OnBnClickedDefault)
    ON_BN_CLICKED(IDC_TRACK, &COpenGraphDialogClientDlg::OnBnClickedTrack)
    ON_BN_CLICKED(IDC_SELECT, &COpenGraphDialogClientDlg::OnBnClickedSelect)
    ON_BN_CLICKED(IDC_PAN, &COpenGraphDialogClientDlg::OnBnClickedPan)
    ON_BN_CLICKED(IDC_ROTATE, &COpenGraphDialogClientDlg::OnBnClickedRotate)
    ON_BN_CLICKED(IDC_WINDOW_ZOOM, &COpenGraphDialogClientDlg::OnBnClickedWindowZoom)
    ON_BN_CLICKED(IDC_PIXEL_PAN, &COpenGraphDialogClientDlg::OnBnClickedPixelPan)
    ON_BN_CLICKED(IDC_SELECT_ALL, &COpenGraphDialogClientDlg::OnBnClickedSelectAll)
    ON_BN_CLICKED(IDC_UNSELECT_ALL, &COpenGraphDialogClientDlg::OnBnClickedUnselectAll)
    ON_BN_CLICKED(IDC_REVERSE_SELECT, &COpenGraphDialogClientDlg::OnBnClickedReverseSelect)
    ON_BN_CLICKED(IDC_SHOW_SELECTED, &COpenGraphDialogClientDlg::OnBnClickedShowSelected)
    ON_BN_CLICKED(IDC_VIEW_FRONT, &COpenGraphDialogClientDlg::OnBnClickedViewFront)
    ON_BN_CLICKED(IDC_VIEW_ISOMETRIC, &COpenGraphDialogClientDlg::OnBnClickedViewIsometric)
    ON_BN_CLICKED(IDC_RESET_VIEW, &COpenGraphDialogClientDlg::OnBnClickedResetView)
    ON_BN_CLICKED(IDC_PROJECT_POINT, &COpenGraphDialogClientDlg::OnBnClickedProjectPoint)
    ON_BN_CLICKED(IDC_DRAW_NODES, &COpenGraphDialogClientDlg::OnBnClickedDrawNodes)
    ON_BN_CLICKED(IDC_DRAW_LINES, &COpenGraphDialogClientDlg::OnBnClickedDrawLines)
    ON_BN_CLICKED(IDC_DRAW_TRIANGLES, &COpenGraphDialogClientDlg::OnBnClickedDrawTriangles)
    ON_BN_CLICKED(IDC_DRAW_QUADS, &COpenGraphDialogClientDlg::OnBnClickedDrawQuads)
    ON_BN_CLICKED(IDC_DRAW_NODES_W, &COpenGraphDialogClientDlg::OnBnClickedDrawNodesW)
    ON_BN_CLICKED(IDC_DRAW_LINES_W, &COpenGraphDialogClientDlg::OnBnClickedDrawLinesW)
    ON_BN_CLICKED(IDC_DRAW_TRIANGLES_W, &COpenGraphDialogClientDlg::OnBnClickedDrawTrianglesW)
    ON_BN_CLICKED(IDC_DRAW_QUADS_W, &COpenGraphDialogClientDlg::OnBnClickedDrawQuadsW)
    ON_BN_CLICKED(IDC_CLEAR, &COpenGraphDialogClientDlg::OnBnClickedClear)
    ON_BN_CLICKED(IDC_SAVE_IMAGE, &COpenGraphDialogClientDlg::OnBnClickedSaveImage)
    ON_WM_ERASEBKGND()
    ON_WM_SIZE()
    ON_WM_MOUSEWHEEL()
END_MESSAGE_MAP()


// COpenGraphDialogClientDlg message handlers

BOOL COpenGraphDialogClientDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

    // jxu
    CRect rect0;
    GetClientRect(&rect0);
    CRect rect(100, 5, rect0.Width()-5, int(rect0.Height() * 0.9));
    m_openglWnd->Create( NULL, //CWnd default
        NULL, //has no name
        WS_CHILD|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|WS_VISIBLE,
        rect,
        this, //this is the parent
        0); //this should really be a different 


	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	// TODO: Add extra initialization here

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void COpenGraphDialogClientDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void COpenGraphDialogClientDlg::OnPaint()
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this function to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR COpenGraphDialogClientDlg::OnQueryDragIcon()
{
	return static_cast<HCURSOR>(m_hIcon);
}


void COpenGraphDialogClientDlg::OnBnClickedDefault()
{
    m_openglWnd->m_openGraph.SetMode(COpenGraph::modeNONE);
}

void COpenGraphDialogClientDlg::OnBnClickedTrack()
{
    m_openglWnd->m_openGraph.SetMode(COpenGraph::modeTRACK);
}

void COpenGraphDialogClientDlg::OnBnClickedSelect()
{
    m_openglWnd->m_openGraph.SetMode(COpenGraph::modeSELECT);
}

void COpenGraphDialogClientDlg::OnBnClickedPan()
{
    m_openglWnd->m_openGraph.SetMode(COpenGraph::modeREALPAN);
}

void COpenGraphDialogClientDlg::OnBnClickedRotate()
{
    m_openglWnd->m_openGraph.SetMode(COpenGraph::modeROTATE);
}

void COpenGraphDialogClientDlg::OnBnClickedWindowZoom()
{
   m_openglWnd->m_openGraph.SetMode(COpenGraph::modeZOOM);
}

void COpenGraphDialogClientDlg::OnBnClickedPixelPan()
{
    m_openglWnd->m_openGraph.Pan(20, 5);
}

void COpenGraphDialogClientDlg::OnBnClickedSelectAll()
{
    m_openglWnd->m_openGraph.SelectAll();
    m_openglWnd->m_openGraph.Render();
}

void COpenGraphDialogClientDlg::OnBnClickedUnselectAll()
{
    m_openglWnd->m_openGraph.UnSelectAll();
    m_openglWnd->m_openGraph.Render();
}

void COpenGraphDialogClientDlg::OnBnClickedReverseSelect()
{
    m_openglWnd->m_openGraph.ReverseSelectAll();
    m_openglWnd->m_openGraph.Render();
}

void COpenGraphDialogClientDlg::OnBnClickedShowSelected()
{
    CIdentity* pIdentity;
    int nCount;
    m_openglWnd->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(",");
    }
    AfxMessageBox(msg);
    delete []pIdentity;
}

void COpenGraphDialogClientDlg::OnBnClickedViewFront()
{
    m_openglWnd->m_openGraph.SetFrontView();
}

void COpenGraphDialogClientDlg::OnBnClickedViewIsometric()
{
    m_openglWnd->m_openGraph.SetIsometricView();
}

void COpenGraphDialogClientDlg::OnBnClickedResetView()
{
    m_openglWnd->m_openGraph.ZoomExtentView();
}

void COpenGraphDialogClientDlg::OnBnClickedProjectPoint()
{
    CPointf pt(0, 0, 0);
    CPointf ptProjected = m_openglWnd->m_openGraph.GetProjectedPoint(pt);
    CString msg;
    CRect rect;
    m_openglWnd->GetClientRect(&rect);
    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]);
    AfxMessageBox(msg);
}

void COpenGraphDialogClientDlg::OnBnClickedDrawNodes()
{
    int fontId = m_openglWnd->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_openglWnd->m_openGraph.AddText(id, 0, CPointf(x, y, z), strText, RGB(125, 123, 0), colorSelected);
            }else
            {
                m_openglWnd->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_openglWnd->m_openGraph.AddNodes(pIdentity, pId, pPt, nNodesPerBatch, nSize, color, colorSelected, 0, strTag, NULL);
        delete []pIdentity;
        delete []pId;
        delete []pPt;
    }

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

    m_openglWnd->m_openGraph.Render();
}

void COpenGraphDialogClientDlg::OnBnClickedDrawLines()
{
    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_openglWnd->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_openglWnd->m_openGraph.AddLines(pIdentity, pId, pPt1, pPt2, nLinesPerBatch, nSize, color, colorSelected, 0, strTag, NULL);
        delete []pIdentity;
        delete []pId;
        delete []pPt1;
        delete []pPt2;
    }

    m_openglWnd->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_openglWnd->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_openglWnd->m_openGraph.Render();
}

void COpenGraphDialogClientDlg::OnBnClickedDrawTriangles()
{
    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_openglWnd->m_openGraph.AddTriangle(1, pt[0], pt[1], pt[2], RGB(123, 0, 123), colorSelected,1, 0, strTag, NULL);
    m_openglWnd->m_openGraph.AddTriangle(2, pt[0], pt[1], pt[3], RGB(65, 0, 0), colorSelected,1, 0, strTag, NULL);
    m_openglWnd->m_openGraph.AddTriangle(3, pt[0], pt[3], pt[2], RGB(123, 0, 0), colorSelected,1, 0, strTag, NULL);
    m_openglWnd->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_openglWnd->m_openGraph.AddTriangles(identity, ids, pt1, pt2, pt3, 2, RGB(0, 0, 255), colorSelected,0.5f, 0, strTag, NULL);
    m_openglWnd->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_openglWnd->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_openglWnd->m_openGraph.Render();
}

void COpenGraphDialogClientDlg::OnBnClickedDrawQuads()
{
    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_openglWnd->m_openGraph.AddQuad(1, pt[1], pt[0], pt[4], pt[5], RGB(65, 0, 0), colorSelected,1, 0, strTag, NULL);
    m_openglWnd->m_openGraph.AddQuad(2, pt[3], pt[2], pt[6], pt[7], RGB(65, 0, 0), colorSelected,1, 0, strTag, NULL);
    m_openglWnd->m_openGraph.AddQuad(3, pt[2], pt[1], pt[5], pt[6], RGB(123, 0, 0), colorSelected,1, 0, strTag, NULL);
    m_openglWnd->m_openGraph.AddQuad(4, pt[0], pt[3], pt[7], pt[4], RGB(123, 0, 0), colorSelected,1, 0, strTag, NULL);
    m_openglWnd->m_openGraph.AddQuad(5, pt[0], pt[1], pt[2], pt[3], RGB(225, 0, 0), colorSelected,1, 0, strTag, NULL);
    m_openglWnd->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_openglWnd->m_openGraph.AddQuads(identity, ids, pt1, pt2, pt3, pt4, 2, RGB(0, 0, 255), colorSelected,0.5f, 0, strTag, NULL);
    m_openglWnd->m_openGraph.AddText(5, 0, CPointf(-0.75, 0, 10), _T("7"), RGB(125, 123, 0), colorSelected);
    m_openglWnd->m_openGraph.AddText(5, 0, CPointf(0.75, 0, 10), _T("8"), RGB(125, 123, 0), colorSelected);

    m_openglWnd->m_openGraph.Render();
}

void COpenGraphDialogClientDlg::OnBnClickedDrawNodesW()
{
    int fontId = m_openglWnd->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_openglWnd->m_openGraph.AddWindowText(id, 0, CPointf(x, y, z), strText, RGB(125, 123, 0), colorSelected);
            }else
            {
                m_openglWnd->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_openglWnd->m_openGraph.AddWindowNodes(pIdentity, pId, pPt, nNodesPerBatch, nSize, color, colorSelected, 0, strTag, NULL);
        delete []pIdentity;
        delete []pId;
        delete []pPt;
    }

    m_openglWnd->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_openglWnd->m_openGraph.AddWindowText(99999, 0, CPointf(m_nCx/2, m_nCy/2, 0), _T("99999"), RGB(255, 0, 0), RGB(0, 255, 0));

    m_openglWnd->m_openGraph.Render();
}

void COpenGraphDialogClientDlg::OnBnClickedDrawLinesW()
{
    int fontId = m_openglWnd->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_openglWnd->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_openglWnd->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_openglWnd->m_openGraph.AddWindowLine(1, pt[0], pt[1], 3, RGB(255, 0, 0), RGB(255, 255, 0), 0, _T(""), NULL);
    m_openglWnd->m_openGraph.AddWindowLine(2, pt[1], pt[2], 3, RGB(255, 0, 0), RGB(255, 255, 0), 0, _T(""), NULL);
    m_openglWnd->m_openGraph.AddWindowLine(3, pt[2], pt[3], 3, RGB(255, 0, 0), RGB(255, 255, 0), 0, _T(""), NULL);
    m_openglWnd->m_openGraph.AddWindowLine(4, pt[3], pt[0], 3, RGB(255, 0, 0), RGB(255, 255, 0), 0, _T(""), NULL);

    m_openglWnd->m_openGraph.Render();
}

void COpenGraphDialogClientDlg::OnBnClickedDrawTrianglesW()
{
    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_openglWnd->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_openglWnd->m_openGraph.AddWindowTriangles(pIdentity, pId, pt1, pt2, pt3, 2, RGB(123, 123, 123), colorSelected,0.5, 0, strTag, NULL);
    m_openglWnd->m_openGraph.Render();
}

void COpenGraphDialogClientDlg::OnBnClickedDrawQuadsW()
{
    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_openglWnd->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_openglWnd->m_openGraph.AddWindowQuads(pIdentity, pId, pt1, pt2, pt3, pt4,2, RGB(123, 123, 123), colorSelected,0.5, 0, strTag, NULL);
    m_openglWnd->m_openGraph.Render();
}

void COpenGraphDialogClientDlg::OnBnClickedClear()
{
    m_openglWnd->m_openGraph.Clear();
    m_openglWnd->m_openGraph.Render();
}

void COpenGraphDialogClientDlg::OnBnClickedSaveImage()
{
    bool bUseWhiteBackground = false;
    // use bmp for highest quality of picture
    const TCHAR* fileName = _T("c:\\temp\\test.bmp");
    m_openglWnd->m_openGraph.SaveImage(fileName, bUseWhiteBackground);
    AfxMessageBox(fileName);
}

BOOL COpenGraphDialogClientDlg::OnEraseBkgnd(CDC* pDC)
{
    //return TRUE;
    return CDialog::OnEraseBkgnd(pDC);
}

void COpenGraphDialogClientDlg::OnSize(UINT nType, int cx, int cy)
{
    if(m_openglWnd)
    {
        m_nCx = cx - 100 - 5;
        m_nCy = int(cy * 0.9);
        ::SetWindowPos(m_openglWnd->m_hWnd,HWND_TOPMOST,100,5,m_nCx, m_nCy,SWP_NOZORDER|SWP_SHOWWINDOW);
    }
}

BOOL COpenGraphDialogClientDlg::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
{
    m_openglWnd->m_openGraph.ZoomMouseWheel(nFlags, zDelta, pt);

    return CDialog::OnMouseWheel(nFlags, zDelta, pt);
}
