// srcwnd.cpp : implementation file  search to setbp.cpp
//

#include "stdafx.h"
#include "tutorial.h"
#include "mainfrm.h"
#include "srcwnd.h"
#include "Bitmap.h"
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

extern BOOL g_bAuto;
extern BOOL g_mbCanDoNext;
/////////////////////////////////////////////////////////////////////////////
// CTWnd

CTWnd::CTWnd(UINT idMenu,UINT idSub,BOOL bTutorial,BOOL bSetByUser/*=TRUE*/)
      :CMDIChildWnd(),m_bTutorial(bTutorial),m_bSetByUser(bSetByUser) 
                                             // when destroy ByUser==0?
{
	 m_pFrameMenu = new CMenu();
	 if(m_pFrameMenu->LoadMenu(idMenu)==NULL)
	   {
	    delete m_pFrameMenu;
	    m_pFrameMenu=0;
	   }
	 else   
	   {
	    m_pWndMenu=m_pFrameMenu->GetSubMenu(idSub); 
	   } 
  m_bMouseClk=1;	   
}

CTWnd::~CTWnd()
{
}         

BEGIN_MESSAGE_MAP(CTWnd,CMDIChildWnd)
	//{{AFX_MSG_MAP(CTWnd)
	ON_WM_CREATE()
	ON_WM_DESTROY()
	ON_WM_NCLBUTTONDBLCLK()
	ON_WM_NCLBUTTONDOWN()
	ON_WM_NCLBUTTONUP()
	ON_WM_NCMOUSEMOVE()
	ON_WM_MDIACTIVATE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CTWnd::ChangToUseOperate(BOOL bSet/*=1*/)
{ 
  if(bSet)
    {
		 m_bTutorial=0; 
		 m_bMouseClk=1;
		 FilterLMClk(0,0);
		 ((CMainFrame *)(AfxGetApp()->m_pMainWnd))->SetByUser(TRUE);	
	}
  else
  	{
	    m_bTutorial=1; 
		m_bMouseClk=1;
	   	FilterLMClk(1,GetSafeHwnd());
  	    ((CMainFrame *)(AfxGetApp()->m_pMainWnd))->SetByUser(0);	
  	} 
}
/////////////////////////////////////////////////////////////////////////////
// CTWnd message handlers
int CTWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here        
	((CMainFrame *)(AfxGetApp()->m_pMainWnd))->SetWnd(this);

	if(m_bTutorial)
	  {   
	   	//FilterLMClk(1,GetSafeHwnd());
  	    ((CMainFrame *)(AfxGetApp()->m_pMainWnd))->SetByUser(0);	
	  } 
	 else
	   ((CMainFrame *)(AfxGetApp()->m_pMainWnd))->SetByUser(TRUE);

	return TRUE;  
}

void CTWnd::OnDestroy()
{                                 
   if(m_bSetByUser)
     ((CMainFrame *)(AfxGetApp()->m_pMainWnd))->SetByUser(0);
   
   FilterLMClk(0,0);
//   ((CMainFrame *)(AfxGetApp()->m_pMainWnd))->SetWnd(0);     

   	if(m_pFrameMenu)
       delete m_pFrameMenu;
	CWnd::OnDestroy();
	
	// TODO: Add your message handler code here
}
void CTWnd::OnNcLButtonDblClk(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
	
//	CWnd::OnLButtonDblClk(nFlags, point);
}

void CTWnd::OnNcLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
	if(m_bTutorial==ST_NOTTUTORIAL && m_bMouseClk)
	  if(nFlags==HTHSCROLL || nFlags==HTVSCROLL)
  	     CWnd::OnNcLButtonDown(nFlags, point);
}

void CTWnd::OnNcLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
	if(m_bTutorial==ST_NOTTUTORIAL && m_bMouseClk)
	  if(nFlags==HTHSCROLL || nFlags==HTVSCROLL)
	     CWnd::OnNcLButtonUp(nFlags, point);
}

void CTWnd::OnNcMouseMove(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
	
//	CWnd::OnMouseMove(nFlags, point);
}

void CTWnd::OnMDIActivate(BOOL bActivate, CWnd* pActivateWnd, CWnd* pDeactivateWnd)
{
	CMDIChildWnd::OnMDIActivate(bActivate, pActivateWnd, pDeactivateWnd);
	
	// TODO: Add your message handler code here
	if(bActivate)
	  {

		if(m_bTutorial)
		  {   
		   	FilterLMClk(1,GetSafeHwnd());
	  	    ((CMainFrame *)(AfxGetApp()->m_pMainWnd))->SetByUser(0);	
		  } 

		if(m_pFrameMenu)
		  {
			((CMainFrame *)
			 (AfxGetApp()->m_pMainWnd))->MDISetMenu(m_pFrameMenu,0);//m_pWndMenu);
			((CMainFrame *)
			 (AfxGetApp()->m_pMainWnd))->DrawMenuBar();
		  }      
		
		((CMainFrame *)(AfxGetApp()->m_pMainWnd))->SetWnd(this);
  
	  }
	else
	  {              
	    FilterLMClk(0,0);
	    CMenu *pMenu;
	   	pMenu=((CMainFrame *)
		      (AfxGetApp()->m_pMainWnd))->GetMainMenu();
		      
		((CMainFrame *)
		 (AfxGetApp()->m_pMainWnd))->MDISetMenu(pMenu,0);
		((CMainFrame *)
		 (AfxGetApp()->m_pMainWnd))->DrawMenuBar();
	  }	  
}

/////////////////////////////////////////////////////////////////////////////
// CSCrollWnd

CSCrollWnd::CSCrollWnd(UINT idMenu,UINT idSub,BOOL bTutorial,BOOL bSetByUser/*=TRUE*/)
           :CTWnd(idMenu,idSub,bTutorial,bSetByUser)
{
  // Font size;
     TEXTMETRIC tm;
     CDC * pDC = GetDC();
     pDC->GetTextMetrics(&tm);
     m_nFontHeight = 13;//tm.tmHeight;// + tm.tmExternalLeading;
     m_nFontWidth  = tm.tmAveCharWidth;
     ReleaseDC(pDC); 
     m_nVertPos=0;
     m_nHorzPos=0;   
     m_nLines=37;
     m_nCLines=0;
     m_nXCaret=0; 
     m_pointCaret.x=0;
     m_pointCaret.y=0;
     m_pBitContent=0;
}

CSCrollWnd::~CSCrollWnd()
{
}

BEGIN_MESSAGE_MAP(CSCrollWnd, CTWnd)
	//{{AFX_MSG_MAP(CSCrollWnd)
	ON_WM_CREATE()
	ON_WM_DESTROY()
	ON_WM_HSCROLL()
	ON_WM_PAINT()
	ON_WM_VSCROLL()
	ON_WM_KILLFOCUS()
	ON_WM_SETFOCUS()
	ON_WM_KEYDOWN()
	ON_WM_SIZE()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

void CSCrollWnd::ChangToUseOperate(BOOL bSet)
{
  CTWnd::ChangToUseOperate(bSet);
}

/////////////////////////////////////////////////////////////////////////////
// CSCrollWnd message handlers

int CSCrollWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CTWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here
    SetScrollRange(SB_VERT,0,m_nMaxHeight,FALSE);
    SetScrollPos(SB_VERT,m_nVertPos,TRUE);
    SetScrollRange(SB_HORZ,0,m_nMaxWidth,FALSE);
    SetScrollPos(SB_HORZ,m_nHorzPos,TRUE);
	return 0;
}

void CSCrollWnd::OnDestroy()
{
	CTWnd::OnDestroy();
	
	// TODO: Add your message handler code here
	if(m_pBitContent)
	  {
	   m_pBitContent->DeleteObject();
	   delete m_pBitContent;
	  } 
	
}
void CSCrollWnd::OnSize(UINT nType, int cx, int cy)
{
	CTWnd::OnSize(nType, cx, cy);
	
	// TODO: Add your message handler code here
	m_xClient  = cx;
    m_yClient  = cy;   
    m_nXPage   = (m_xClient/m_nFontHeight);
    m_nYPage   = (m_yClient/m_nFontHeight);
	
}

void CSCrollWnd::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
	// TODO: Add your message handler code here and/or call default 
	if(m_bTutorial)
	   goto SRCGRP_LABEL;
	   
	switch(nChar)
	 {
	  case VK_UP:                               
	       m_pointCaret.y--;  
	       if(m_pointCaret.y<=0)
	       SendMessage(WM_VSCROLL,SB_LINEUP,0L);
	       break;
	  case VK_DOWN:       
	       m_pointCaret.y++;
	       if(m_pointCaret.y>=m_yClient/m_nFontHeight)
	          SendMessage(WM_VSCROLL,SB_LINEDOWN,0L);
	       break;
	  case VK_PRIOR:      
	       SendMessage(WM_VSCROLL,SB_PAGEUP,0L);
	       break;
	  case VK_NEXT:
	       SendMessage(WM_VSCROLL,SB_PAGEDOWN,0L);
	       break;
	  case VK_LEFT:    
	       m_pointCaret.x--;
	       if(m_pointCaret.x<=m_nXCaret)
	          SendMessage(WM_HSCROLL,SB_LINEUP,0L);
	       break;
	  case VK_RIGHT:      
	       m_pointCaret.x++;
	       if(m_pointCaret.x>=((m_xClient-m_nXCaret)/m_nFontWidth))
	         SendMessage(WM_HSCROLL,SB_LINEDOWN,0L);
	       break;
	  case VK_HOME:      
	       m_pointCaret.x=m_nXCaret;
	       SendMessage(WM_HSCROLL,SB_TOP,0L);
	       break;
	  case VK_END:        
	       m_pointCaret.x=(m_xClient-m_nXCaret)/m_nFontWidth;         
	       SendMessage(WM_VSCROLL,SB_BOTTOM,0L);
	       break;                          
	  default:
	       break;
	  
	 }       
	
	m_pointCaret.x=(max(0,min(m_pointCaret.x,m_xClient/m_nFontWidth)));
	m_pointCaret.y=max(0,min(m_pointCaret.y,m_yClient/m_nFontHeight)); 
	POINT point=m_pointCaret;
	point.x =m_nXCaret+m_pointCaret.x*m_nFontWidth;
	point.y =m_pointCaret.y*m_nFontHeight;
	SetCaretPos(point); 

SRCGRP_LABEL:	
	CTWnd::OnKeyDown(nChar, nRepCnt, nFlags);
}

void CSCrollWnd::OnHScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	// TODO: Add your message handler code here and/or call default
	if(m_bTutorial)
	   goto SRCGRP_HSCROLL;   
	   
	m_nHorzOld=m_nHorzPos;
	switch(nSBCode)
	 {
	    case SB_LINEUP:
	         m_nHorzPos--; 
	         break;
	    case SB_LINEDOWN:
	         m_nHorzPos++; 
	         break;
	    case SB_PAGEUP:
	    	 m_nHorzPos -= m_nXPage; 
	         break;
	    case SB_PAGEDOWN: 
	    	 m_nHorzPos += m_nXPage; 
	         break;
	    case SB_TOP:
	         m_nHorzPos=m_nXCaret;
	         break;
	    case SB_BOTTOM:
	         m_nHorzPos = m_nMaxWidth;
	         break;
	    case SB_THUMBTRACK:
	         m_nHorzPos=int(nPos);
	         break;
	    default:
	         break;
	 }
	
	m_nHorzPos=max(0,min(m_nHorzPos,m_nMaxWidth/m_nFontWidth-m_nXPage));
	if(m_nHorzPos>300)
	   {
	    m_nHorzPos=300;
	    return;
	   }
	if(m_nHorzPos != GetScrollPos(SB_HORZ))
	  { 
	    CRect r;
	    GetClientRect(&r);
	    r.left+=m_nXCaret;
	    int x = (m_nHorzOld-m_nHorzPos)*m_nFontWidth;
	    ScrollWindow(x,0,&r,&r);//;NULL);
	    UpdateWindow();
	    SetScrollPos(SB_HORZ,m_nHorzPos*m_nFontWidth,TRUE);
	  }               

SRCGRP_HSCROLL:	
	CTWnd::OnHScroll(nSBCode, nPos, pScrollBar);
}

void CSCrollWnd::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar)
{
	// TODO: Add your message handler code here and/or call default
	if(m_bTutorial)
	   goto SRCGRP_VSCROLL;
	m_nVertOld=m_nVertPos;
	switch(nSBCode)
	 {
	    case SB_LINEUP:
	         m_nVertPos--; 
	         break;
	    case SB_LINEDOWN:
	         m_nVertPos++; 
	         break;
	    case SB_PAGEUP:
	    	 m_nVertPos -= m_nYPage; 
	         break;
	    case SB_PAGEDOWN: 
	    	 m_nVertPos += m_nYPage; 
	         break;
	    case SB_TOP:
	         m_nVertPos=0;
	         break;
	    case SB_BOTTOM:
	         m_nVertPos = m_nMaxHeight;
	         break;
	    case SB_THUMBTRACK:
	         m_nVertPos=int(nPos);
	         break;
	    default:
	         break;
	 }                         
	m_nVertPos=max(0,min(m_nVertPos,m_nLines));
	if(m_nVertPos != GetScrollPos(SB_VERT))
	  {
        int y=(m_nVertOld-m_nVertPos)*m_nFontHeight;
	    ScrollWindow(0,y,NULL,NULL);
	    if(y<0)
	       m_nCLines++;
	    else
	     if(y>0)
	       m_nCLines--;            

	    SetScrollPos(SB_VERT,m_nVertPos*m_nFontHeight,TRUE);
	  }               
	                       
SRCGRP_VSCROLL:	                       
	CTWnd::OnVScroll(nSBCode, nPos, pScrollBar);
}
void CSCrollWnd::OnPaint()
{      
	CPaintDC dc(this); // device context for painting
	if(m_pBitContent==NULL)
	  return;
	// TODO: Add your message handler code here
	BITMAP bm;
	CRect rect;
	GetClientRect(&rect);
	int cy=rect.Height()-rect.Height()/m_nFontHeight;
	CDC *pDC=new CDC;
	pDC->CreateCompatibleDC(&dc);
	m_pBitContent->GetObject(sizeof(BITMAP),&bm);
	m_nMaxHeight=bm.bmHeight;
	m_nMaxWidth=bm.bmWidth;
	dc.SaveDC();
	pDC->SaveDC();
	pDC->SelectObject(m_pBitContent);

	dc.BitBlt(	
	          dc.m_ps.rcPaint.left,//+m_nXCaret,
	          dc.m_ps.rcPaint.top,
	          dc.m_ps.rcPaint.right-dc.m_ps.rcPaint.left,//-m_nXCaret,
	          dc.m_ps.rcPaint.bottom-dc.m_ps.rcPaint.top,
	          pDC,
	          m_nHorzPos*m_nFontWidth+dc.m_ps.rcPaint.left,//+m_nXCaret,
	          m_nVertPos*m_nFontHeight+dc.m_ps.rcPaint.top,SRCCOPY);
	          
	dc.BitBlt(0,
	          dc.m_ps.rcPaint.top,
	          m_nXCaret,
	          dc.m_ps.rcPaint.bottom-dc.m_ps.rcPaint.top,
	          pDC,
	          0,
	          m_nVertPos*m_nFontHeight+dc.m_ps.rcPaint.top,SRCCOPY);
	          
	dc.RestoreDC(-1);
	pDC->RestoreDC(-1);
	pDC->DeleteDC();
	delete pDC;

	// Do not call CTWnd::OnPaint() for painting messages
}


void CSCrollWnd::OnKillFocus(CWnd* pNewWnd)
{
	CTWnd::OnKillFocus(pNewWnd);
	
	// TODO: Add your message handler code here
	HideCaret();
}

void CSCrollWnd::OnSetFocus(CWnd* pOldWnd)
{
	CTWnd::OnSetFocus(pOldWnd);
	
	// TODO: Add your message handler code here
	CreateSolidCaret(2,m_nFontHeight);    
	ShowCaret();          

	POINT p=m_pointCaret;
	p.x+=m_nXCaret;
    SetCaretPos(p);
	
}

/*-----------------------------------------------------------------*/
/*               to display source window                          */
/*-----------------------------------------------------------------*/ 
void CMainFrame::OnShowSrcWnd()
{
  m_pWnd=0;                           
 if(!bByUser)
   {
     CSrcWnd *pSrcWnd= new CSrcWnd(IDR_SOURCE,6,ST_TUTORIAL);
     pSrcWnd->ShowWindow(SW_SHOW);
     //m_pWnd=pSrcWnd;
     //pSrcWnd->SetFocus();
   }  
 else
  {
     CSrcWnd *pSrcWnd= new CSrcWnd(IDR_SOURCE,6,ST_NOTTUTORIAL);//,IDW_SRC_WND);
     pSrcWnd->ShowWindow(SW_SHOW);
     //m_pWnd=pSrcWnd;
  } 
 
}

 
/////////////////////////////////////////////////////////////////////////////
// CSrcWnd

CSrcWnd::CSrcWnd(UINT idMenu,UINT idSub,BOOL bTutorial,BOOL bSetByUser/*=TRUE*/)
        :CSCrollWnd(idMenu,idSub,bTutorial,bSetByUser)
{             
     UINT nIdx[]={0x0,0x2,0x3,0x6,0x7,0x8,0x9,0xb,0xc,0xf,0x10,0x11,
                  0x12,0x14,0x15,0x18,0x19,0x1a,0x1b,0x1b,0x1c,0x1d,
                  0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x29,0x2a,
                  0x2c,0x2e,0x30,0x33,0x34,0x35,0x37,0x38,0x888};
	 m_pLineBp =(BOOL *) new BOOL[100];
	 _fmemset(m_pLineBp,0,99);
	 m_pLineBp[17]=0;
     m_nOldStep=-1;    
  	 if(g_bAuto)
	 {
	   g_mbCanDoNext=0;
	   AfxGetApp()->m_pMainWnd->KillTimer(IDAUTO);
	  }
         
     m_pBitContent = new CBitmap;
     m_pBpMap      = new CBitmap;
     m_pOldBp      = new CBitmap;
     m_pBpMap->LoadBitmap(IDB_BP);
     m_nWin_Modal=SR_ASSAMBLE;//SR_SOURCE; 
     m_nBK=48;      
     m_nStep=0;
	 Create(  NULL,//m_sClassName.GetBuffer(m_sClassName.GetLength()),
	         "Source",             //Window Name
	          WS_OVERLAPPEDWINDOW|WS_CHILD|WS_VISIBLE|
	          WS_HSCROLL|WS_VSCROLL);
	 m_hMemIdx = GlobalAlloc(GPTR,sizeof(UINT)*100);          
	 m_pLineIndex = (UINT *)GlobalLock(m_hMemIdx);
	 for(int i=0;i<=sizeof(nIdx);i++)
	     m_pLineIndex[i]=nIdx[i];
	 GlobalUnlock(m_hMemIdx);    
}

CSrcWnd::~CSrcWnd()
{
}

void CSrcWnd::GetLineBpInfo(CTListBox *pListBox,CTEdit *pEdit)
{ 
 m_pLineIndex = (UINT *) GlobalLock(m_hMemIdx);
 char szText[10];
 char szlpText[20];      
 for(int i=0;i<39;i++)
    {     
     if(i>=0 && i<=13)
        lstrcpy(szText,"17");
     else
     if(i>=14 && i<=32)
        lstrcpy(szText,"18");
     else
        lstrcpy(szText,"19");
        
     if(m_pLineBp[i+1])
       {          
        char szLine[10];
        char szLineNo[10];
        itoa(m_pLineIndex[i],szLine,16);
        switch(lstrlen(szLine))
           {
            case 1:
                 sprintf(szLineNo,"000%s",szLine);
                 break;
            case 2:    
                 sprintf(szLineNo,"00%s",szLine);
                 break;
           }
        sprintf(szlpText,"+  %s #PRIME1#%s",szLineNo,szText);
        pListBox->AddString(szlpText);
        pEdit->SetWindowText(szLineNo);
       }
    } 
  GlobalUnlock(m_hMemIdx);  
}   

void CSrcWnd::AddBp(long Line,CTListBox *pListBox)
{         
  int nLine=-1;
  char szText[5];
  m_pLineIndex = (UINT *) GlobalLock(m_hMemIdx);
  for(int i=0;i<38;i++)
     {      
	     if(i>=0 && i<=13)
	        lstrcpy(szText,"17");
	     else
	     if(i>=14 && i<=32)
	        lstrcpy(szText,"18");
	     else
	        lstrcpy(szText,"19");
	
	     if(long(m_pLineIndex[i]) == Line)
	        {
		        char szLine[10];
		        char szLineNo[10];
		        char szlpText[20]; 
		        if(m_pLineBp[i+1])
		          {
		           MessageBeep(-1);
		           return;
		          }
		        m_pLineBp[i+1]=1;
		        itoa(m_pLineIndex[i],szLine,16);
		        switch(lstrlen(szLine))
		           {
		            case 1:
		                 sprintf(szLineNo,"000%s",szLine);
		                 break;
		            case 2:    
		                 sprintf(szLineNo,"00%s",szLine);
		                 break;
		           }
		        sprintf(szlpText,"+  %s #PRIME1#%s",szLineNo,szText);
		        pListBox->AddString(szlpText);
		        nLine = i;
		        break;
	        }
/*
	    else     
	     {      
          MessageBeep(-1);
	      return;
	     } 
*/
     } 
                         
  if(nLine <0)
    { MessageBeep(-1);
	  return;}
                         
  GlobalUnlock(m_hMemIdx);  
    
  BITMAP bm;
  m_pBpMap->GetObject(sizeof(BITMAP),&bm);  
  CClientDC dc(this);
  CDC *pSrcDC = new CDC;
  CDC *pDesDC = new CDC;
  pSrcDC->CreateCompatibleDC(&dc);
  pDesDC->CreateCompatibleDC(&dc);
  pSrcDC->SaveDC();
  pDesDC->SaveDC();
  pSrcDC->SelectObject(m_pBpMap);
  pDesDC->SelectObject(m_pBitContent);
  pDesDC->BitBlt(4,(nLine)*m_nFontHeight,bm.bmWidth,bm.bmHeight,
                  pSrcDC,0,0,SRCCOPY);
  pSrcDC->RestoreDC(-1);
  pDesDC->RestoreDC(-1);
  pSrcDC->DeleteDC();
  pDesDC->DeleteDC();
  delete pDesDC;
  delete pSrcDC;
}
                     
BOOL CSrcWnd::DeleteBp(CTListBox *pListBox)
{          
 int nLine;                 
 int nCurLine=0;
 
 if(pListBox==NULL)
   {
    nLine=-1;
   } 
 else  
   if((nLine = pListBox->GetCurSel())==LB_ERR)
     {
      MessageBeep(-1);
      return 0;
     }
   else   
    {
     pListBox->DeleteString((UINT)nLine);
     nLine++;
    } 
  
 BITMAP bm;
 CDC *pDC = new CDC;
 CClientDC dc(this);
 pDC->CreateCompatibleDC(&dc);
 pDC->SaveDC();
 pDC->SelectObject(m_pBitContent);
 m_pBpMap->GetObject(sizeof(BITMAP),&bm); 
  
 for(int i=0; i<38 ;i++)
    {
     if(m_pLineBp[i+1])  
      {
	     nCurLine++;
	     if(nLine==-1)
	        {
	         m_pLineBp[i+1]=0;
	         pDC->PatBlt(4,i*m_nFontHeight,bm.bmWidth,bm.bmHeight,WHITENESS);
	        }
	     else  
	     if(nCurLine==nLine)
	       {
	         m_pLineBp[i+1]=0;
	         pDC->PatBlt(4,i*m_nFontHeight,bm.bmWidth,bm.bmHeight,WHITENESS);
	       } 
	  }     
    }//for
  pDC->RestoreDC(-1);
  pDC->DeleteDC();
  delete pDC; 
  return 1;
}
void CSrcWnd::ChangeMode(UINT nMode)                     
{        
    UINT nBit1;
    UINT nBit2;         
    char szText[200];
    int nBp;
    
    m_nWin_Modal = nMode;
	switch(m_nWin_Modal)
	  {
	   case SR_SOURCE: 
	        nBit1=IDB_SRC1;
	        nBit2=IDB_SRC2;
	        lstrcpy(szText,"Source: C:\\EP-SLD\\SAMPLES\\PRIME.C");
	        nBp=68;
	        break;
	   case SR_ASSAMBLE: 
	        nBit1=IDB_ASM1;
	        nBit2=IDB_ASM2;
	        lstrcpy(szText,"Source: [Disassembly]");
	        nBp=62; 
	        break;
	   case SR_MIXED:
	        nBit1=IDB_MIX1;
	        nBit2=IDB_MIX2;
	        lstrcpy(szText,"Source: C:\\EP-SLD\\SAMPLES\\PRIME.C");
	        nBp=68;
	        break;
	   default:
	        break;
	  }                  
    BuildContent(nBit1,nBit2,m_pBitContent,
                 nBp,TRUE,szText);
	Invalidate();
	UpdateWindow();
}

void CSrcWnd::Step(int nStep)
{
	m_nStepLine=nStep;
	SetStepLine(m_nStepLine);
}
BEGIN_MESSAGE_MAP(CSrcWnd,CSCrollWnd)
	//{{AFX_MSG_MAP(CSrcWnd)
	ON_WM_CREATE()
	ON_WM_DESTROY()
	ON_WM_MOUSEMOVE()
	ON_WM_LBUTTONDOWN()
	ON_COMMAND(ID_RUN_BREAKPOINT, OnRunBreakpoint)
	ON_WM_MDIACTIVATE()
	ON_COMMAND(ID_RUN_GO, OnRunGo)
	ON_COMMAND(ID_VIEW_MIXED, OnViewMixed)
	ON_COMMAND(ID_VIEW_SOURCEONLY, OnViewSourceonly)
	ON_COMMAND(ID_RUN_STEPOVER, OnRunStepover)
	ON_WM_TIMER()
	ON_WM_SETFOCUS()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()
void CSrcWnd::OnRunStepover()
{
	// TODO: Add your command handler code here
	UINT ID=((CMainFrame *)(AfxGetApp()->m_pMainWnd))->GetMenuAct();
	BOOL bUse=((CMainFrame *)(AfxGetApp()->m_pMainWnd))->GetByUser();
	if(ID != UINT(ID_RUN_STEPOVER|ID_RUN_STEPINTO) || !bUse)
	  {
	    MessageBeep(-1);
	    return;
	  }            
	  
	AfxGetApp()->DoWaitCursor(0);
	AfxGetApp()->DoWaitCursor(1);
	SetMouse(0);
	SetTimer(TIMER,55,NULL);
}
void CSrcWnd::OnVRunStepover()
{
	AfxGetApp()->DoWaitCursor(0);
	AfxGetApp()->DoWaitCursor(1);
	SetMouse(0);
	SetTimer(TIMER,55,NULL);
}
void CSrcWnd::OnTimer(UINT nIDEvent)
{
	// TODO: Add your message handler code here and/or call default
	static int nCount=0;                  
	nCount++;
	AfxGetApp()->DoWaitCursor(1);
	
	if(nCount>20)
	  {        
	   	int step[]={17,18,19,18,19,18,19,18,20,21,20,21,20,21,20,21,20,21,20,21,
	            20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,20,21,
	            20,21,20,21,20,21,20,21,20};

		KillTimer(TIMER);
		AfxGetApp()->DoWaitCursor(-1);
		if(m_nStep>=sizeof(step))
		   m_nStep=0;
		m_nStep++;
		Step(step[m_nStep]-1);
		nCount=0;
		SetMouse(1);   
		::SetCursor(::LoadCursor(NULL,IDC_ARROW));
        ShowCursor(TRUE);
	 }	
	CSCrollWnd::OnTimer(nIDEvent);
}

void CSrcWnd::OnViewMixed()
{
	// TODO: Add your command handler code here   
	UINT ID=((CMainFrame *)(AfxGetApp()->m_pMainWnd))->GetMenuAct();
	if(ID != (ID_VIEW_MIXED|ID_VIEW_SOURCEONLY))
	  {
	    MessageBeep(-1);
	    return;
	  }   
	   
	if(((CMainFrame *)(AfxGetApp()->m_pMainWnd))->
	   GetSrcWnd())                                 
	   ChangeMode(SR_MIXED);
}

void CSrcWnd::OnViewSourceonly()
{
	// TODO: Add your command handler code here
	UINT ID=((CMainFrame *)(AfxGetApp()->m_pMainWnd))->GetMenuAct();
	if(ID != (ID_VIEW_MIXED|ID_VIEW_SOURCEONLY))
	  {
	    MessageBeep(-1);
	    return;
	  }   

	if(((CMainFrame *)(AfxGetApp()->m_pMainWnd))->
	   GetSrcWnd())   
	   ChangeMode(SR_SOURCE); 
}

void CSrcWnd::OnRunGo()
{
	// TODO: Add your command handler code here

	if(((CMainFrame *)(AfxGetApp()->m_pMainWnd))->GetMenuAct()!=
	      ID_RUN_GO)
	   {
	    MessageBeep(-1);
	    return;
	   }      
	
	ChangeMode(SR_SOURCE); 
	if(((CMainFrame *)AfxGetApp()->m_pMainWnd)->GetCaseID()==ID_CASE_GO)
	  { 
	   Step(16);
	   m_bSetBk=1;                                
	   PostMessage(WM_LBUTTONDOWN,0,MAKELONG(12,215));
	   
	   if(((CMainFrame *)AfxGetApp()->m_pMainWnd)->GetByUser())
	      ((CMainFrame *)AfxGetApp()->m_pMainWnd)->SetByUser(0);
	  } 

}

void CSrcWnd::ChangToUseOperate(BOOL bSet)
{ 
  m_nStep=0;
  CSCrollWnd::ChangToUseOperate(bSet);
  
}

/////////////////////////////////////////////////////////////////////////////
// CSrcWnd message handlers
int CSrcWnd::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CSCrollWnd::OnCreate(lpCreateStruct) == -1)
		return -1;                                           
	m_bDelete=0;	
	ShowScrollBar(SB_BOTH);
	((CMainFrame *)(AfxGetApp()->m_pMainWnd))->SetSrcWnd(this);
	// TODO: Add your specialized creation code here
	if(((CMainFrame *)(AfxGetApp()->m_pMainWnd))->
	    GetCaseID() == ID_CASE_MODE_SEL)
	   MoveWindow(0,0,330,380);
	else
	   MoveWindow(0,0,400,300);
//	if(!m_bTutorial)
      ((CMainFrame *)(AfxGetApp()->m_pMainWnd))->SetByUser(0);
    CRect rectClient;
    GetClientRect(&rectClient);

    m_hCursor=AfxGetApp()->LoadCursor(IDC_BULLEYE);
    m_hArrow=::LoadCursor(NULL,IDC_ARROW);

    BuildContent(IDB_ASM1,IDB_ASM2,m_pBitContent,
                 62,0,"Source: [Disassembly]");
    
    ((CMainFrame *)(AfxGetApp()->m_pMainWnd))->
    m_nSourceWnd=ID_WINDOW_SOURCE;
  	 if(g_bAuto)
	 {
	   g_mbCanDoNext=1;
	   AfxGetApp()->m_pMainWnd->SetTimer(IDAUTO,5000,NULL);
	  }

	return 0;
}

void CSrcWnd::OnDestroy()
{  
    CSCrollWnd::OnDestroy();
    ((CMainFrame *)(AfxGetApp()->m_pMainWnd))->SetSrcWnd(0);
    ((CMainFrame *)(AfxGetApp()->m_pMainWnd))->
    m_nSourceWnd=0;
	::DeleteObject(m_hBitmap);
	m_pBpMap->DeleteObject();
	if(m_nOldStep>=0)
	   m_pOldBp->DeleteObject();
//	m_pBitContent->DeleteObject();
	delete m_pBpMap;
	delete m_pLineBp;
	delete m_pOldBp;

    while(GlobalUnlock(m_hMemIdx)!=0);
    GlobalFree(m_hMemIdx);
	// TODO: Add your message handler code here 

}
void CSrcWnd::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
	BOOL bCursor=0;
	switch(m_nWin_Modal)
	  {
	   case SR_SOURCE: 
	        if(point.x < m_nBK)//only use here
	           bCursor=1;
	        break;
	   case SR_ASSAMBLE: 
	        if(point.x < 48)
	           bCursor=1;
	        break;
	   case SR_MIXED:
	        if(point.x < m_nBK)//only use here
	           bCursor=1;
	        break;
	   default:
	        break;
	  }                  
	if(bCursor==1)
	  {
	   ::SetCursor(m_hCursor);
	   m_bSetBk=1;
	  } 
	else          
	  {
	   ::SetCursor(m_hArrow);
	    m_bSetBk=0;
	  }
	  
	CSCrollWnd::OnMouseMove(nFlags, point);
}

void CSrcWnd::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
	LButtonDown(point);
	CTWnd::OnLButtonDown(nFlags, point);
}	     
void CSrcWnd::LButtonDown( CPoint point)
{
	if(m_bSetBk)
	  {      
	   int y=point.y/m_nFontHeight;     
	   if(m_nWin_Modal==SR_ASSAMBLE)
	     {
	      if(m_nCLines+y+1==2)
	        {
	          MessageBeep(-1);
	          return;
	        }  

	     }
	   if(((CMainFrame *)AfxGetApp()->m_pMainWnd)->GetCaseID()==ID_CASE_GO &&
	      m_nWin_Modal==SR_ASSAMBLE)        
	     {
	      if(m_nCLines+y+1!=3)
	        {
	          MessageBeep(-1);
	          return;
	        }  
	     }
       if((m_nCLines+y+1)<=98)
         m_pLineBp[m_nCLines+y+1]=m_pLineBp[m_nCLines+y+1]==1?0:1;
       else 
        {       
         AfxMessageBox("Line Out Of Range!");
         return; 
        } 
	   BITMAP bm;
	   CClientDC dc(this);
	   CDC     *pDC = new CDC; 
	   CDC     *pSrcDC=new CDC;   
	   CBitmap *pBitmap = m_pBpMap;

	   pBitmap->GetObject(sizeof(BITMAP),&bm);
	   pDC->CreateCompatibleDC(&dc);
	   pSrcDC->CreateCompatibleDC(&dc);
	   pSrcDC->SelectObject(m_pBitContent);
	   pDC->SaveDC();
	   pSrcDC->SaveDC();
	   dc.SaveDC();
	   pDC->SelectObject(pBitmap);
	   if(m_pLineBp[m_nCLines+y+1]==0)   
	     {
	      dc.PatBlt(4,y*m_nFontHeight,bm.bmWidth,bm.bmHeight,WHITENESS);
	      pSrcDC->PatBlt(4,(y+m_nCLines)*m_nFontHeight,bm.bmWidth,bm.bmHeight,WHITENESS);
	     } 
       else
         {
	      dc.BitBlt(4,y*m_nFontHeight,bm.bmWidth,bm.bmHeight,pDC,0,0,SRCCOPY);
	      pSrcDC->BitBlt(4,(y+m_nCLines)*m_nFontHeight,bm.bmWidth,bm.bmHeight,pDC,0,0,SRCCOPY);
	     } 
	   pDC->RestoreDC(-1);
	   pSrcDC->RestoreDC(-1);
	   dc.RestoreDC(-1);
	   pDC->DeleteDC();
	   pSrcDC->DeleteDC();
	   delete pDC; 
	   delete pSrcDC;  
//	   int OldLine=m_nStepLine;
//	   m_nStepLine=m_nCLines+y;
//	   SetStepLine(m_nStepLine,OldLine);
	  }
}             
/*-------------------------------------------------------*/
/*           set step line color                         */
/*-------------------------------------------------------*/
void CSrcWnd::SetStepLine(int nStepLine, int nOldLine/*=-1*/)
{                         
 if(nStepLine == nOldLine)
    return;
 int       nPos=nStepLine;           
 const int xPos=80; 
 CClientDC dc(this);
 CDC       *pDC    = new CDC; 
 CDC       *pOldDC = new CDC;
 CPen      pen(PS_SOLID,1,RGB(255,255,0));

 pDC->CreateCompatibleDC(&dc);
 pOldDC->CreateCompatibleDC(&dc);
 pDC->SelectObject(m_pBitContent);

 dc.SaveDC();
 pDC->SaveDC();   
 pOldDC->SaveDC();
  
 dc.SetROP2(R2_MASKPEN);
 dc.SelectObject(&pen);       

 
 if(m_nOldStep >=0 ) 
   {            
	    CDC       *pSrcDC = new CDC;
	    pSrcDC->CreateCompatibleDC(&dc);
	    pSrcDC->SaveDC();
     
        pSrcDC->SelectObject(m_pOldBp);         
	    pDC->BitBlt(xPos,m_nOldStep*m_nFontHeight,300,m_nFontHeight,
		            pSrcDC,0,0,SRCCOPY);
		if((m_nOldStep-m_nCLines)>=0) 
	        dc.BitBlt(xPos,(m_nOldStep-m_nCLines)*m_nFontHeight,300,m_nFontHeight,
		              pSrcDC,0,0,SRCCOPY);
		              
	   pSrcDC->RestoreDC(-1);
	   pSrcDC->DeleteDC();  
	   delete pSrcDC;   
	   m_pOldBp->DeleteObject();
  } 

 m_pOldBp->CreateCompatibleBitmap(&dc,300,m_nFontHeight);
 pOldDC->SelectObject(m_pOldBp);
    
 pOldDC->PatBlt(0,0,300,m_nFontHeight,WHITENESS);
 pOldDC->BitBlt(0,0,300,m_nFontHeight,
		          &dc,
		          xPos,(nPos-m_nCLines)*m_nFontHeight,
		          SRCCOPY);
    
 for(int i=(nPos-m_nCLines)*m_nFontHeight;
	     i<(nPos-m_nCLines+1)*m_nFontHeight;i++)
	 {
	  dc.MoveTo(xPos,i);     
	  dc.LineTo(300+xPos,i);
	 }           
         
  pDC->BitBlt(xPos,nPos*m_nFontHeight,
	          300+xPos,m_nFontHeight,
	          &dc,
	          xPos,(nPos-m_nCLines)*m_nFontHeight,
	          SRCCOPY);
	          
 m_nOldStep=nStepLine;
 dc.RestoreDC(-1); 
 pDC->RestoreDC(-1);
 pOldDC->RestoreDC(-1);

 pDC->DeleteDC();
 pOldDC->DeleteDC();
 delete pDC;
 delete pOldDC;

}
/*-------------------------------------------------------*/
/*            Build Content                              */
/*-------------------------------------------------------*/
void CSrcWnd::BuildContent(int nidB1,
                           int nidB2,
                           CBitmap *pBitmap,
                           int nxSCroll, 
                           BOOL bObject,/*=0*/
                           LPSTR lpTitle/*=0*/)
{              
 if(lpTitle)
    SetWindowText(lpTitle);
 m_nXCaret=nxSCroll;
 HINSTANCE hInst=(HINSTANCE)(((CTutorialApp *)AfxGetApp())->m_hLibrary);
 HBITMAP   hBitmap1 = ::LoadBitmap(hInst,MAKEINTRESOURCE(nidB1));
 HBITMAP   hBitmap2 = ::LoadBitmap(hInst,MAKEINTRESOURCE(nidB2));
       
 if(hBitmap1==NULL || hBitmap2==NULL)      
    AfxMessageBox("Could not find resource library!");
    
 int h;        
 if(bObject) 
  {
   pBitmap->DeleteObject();
   m_bDelete=1;
  } 

 CClientDC dc(this);
 CDC *pDesDC=new CDC;
 CDC *pSrcDC=new CDC;
 BITMAP  bm;
 CBitmap *pSrc1 = new CBitmap;
 CBitmap *pSrc2 = new CBitmap;
 CBitmap *pSrcBitmap1;
 CBitmap *pSrcBitmap2;

 pBitmap->CreateCompatibleBitmap(&dc,621,600);
 pSrcBitmap1 = pSrc1->FromHandle(hBitmap1);
 pSrcBitmap2 = pSrc2->FromHandle(hBitmap2);
 
 pDesDC->CreateCompatibleDC(&dc); 
 pSrcDC->CreateCompatibleDC(&dc); 
 pDesDC->SaveDC();
 pSrcDC->SaveDC();
 
 pDesDC->SelectObject(pBitmap); 
 pDesDC->PatBlt(0,0,621,600,WHITENESS);
 pSrcDC->SelectObject(pSrcBitmap1);
 pSrcBitmap1->GetObject(sizeof(BITMAP),&bm);
 pDesDC->BitBlt(0,0,621,bm.bmHeight,pSrcDC,0,0,SRCCOPY);
 h=bm.bmHeight;
 
 pSrcDC->SelectObject(pSrcBitmap2);
 pSrcBitmap2->GetObject(sizeof(BITMAP),&bm);
 pDesDC->BitBlt(0,h,621,bm.bmHeight,pSrcDC,0,0,SRCCOPY);
 
 pDesDC->RestoreDC(-1);
 pSrcDC->RestoreDC(-1);
 pDesDC->DeleteDC();
 pSrcDC->DeleteDC();
 
 delete pDesDC;
 delete pSrcDC;
 delete pSrc1;
 delete pSrc2;
 
 pBitmap->GetObject(sizeof(BITMAP),&bm);
 m_nMaxHeight=bm.bmHeight;
 m_nMaxWidth =bm.bmWidth;

 //nLines=37;//nMaxHeight/nFontHeight-nYPage;
 _fmemset(m_pLineBp,0,99);
 ::DeleteObject(hBitmap1);
 ::DeleteObject(hBitmap2);
 
} 
/*-----------------------------------------------------------------*/
/*              Show Breakpoint dialog box                         */
/*-----------------------------------------------------------------*/    
void CSrcWnd::OnRunBreakpoint()
{
	// TODO: Add your command handler code here
	 g_mbCanDoNext=0;   
	 if(((CMainFrame *)(AfxGetApp()->m_pMainWnd))->GetMenuAct()!=
	      ID_RUN_BREAKPOINT)
	   {
	    MessageBeep(-1);
	    return;
	   }      
      
	 ((CMainFrame *)(AfxGetApp()->m_pMainWnd))->SetDlgWnd(0);                     
/*
	 if(((CMainFrame *)(AfxGetApp()->m_pMainWnd))->GetByUser())
	   {
	    CSrcGroupDlg   *m_pSrcDlg=new CSrcGroupDlg(5,           //page
					                               0,           // is child
					                               this,        // parent window
					                               1,           // not modal dialog
					                               FALSE);      // bSetByUser=0;
        m_pSrcDlg->DoModal();
                                        
	   } 
	 else
*/
//	   {         
                                      
	    CBPDialog   *m_pSrcDlg=new CBPDialog(this);          // not modal dialog
//		MessageBeep(-1);			                               
        
        m_pSrcDlg->ShowWindow(SW_SHOW);   
        g_mbCanDoNext=1;   
    
//	   }
}


void CSrcWnd::OnMDIActivate(BOOL bActivate, CWnd* pActivateWnd, CWnd* pDeactivateWnd)
{
	CSCrollWnd::OnMDIActivate(bActivate, pActivateWnd, pDeactivateWnd);
	
	// TODO: Add your message handler code here
	if(bActivate)
	  {AfxGetApp()->m_pMainWnd->SendMessage(TM_WIN_CHANGE,WID_SOURCE,0);
	   ((CMainFrame *)(AfxGetApp()->m_pMainWnd))->SetWnd(this);
	  }
	else
	  AfxGetApp()->m_pMainWnd->SendMessage(TM_WIN_CHANGE,WID_MAIN,0);
}
void CSrcWnd::OnSetFocus(CWnd* pOldWnd)
{
	CSCrollWnd::OnSetFocus(pOldWnd);
	
	// TODO: Add your message handler code here
	((CMainFrame *)(AfxGetApp()->m_pMainWnd))->SetWnd(this);
	
}



