/* -----------------------------------------------------------------------------

 Copyright (C) Siemens AG 1994-2001,  ALL RIGHTS RESERVED

 This software is protected by the inclusion of the above copyright
 notice. This software may not be provided or otherwise made available
 to, or used by, any other person. No title to or ownership of the
 software is  hereby  transferred.
 The information contained in this document is considered the
 CONFIDENTIAL and PROPRIETARY information of Siemens AG and may
 not be disclosed or discussed with anyone who is not employed by
 Siemens AG, unless the individual / company
 (i) has an express need to know such information, and
 (ii) disclosure of information is subject to the terms of a duly
 executed Confidentiality and Non-Disclosure Agreement between
 Siemens AG and the individual / company.



.AUTHOR         Zhang Jing (SLC)

.FILENAME       sp_jheapview.cpp

.VERSION        01.00.00

.DATE           2004-02-17

.SHORT_DESCR    Runtime Heap for Shaped Ui

.SW_COMPONENT   MMI PC-SIMULATION

.SW_TYPE        

.EXIT_CODES

.CHANGE_CONTROL 
Version  Date        Changed by
         Reason of change
--------------------------------------------------------------------------------
01.00.00 2004-02-17  Zhang Jing (SLC)
         Initial version

*/
#include "smsafxh.h"
#include "sp_JHeapViewh.h"
#include "sp_linkedlisth.h"
#include "time.h"
#include <afxmt.h>

// CJavaHeapView
// CJavaHeapInfo dialog
static int JavaHeapPosX = 10;
static int JavaHeapPosY = 80;


#ifdef JAVA_SDK
extern "C" long GlobalTotalJavaHeapSize;
extern "C" long GlobalLastJavaHeapSize;
#endif

#define JAVA_HEAP_TIMER    0x1001
#define JAVA_CELL_WIDTH    15



IMPLEMENT_DYNCREATE(CJavaHeapView, CWnd)

CJavaHeapView::CJavaHeapView()
{
	m_WidthOfGrid = 0;

	m_ViewLeft = JAVA_VIEW_LEFT;   // the start of the view left
	m_ViewTop = JAVA_VIEW_TOP;    // the start of the view top
	m_ViewRight = JAVA_VIEW_RIGHT;  // the right position of the view 
	m_ViewBottom = JAVA_VIEW_BOTTOM; // the bottom position of the view 
	m_CellWidth = JAVA_CELL_WIDTH;  // the width of the pane in background
	m_CountPoints = 0;


}

CJavaHeapView::~CJavaHeapView()
{
}

BEGIN_MESSAGE_MAP(CJavaHeapView, CWnd)
	ON_WM_PAINT()
	ON_WM_CREATE()
	ON_WM_TIMER()
	ON_WM_DESTROY()
END_MESSAGE_MAP()


// CJavaHeapView drawing

void CJavaHeapView::OnDraw(CDC* pDC)
{
}


// CJavaHeapView diagnostics

#ifdef _DEBUG
void CJavaHeapView::AssertValid() const
{
	CWnd::AssertValid();
}

void CJavaHeapView::Dump(CDumpContext& dc) const
{
	CWnd::Dump(dc);
}
#endif //_DEBUG


/*
 * In this function, paint the panes and the line 
 */
void CJavaHeapView::Paint()
{
	CMutex mutex;

	mutex.Lock();
	CPaintDC dc(this); // device context for painting
	CDC  * pdc;
	//HBrush br;
	int start, width, count, i;
	CRect rc = CRect(0,0,JAVA_VIEW_RIGHT,JAVA_VIEW_BOTTOM);
    pdc = GetDC();
	//ppp = GetDC();
	 
	
#if COORDINATE_MAP  // not defined
	// set coordinate
	pdc->SetMapMode(MM_ANISOTROPIC);
	pdc->SetViewportOrg(rc.right, rc.bottom);
	pdc->SetViewportExt(rc.right, rc.bottom);
	pdc->SetWindowOrg(rc.right, rc.bottom);
	pdc->SetWindowExt(rc.right, rc.bottom);
#endif


	// here we start to draw the panes of the background
	pdc->MoveTo(0,0);

	
	pdc->Rectangle(&rc);
	
	FillRect(pdc->m_hDC, &rc, (HBRUSH)(COLOR_BTNFACE+1));

	if (JavaHeapPosX == 65535) JavaHeapPosX = 0;
	count = (JAVA_VIEW_RIGHT - JAVA_VIEW_LEFT) / JAVA_CELL_WIDTH; 
	width = JAVA_VIEW_RIGHT - JAVA_VIEW_LEFT;

	// the start point of the vertical line
	// so the cell can move
	start = m_WidthOfGrid * JAVA_CELL_WIDTH / m_CellWidth;

	// vertical lines
	for (i = 0; i <	 count; i++)
	{
#if 1
		pdc->MoveTo(width - (start + i * JAVA_CELL_WIDTH), 0);
		pdc->LineTo(width- (start + i * JAVA_CELL_WIDTH), JAVA_VIEW_BOTTOM);
#else
		pdc->MoveTo((start + i * JAVA_CELL_WIDTH), JAVA_VIEW_BOTTOM);
		pdc->LineTo((start + i * JAVA_CELL_WIDTH), 0);

#endif
	}

	// horizontal lines
	for (i = 0; i <	 count; i++)
	{
		pdc->MoveTo( 0, (i + 1) * JAVA_CELL_WIDTH);
		pdc->LineTo( JAVA_VIEW_RIGHT, (i + 1) * JAVA_CELL_WIDTH);
	}

#if 0
	//test
	pdc->MoveTo (JavaHeapPosX,50);
	JavaHeapPosX += 5;
	pdc->LineTo (JavaHeapPosX,50);
#endif

	// draw the animation line
	HEAPITEMDATA * pItem = (HEAPITEMDATA * )m_DLList->dltofirst();
	int pos = m_DLList->dlposn();
	int Count = m_DLList->dlcount();
	//pdc->MoveTo(m_ViewRight, m_ViewBottom);
	if (pItem)
	pdc->MoveTo((m_ListAmount - (Count - pos)) * m_ListStepX, 
		//(m_ViewTop-m_ViewBottom)-(pItem->heapSize/10000 * m_ListStepY - 20)); 
		(pItem->heapSize/10000 * m_ListStepY - 100)); 

	while (pItem)
	{
		pdc->LineTo((m_ListAmount - (Count - pos)) * m_ListStepX, 
			//(m_ViewTop-m_ViewBottom)-(pItem->heapSize/10000 * m_ListStepY - 20)); 
			(pItem->heapSize/10000 * m_ListStepY - 100)); 
		pItem = (HEAPITEMDATA *)m_DLList->dlgofwd();
		pos = m_DLList->dlposn();
	}

	mutex.Unlock();
}

int CJavaHeapView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	// for draw the panes of the background
	SetTimer(JAVA_HEAP_TIMER,1000,NULL);

	InitLinkdList(m_ViewRight - m_ViewLeft);

	// 
	return 0;
}

void CJavaHeapView::OnPaint()
{
	Paint();

}

/*
 * This function sets the pane step and heap data
 */
void CJavaHeapView::OnTimer(UINT nIDEvent)
{
	if (nIDEvent == JAVA_HEAP_TIMER)
	{
		
		// 15 step draw panes
		m_WidthOfGrid++;
		if (m_WidthOfGrid == m_CellWidth) m_WidthOfGrid = 0;
			RunTimeHeapPos();
		OnPaint();
	}

	CWnd::OnTimer(nIDEvent);
}

void CJavaHeapView::OnDestroy()
{
	CWnd::OnDestroy();
	// TODO: Add your message handler code here
	HEAPITEMDATA * pItem = (HEAPITEMDATA *)m_DLList->dltofirst();
	int Count = m_DLList->dlcount();


	while (pItem)
	{
		pItem = (HEAPITEMDATA *)m_DLList->dlgofwd();
		m_DLList->dldelete();
	}
	
	delete m_DLList;
}

/*
 * for sort and find the item
 */
int Compare1(const void* d1, const void *d2) 
{
	HEAPITEMDATA * h1 = (HEAPITEMDATA *)d1;
	HEAPITEMDATA * h2 = (HEAPITEMDATA *)d2;	

	return ( (time_t)h1->time - (time_t)h2->time);
}

/*
 *  release the heapitem memory, if there needs 
 */
int FreeData(LPVOID p)
{
	return 0;
}

void CJavaHeapView::InitLinkdList(int amount)
{
	m_ListAmount = amount;

	m_DLList = new CLinkedList(sizeof(HEAPITEMDATA), Compare1, NULL);

	m_ListStepX = 1;//= (m_ViewRight - m_ViewLeft) / m_ListAmount; 


}

/*
 * This function is called by the main frame window which set status bar info
 */
void CJavaHeapView::RunTimeHeapPos()
{
	CMutex mutex;

	//mutex.Lock();
	HEAPITEMDATA * pFirst;
	HEAPITEMDATA * pItem = new HEAPITEMDATA;
#ifdef JAVA_SDK
	pItem->heapSize = GlobalLastJavaHeapSize;
#endif
	pItem->time = time(&pItem->time);

#ifdef JAVA_SDK
	// init the y coordinate
	if (GlobalTotalJavaHeapSize)
#endif
	m_ListStepY = 1;//= (m_ViewBottom - m_ViewTop) / (GlobalTotalJavaHeapSize/1000);

	// if the node amount is not reach the amout 
	// add it
	if (m_DLList->dlcount() <= m_ListAmount)
	{
		m_DLList->dladdins((LPVOID*)pItem);
	}
	else
	{
		// find the first node who's time is the earlist
		pFirst = (HEAPITEMDATA*)m_DLList->dltofirst();
		// replace the node with the lastest
		m_DLList->dlreplace((LPVOID)pItem);
		// sort it, so the first always the earlist 
		m_DLList->dlqsort();
	}

}

