/****************************************************************************
**
**  Name:  peribuf.cpp
**
**  Description:
**     Source file for peripheral presenter buffer edit.                
**
**  $Log:   
** 
**  $Header:   S:/tbird/arcppc/peri/peribuf.cpv   1.0   17 Jan 1997 08:47:32   kevin  $
**
**  Copyright (C) 1993 Microtek International.  All rights reserved.
**
*****************************************************************************/


                       /****************************
                        *                          *
                        *       INCLUDE FILES      *
                        *                          *
                        ****************************/

#define WIN31
#define STRICT

#ifndef _PERIPRES_
#include "peripres.h"
#endif

#ifndef _PERIDIAL_
#include "peridial.h"
#endif

#ifndef _TBIRDMEM_
#include "tbirdmem.h"
#endif

#ifndef _ADDR_
#include "addr.h"
#endif

// BorlandC includes
#ifndef __CTYPE_H
#include <ctype.h>
#endif

#ifndef __STDIO_H
#include <stdio.h>
#endif


                       /****************************
                        *                          *
                        *        DEFINITIONS       *
                        *                          *
                        ****************************/


                       /****************************
                        *                          *
                        *       EXTERNALS          *
                        *                          *
                        ****************************/

extern PTPeriServer PeriServer;   // Peripheral server object ptr

                       /****************************
                        *                          *
                        *        PROTOTYPES        *
                        *                          *
                        ****************************/

VOID SubstEditVal (HWND hDlg, HWND hwndList, BOOLEAN moveCurSel);
U8 * formatTmpBuf(U16 offset);
PRIVATE PTRegister BufReg;
PRIVATE RETCODE BufErr;
PRIVATE int tabStops[2] = {24, 48};
PRIVATE LPU8 bufPtr = NULL;
PRIVATE LPU8 tmpBufPtr = NULL;
PRIVATE U32 bufSize;
PRIVATE U32 bufLength;

/*****************************************************************************
**
**  formatTmpBuf
**
*****************************************************************************/
U8* formatTmpBuf(U16 offset) {
   CHAR bufChar[4];
   PRIVATE CHAR statTempVal[32];
   U8 tmpU8;
   U16 tmpU16;
   U32 tmpU32;
   bufChar[0] = ' ';
   bufChar[1] = ' ';
   bufChar[2] = ' ';
   bufChar[3] = ' ';
   statTempVal[0] = ' ';
   statTempVal[1] = '\0';
   switch(bufSize) {
      case 1:
         if (isprint(*tmpBufPtr)) {
            bufChar[0] = (CHAR) *tmpBufPtr;
         }
         tmpU8 = *((U8 *) tmpBufPtr);
         sprintf(statTempVal,"+%3.3ld\t0x%2.2lX\t%c", (S32)(offset * bufSize), 
            (U32) tmpU8, bufChar[0]);
         break;
      case 2:
         if (isprint(*tmpBufPtr)) {
            bufChar[0] = (CHAR) *tmpBufPtr;
         }
         if (isprint(*(tmpBufPtr + 1))) {
            bufChar[1] = (CHAR) *(tmpBufPtr + 1);
         }
         tmpU16 = *((U16 *) tmpBufPtr);
         tmpU16 = MemSwapBytesInWord(tmpU16);
         sprintf(statTempVal,"+%3.3ld\t0x%4.4lX\t%c%c",
                 (S32)(offset * bufSize),(U32) tmpU16, bufChar[0], bufChar[1]);
         break;
      case 4:
         if (isprint(*tmpBufPtr)) {
            bufChar[0] = (CHAR) *tmpBufPtr;
         }
         if (isprint(*(tmpBufPtr + 1))) {
            bufChar[1] = (CHAR) *(tmpBufPtr + 1);
         }
         if (isprint(*(tmpBufPtr + 2))) {
            bufChar[2] = (CHAR) *(tmpBufPtr + 2);
         }
         if (isprint(*(tmpBufPtr + 3))) {
            bufChar[3] = (CHAR) *(tmpBufPtr + 3);
         }
         tmpU32 = *((U32 *) tmpBufPtr);
         tmpU32 = MemSwapBytesInLong(tmpU32);
         sprintf(statTempVal,"+%3.3ld\t0x%8.8lX\t%c%c%c%c",
                 (S32) (offset * bufSize), (U32) tmpU32,
                 bufChar[0], bufChar[1], bufChar[2], bufChar[3]);
         break;
   }
   return (statTempVal);
}

/*****************************************************************************
**
**  EditBuffer
**
*****************************************************************************/
RETCODE EditBuffer(HINSTANCE module, HWND parent, PTRegister reg) {
   U16 helpIndex;
   WORD helpEntry;
   HANDLE helpWnd;
   HWND tmp;
   U16 rval;
   PRIVATE DLGPROC lpfnMainDlgProc;

   BufErr = GOOD; // static global for convenience
   helpIndex = HI_PERIPHERAL;
   helpEntry = HE_EDITPERIPHREGBUFFER;
   RegisterHelpEntry(helpIndex, (long) parent, helpEntry);

   if ((lpfnMainDlgProc = (DLGPROC)MakeProcInstance((FARPROC) MainDlgProc,
      module)) != NULL) {
      BufReg = reg;
      tmp = parent;
      DialogBox (module, DIA_EDITBUF, tmp, lpfnMainDlgProc);
      FreeProcInstance((FARPROC)lpfnMainDlgProc);
   }
   return (BufErr);
}

/*****************************************************************************
**
**  SubstEditVal
**
*****************************************************************************/
// Find the position of the current selection in the listbox, and try
// putting the value in the edit control back into the list box
VOID SubstEditVal (HWND hDlg, HWND hwndList, BOOLEAN moveCurSel) {
   S16 mVal;
   U8 *tempVal;
   U32 lTmp;
   U16 iTmp;
   U8 cTmp;
   U32 maxVal;
   CHAR *endptr;
   U8 tempEditVal[32];

   mVal = SendMessage(hwndList, LB_GETCURSEL, 0, 0L);
   if (mVal != LB_ERR) {
      GetDlgItemText(hDlg, EB_EDIT_ID, (LPSTR) tempEditVal, 32);
      if (bufSize == 1) maxVal = 255L; 
      else if (bufSize == 2) maxVal = 65535L; 
      else maxVal = 42949667295L;
      lTmp = strtoul(tempEditVal, &endptr, 0);
      if ((endptr != NULL && *endptr != '\0' && !isspace(*endptr)) || 
            lTmp > maxVal) {
         MessageBeep(0); // this is quicker than a MessageBox...
         return; // error
      }
      tmpBufPtr = bufPtr + (mVal * bufSize);
      if (bufSize == 1) {
         cTmp = lTmp;
         *((U8 *)tmpBufPtr) = cTmp;
      }
      else if (bufSize == 2) {
         iTmp = lTmp;
         iTmp = MemSwapBytesInWord(iTmp);
         *((U16 *)tmpBufPtr) = iTmp;
      }
      else if (bufSize == 4) {
         lTmp = MemSwapBytesInLong(lTmp);
         *((U32 *)tmpBufPtr) = lTmp;
      }
      tempVal = formatTmpBuf(mVal);
      if (tempVal != NULL && tempVal[0] != '\0') {
         SendMessage(hwndList, LB_DELETESTRING, mVal, 0L);
         SendMessage(hwndList, LB_INSERTSTRING, mVal, (LONG) (LPSTR) tempVal);
      }
      if (moveCurSel && mVal < (bufLength/bufSize) - 1) {
         SendMessage(hwndList, LB_SETCURSEL, mVal + 1, 0L);
      }
      else {
         SendMessage(hwndList, LB_SETCURSEL, mVal, 0L);
      }
      SendMessage(hDlg, WM_COMMAND, EB_LISTBOX_ID,
         (LONG) LBN_SELCHANGE << 16);
   }
}

/*****************************************************************************
**
**  MainDlgProc
**
*****************************************************************************/
BOOL EXPORT MainDlgProc (HWND hDlg, UINT message, UINT wParam, LONG lParam) {
   HWND hwndList, hwndEdit;
   S16 i, mVal;
   U16 ln = 0, iTmp, maxBufIndex;
   U32 lTmp;
   S8 regAddr[32], mnemonic[MAX_MNEMONIC];
   U8 bufChar[4], *tempVal, tempEditVal[32];
   PTRegister reg;
   DESCRIPTOR tmpDesc = NULL, tmpByteDesc = NULL;
   LPSTR lpTok = NULL;
   RETCODE err;
   S8 desc[MAX_INFOSTR], groupname[MAX_MNEMONIC], caption[2 * MAX_INFOSTR];
   PTGroup grp;
  
   reg = BufReg;
   hwndList = GetDlgItem(hDlg, EB_LISTBOX_ID);
   hwndEdit = GetDlgItem(hDlg, EB_EDIT_ID);
   
   switch (message) {
      case WM_INITDIALOG:
         mnemonic[0] = '\0';
         desc[0] = '\0';
         caption[0] = '\0';
         reg->GetName(mnemonic);
         reg->GetDesc(desc);
         grp = PeriServer->GetGroupInfo(reg->GetGroupId());
         grp->GetName(groupname);
         regAddr[0] = '\0';
         if ((err = PeriServer->GetRegisterAddress(reg,&tmpDesc)) != GOOD) {
            BufErr = err;
         }
         else if ((err = AdrConvAddressToTextWithParams(tmpDesc, FALSE,
            FALSE,regAddr)) != GOOD) {
            BufErr = err;
         }
         // 04/15/94 - Nghia
         // destroy the tmpDesc before exit
         if (tmpDesc != NULL) AdrDestroyAddress(tmpDesc);

         if (BufErr != GOOD) {
            EndDialog (hDlg, 0);
            return (TRUE);
         }
         sprintf(caption,"%s %s - %s", groupname, mnemonic, desc);
         SetWindowText(hDlg, caption);
         SetDlgItemText(hDlg, EB_ADDRESS_ID, (LPSTR) regAddr);
         SetDlgItemText(hDlg, EB_BASEADDRESS_ID, (LPSTR) regAddr);
         bufPtr = reg->GetBufferValue();
         if (bufPtr == NULL) {
            EndDialog (hDlg, 0);
            return (TRUE);
         }
         SendMessage(hwndList, WM_SETREDRAW, 0, 0L);
         SendMessage(hwndList, LB_SETTABSTOPS, 2, (LONG) 
           (int FAR *) &tabStops);
         tmpBufPtr = bufPtr;
         bufSize = reg->GetSize();
         bufLength = reg->GetFieldCnt();
         maxBufIndex = (bufLength / bufSize) - 1;
         for (i = maxBufIndex; i >= 0; i--) {
            tempVal = formatTmpBuf(ln);
            if (tempVal == NULL) break;
            if (ln == 0) {
               if (bufSize == 1) {
                   sprintf(tempEditVal,"0x%2.2lX", (U32) *tmpBufPtr);
               }
               else if (bufSize == 2) {
                   iTmp = *((U16 *) tmpBufPtr);
                   iTmp = MemSwapBytesInWord(iTmp);
                   sprintf(tempEditVal,"0x%4.4lX", (U32) iTmp);
               }
               else if (bufSize == 4) {
                   lTmp = *((U32 *) tmpBufPtr);
                   lTmp = MemSwapBytesInLong(lTmp);
                   sprintf(tempEditVal,"0x%8.8lX", (U32) lTmp);
               }
               SetDlgItemText(hDlg, EB_EDIT_ID, (LPSTR) tempEditVal);
               //SendMessage(hwndEdit, EM_SETSEL, 0,
               //(LONG)strlen(tempEditVal) << 16 | 2);
            }
            SendMessage(hwndList, LB_INSERTSTRING, ln++,
               (LONG) (LPSTR) tempVal);
            tmpBufPtr += (bufSize);
         }
         SendMessage(hwndList, WM_SETREDRAW, 1, 0L);
         InvalidateRect(hwndList, NULL, FALSE);
         SendMessage(hwndList, LB_SETCURSEL, 0, 0L);
         SetFocus(hwndList);
         return (TRUE);

      case WM_COMMAND:
         switch (wParam) {
            case IDOK:
               if (GetFocus() == hwndEdit) {
                  SubstEditVal(hDlg, hwndList, TRUE);
                  GetDlgItemText(hDlg, EB_EDIT_ID, (LPSTR) tempEditVal, 32);
                  SendMessage(hwndEdit, EM_SETSEL, 0,
                              (LONG)strlen(tempEditVal) << 16 | 2);
               }
               else if (GetFocus() != hwndList) {
                  PeriServer->SetRegValue(reg, bufPtr);
                  EndDialog (hDlg, 0);
               }
               return TRUE;
               
            case IDCANCEL:
               BufErr = PeriServer->ReadRegValue(reg, NULL); // restore
               EndDialog (hDlg, 0);
               return (TRUE);
               
            case EB_LISTBOX_ID:
               if (HIWORD(lParam) == LBN_SELCHANGE) {
                  regAddr[0] = '\0';
                  mnemonic[0] = '\0';
                  if ((err = PeriServer->GetRegisterAddress(reg,&tmpDesc))
                      != GOOD) {
                     BufErr = err;
                  }
                  else if ((err = AdrDuplicateAddress(tmpDesc,
                     (DESCRIPTOR FAR *) &tmpByteDesc)) != GOOD) { 
                     BufErr = err;
                  }
                  mVal = SendMessage(hwndList, LB_GETCURSEL, 0, 0L);
                  AdrAddToAddress(tmpByteDesc, (LONG) (mVal * bufSize));
                  if ((err = AdrConvAddressToTextWithParams(tmpByteDesc,
                     FALSE,FALSE,regAddr)) != GOOD) {
                     BufErr = err;
                  }
                  // 04/15/94 - Nghia
                  // destroy the tmpDesc and tmpByteDesc before exit
                  if (tmpDesc != NULL) AdrDestroyAddress(tmpDesc);
                  if (tmpByteDesc != NULL) AdrDestroyAddress(tmpByteDesc);
                  
                  if (BufErr != GOOD) {
                     EndDialog (hDlg, 0);
                     return (TRUE);
                  }
                  SetDlgItemText(hDlg, EB_ADDRESS_ID, (LPSTR) regAddr);
                  if (mVal != LB_ERR) {
                     SendMessage(hwndList, LB_GETTEXT, mVal,
                                 (LONG)(LPSTR) regAddr);
                     lpTok = _fstrtok((LPSTR) regAddr, "\t");
                     lpTok = _fstrtok(NULL, "\t");
                     SetDlgItemText(hDlg, EB_EDIT_ID, (LPSTR) lpTok);
                     //SendMessage(hwndEdit, EM_SETSEL, 0,
                     //(LONG) strlen(lpTok) << 16 | 2);
                  }
               }
               return (TRUE);

            case EB_EDIT_ID:
               if (HIWORD(lParam) == EN_SETFOCUS) {
                  GetDlgItemText(hDlg, EB_EDIT_ID, (LPSTR) tempEditVal, 16);
                  SendMessage(hwndEdit, EM_SETSEL, 0,
                              (LONG)strlen(tempEditVal) << 16 | 2);
               }
               if (HIWORD(lParam) == EN_KILLFOCUS) {
                  SubstEditVal(hDlg, hwndList, FALSE);
               }
               return (TRUE);
               
            case IDHELP:
               WinHelp(hDlg, "PWRVIEWS.HLP",
                  HELP_CONTEXT, HE_EDITPERIPHREGBUFFER);
               return TRUE;
      }
      break;
   }
   return (FALSE);
}
//***************************** E O F *****************************************
