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

 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         Sun Min (SLC)

.FILENAME       smtktoolJavaHeapView.cpp

.VERSION        01.00.00

.DATE           2004-06-17

.SHORT_DESCR    Runtime Heap for Shaped Ui

.SW_COMPONENT    SMTK EMULATOR

.SW_TYPE        

.EXIT_CODES

.CHANGE_CONTROL 
Version  Date        Changed by
         Reason of change
--------------------------------------------------------------------------------
01.00.00 2004-06-17  Sun Min (PEK)
                     Initial version
01.00.01 2004-06-18  Sun Min (PEK)
                     Use this file only for SHAPED UI
01.01.00 2004-08-18  Sun Min(PEK)
                     Functino paint(), SetJavaHeapViewPos(), InitLinkdList(),
                     OnCreate(), SaveHeapValue()() modified
01.01.01 2004-11-04  Sun Min(PEK)
                     Enable SMTK tool both in MDV and Shaped UI
*/

//2004-11-04 SunMin: modify to enable SMTK tool both in MDV and Shaped UI
#ifdef JAVA_SDK

#include "smsafxh.h"
#include "smtktoolJavaHeapViewh.h"
#include "sp_linkedlisth.h"
#include "time.h"
#include <afxmt.h>

// CSmtkJavaHeapView
// CJavaHeapInfo dialog



#ifdef JAVA_SDK
extern "C" long GlobalTotalJavaHeapSize;
extern "C" long GlobalLastJavaHeapSize;
#endif


#ifdef JAVA_SDK
extern "C" {
	long getHeapSize();
	long memoryFree();
}
#endif

IMPLEMENT_DYNCREATE(CSmtkJavaHeapView, CWnd)

CSmtkJavaHeapView::CSmtkJavaHeapView()
{
	m_startOfGrid = 0;
	m_CellWidth = 12;  // the width of the pane in background
}

CSmtkJavaHeapView::~CSmtkJavaHeapView()
{
}

BEGIN_MESSAGE_MAP(CSmtkJavaHeapView, CWnd)
	ON_WM_PAINT()
	ON_WM_CREATE()
	ON_WM_TIMER()
	ON_WM_DESTROY()
END_MESSAGE_MAP()


#ifdef _DEBUG
void CSmtkJavaHeapView::AssertValid() const
{
	CWnd::AssertValid();
}


void CSmtkJavaHeapView::Dump(CDumpContext& dc) const
{
	CWnd::Dump(dc);
}

#endif //_DEBUG


/*
 * In this function, paint the panes and the line 
 */

void CSmtkJavaHeapView::Paint()
{
	CMutex mutex;
	
	mutex.Lock();
	CPaintDC dc(this); // device context for painting
	CDC*   pdc;
	CBitmap* pMemBit=NULL;
	CPen* pPen1=NULL;
	CDC*   pdcMemory=NULL;
	pdcMemory=new CDC;
	pMemBit=new CBitmap;
	pPen1=new CPen;
	
	
	int currentGridPos;
	CRect rc = CRect(0,0,m_ViewWidth,m_ViewHeight);
    pdc = GetDC();
	pdcMemory->CreateCompatibleDC(pdc);
	pMemBit->CreateCompatibleBitmap(pdc,m_ViewWidth,m_ViewHeight);
	CBitmap* pOldBitmap=pdcMemory->SelectObject(pMemBit);
	pPen1->CreatePen(PS_SOLID,1,RGB(0,255,0));
	CPen* pOldPen=pdcMemory->SelectObject(pPen1);
	
	// here we start to draw the panes of the background
	pdcMemory->MoveTo(0,0);

	
	// vertical lines
	currentGridPos=m_startOfGrid;	
	while(currentGridPos<m_ViewWidth)
	{
		pdcMemory->MoveTo(m_ViewWidth - currentGridPos, 0);
		pdcMemory->LineTo(m_ViewWidth - currentGridPos, m_ViewBottom);
		currentGridPos+=m_CellWidth;
	}

	// horizontal lines
	currentGridPos=0;
	while(currentGridPos<m_ViewHeight)
	{
		pdcMemory->MoveTo( 0, m_ViewHeight-currentGridPos);
		pdcMemory->LineTo( m_ViewWidth, m_ViewHeight-currentGridPos);
		currentGridPos+=m_CellWidth;
	}

    
	// draw the animation line
	SMTKHEAPITEMDATA * pItem = (SMTKHEAPITEMDATA * )m_DLList->dltolast();
	int pos = m_DLList->dlposn();
	int Count = m_DLList->dlcount();
#ifdef JAVA_SDK
	long totalHeapSize=getHeapSize();
#endif
	float xPos,yPos;
	CPen* pPen2=NULL;
	pPen2=new CPen;
	pPen2->CreatePen(PS_SOLID,1,RGB(255,0,0));
	pdcMemory->SelectObject(pPen2);
	if(totalHeapSize!=0)
	{
	    int i=0;
	if (pItem)
	{
                        xPos=(m_ListAmount-i)*m_ListStepX;
		yPos=((float)pItem->heapSize/(float)totalHeapSize)* (float)m_ViewHeight; 
		pdcMemory->MoveTo((long)xPos,(long)yPos);
	}
            for(i=0;(i<Count)&&(i<=(m_ListAmount+1));i++)
	{
			 xPos=(m_ListAmount-i)*m_ListStepX;
		yPos=((float)pItem->heapSize/(float)totalHeapSize)*(float) m_ViewHeight; 
		pdcMemory->LineTo((long)xPos,(long)yPos); 
			 pItem = (SMTKHEAPITEMDATA *)m_DLList->dlgoback();
		pos = m_DLList->dlposn();
	}
	}
	pdc->BitBlt(0,0,m_ViewWidth,m_ViewHeight,pdcMemory,0,0,SRCCOPY);
	pdcMemory->SelectObject(pOldBitmap);
	pdcMemory->SelectObject(pOldPen);	
	if(pdcMemory!=NULL)
     delete pdcMemory;
	if(pMemBit!=NULL)
	 delete pMemBit;
	if(pPen1!=NULL)
		delete pPen1;
	if(pPen2!=NULL)
		delete pPen2;
    ReleaseDC(pdc);
	mutex.Unlock();
	
}

int CSmtkJavaHeapView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;

	// set the timer to normal
	m_nCurrentTimer=SetTimer(1002,1500,NULL);
	m_nTimerStatus=1;

	
	iMaxPointSaved=2000;
	InitLinkdList(m_ViewRight - m_ViewLeft);	
	return 0;
}

void CSmtkJavaHeapView::OnPaint()
{
	Paint();

}

/*
 * This function sets the pane step and heap data
 */
void CSmtkJavaHeapView::OnTimer(UINT nIDEvent)
{
	if (nIDEvent == m_nCurrentTimer)
	{
		m_startOfGrid++;
		if (m_startOfGrid == m_CellWidth) m_startOfGrid = 0;
			SaveHeapValue();
		OnPaint();
	}
	CWnd::OnTimer(nIDEvent);
}

void CSmtkJavaHeapView::OnDestroy()
{
	CWnd::OnDestroy();
	// TODO: Add your message handler code here
	SMTKHEAPITEMDATA * pItem = (SMTKHEAPITEMDATA *)m_DLList->dltofirst();
	int Count = m_DLList->dlcount();
	while (pItem)
	{
		pItem = (SMTKHEAPITEMDATA *)m_DLList->dlgofwd();
		m_DLList->dldelete();
	}	
	delete m_DLList;
	KillTimer(m_nCurrentTimer);
}

/*
 * for sort and find the item
 */
int SmtkCompare1(const void* d1, const void *d2) 
{
	SMTKHEAPITEMDATA * h1 = (SMTKHEAPITEMDATA *)d1;
	SMTKHEAPITEMDATA * h2 = (SMTKHEAPITEMDATA *)d2;	

	return ( (time_t)h1->time - (time_t)h2->time);
}




void CSmtkJavaHeapView::InitLinkdList(int amount)
{
	m_ListAmount = amount;
	m_DLList = new CLinkedList(sizeof(SMTKHEAPITEMDATA), SmtkCompare1, NULL);
	m_ListStepX =1; 

}

/*
 * This function is called to read current free java heap and save it to double linked list 
 */

void CSmtkJavaHeapView::SaveHeapValue()
{
	CMutex mutex;
	int iMaxPointSaved=2000;
	//long totalHeap;
	SMTKHEAPITEMDATA * pFirst;
	SMTKHEAPITEMDATA * pItem = new SMTKHEAPITEMDATA;
#ifdef JAVA_SDK
	pItem->heapSize = getHeapSize();
	pItem->heapSize=memoryFree();
#endif
	pItem->time = time(&pItem->time);

	
	
	// if the node amount is not reach the amout 
	// add it
	if (m_DLList->dlcount() <= iMaxPointSaved)
	{
		m_DLList->dladdins((LPVOID*)pItem);
	}
	else
	{
		// find the first node who's time is the earlist
		pFirst = (SMTKHEAPITEMDATA*)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();
	}

}

void CSmtkJavaHeapView::SetJavaHeapViewPos(CRect cRect)
{
	m_ViewBottom=cRect.bottom;
	m_ViewLeft=cRect.left;
	m_ViewTop=cRect.top;
	m_ViewRight=cRect.right;
	m_ViewWidth=m_ViewRight-m_ViewLeft;
	m_ViewHeight=m_ViewBottom-m_ViewTop;
	m_ListAmount=m_ViewWidth;
}

void CSmtkJavaHeapView::SetUpdateRate(int checkStatus)
{
	if(m_nTimerStatus!=checkStatus)
	{
        m_nOldTimer=m_nCurrentTimer;
		if(checkStatus==0)
            m_nCurrentTimer=SetTimer(1001,500,NULL);
        else if(checkStatus==1)
            m_nCurrentTimer=SetTimer(1002,1500,NULL);
		else m_nCurrentTimer=SetTimer(1003,3000,NULL);
		KillTimer(m_nOldTimer);
		m_nTimerStatus=checkStatus;
	}
}
	
#endif //define USE_SHAPED_UI
