
// StressView.cpp : implementation of the CStressView class
//

#include "stdafx.h"
// SHARED_HANDLERS can be defined in an ATL project implementing preview, thumbnail
// and search filter handlers and allows sharing of document code with that project.
#ifndef SHARED_HANDLERS
#include "Stress.h"
#endif

#include "StressDoc.h"
#include "StressView.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#endif

#define ID_RUNONTIMER			1000
#define ID_RUNONTIMER_ELLAPSE	100

#include <locale>

// Formats the giving double value as a number using the 0.000, without locale settings: Characters "0" through "9", One decimal point (dot) if the number is a floating-point value, A minus sign in the first character position if the number is a negative value.
static CString Double( double Number )
{
	//*Fixed: The format predefined function in the formatted expression could display wrong digits if using grouping separators. 
	setlocale( LC_NUMERIC, "C" );
	char szNumber[1024] = "";
	sprintf_s( szNumber, "%f", Number );
	setlocale( LC_NUMERIC, "" );

	//*Fixed: Removes the 0 from the tail of the number after the decimal separator in the generated code, if the user changes a property of Integer/Number type.
	char* p = strchr( szNumber, '.' );
	if ( p != NULL )
	{
		char* pD = p;
		for ( p++; ( *p != 0 ); p++ );
		for ( p--; ( p != pD ) && ( *p == '0' ); p-- );
		if ( p != pD )
			p++;
		*p = 0;
	}
	USES_CONVERSION;
	return A2T(szNumber);
}


static CString FormatNumber( double dbValue, long nNumDigits = 0 )
{
	USES_CONVERSION;
	NUMBERFMT nfml = {0};
	nfml.NumDigits = nNumDigits;
	nfml.lpDecimalSep = _T(".");
	nfml.Grouping = 3;
	nfml.lpThousandSep = _T(",");
	nfml.LeadingZero = 1;

	TCHAR szOut[1024] = {'\0'};
	CString strNumber = Double( dbValue );
	GetNumberFormat( NULL, NULL, strNumber, &nfml, szOut, 1024 );
	return szOut;
}

// CStressView

IMPLEMENT_DYNCREATE(CStressView, CFormView)

BEGIN_MESSAGE_MAP(CStressView, CFormView)
	ON_WM_CONTEXTMENU()
	ON_WM_RBUTTONUP()
	ON_WM_SIZE()
	ON_WM_CTLCOLOR()
	ON_BN_CLICKED(IDC_CHECKTIMER, &CStressView::OnBnClickedChecktimer)
	ON_BN_CLICKED(IDC_BUTTON1, &CStressView::OnBnClickedButton1)
	ON_BN_CLICKED(IDC_BUTTON2, &CStressView::OnBnClickedButton2)
	ON_BN_CLICKED(IDC_BUTTON3, &CStressView::OnBnClickedButton3)
	ON_BN_CLICKED(IDC_BUTTON4, &CStressView::OnBnClickedButton4)
	ON_BN_CLICKED(IDC_BUTTON5, &CStressView::OnBnClickedButton5)
	ON_WM_TIMER()
END_MESSAGE_MAP()

// CStressView construction/destruction

CStressView::CStressView()
	: CFormView(CStressView::IDD)
	, m_random(false)
	, m_nRunTestCount( 0 )
	, m_nLastRunTest(1)
{
	// TODO: add construction code here

}

CStressView::~CStressView()
{
}

void CStressView::DoDataExchange(CDataExchange* pDX)
{
	CFormView::DoDataExchange(pDX);
	DDX_Control(pDX, IDC_CHECKTIMER, m_runOnTimer);
	DDX_Control(pDX, IDC_CHECKRANDOM, m_runRandom);
}

BOOL CStressView::PreCreateWindow(CREATESTRUCT& cs)
{
	// TODO: Modify the Window class or styles here by modifying
	//  the CREATESTRUCT cs

	return CFormView::PreCreateWindow(cs);
}

void CStressView::OnInitialUpdate()
{
	CFormView::OnInitialUpdate();
	GetParentFrame()->RecalcLayout();
	ResizeParentToFit();

	m_spControl = GetDlgItem(IDC_TREE1)->GetControlUnknown();
	if ( m_spControl != NULL )
	{
		m_spItems = m_spControl->Items;
		m_spControl->BeginUpdate();

		EXTREELib::IAppearancePtr spAppearance = m_spControl->VisualAppearance;
		if ( spAppearance != NULL )
		{
			CString s = _T("gBFLBCJwBAEHhEJAEGg4BZMMQAAYAQGKIYBkAKBQAGaAoDDMMAzQwAAwjOK8EwsACEIrjKCRShyCYZRhGcTALD8EhhECTZKkAZAEiKLoaRzAcwyDAcQRFCKUJxhEY5ai+NobRDLMywSAUEreDAQQAoeiYWj0AIpQzKFCzdBIFw2ByEaCmQAKToqSJeUxCMQjEKoSzHMqIRpGCxoJqqbJUQLEMTVNAdNRfOCnaaqhakSTvO6ZZjkCb4ajiKqHVDiErYIAAETFBIGJJgOraLqCF56SBPEjVbIUQTpRqEawgPIaDxORpfZTFVj2eAFSZZNy0bTuKK5AhHDoDZ7pF74XhVd41Aa9c5jOqtWzueJ7b5UVz5dTOQwTW8uEaWRyeX4yjadZ0iABxXHKOZSjqVR5n0HgXGuIBQDSGJOgcU4RhQYwgCMVJIESX4EGgbQJBQc40HIUJEFwIYcHGAgQGCb4Ak6cx6AaAZgggJgKgKYBjl4DoAE6dAOAQMYhEMWgWgWYYIGYGoGmEaBQkaA4PHQDJOgiYBDn4JoJmKCImCqCoiAgEgjDOEA4F4Jw5mMSJWKuY4ImYNIICFIgHggI4pAYQoNGASJ0ACD5gmgHg1hKIxJDCZ4TiOCQWBaD4glgOhDhWY4ZEiVoVA2aQCFiF5jEkahcheJgJGIYoRmUU5eE6GpgGkLhtg7MweBKAQgDiLh2h2YooBIIBAmFM5ugMKEdDXPAEA0ASAg=");
			spAppearance->Add( 1, (LPCTSTR)s );
			s = _T("gBFLBCJwBAEHhEJAEGg4BHQDg6AADACAxRDAMgBQKAAzQFAYahyGCGAAGEaBQgmFgAQhFcZQSKUOQTDKMIziYBYfgkMIgSbJUgDGAkRRdDSOYDmGQYDiCIoRShOMIjHLUXxtDaIZwhEAoJa0HAkABRVIRNLoARTAaeJKoSboJBGGwUQjQUB1HRNDy7JasY4GURYRDKY4RDSMFiQTZNVypAaIYqqa4JPrWNYqXhAdLgAKcSTtF6ZZjkCb4apqTpNVDeWCRPkDYYDBLJNZ0LT1FYZPLDZzlCrJCiCcwAY5AdYZBiQAS5SzLIqsWx7Cq4AJtWhaVwxXIEI5CADPchveTqNrvCaZW7FdAwTq+dw1XqVczuXLsPADI6gcZNeq6Xo7GEbJZEaa4bF4bh/guUZSuUEISgGJJGHQOocgyIwZAKKhaAAIQTH2MYhjQJBRAmZ5uiQIYIjmU5dlECQBkONJ8DsTIznSYQok+Ux4hmAhgjgKgMgOYJoEYDYEmECBSA6AZPmOPJNgAIAjjiTA/E4YpIn0PJOBOdJ1DmYhoiIJ4KSyLgugqIwIjYMYKmIQ54mcLJPCOEJCSuIoSCMOBPkORJbD8DpzFYRIRiQWQeEqEhkkkIhOhKZJ5CYQg/g8Q4IncNwJmgPJ2DoJBDFoXYXk6eR6GGGAmCmFhkhmZg5iSVlLHOJJ5DaCRZGiaYRA0eZSHYO5nFmYh3h4Z5Jm4foeigAxeGwOomnmRgOD2DojnCcA2iiKgyguIxpAoPo");
			s = s + _T("SiOKRKEaFYkmiWYwmuIRliOLhBDcKZ6gSl4qDqCokimahqiaJYqk2SYwmyJwgmOYJsD8DwjHqNItisWpejqLhrkqYo+i6a56naNw/g+E42jCApPgOOJ8gkLI5ALGpsmsRpNjSbQLFKUo0CwQ4+kcP2TEIIw5C2e4EnOOAuDu345m4a4mmWOpOEsEJxjaT4TkYJg5i8O5UnWPQvHuWp4j6b4rnaeY/k4Y54noPIvAOSJ9hacBziMCZCnCDA3AqQ4wysEpEHCHAInPqgjk8Bw6jGPB2giR4xkwfwikgchMgMJoiA+Y5snSRlLnSdw7DKbJDC+TBzEyTw2xqDJXDmTZzByJJ186axwm+UI0EOYxDlGNBdB8SpSHSTQjE4O5yhOXpbD6dAbHaXI3jUbRnFiVp1H0dxaleNZNGifg/DUKZCAaAgsy8eZGg+A5EnsPZ1guSxtjcNwtlcdJdncPZneedo7GSO4NokxYAcAUHMCwMQYjGD8OoTgRhBjEHiJwL4HRihyA4G8EYxxPCnA4GwLIHgjgZEGA4JAJhcj6DkJUaArwigJDoHAW4TQDj0AOPEcwbBhiIAQQE");
			spAppearance->Add( 2, (LPCTSTR)s );
		}
		
		m_spControl->BackColorHeader = 0x1000000;
		m_spControl->SelBackColor = 0x2000000;
		m_spControl->SelForeColor = RGB(0,0,0);
		m_spControl->ShowFocusRect = false;
		m_spControl->MarkSearchColumn = false;
		m_spControl->HeaderHeight = 24;
		m_spControl->DefaultItemHeight = 20;
		m_spControl->Columns->Clear();
		m_spControl->Appearance = EXTREELib::None2;
		m_spControl->BackColorLevelHeader = m_spControl->BackColor;
		m_spControl->DrawGridLines = EXTREELib::exAllLines;
		m_spControl->GridLineStyle = (EXTREELib::GridLinesStyleEnum )(EXTREELib::exGridLinesHDot4 | EXTREELib::exGridLinesVSolid);
		m_spControl->GridLineColor = RGB(240,240,240);
		EXTREELib::IColumnPtr spColumn = m_spControl->Columns->Add( _T("Items") );
		if ( spColumn != NULL )
			spColumn->FormatColumn = _T("`Item ` + (1 index `` format `0`)");
		m_spControl->EndUpdate();
	}
}

void CStressView::OnRButtonUp(UINT /* nFlags */, CPoint point)
{
	ClientToScreen(&point);
	OnContextMenu(this, point);
}

void CStressView::OnContextMenu(CWnd* /* pWnd */, CPoint point)
{
#ifndef SHARED_HANDLERS
	theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT, point.x, point.y, this, TRUE);
#endif
}


// CStressView diagnostics

#ifdef _DEBUG
void CStressView::AssertValid() const
{
	CFormView::AssertValid();
}

void CStressView::Dump(CDumpContext& dc) const
{
	CFormView::Dump(dc);
}

CStressDoc* CStressView::GetDocument() const // non-debug version is inline
{
	ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CStressDoc)));
	return (CStressDoc*)m_pDocument;
}
#endif //_DEBUG


// CStressView message handlers

HBRUSH CStressView::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
	return (HBRUSH)GetStockObject( WHITE_BRUSH );
}

void CStressView::OnSize(UINT nType, int cx, int cy)
{
	CFormView::OnSize(nType, cx, cy);

	if ( m_spControl != NULL )
	{
		HWND hWnd = (HWND)m_spControl->hWnd;
		if ( ::IsWindow( hWnd ) )
		{
			CRect rtClient; GetClientRect( &rtClient );

			rtClient.InflateRect( -6, -6 );
			rtClient.top += 38;

			CWnd::FromHandle( hWnd )->SetWindowPos( NULL, rtClient.left, rtClient.top, rtClient.Width(), rtClient.Height(), SWP_NOZORDER | SWP_NOACTIVATE | SWP_SHOWWINDOW );
		}
	}
}

void CStressView::OnBnClickedChecktimer()
{
	if ( m_runOnTimer.GetCheck() )
		SetTimer( ID_RUNONTIMER, ID_RUNONTIMER_ELLAPSE, NULL );
	else
		KillTimer( ID_RUNONTIMER );
}

void CStressView::runTest( long nIndex )
{
	CWaitCursor wait;

	if ( nIndex >= 0 )
		m_nLastRunTest = nIndex;
	m_nRunTestCount++;
	DWORD dwTickCount = GetTickCount();
	long nItems = 0;
	if ( m_spControl != NULL )
		if ( m_spItems != NULL )
		{
			switch ( nIndex )
			{
				case 0:
				{
					nItems = 1000;
					break;
				}
				case 1:
				{
					nItems = 10000;
					break;
				}
				case 2:
				{
					nItems = 100000;
					break;
				}
				case 3:
				{
					nItems = 1000000;
					break;
				}
			}

			m_spControl->BeginUpdate();
			m_spItems->RemoveAllItems();
			long k = GetTickCount() % 255;
			BOOL bLarge = TRUE || ( nItems > 1000 );
			DATE dtStart = m_dtFirstVisibleDate;
			for ( long i = 0; i < nItems; i++ )
			{
				EXTREELib::HITEM hItem = m_spItems->InsertItem( NULL );
			}
			m_spControl->EndUpdate();
		}

	if ( CWnd* pFrame = AfxGetMainWnd())
	{

		CString strTitle = theApp.m_pszAppName;
		{
			strTitle += _T("; Exontrol.ExTree, Version: ");
			USES_CONVERSION;
			strTitle += OLE2T(m_spControl->Version);
		}
		{
			strTitle += _T("; TTE: ");
			strTitle += FormatNumber( GetTickCount() - dwTickCount );
			strTitle += _T(" ms");
		}
		{
			strTitle += _T("; Items: ");
			strTitle += FormatNumber( nItems );
		}
		{
			strTitle += _T("; Runs: ");
			strTitle += FormatNumber( m_nRunTestCount );
		}
		pFrame->SetWindowText( strTitle );
	}
}

void CStressView::OnBnClickedButton1()
{
	runTest(0);
}

void CStressView::OnBnClickedButton2()
{
	runTest(1);
}


void CStressView::OnBnClickedButton3()
{
	runTest(2);
}

void CStressView::OnBnClickedButton4()
{
	runTest(3);
}

void CStressView::OnBnClickedButton5()
{
	runTest(-1);
}


void CStressView::OnTimer(UINT_PTR nIDEvent)
{
	CFormView::OnTimer(nIDEvent);

	switch ( nIDEvent )
	{
		case ID_RUNONTIMER:
		{
			KillTimer( nIDEvent );
			if ( !( GetAsyncKeyState( VK_LBUTTON ) < 0 ) )
				if ( !( GetAsyncKeyState( VK_RBUTTON ) < 0 ) )
				{
					long nRunTest = m_nLastRunTest;
					if ( m_runRandom.GetCheck() )
						nRunTest = rand() % 4;
					runTest( nRunTest );
				}
			OnBnClickedChecktimer();
			break;
		}
	}
}
