// firstlook.cpp : implementation of the CMainFrame class
//
#include "stdafx.h"
#include "tutorial.h"
#include "tmouse.h"
#include "mainfrm.h"    
#include "time.h"

#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif

#define WIDTHBYTES(bits)     (((bits) + 31) / 32 * 4)
#define IS_WIN30_DIB(lpbi)   ((*(LPDWORD) (lpbi)) == sizeof (BITMAPINFOHEADER))

extern void Delay(int nDelay,BOOL bShow=0);
extern BOOL g_bStop;
extern BOOL g_mbCanDoNext;
extern BOOL g_bAuto;
/*-------------------------------------------------------*/
/*              Auto play introduce ep/sld               */
/*-------------------------------------------------------*/
void CMainFrame::OnAutoPlay()                       
{
  SetSysMouse(1);

  HINSTANCE hInst=m_hFlookInst;
  if(m_hBitmap)
    {DeleteObject(m_hBitmap);
     m_hBitmap=0;}
  m_hBitmap = LoadBitmap(hInst,"EPSLD");
  
  if(m_hBitmap==0)
     {AfxMessageBox("Can not find first look resource!");
      return ;} 
  m_nPlaySpeed=10;
  m_nPlayCount=0;
  bCase2Paint=0;  
  PastePicutre(1,8,8);   
  Delay(5000);
  m_hBitmap = LoadBitmap(hInst,"OBJ");
  PastePicutre(1,8,8);   
  Delay(5000);
  m_hBitmap = LoadBitmap(hInst,"CPU");
  PastePicutre(1,8,8);   
  Delay(5000); 
  DefragRestore(m_Message);
  SetTimer(AUTOTIMER,500,NULL);
  m_nPlayCount=8;
  
  SetSysMouse(0);

  m_pMeter = new  CPlayMeter (CWnd::FromHandle(m_hWndMDIClient));
  if(m_StopDome.m_hWnd)
     if(!m_StopDome.IsWindowVisible());
        m_StopDome.ShowWindow(SW_SHOW);
  m_nCanDoNext=1;
} 
/*-------------------------------------------------------*/
/*             OnAutoTimer                               */
/*-------------------------------------------------------*/
void CMainFrame::OnAutoTimer(BOOL bInit/*=0*/)
{
 static int nCase=0;                    
 if(bInit) 
   { 
    m_nCanDoNext=-1;
    m_nPlayCount=0;
    nCase=0;
    return;
   }                         
 
 if(m_nCanDoNext==-1)  
    return;
    
 m_nPlayCount++;
 if(m_nPlayCount<m_nPlaySpeed )
   return;
 
 nCase++;

 if(nCase%2==0)
   { m_bCanPal=0;
     m_nPlayCount=-200;
     m_nCanDoNext=0;}
    
 switch(nCase)
  { 
   case 3:
   case 5:  
   case 9:
   case 11:
   case 13:
   case 15:
   case 21:
   case 23:
   case 25:
   case 27:
   case 29:
   case 31:
   case 33:
   case 39:      
   case 43:
   case 45: 
        return;
   case 1:         
   case 7:
   case 17:      
   case 19:
   case 35:
   case 37:
   case 41:
   case 47:
   case 49:
     SetProp(m_hWnd,"ClearScreen",(HANDLE)1);
     m_nCanDoNext=0;
     DefragRestore(m_Message);
     //StopPlay();
     m_nCanDoNext=1;
     return; 
   case 2:                        
     OnShowFLook(ID_FIRST_SOURCE);
     break;
   case 4:
     OnShowFLook(ID_SRC_ASM);
     break;
   case 6:
     OnShowFLook(ID_SRC_MIX);
     break;
   case 8:
     OnShowFLook(ID_FIRST_MEMORY);
     break;
   case 10:
     OnShowFLook(ID_MEM_3);
     break;
   case 12:
     OnShowFLook(ID_MEM_DEC);
     break;
   case 14:
     OnShowFLook(ID_MEM_HEX);
     break;
   case 16:  
     OnShowFLook(ID_MEM_WORD);
     break;
   case 18:          
     OnShowFLook(ID_FIRST_BITMEMORY);
     break;
   case 20:          
     OnShowFLook(ID_FIRST_STACK);
     break;
   case 22:          
     OnShowFLook(ID_STK_EXTV);
     break;
   case 24:          
     OnShowFLook(ID_STK_FFL);
     break;
   case 26:          
     OnShowFLook(ID_STK_LAF);
     break;
   case 28:          
     OnShowFLook(ID_STK_FULL);
     break;
   case 30:          
     OnShowFLook(ID_STK_VARSEL);
     break;
   case 32:          
     OnShowFLook(ID_STK_VARMODIFY);
     break;
   case 34:          
     OnShowFLook(ID_STK_VAR);
     break;
   case 36:         
     OnShowFLook(ID_FIRST_VAR);
     break;
   case 38:         
     OnShowFLook(ID_FIRST_TRACE);
     break;                      
   case 40:         
     OnShowFLook(ID_TRACE_INSTRUCTION);
     break;                      
   case 42:         
     OnShowFLook(ID_FIRST_CPU);
     break;
   case 44:         
     OnShowFLook(ID_CPU_DEC);
     break;
   case 46:         
     OnShowFLook(ID_CPU_HEX);
     break;
   case 48:         
     OnShowFLook(ID_FIRST_PER);
     break;
   case 50:         
     OnShowFLook(ID_FIRST_SHELL);
     break;
   default:       
     SetProp(m_hWnd,"ClearScreen",(HANDLE)0);
     OnStopDome();
     m_nPlayCount=0; 
     nCase=0;
     return;
  } 
 
  Delay(200);
  SetProp(m_hWnd,"ClearScreen",(HANDLE)0);
  m_nPlayCount=0;
}
/*-------------------------------------------------------*/
/*             DrawFirstLookTitle                        */
/*-------------------------------------------------------*/
void CMainFrame::DrawFirstLookTitle()
{                               
  if(g_bAuto)
    {
     KillTimer(IDAUTO);
    } 
   m_nCanDoNext=0;

  int    orgX;
  LONG   dwDelay=0;
  BITMAP bm;
  MSG    msg;
  CBitmap *pBitmap=new CBitmap;
  pBitmap->LoadBitmap(IDB_TITLE);
  pBitmap->GetObject(sizeof(BITMAP),&bm);
  CWindowDC dc(this);
  CDC SrcDC;
  SrcDC.CreateCompatibleDC(&dc);
  SrcDC.SaveDC();
  SrcDC.SelectObject(pBitmap);
  orgX=(640-bm.bmWidth)/2;
  for(int i=0;i<bm.bmHeight;i+=20)
     {
      if(PeekMessage(&msg,NULL,0,0,PM_REMOVE))
         {
          TranslateMessage(&msg);
          DispatchMessage(&msg);
         }
       dwDelay=GetTickCount();
       dc.StretchBlt(orgX,(40+bm.bmHeight-i),bm.bmWidth,i,
                    &SrcDC,0,0,bm.bmWidth,bm.bmHeight,SRCCOPY);
      while(GetTickCount()<(DWORD)(dwDelay+20));             
     } 
                   
  SrcDC.RestoreDC(-1);
//////////////////////////////////////////////////////////////  
  SrcDC.DeleteDC();
  pBitmap->DeleteObject();  
  delete pBitmap;
  SetFullKey(0);
  SetMouse(0);
  
  SetTimer( MANTIMER,400,NULL );
} 

void CMainFrame::OnManTimer() //man go
{                      
  static int nNum=-1;
  static CRect rectOld(90,80,450+90,240+69);
  static int orgX=90;
  static CBitmap Bitmap[4];
  static BOOL bIni=1;
  static POINT pointTitle;
  nNum++;
                     
  CBrush brush(RGB(0,128,128));                   
  CWindowDC dc(this);          
  dc.SaveDC();
  int orgY=270;
  int nChoice=nNum%3;
             
  
  if(nNum==0)
    {    
     bIni=0;
     Bitmap[0].LoadBitmap(IDB_RIGHT1);
     Bitmap[1].LoadBitmap(IDB_RIGHT2);
     Bitmap[2].LoadBitmap(IDB_RIGHT3);
     Bitmap[3].CreateCompatibleBitmap(&dc,450,240);
     orgX=90;
     pointTitle.x=90;
     pointTitle.y=69; 
     CDC DesDC;
     DesDC.CreateCompatibleDC(&dc);
     DesDC.SaveDC();
     DesDC.SelectObject(&Bitmap[3]);
     DesDC.BitBlt(0,0,450,240,&dc,90,69,SRCCOPY);
     DesDC.RestoreDC(-1);
     DesDC.DeleteDC();
    }  
    
///////////////////////////////////////////////////////////
    
  BITMAP  bm;          
  CDC manDC;
  CDC desDC;
  CRect rect;   
  
  GetWindowRect(&rect);
  manDC.CreateCompatibleDC(&dc);
  desDC.CreateCompatibleDC(&dc);
  manDC.SaveDC();
  desDC.SaveDC();

  manDC.SelectObject(&Bitmap[nChoice]);
  desDC.SelectObject(&Bitmap[3]);

  Bitmap[nChoice].GetObject(sizeof(BITMAP),&bm);
     
  CRect rt(0,0,rectOld.right+50,440);   
  dc.FillRect(&rt,&brush);   

  dc.BitBlt(orgX+bm.bmWidth,69,450,240, &desDC,
            0,0,SRCCOPY);
                      
 // dc.PatBlt(pointTitle.x-10,pointTitle.y,bm.bmWidth+10,240,PATCOPY);   
  pointTitle.x=orgX+bm.bmWidth;          
  dc.BitBlt(orgX+10,orgY,bm.bmWidth,bm.bmHeight,
              &manDC,0,0,SRCCOPY);

  dc.RestoreDC(-1); 
             
  rectOld.SetRect(orgX,orgY,
                  orgX+bm.bmWidth,orgY+bm.bmHeight);
  orgX+=bm.bmWidth;
                    
////////////////////////////////////////////////////////////////                    
  manDC.RestoreDC(-1);               
  manDC.DeleteDC();              
  desDC.RestoreDC(-1);               
  desDC.DeleteDC();              

  if(orgX > rect.right+32) 
    {     
     KillTimer(MANTIMER);
     Bitmap[0].DeleteObject();
     Bitmap[1].DeleteObject();
     Bitmap[2].DeleteObject();
     Bitmap[3].DeleteObject();
     nNum=-1;
     orgX=100;    
     rectOld.right=80;
     bIni=1;
     SetMouse(1);
     SetFullKey(1);      
     PostMessage(WM_COMMAND,ID_AUTO_PLAY);//OnAutoPlay);
    }
}
/*-------------------------------------------------------*/
/*             StartScreen                               */
/*-------------------------------------------------------*/
void CMainFrame::StartScreen(int orgX,int orgY,int nCX,int nCY,BOOL bBlack)
{ 
 SetMouse(0);
 SetFullKey(0);
 m_bCanPal=0;
 while(ShowCursor(0)>=0);
 HBITMAP hSrcBit;
 HBITMAP hOldBit;
 HDC     hSrcDC;
 HDC     hDC=::GetWindowDC(m_hWnd);
 hSrcBit=::CreateCompatibleBitmap(hDC,nCX,nCY);
 hSrcDC =::CreateCompatibleDC(hDC); 

 hOldBit=(HBITMAP)::SelectObject(hSrcDC,hSrcBit);
 ::BitBlt(hSrcDC,0,0,nCX,nCY,hDC,orgX,orgY,SRCCOPY);    
 ::SelectObject(hSrcDC,hOldBit);
 ::DeleteDC(hSrcDC);
 ::ReleaseDC(m_hWnd,hDC);
///////////////////////////////////////////////////////////

 BitmapToDIB (orgX,orgY,hSrcBit,bBlack);
 DeleteObject(hSrcBit);
 SetMouse(1);
 SetFullKey(1); 
 while(ShowCursor(1)<0);
}
/*-------------------------------------------------------*/
/*              Create Logic Palette                     */
/*-------------------------------------------------------*/
HPALETTE CMainFrame::CreateLogPalette(LPSTR lpDIB)
{
 HGLOBAL hMem;
 LPLOGPALETTE pLogPal;
 RGBQUAD far * lpRGB;
 int nPalSize= PaletteSize(lpDIB)/sizeof(RGBQUAD);
 
 hMem=GlobalAlloc(GPTR,sizeof(LOGPALETTE)+
                  nPalSize * sizeof(PALETTEENTRY));
 pLogPal=(LPLOGPALETTE)GlobalLock(hMem);
 if(pLogPal==NULL)                 
    return 0;
 pLogPal->palVersion=0x300;
 pLogPal->palNumEntries=nPalSize;
 lpRGB=(RGBQUAD far *)(lpDIB+sizeof(BITMAPINFOHEADER));
             
 for(int i=0;i<nPalSize;i++)
    {
     pLogPal->palPalEntry[i].peRed=lpRGB->rgbRed;
     pLogPal->palPalEntry[i].peGreen=lpRGB->rgbGreen;
     pLogPal->palPalEntry[i].peBlue=lpRGB->rgbBlue;
     pLogPal->palPalEntry[i].peFlags=NULL;//PC_RESERVED;//PC_EXPLICIT;
     lpRGB++;
    }    
 HPALETTE hPal=CreatePalette((LPLOGPALETTE)pLogPal);
 GlobalUnlock(hMem);    
 GlobalFree(hMem);
 return (hPal);       
}         
                    
HPALETTE CMainFrame::SetPalette(HDC &hDC,HPALETTE &hPal,BOOL bRestore)
{ 
 if(!hPal)
    return 0;
 HPALETTE hOldPal;
 if(!bRestore)   
    SetSystemPaletteUse(hDC,SYSPAL_STATIC);
 hOldPal=SelectPalette(hDC,hPal,TRUE);
 RealizePalette(hDC);
 return(hOldPal);
}
/*-------------------------------------------------------*/
/*             show dib bit map                          */
/*-------------------------------------------------------*/
BOOL CMainFrame::BitmapToDIB (int orgX,int orgY,HBITMAP hBitmap,BOOL bBlack)
{                               
   BITMAP             Bitmap;
   BITMAPINFOHEADER   bmInfoHdr;
   LPBITMAPINFOHEADER lpbmInfoHdr;
   LPSTR              lpBits;
   HDC                hMemDC;
   HANDLE             hDIB;

      // Do some setup -- make sure the Bitmap passed in is valid,
      //  get info on the bitmap (like its height, width, etc.),
      //  then setup a BITMAPINFOHEADER.

   if (!hBitmap)
      return 0;

   if (!GetObject (hBitmap,sizeof (Bitmap), (LPSTR) &Bitmap))
      return 0;

   InitBitmapInfoHeader (&bmInfoHdr,
                         Bitmap.bmWidth,
                         Bitmap.bmHeight,
                         Bitmap.bmPlanes * Bitmap.bmBitsPixel);


      // Now allocate memory for the DIB.  Then, set the BITMAPINFOHEADER
      //  into this memory, and find out where the bitmap bits go.
   int nPaletteSize=PaletteSize ((LPSTR) &bmInfoHdr);
   hDIB = GlobalAlloc (GPTR, sizeof (BITMAPINFOHEADER) +
                       nPaletteSize+ bmInfoHdr.biSizeImage);

   if (!hDIB)
      return NULL;

   lpbmInfoHdr  = (LPBITMAPINFOHEADER) GlobalLock (hDIB);
   *lpbmInfoHdr = bmInfoHdr;
   lpBits       = (LPSTR) lpbmInfoHdr + 
                  *(LPDWORD)(LPSTR) lpbmInfoHdr + 
                  PaletteSize ((LPSTR) lpbmInfoHdr);

      // Now, we need a DC to hold our bitmap.  If the app passed us
      //  a palette, it should be selected into the DC.

   hMemDC       =  ::GetWindowDC (m_hWnd);
                    //CreateDC("DISPLAY",NULL,NULL,NULL);
                         
   if (!GetDIBits (hMemDC,
                   hBitmap,
                   0,
                   Bitmap.bmHeight,
                   lpBits,
                   (LPBITMAPINFO) lpbmInfoHdr,
                   DIB_RGB_COLORS))
      {
       GlobalUnlock (hDIB);
       GlobalFree (hDIB);
       hDIB = NULL;
       AfxMessageBox("Cant create  bitmap !");
      }
             
   HPALETTE hPal,hOldPal;//=CreateLogPalette((LPSTR)lpbmInfoHdr);          
   BOOL bOut=0;
   HDC dc = ::CreateCompatibleDC(hMemDC);
   int nCount=0;        
   HBITMAP hBit,hOldBit;
   hBit=CreateDIBitmap(hMemDC,
	                   (LPBITMAPINFOHEADER) lpbmInfoHdr,
	                   CBM_INIT,lpBits,
	                   (LPBITMAPINFO) lpbmInfoHdr,
	                   DIB_RGB_COLORS);
   if(!hBit)	                            
       return 0;
       
   const int nRel=bBlack? 56:8;

   for(;;)
      {                                                  
//       lpbmInfoHdr  = (LPBITMAPINFOHEADER) GlobalLock (hDIB);
       RGBQUAD far *lpRGB=(RGBQUAD far *)((LPSTR)lpbmInfoHdr + 
                            sizeof(BITMAPINFOHEADER));

	   for(int i=0;i<int(nPaletteSize/sizeof (RGBQUAD));i++)
	      {
	       lpRGB[i].rgbBlue=bBlack ? 
	                        (lpRGB[i].rgbBlue -nRel<=0 ? 0 : 
	                         lpRGB[i].rgbBlue -nRel):
	                        nCount*nRel>=160 ? 128:
	                        lpRGB[i].rgbBlue<128 ? lpRGB[i].rgbBlue+nRel
	                        :(lpRGB[i].rgbBlue>=128 && 
	                          lpRGB[i].rgbBlue<=130)
	                         ? 128 :lpRGB[i].rgbBlue -nRel ;
	       
	       lpRGB[i].rgbRed =bBlack ? 
	                        (lpRGB[i].rgbRed-nRel<=0 ? 0 : 
	                         lpRGB[i].rgbRed-nRel):
	                        nCount*nRel>=160 ? 0 :
	                        lpRGB[i].rgbRed>10 ? lpRGB[i].rgbRed-nRel:0; 

	       lpRGB[i].rgbGreen=bBlack ? 
	                         (lpRGB[i].rgbGreen-nRel<=0 ? 0 : 
	                          lpRGB[i].rgbGreen-nRel):
	                         nCount*nRel>=160 ? 128 :
	                         lpRGB[i].rgbGreen<128 ? lpRGB[i].rgbGreen+nRel
	                         :(lpRGB[i].rgbGreen>=128 && 
	                         lpRGB[i].rgbGreen<=130 )
	                         ?128 : lpRGB[i].rgbGreen - nRel ;
           
           
	       if((bBlack?
	          (!lpRGB[i].rgbGreen &&
	           !lpRGB[i].rgbBlue   &&
	           !lpRGB[i].rgbRed):
	          (lpRGB[i].rgbGreen==128 &&
	           lpRGB[i].rgbBlue==128 &&
	           lpRGB[i].rgbRed==0)))
	          bOut=1;
	       else
	          bOut=0;              
          }                                 
          
      hPal=CreateLogPalette((LPSTR)lpbmInfoHdr);                    
      hOldPal=SetPalette(hMemDC,hPal);
                                            
      int x=SetDIBits(hMemDC,
                hBit,
                0,
                Bitmap.bmHeight,
                lpBits,
                (LPBITMAPINFO) lpbmInfoHdr,
                DIB_RGB_COLORS);
       ASSERT(x);
	   hOldBit=(HBITMAP)::SelectObject(dc,hBit);
	   ::BitBlt(hMemDC,WinCxy.x+orgX,WinCxy.y+orgY,
	            Bitmap.bmWidth,Bitmap.bmHeight,
	            dc,0,0,SRCCOPY);
	   ::SelectObject(dc,hOldBit);

       SetPalette(hMemDC,hOldPal);
       DeleteObject(hPal);
       
	   nCount++;
	   
	   if(nCount>40 || bOut) 
	     break;

  }              

  // Finally, clean up and return.
  if(!bBlack)
   {      
    CRect rect;
    rect.left  = WinCxy.x+orgX;
    rect.top   = WinCxy.y+orgY;
    rect.right = rect.left+Bitmap.bmWidth;
    rect.bottom= rect.top+Bitmap.bmHeight;
    CBrush brush(RGB(0,128,128));
    CDC::FromHandle(hMemDC)->FillRect(&rect,&brush);  
   } 
   ::DeleteDC(dc);   
   ::DeleteObject(hBit);
   ::ReleaseDC(m_hWnd,hMemDC);
   if(hDIB)
     {GlobalUnlock(hDIB);
      GlobalFree(hDIB);}
   return 1;
} 
/*-----------------------------------------------------------------*/
/*               Get Palette size                                  */
/*-----------------------------------------------------------------*/
WORD CMainFrame::PaletteSize (LPSTR lpbi)
{
   WORD wBitCount;
   WORD nClrUsed;

      // If this is a Windows style DIB, the number of colors in the
      //  color table can be less than the number of bits per pixel
      //  allows for (i.e. lpbi->biClrUsed can be set to some value).
      //  If this is the case, return the appropriate value.

      DWORD dwClrUsed;

      dwClrUsed = ((LPBITMAPINFOHEADER) lpbi)->biClrUsed;

      if (dwClrUsed)
         return (WORD) dwClrUsed;
      // Calculate the number of colors in the color table based on
      //  the number of bits per pixel for the DIB.

      wBitCount = ((LPBITMAPINFOHEADER) lpbi)->biBitCount;

   switch (wBitCount)
      {
      case 1:
         nClrUsed=2;
         break;
      case 4:
         nClrUsed=16;
         break;

      case 8:
         nClrUsed=256;
         break;

      default:
         return 0;
      }
 
 return (nClrUsed * sizeof (RGBQUAD));
}


void CMainFrame::
     InitBitmapInfoHeader (LPBITMAPINFOHEADER lpBmInfoHdr,
                                        DWORD dwWidth,
                                        DWORD dwHeight,
                                          int nBPP)
{
   _fmemset (lpBmInfoHdr, 0, sizeof (BITMAPINFOHEADER));

   lpBmInfoHdr->biSize      = sizeof (BITMAPINFOHEADER);
   lpBmInfoHdr->biWidth     = dwWidth;
   lpBmInfoHdr->biHeight    = dwHeight;
   lpBmInfoHdr->biPlanes    = 1;

   if (nBPP <= 1)
      nBPP = 1;
   else if (nBPP <= 4)
      nBPP = 4;
   else if (nBPP <= 8)
      nBPP = 8;
   else
      nBPP = 24;

   lpBmInfoHdr->biBitCount  = nBPP;
   lpBmInfoHdr->biSizeImage = WIDTHBYTES (dwWidth * nBPP) * dwHeight;
}
                     
void CMainFrame::BitmapProcess(CDC &dc,CBitmap *pBitmap)
{ 
 BITMAP       bm;
 LPBITMAPINFO lpBitsInfo;
 HGLOBAL      hMem;
 HGLOBAL      hBitMem;
 BYTE         far *lpBits;
 HDC          hDC=::GetWindowDC(m_hWnd);
 pBitmap->GetObject(sizeof(BITMAP),&bm);
 hMem=GlobalAlloc(GPTR,sizeof(BITMAPINFOHEADER)+16*sizeof(RGBQUAD));
 hBitMem=GlobalAlloc(GPTR,bm.bmWidthBytes*bm.bmHeight+1); 
 lpBitsInfo=(LPBITMAPINFO)GlobalLock(hMem);
 lpBits=(BYTE far *)GlobalLock(hBitMem);
 GetDIBits(hDC,(HBITMAP)pBitmap->GetSafeHandle(),
           0,bm.bmHeight-1,lpBits,lpBitsInfo,DIB_RGB_COLORS);
 pBitmap->GetBitmapBits(bm.bmWidthBytes*bm.bmHeight,lpBits);          
 for(int i=0;i<16;i++)
  {lpBitsInfo->bmiColors[i].rgbBlue=0;
   lpBitsInfo->bmiColors[i].rgbGreen=0;         
   lpBitsInfo->bmiColors[i].rgbRed=0;}
                        
 SetDIBitsToDevice(dc.GetSafeHdc(),0,50,146,350,146,350,0,bm.bmHeight,
                   lpBits,lpBitsInfo,DIB_RGB_COLORS);
/*                                            
 SetDIBits(dc.GetSafeHdc(),(HBITMAP)pBitmap->GetSafeHandle(),
           0,bm.bmHeight-1,NULL,lpBitsInfo,DIB_RGB_COLORS);          
*/           
 ::ReleaseDC(m_hWnd,hDC);
 GlobalUnlock(hMem);
 GlobalFree(hMem); 
 GlobalUnlock(hBitMem);
 GlobalFree(hBitMem); 
}

/////////////////////////////////////////////////////////////////////////////
// CPlayMeter

CPlayMeter::CPlayMeter(CWnd *pParent,BOOL bMeter/*=1*/)
{               
  m_bMeter=bMeter;
  CRect rectMeter;
  
  if(bMeter) 
    {
     ((CMainFrame *)(AfxGetApp()->m_pMainWnd))->SetPlaySpeed(10);
     rectMeter.SetRect(300+50,410,400+47+50,434);
    }     
  else
    rectMeter.SetRect(440,410,440+120,434);
    
  pParent->ClientToScreen(&rectMeter);
  
  CreateEx(WS_EX_TOPMOST,AfxRegisterWndClass(CS_HREDRAW|CS_VREDRAW),
         NULL,WS_POPUP|WS_VISIBLE,
         rectMeter.left,rectMeter.top,rectMeter.Width(),rectMeter.Height(),
         NULL,NULL,NULL);
  m_bLBD=0;
  rectDir.SetRect(12,4,20,20);
  m_MeterRang=rectMeter.Width()-8-55;
  m_MeterOrg=8;
  m_hArrow=	((CMainFrame *)(AfxGetApp()->m_pMainWnd))->   
             GetArrowCursor();
  m_hCursor=((CMainFrame *)(AfxGetApp()->m_pMainWnd))->
	          GetHandCursor();
  	          
}

CPlayMeter::~CPlayMeter()
{
}

BEGIN_MESSAGE_MAP(CPlayMeter, CWnd)
	//{{AFX_MSG_MAP(CPlayMeter)
	ON_WM_PAINT()
	ON_WM_LBUTTONDOWN()
	ON_WM_MOUSEMOVE()
	ON_WM_CREATE()
	ON_WM_DESTROY()
	ON_WM_LBUTTONUP()
	ON_WM_LBUTTONDBLCLK()
	ON_WM_SETCURSOR()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CPlayMeter message handlers

void CPlayMeter::OnPaint()
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here
	if( m_bMeter ) 
      {
		GetClientRect(&m_WinRect);
		CreateMeter(dc);
		PaintMeter(dc);
		PaintDirector();
	  }
	else
	  PaintDelay(dc);                                      
	 
	 
	// Do not call CButton::OnPaint() for painting messages
}
                                                           
/*-------------------------------------------------------*/
/*           play Delay light                            */
/*-------------------------------------------------------*/
void CPlayMeter::SetDelayScreen(int nLight,int nLED,BOOL bOnlyChar/*=0*/)
{ 
                  
 m_nLight=nLight;
 m_nLED  = nLED >= 999? 999:nLED;
 CClientDC dc(this); 
 if(!bOnlyChar)
    PaintLight(dc);
 PaintChar(dc);
}
void CPlayMeter::PaintDelay(CDC &dc)
{ 
 POINT pointBlack[]={11,0, 70,0, 70,23, 11,23};
 POINT pointWhite[]={11,1, 69,1, 69,22, 11,22};               
 dc.SaveDC();
 BITMAP bm;
 CDC    SrcDC;
 SrcDC.CreateCompatibleDC(&dc);
 CRect  rect;
 GetClientRect(&rect);
 CBrush brush(RGB(192,192,192));
 dc.FillRect(&rect,&brush);
 m_pBitMeter->GetObject(sizeof(BITMAP),&bm);
 SrcDC.SelectObject(m_pBitMeter);
 dc.BitBlt(rect.Width()-bm.bmWidth,0,bm.bmWidth,bm.bmHeight,&SrcDC,0,0,SRCCOPY);

 dc.SelectObject((CPen *)CPen::FromHandle((HPEN)GetStockObject(WHITE_PEN)));
 dc.Polyline(pointWhite,sizeof(pointWhite)/sizeof(POINT));
 dc.Arc(1,1, 23,23, 12,1, 12,23);

 dc.SelectObject((CPen *)CPen::FromHandle((HPEN)GetStockObject(BLACK_PEN)));
 dc.Polyline(pointBlack,sizeof(pointBlack)/sizeof(POINT));
 dc.Arc(0,0, 24,24, 12,0, 12,24);
 SrcDC.DeleteDC();
 dc.RestoreDC(-1);
 
 PaintLight(dc);
 PaintChar(dc);
}

void CPlayMeter::PaintLight(CDC &dc)
{
 dc.SaveDC();
 CBrush redBrush(RGB(255,0,0));
 CBrush yellowBrush(RGB(255,255,0));
 CBrush greenBrush(RGB(0,255,0));
 
 dc.SelectObject((CBrush *)CBrush::FromHandle((HBRUSH)GetStockObject(BLACK_BRUSH)));
 dc.Ellipse(8 ,3,26,21);
 dc.Ellipse(28,3,46,21);
 dc.Ellipse(48,3,66,21);  
 switch(m_nLight){
    case 1:                  
      dc.SelectObject(&greenBrush);
      dc.Ellipse(8 ,3,26,21);     
      break;
    case 2:
      dc.SelectObject(&yellowBrush);
      dc.Ellipse(28,3,46,21);     
      break;            
    case 3:
      dc.SelectObject(&redBrush);
      dc.Ellipse(48,3,66,21);     
      break;           
   }   

 dc.RestoreDC(-1);
}
                                      
void CPlayMeter::PaintChar(CDC &dc)
{
 int p[]={70+34,70+19,70+4};
 dc.SaveDC();   
 CDC SrcDC;
 SrcDC.CreateCompatibleDC(&dc);
 int nIdx;
 m_nLED;
 
 for(int i=0;i<3;i++)
  {
	 nIdx=m_nLED%10;
	 m_nLED = m_nLED/10;
	 if(nIdx<0 || nIdx >9)
	    continue;
	 m_LED[nIdx];     
	 SrcDC.SelectObject(&m_LED[nIdx]);
	 dc.BitBlt(p[i],2,13,20,&SrcDC,0,0,SRCCOPY);
  }
 
 SrcDC.DeleteDC();
 dc.RestoreDC(-1);
}
/*-------------------------------------------------------*/
/*           play meter                                  */
/*-------------------------------------------------------*/                   
void CPlayMeter::CreateMeter(CDC &dc)
{ 
 BITMAP bm;
 CRect rect;
 GetClientRect(&rect);
 m_pBitMeter->GetObject(sizeof(BITMAP),&bm);
 MeterBitmap->DeleteObject();
 MeterBitmap->CreateCompatibleBitmap(&dc,rect.Width(),bm.bmHeight);
///////////////////////////////////////////////////////////
 CDC SrcDC;
 CDC DesDC;
 SrcDC.CreateCompatibleDC(&dc);
 DesDC.CreateCompatibleDC(&dc);
 SrcDC.SaveDC();
 DesDC.SaveDC();
 SrcDC.SelectObject(m_pBitMeter);
 DesDC.SelectObject(MeterBitmap);
 DesDC.BitBlt(0,0,20,bm.bmHeight,&SrcDC,0,0,SRCCOPY);
 int nLen=rect.Width()-40;   
 if(nLen>=0)
    DesDC.StretchBlt(20,0,nLen,bm.bmHeight,
                     &SrcDC,20,0,bm.bmWidth-87,bm.bmHeight,SRCCOPY);
 DesDC.BitBlt(rect.Width()-67,0,67,bm.bmHeight,&SrcDC,bm.bmWidth-67,0,SRCCOPY);
 
 SrcDC.RestoreDC(-1);
 DesDC.RestoreDC(-1);
 SrcDC.DeleteDC();
 DesDC.DeleteDC();
}
 
void CPlayMeter::PaintMeter(CDC &dc)
{ 
 CDC SrcDC;
 BITMAP bm;                      
 CRect rect;
 GetClientRect(&rect);
 MeterBitmap->GetObject(sizeof(BITMAP),&bm);
 SrcDC.CreateCompatibleDC(&dc);
 SrcDC.SaveDC(); 
 SrcDC.SelectObject(MeterBitmap);
 dc.BitBlt(0,0,rect.Width(),bm.bmHeight,&SrcDC,0,0,SRCCOPY);
 SrcDC.RestoreDC(-1);                                     
 SrcDC.DeleteDC();
}
void CPlayMeter::PaintDirector()
{          
 BITMAP bm;
 CClientDC dc(this);
 CDC SrcDC;                 
 CDC BkDC; 
 CDC DigitDC;
 MeterBitmap->GetObject(sizeof(BITMAP),&bm);
 SrcDC.CreateCompatibleDC(&dc);
 BkDC.CreateCompatibleDC(&dc);
 DigitDC.CreateCompatibleDC(&dc);
 SrcDC.SaveDC();              
 BkDC.SaveDC();           
 DigitDC.SaveDC();             
 if(m_bLBD)
   SrcDC.SelectObject(m_pDirSel);
 else  
   SrcDC.SelectObject(m_pBitDirector);
 BkDC.SelectObject(MeterBitmap);
 dc.BitBlt(0,0,bm.bmWidth-50,bm.bmHeight,&BkDC,0,0,SRCCOPY);

 dc.BitBlt(rectDir.left,rectDir.top,
           rectDir.Width(),rectDir.Height(),&SrcDC,0,0,SRCCOPY);
///////////////////////////////////////////////////////////
 CRect rect;
 GetClientRect(&rect);
 int nMeterCx=rectDir.left+rectDir.Width()/2-m_MeterOrg;
 int nCal=0;    
 int nIdx=0;
 if(nMeterCx>=m_MeterRang-4)
   nCal=60;
 else
 if(nMeterCx<=4)
   nCal=1;
 else
   nCal=60*nMeterCx/m_MeterRang;
 if(nCal>60)
    nCal=60;
 else
 if(nCal<0)
    nCal=0;             
    
 m_SetSpeed=nCal;   
 
 nIdx=nCal>=10 ? nCal/10 : 0;
 if(nIdx<0 || nIdx >9)
    nIdx=0;
 DigitDC.SelectObject(&m_LED[nIdx]);
 dc.BitBlt(rect.right-40,2,13,20,&DigitDC,0,0,SRCCOPY);
 nIdx=nCal>=10 ? nCal%10 : nCal;
 if(nIdx<0 || nIdx >9)
    nIdx=0;              
 DigitDC.SelectObject(&m_LED[nIdx]);
 dc.BitBlt(rect.right-25,2,13,20,&DigitDC,0,0,SRCCOPY);
///////////////////////////////////////////////////////////           
 SrcDC.RestoreDC(-1);                   
 BkDC.RestoreDC(-1);
 DigitDC.RestoreDC(-1);
 SrcDC.DeleteDC();
 BkDC.DeleteDC();    
 DigitDC.DeleteDC();
}
void CPlayMeter::OnLButtonDown(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
    if(!m_bMeter) 
       return;

	if(point.x>m_WinRect.right-47)
	   SetCursor(m_hArrow);
	
	if(rectDir.PtInRect(point) &&              
	   (((CMainFrame *)(AfxGetApp()->m_pMainWnd))->
	   GetCanDoNext()==1))
	  { m_bLBD=1;
	    ((CMainFrame *)(AfxGetApp()->m_pMainWnd))->   
	                SetPlayCount(-200);   
	    PaintDirector();
	    SetCapture();}
	    
	//CWnd::OnLButtonDown(nFlags, point);
}

void CPlayMeter::OnLButtonUp(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
    if(!m_bMeter) 
       return;

	if(point.x>m_WinRect.right-47)
	   SetCursor(m_hArrow);
	
	if(m_bLBD)
	  SetMeter();
	//CWnd::OnLButtonUp(nFlags, point);
}

void CPlayMeter::SetMeter()
{
		m_bLBD=0;        
		ReleaseCapture();
		PaintDirector();
        CRect rect;
        GetClientRect(&rect);
        int nMeterCx=rectDir.left+rectDir.Width()/2-m_MeterOrg;
        int nCal=0;    
        if(nMeterCx>=m_MeterRang-4)
        nCal=60;
        else
        if(nMeterCx<=4)
        nCal=1;
        else
        nCal=60*nMeterCx/m_MeterRang;
        if(nCal != m_SetSpeed)
           m_SetSpeed=nCal;   
        
		HANDLE x=GetProp(AfxGetApp()->m_pMainWnd->m_hWnd,"ClearScreen");
		if(x!=0)
		  {((CMainFrame *)(AfxGetApp()->m_pMainWnd))->   
	                SetPlayCount((2*m_SetSpeed)+1);  
	      }          
        else
          ((CMainFrame *)(AfxGetApp()->m_pMainWnd))->   
	                SetPlayCount(-1);
	                                   
	    ((CMainFrame *)(AfxGetApp()->m_pMainWnd))->
	      SetPlaySpeed(2*m_SetSpeed);   
}

void CPlayMeter::OnMouseMove(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
	CWnd::OnMouseMove(nFlags, point);
     
    if(!m_bMeter) 
       return;
       
	if(point.x>m_WinRect.right-47)
	   SetCursor(m_hArrow);

	if(m_bLBD==0)
	   return;
///////////////////////////////////////////////////////////
	((CMainFrame *)(AfxGetApp()->m_pMainWnd))->   
	                SetPlayCount(-200);   
	CRect rect,rectRang;
	GetClientRect(&rect);
	rectRang=rect;
	if(point.x<rect.left+8)
	  return;
	else    
	if(point.x>int(rect.right-55))
	  return;
	else                  
	{ rectDir.left=point.x-5;
	  rectDir.right=rectDir.left+8;}
    
    PaintDirector();
    rectRang.right-=40;
    rectRang.top-=20;
    rectRang.bottom==20;
    if(!rectRang.PtInRect(point))
      SetMeter();
}

int CPlayMeter::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
	if (CWnd::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here
	m_nLight=1;
	m_nLED=0;
	CClientDC dc(GetParent());
    m_pBitMeter    = new CBitmap;
    BOOL x;
                                  
    if(m_bMeter)                              
	 { 
	   m_pBitDirector = new CBitmap;
       m_pDirSel      = new CBitmap;
       MeterBitmap    = new CBitmap;
	   x=m_pBitMeter->LoadBitmap("METER");
	   ASSERT(x);
	   x=m_pBitDirector->LoadBitmap("DIRECTOR");
	   ASSERT(x);                  
	   m_pDirSel->LoadBitmap("DIR_SEL");;
	   MeterBitmap->CreateCompatibleBitmap(&dc,10,10);
      }
	else
	   x=m_pBitMeter->LoadBitmap("DELAY");

	m_LED[0].LoadBitmap("LED_0");
	m_LED[1].LoadBitmap("LED_1");
    m_LED[2].LoadBitmap("LED_2");
    m_LED[3].LoadBitmap("LED_3");
    m_LED[4].LoadBitmap("LED_4");
    m_LED[5].LoadBitmap("LED_5");
    m_LED[6].LoadBitmap("LED_6");
    m_LED[7].LoadBitmap("LED_7");
    m_LED[8].LoadBitmap("LED_8");
    m_LED[9].LoadBitmap("LED_9");
	return 0;
}

void CPlayMeter::OnDestroy()
{
	CWnd::OnDestroy();
	
	// TODO: Add your message handler code here
	m_pBitMeter->DeleteObject();
    delete m_pBitMeter;
  
   if(m_bMeter)
	 {
      m_pBitDirector->DeleteObject();
      MeterBitmap->DeleteObject();
      m_pDirSel->DeleteObject();
      delete m_pBitDirector;       
      delete m_pDirSel;
      delete MeterBitmap;
     } 
      
    for(int i=0;i<10;i++)
        m_LED[i].DeleteObject();
}




void CPlayMeter::OnLButtonDblClk(UINT nFlags, CPoint point)
{
	// TODO: Add your message handler code here and/or call default
	//CButton::OnLButtonDblClk(nFlags, point);
}


BOOL CPlayMeter::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
{
	// TODO: Add your message handler code here and/or call default
	
	BOOL x=CWnd::OnSetCursor(pWnd, nHitTest, message); 
	if(nHitTest==HTCLIENT && m_bMeter)
	   SetCursor(m_hCursor);
    return x;
}
