/***************************************************************************
**
**    $Header$
**
**    $Log$
** 
****************************************************************************/

/////////////////////////////////////////////////////////////////////////////
//
//  File name:  MYEDIT2.CPP
//
//  Description:The implement file for the class: CMyEdit2
//
//  Author:     Lane Li
//
//  Date:       09/10/95
//
//  Modification:
//
//      1. 09/10/95, Initial version
//
//
//  Copyright (C) 1995 Microtek International. All rights reserved.
//
/////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////
// myedit2.cpp
// Lane Li
// 95/7
///////////////////////////////////////////
#include "stdafx.h"
#include "resource.h"

#include "myedit2.h"

/////////////////////////////////////////////////////////////////////////////
// ParsedEdit

CMyEdit2::CMyEdit2()
: m_wParseStyle(0), m_nMin(0), m_nMax(0)
{

}

BEGIN_MESSAGE_MAP(CMyEdit2, CEdit)
    //{{AFX_MSG_MAP(CMyEdit2)
    ON_WM_CHAR()
    ON_WM_VSCROLL()     // for associated spin controls
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// Creating from C++ code

BOOL CMyEdit2::Create(DWORD dwStyle, const RECT& rect,
        CWnd* pParentWnd, UINT nID)
{
    m_wParseStyle = LOWORD(dwStyle);
    // figure out edit control style
    DWORD dwEditStyle = MAKELONG(ES_LEFT, HIWORD(dwStyle));
    return CWnd::Create("EDIT", NULL, dwEditStyle, rect, pParentWnd, nID);
}

/////////////////////////////////////////////////////////////////////////////
// Aliasing on top of an existing Edit control

BOOL CMyEdit2::SubclassEdit(UINT nID, CWnd* pParent, WORD wParseStyle)
{
    m_wParseStyle = wParseStyle;

    // SubclassWindow requires an HWND so we call the Windows GetDlgItem
    // and avoid creating a tempory CWnd and then calling GetSafeHwnd
    HWND hWndEdit = ::GetDlgItem(pParent->m_hWnd, nID);
    if (hWndEdit == NULL)   return FALSE;
    else return SubclassWindow(hWndEdit);
}

/////////////////////////////////////////////////////////////////////////////
// Input character filter

void CMyEdit2::OnChar(UINT nChar, UINT nRepCnt, UINT nFlags)
{
    WORD type;
    char buf[20];
    
    memset( buf, 0, 20 );    
    GetParent()->GetDlgItemText(GetDlgCtrlID(),buf,10);
    if(nChar < 0x20)    type = PES_ALL;     // always allow control chars
    else if(nChar >= '0' && nChar <= '9')   type = PES_NUMBERS;
    else if(nChar >= 'A' && nChar <= 'Z')   type = PES_LETTERS;
    else if(nChar >= 'a' && nChar <= 'z')   type = PES_LETTERS;
    else                                    type = PES_OTHERCHARS;
                      
   if ((buf[0]=='0')&&(buf[1]!='x')&&(buf[1]!='X')) {
      if ((nChar =='x')||(nChar =='X')) type = PES_NUMBERS;
   }
   
   switch (m_uAddOrLen) {
      case  0:          // Address
            if (nChar >= 'a' && nChar <= 'f') type = PES_NUMBERS;
            if (nChar >= 'A' && nChar <= 'F') type = PES_NUMBERS;
            break;
            
      case  1:          // Length
            if ((buf[0]=='0')&&((buf[1]=='x')||(buf[1]=='X'))) {
               if (nChar >= 'a' && nChar <= 'f') type = PES_NUMBERS;
               if (nChar >= 'A' && nChar <= 'F') type = PES_NUMBERS;
            }
            break;
   }                        
   
   if (m_wParseStyle & type)
      CEdit::OnChar(nChar, nRepCnt, nFlags);  // permitted
   else        // illegal character - inform parent
      OnBadInput();
}

/////////////////////////////////////////////////////////////////////////////
// Spin controls will send scroll messages

void CMyEdit2::OnVScroll(UINT nSBCode, UINT, CScrollBar*)
{
   char buf[20];
   long value;
   long nOld,nNew;
   int nDelta = 0;
   CString  strTemp;
   char lpszTemp1[125];
   char lpszTemp2[125];   
   UINT  uValue = 0;
      
   GetWindowText(strTemp);
   strcpy(lpszTemp1, strTemp.GetBuffer(strTemp.GetLength()));
      
   if (('x' == lpszTemp1[1]) || ('x' == lpszTemp1[1])) {
      strcpy(lpszTemp2, &lpszTemp1[2]);
      sscanf(lpszTemp2, "%x", &uValue);
   }      
   else {
      if (m_uAddOrLen == 0) {  // address
         strcpy(lpszTemp2, lpszTemp1);
         sscanf(lpszTemp2, "%x", &uValue); 
      }         
      else if (m_uAddOrLen == 1) {     // Length
         strcpy(lpszTemp2, lpszTemp1);
         sscanf(lpszTemp2, "%d", &uValue); 
      }         
   }        
   //uValue = (UINT)atoi(lpszTemp2);
      
   UINT  iMod = 0;                              
      
   switch(m_uWhichEdit) {
      case  1:
            iMod = uValue % 0x80;
            if ( nSBCode == SB_LINEDOWN ) {
               if (0 == iMod)
                  nDelta = -0x80;
               else
                  nDelta = -(int)(iMod);
            }               
            else if ( nSBCode == SB_LINEUP )
                    nDelta = +(int)(0x80-iMod);                        
            break;
      case  2:
            switch(m_uAddOrLen) {
               case  0:
                     iMod = (uValue+1) % 0x80;
                     break;
               case  1: 
                     iMod = uValue % 0x80;
                     break;
            }            
            
            if ( nSBCode == SB_LINEDOWN ) {
               switch(m_uAddOrLen) {
                 case   0:             // Address                          
                        if (0x7f > uValue)
                             nDelta = 0x7f - uValue;
                     else {
                           if (0 == iMod)
                              nDelta = -0x80;
                           else
                              nDelta = -(int)(iMod);
                     }                    
                     break;
                 case  1:              // Length   
                        if (0 == iMod)
                           nDelta = -0x80;
                        else
                           nDelta = -(int)(iMod);
                     break;
               }                   
            }               
            else if ( nSBCode == SB_LINEUP )
                  switch(m_uAddOrLen) {
                    case   0:
                        nDelta = +(int)(0x80-iMod);
                        break;
                    case   1:
                        nDelta = +(int)(0x80-iMod);
                        break;
            }                    
            break;
      }   

    // set the focus to this edit item and select it all
    SetFocus();

    //Get the number in the control.
    BOOL bOk;
//    int nOld = GetParent()->GetDlgItemInt(GetDlgCtrlID(), &bOk);
    bOk=TRUE;
    GetParent()->GetDlgItemText(GetDlgCtrlID(),buf,10);
    buf[10]='\0';                       

    switch (m_uAddOrLen) {
      case  0:          // Address
            value = strtol(buf, NULL, 16);
            nOld = value;
            break;

      case 1:           // Length                        
           if ((buf[0]=='0')&&((buf[1]=='x')||(buf[1]=='X'))) {
             value = strtol(buf,NULL,16);
             nOld = value;
           }                     
           else {
              value = strtol(buf,NULL,10);
              nOld = value;
           }
           break;
    }                               
   
    CString strAddr = "0x";
        
    if(bOk) {                             
        // The MuScroll control also supports range checking
        // for this example, we just prevent overflow
        nNew = nOld + nDelta;
        if (nNew >= m_nMin && nNew <= m_nMax) {
//            GetParent()->SetDlgItemInt(GetDlgCtrlID(), nNew);
          switch (m_uAddOrLen) {
            case  0:          // Address
                  _ltoa(nNew, buf, 16);
                  strAddr += buf;
                  GetParent()->SetDlgItemText(GetDlgCtrlID(), 
                                             /*buf*/strAddr);
                  break;
            
            case  1:          // Length
                  if ((buf[0]=='0')&&((buf[1]=='x')||(buf[1]=='X'))) {
                     _ltoa(nNew,buf+2,16);
                     GetParent()->SetDlgItemText(GetDlgCtrlID(), buf);
                  }   
                  else {
                     _ltoa(nNew,buf,10);
                     GetParent()->SetDlgItemText(GetDlgCtrlID(), buf);
                  }
                  break;                  
          }                  
        }
        else    bOk = FALSE;
    }

    if (!bOk)   OnBadInput();
    SetSel(0, -1);
}

////////////////////////////////////////////////////////
// default bad input handler, beep (unless parent notification
//    returns -1.  Most parent dialogs will return 0 or 1 for command
//    handlers (i.e. Beep is the default)
////////////////////////////////////////////////////////
void CMyEdit2::OnBadInput()
{
    if (GetParent()->SendMessage(WM_COMMAND,
                                 GetDlgCtrlID(), 
                                 MAKELONG(m_hWnd, PEN_ILLEGALCHAR)) != -1)
        MessageBeep(-1);
}

/////////////////////////////////////////////////////////////////////////////
