//====START_GENERATED_PROLOG======================================
//
//
//   COMPONENT_NAME: odother
//
//   CLASSES: none
//
//   ORIGINS: 82,27
//
//
//   (C) COPYRIGHT International Business Machines Corp. 1995,1996
//   All Rights Reserved
//   Licensed Materials - Property of IBM
//   US Government Users Restricted Rights - Use, duplication or
//   disclosure restricted by GSA ADP Schedule Contract with IBM Corp.
//   	
//   IBM DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
//   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
//   PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL, INDIRECT OR
//   CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF
//   USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
//   OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
//   OR PERFORMANCE OF THIS SOFTWARE.
//
//====END_GENERATED_PROLOG========================================
//
// @(#) 1.8 com/src/samples/cardgame/iodcard.cpp, odcardgamepart, od96nt, odnt9712d 3/4/97 18:24:32 [3/21/97 17:40:15]

/*
 *  This file was generated by the SOM Compiler.
 *  Generated using:
 *     SOM incremental update: 2.43
 */


/*
 *  This file was generated by the SOM Compiler and Emitter Framework.
 *  Generated using:
 *      SOM Emitter emitxtm: 2.41
 */

#ifndef SOM_Module_CardGame_Source
#define SOM_Module_CardGame_Source
#endif
#define CardGame_Class_Source
#define VARIABLE_MACROS
#define METHOD_MACROS

#ifndef _ALTPOINT_
#include "AltPoint.h" //  MUST be included BEFORE os2.h
#endif

#ifdef _PLATFORM_WIN32_
#   include <windows.h>
#   include <winuser.h>
#   include <wingdi.h>
#   define DosBeep(x, y) Beep(x, y)
#   define NULLHANDLE kODNULL
#endif

#   include <odall.h>
#   include <ODRes.h>

#ifndef _STORUTIL_
#include <storutil.h>
#endif


#include <stdio.h>
#include <stdtypio.h>
#include <stdlib.h>
#include <time.h>

#include "iodcard.xih"
#include "Resource.h"

#ifdef _LEFT_TO_PORT_
#ifndef SOM_EmbeddedCardIterator_xh
#include "CardIter.xh"
#endif

#ifndef SOM_CardGameNoteBook_xh
#include "CardNote.xh"
#endif
#endif

#ifndef _FOCUSLIB_
#include "FocusLib.h"
#endif

#ifndef _ODUTILS_
#include "ODUtils.h"  //  Definitions of ODReleaseObject, ODCopyAndRelease
#endif

#include "iodcard.hpp"


#ifdef _PLATFORM_WIN32_
LRESULT CALLBACK BetEntryDlgProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{
   UINT BetValue;
   BOOL error;

   switch (msg) {
   case WM_INITDIALOG:
      SetDlgItemInt(hwnd, DollarEntryField, DEFAULT_BET, kODFalse);
      break;

   case WM_COMMAND:
      switch (LOWORD(wParam)) {
      case OK_BUTTON:
         BetValue = GetDlgItemInt(hwnd, DollarEntryField, &error, kODFalse);
         if ((BetValue<BET_LOWER_BOUND) || (BetValue>BET_UPPER_BOUND)) {
            MessageBox(hwnd, (PSZ) BetErrorMsg, (PSZ) NULL,
               MB_OK | MB_ICONSTOP | MB_SETFOREGROUND);
            SetDlgItemInt(hwnd, DollarEntryField, DEFAULT_BET, kODFalse);
         } else {
            EndDialog(hwnd, BetValue);
         } /* endif */
         break;
      case CANCEL_BUTTON:
         EndDialog(hwnd, kODNULL);
         break;
      } /* endswitch */
      break;
   default:
      return(kODFalse);
   } /* endswitch */
   return(kODTrue);
}
#endif

#ifdef _LEFT_TO_PORT_
MRESULT EXPENTRY BetEntryDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
   MRESULT ReturnValue = kODFalse;

   LONG BetValue;
   switch (msg) {
   case WM_INITDLG:
      WinSendDlgItemMsg(hwnd, DollarSpinButton, SPBM_SETLIMITS,
         MPFROMLONG(BET_UPPER_BOUND), MPFROMLONG(BET_LOWER_BOUND));
      WinSendDlgItemMsg(hwnd, DollarSpinButton, SPBM_SETCURRENTVALUE,
         MPFROMLONG(DEFAULT_BET), NULL);
      break;
   case WM_COMMAND:
      switch (SHORT1FROMMP(mp1)) {
      case DID_OK:
         WinSendDlgItemMsg(hwnd, DollarSpinButton, SPBM_QUERYVALUE,
            &BetValue, NULL);
         if ((BetValue<BET_LOWER_BOUND) || (BetValue>BET_UPPER_BOUND)) {
            WinMessageBox(HWND_DESKTOP, hwnd, (PSZ)BetErrorMsg, (PSZ)NULL, 0,
               MB_ENTER | MB_ERROR);
            WinSendDlgItemMsg(hwnd, DollarSpinButton, SPBM_SETCURRENTVALUE,
               MPFROMLONG(DEFAULT_BET), NULL);
         } else {
            WinDismissDlg(hwnd, BetValue);
         } /* endif */
         break;
      case DID_CANCEL:
         WinDismissDlg(hwnd, kODNULL);
         break;
      } /* endswitch */
      break;
   default:
      return(WinDefDlgProc(hwnd, msg, mp1, mp2));
     break;
   } /* endswitch */
   return(ReturnValue);
}


MRESULT EXPENTRY PartInfoDlgProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
   MRESULT ReturnValue = kODFalse;

   switch (msg) {
   case WM_INITDLG:
      WinSetWindowText(WinWindowFromID(hwnd, PartInfoPartName),
         kPartHandlerDisplayName);

/*      following code unnecessary, left for posterity's sake to show how    */
/*      create an embedded icon.  Unfortunately, this approach was device    */
/*      dependent, so I changed the icon to be part of the dialog definition */
/*      in the .rc file (allowing me to specify its position in device       */
/*      independent dialog coordinates)                                      */
#if 0
      if (mp2!=NULL) {
         HWND IconHWND = WinCreateWindow(hwnd, WC_STATIC, "", WS_VISIBLE,
            GAMEICON_X_POS, GAMEICON_Y_POS, ICON_WIDTH, ICON_HEIGHT, hwnd,
            HWND_TOP, GAMEICON_ID, NULL, NULL);
         WinSetWindowBits(IconHWND, QWL_STYLE, SS_ICON, SS_ICON);
         WinSendMsg(IconHWND, SM_SETHANDLE, mp2, (MPARAM) 0);
      } /* endif */
#endif
      break;
   case WM_COMMAND:
      {
         short button = SHORT1FROMMP(mp1);
         if (button==DID_OK) {
            WinDismissDlg(hwnd, button);
         } /* endif */
      }
      break;
   default:
      return(WinDefDlgProc(hwnd, msg, mp1, mp2));
     break;
   } /* endswitch */

   return(ReturnValue);
}
#endif


SOM_Scope void  SOMLINK CardGameCommonInitCardGame(CardGame *somSelf,
                                                      Environment *ev)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameCommonInitCardGame");

//   _CommonInitSimplePart(ev);

   time_t CurrentTime;
   srand(time(&CurrentTime));

   _MySession = _GetStorageUnit(ev)->GetSession(ev);

   _ViewAsSmallIcon = _MySession->Tokenize(ev, kODViewAsSmallIcon);
   _ViewAsLargeIcon = _MySession->Tokenize(ev, kODViewAsLargeIcon);
   _ViewAsThumbnail = _MySession->Tokenize(ev, kODViewAsThumbnail);
   _ViewAsFrame = _MySession->Tokenize(ev, kODViewAsFrame);

   _DefaultPresentation = _MySession->Tokenize(ev, kODPresDefault);

   _MenuFocus = _MySession->Tokenize(ev, kODMenuFocus);

#ifdef _LEFT_TO_PORT_
   _fLinkStatus = new char[256];
#endif

#ifdef _PLATFORM_WIN32_
   _MyResources = GetModuleHandle(kCardGameFileName);
#endif

#ifdef _LEFT_TO_PORT_
   DosQueryModuleHandle(kCardGameFileName, &_MyResources);
#endif

   _LoadMyMenuBar(ev);
}


SOM_Scope void  SOMLINK CardGameLoadMyMenuBar(CardGame *somSelf,
                                               Environment *ev)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameLoadMyMenuBar");

   _MyMenuBar = _MySession->GetWindowState(ev)->CopyBaseMenuBar(ev);

   if (_MyMenuBar) {
      ODPlatformMenuBar GameMenu;

#ifdef _PLATFORM_OS2_
      GameMenu = WinLoadMenu(HWND_OBJECT, _MyResources, GameMenuID);
#elif defined(_PLATFORM_WIN32_)
      GameMenu = LoadMenu(_MyResources, MAKEINTRESOURCE(GameMenuID));
#endif

      if (GameMenu!=NULLHANDLE) {
         _MyMenuBar->AddMenuLast(ev, GameMenuID, GameMenu, _MyWrapper);
         _MyMenuBar->SetMenuItemText(ev, ID_BASEMENUBAR, GameMenuID, "&Game");
      } /* endif */

      ODPlatformMenuBar ActionsMenu;

#ifdef _PLATFORM_OS2_
      ActionsMenu = WinLoadMenu(HWND_OBJECT, _MyResources, ActionsMenuID);
#elif defined(_PLATFORM_WIN32_)
      ActionsMenu = LoadMenu(_MyResources, MAKEINTRESOURCE(ActionsMenuID));
#endif

      if (ActionsMenu!=NULLHANDLE) {
         _MyMenuBar->AddMenuLast(ev, ActionsMenuID, ActionsMenu, _MyWrapper);
         _MyMenuBar->SetMenuItemText(ev, ID_BASEMENUBAR, ActionsMenuID, "&Actions");
      } /* endif */

#ifdef _LEFT_TO_PORT_
      ODPlatformMenuItem item;
      memset(&item, 0, sizeof(MENUITEM));

      item.id = MenuSeparator;
      item.afStyle = MIS_SEPARATOR; /* Put separator at end of View Menu */
      _MyMenuBar->AddMenuItemLast(ev, IDMS_HELP, kODNULL, &item);

      item.id = MenuDescription; /* Insert "Description" into Help menu */
      item.afStyle = MIS_TEXT;
      _MyMenuBar->AddMenuItemLast(ev, IDMS_HELP, kODNULL, &item);
      _MyMenuBar->SetMenuItemText(ev, IDMS_HELP, MenuDescription,
         "Part Handler Description");

      item.id = MenuPartInfo; /* Insert "Part Info" into Help menu */
      _MyMenuBar->AddMenuItemLast(ev, IDMS_HELP, kODNULL, &item);
      _MyMenuBar->SetMenuItemText(ev, IDMS_HELP, MenuPartInfo,
         "Part Handler Information");
#endif
   } /* endif */
}


SOM_Scope void  SOMLINK CardGameMessageBox(CardGame *somSelf,
                                            Environment *ev,
                                           ODPlatformWindow hwnd,
                                           char* title, char* msg)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameMessageBox");

#ifdef _PLATFORM_OS2_
    WinMessageBox(HWND_DESKTOP, hwnd, (PSZ)msg, (PSZ)title, 0,
       MB_OK | MB_INFORMATION | MB_MOVEABLE);
#elif defined(_PLATFORM_WIN32_)
    MessageBox(hwnd, (PSZ)msg, (PSZ)title,
       MB_OK | MB_ICONINFORMATION | MB_SETFOREGROUND);
#endif
}


SOM_Scope void  SOMLINK CardGameSizeFrame(CardGame *somSelf,
                                           Environment *ev, ODFacet* facet)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameSizeFrame");

    ODFrame *frame = facet->GetFrame(ev);

    LONG width = _CurrentGame==STUD_7_POKER ? DEFAULT7_WIDTH : DEFAULT5_WIDTH;
    LONG height = DEFAULT_HEIGHT;

#ifdef _PLATFORM_OS2_
    RECTL frameRect = {0, 0, width, height};
#elif defined(_PLATFORM_WIN32_)
    RECT frameRect = {0, 0, width, height};
#endif

    if (!frame->IsRoot(ev)) {
       ODRect newODRect(frameRect);
       ODShape* newShape = facet->CreateShape(ev);

       newShape->SetRectangle(ev, &newODRect);

       ODCanvas *canvas = facet->GetCanvas(ev);
       ODTransform *frameXform = facet->AcquireFrameTransform(ev, canvas);

       ODPoint* scale = new ODPoint;
       frameXform->GetScale(ev, scale);
       frameXform->Release(ev);

       ODTransform* newTransform = facet->CreateTransform(ev);
       newTransform->ScaleBy(ev, scale);

       newShape->InverseTransform(ev, newTransform);

       frame->RequestFrameShape(ev, newShape, canvas);
       frame->ChangeUsedShape(ev, kODNULL, canvas);
    } else {
#ifdef _LEFT_TO_PORT_
       ODWindow *window = facet->GetWindow(ev);
       ODPlatformWindow hwnd = window->GetPlatformWindow(ev);

       WinCalcFrameRect(hwnd, &frameRECTL, kODFalse);

       width = frameRECTL.xRight-frameRECTL.xLeft;
       height = frameRECTL.yTop-frameRECTL.yBottom;

       LONG ScreenWidth = WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
       LONG ScreenHeight = WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);

       LONG xOffset = (ScreenWidth-width)/2;
       LONG yOffset = (ScreenHeight-height)/2;

       WinSetWindowPos(hwnd, NULL, xOffset>0 ? xOffset : 0,
          yOffset>0 ? yOffset : 0,
          width<ScreenWidth ? width : ScreenWidth,
          height<ScreenHeight ? height : ScreenHeight,
          SWP_SIZE | SWP_MOVE);

#else  //      since we didn't opt to resize the DocShell (which causes a
       //      FrameShapeChanged on the root frame), we at least need to
       //      let ourselves know that we need to recompute our geometry,
       //      since when we are the root we won't have any container
       //      calling ChangeGeometry on our facet
       _GeometryChanged(ev, facet, kODTrue, kODTrue);
#endif
    } /* endif */
}


SOM_Scope void  SOMLINK CardGameCreateEmbeddedBMPParts(CardGame *somSelf,
                                                            Environment *ev,
                                                           ODFacet* facet,
                                                           ODBoolean FirstFive)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameCreateEmbeddedBMPParts");

    ODDraft *draft = _GetStorageUnit(ev)->GetDraft(ev);
    ODFrame *frame = facet->GetFrame(ev);

    ODCanvas *canvas = facet->GetCanvas(ev);
    ODTransform *frameXform = facet->AcquireFrameTransform(ev, canvas);

    ODPoint* scale = new ODPoint;
    frameXform->GetScale(ev, scale);
    frameXform->Release(ev);

    ODTransform* scaleXform = facet->CreateTransform(ev);
    scaleXform->ScaleBy(ev, scale);

    int FirstCard, LastCard;
    ODPoint offset(0x10000, DEALER_Y_POS*0x10000);
    if (FirstFive) {
       FirstCard = 1;
       LastCard = 5;
       offset.x *= CARD1_X_POS;

       for (int index=1; index<=7; index++) { /* Create all Picture Parts */
          _DealerBMPPartWrapper[index] = draft->CreatePart(ev,
             kKindBitmapPart, kODNULL);
          _PlayerBMPPartWrapper[index] = draft->CreatePart(ev,
             kKindBitmapPart, kODNULL);
       } /* endfor */
    } else {
       FirstCard = 6;
       LastCard = 7;
       offset.x *= CARD6_X_POS;
    } /* endif */

    ODRect rect(0, CARD_HEIGHT*0x10000, CARD_WIDTH*0x10000, 0);

    char* BlankFileName = _DetermineCardBitmapFileName(ev, BLANK);

    for (int index=FirstCard; index<=LastCard; index++) {
       ODShape *frameShape = facet->CreateShape(ev);
       frameShape->SetRectangle(ev, &rect);
       frameShape->InverseTransform(ev, scaleXform);

       ODFrame *embeddedFrame = draft->CreateFrame(ev, kODFrameObject, frame,
          frameShape, canvas, _DealerBMPPartWrapper[index], _ViewAsFrame,
          _DefaultPresentation, kODFalse, kODFalse);

       embeddedFrame->SetFrozen(ev, kODTrue);
       embeddedFrame->SetDroppable(ev, kODFalse);

       ODShape *clipShape = facet->CreateShape(ev);
       clipShape->CopyFrom(ev, frameShape);

       ODPoint ScaledOffset(offset.x, offset.y);
       scaleXform->InvertPoint(ev, &ScaledOffset);
       ODTransform *externalXform = facet->CreateTransform(ev);
       externalXform->SetOffset(ev, &ScaledOffset);

       _DealerCardFacet[index] = facet->CreateEmbeddedFacet(ev, embeddedFrame,
          clipShape, externalXform, kODNULL, canvas, kODNULL, kODFrameInFront);

       offset.x += (CARD_WIDTH+CARD_SPACE)*0x10000;
    } /* endfor */

    offset.x = (FirstFive ? CARD1_X_POS : CARD6_X_POS)*0x10000;
    offset.y = PLAYER_Y_POS*0x10000;

    for (index=FirstCard; index<=LastCard; index++) {
       ODShape *frameShape = facet->CreateShape(ev);
       frameShape->SetRectangle(ev, &rect);
       frameShape->InverseTransform(ev, scaleXform);

       ODFrame *embeddedFrame = draft->CreateFrame(ev, kODFrameObject, frame,
          frameShape, canvas, _PlayerBMPPartWrapper[index], _ViewAsFrame,
          _DefaultPresentation, kODFalse, kODFalse);

       embeddedFrame->SetFrozen(ev, kODTrue);
       embeddedFrame->SetDroppable(ev, kODFalse);

       ODShape *clipShape = facet->CreateShape(ev);
       clipShape->CopyFrom(ev, frameShape);

       ODPoint ScaledOffset(offset.x, offset.y);
       scaleXform->InvertPoint(ev, &ScaledOffset);
       ODTransform *externalXform = facet->CreateTransform(ev);
       externalXform->SetOffset(ev, &ScaledOffset);

       _PlayerCardFacet[index] = facet->CreateEmbeddedFacet(ev, embeddedFrame,
          clipShape, externalXform, kODNULL, canvas, kODNULL, kODFrameInFront);

       offset.x += (CARD_WIDTH+CARD_SPACE)*0x10000;
    } /* endfor */
}


SOM_Scope void  SOMLINK CardGameCreateEmbeddedControls(CardGame *somSelf,
                                                       Environment *ev,
                                                      ODPlatformWindow hwnd)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameCreateEmbeddedControls");

#ifdef _PLATFORM_OS2_
    _FrameHWND = WinCreateWindow(hwnd, WC_STATIC, NULL, SS_FGNDFRAME,
       0, 0, 0, 0, hwnd, HWND_TOP, FRAME_ID, NULL, NULL);

    _TitleHWND = WinCreateWindow(hwnd, WC_STATIC, BlackJackTitle,
       SS_TEXT | DT_CENTER | DT_VCENTER, 0, 0, 0, 0, hwnd, HWND_TOP, TITLE_ID,
       NULL, NULL);

    _RectangleHWND = WinCreateWindow(hwnd, WC_STATIC, NULL, SS_FGNDRECT,
       0, 0, 0, 0, hwnd, HWND_TOP, RECTANGLE_ID, NULL, NULL);

    _MoneyHWND = WinCreateWindow(hwnd, WC_STATIC, NULL,
       SS_TEXT | DT_CENTER | DT_VCENTER, 0, 0, 0, 0, hwnd, HWND_TOP, MONEY_ID,
       NULL, NULL);

#ifdef _LEFT_TO_PORT_
    _MoneyLinkHWND = WinCreateWindow(hwnd, WC_STATIC, NULL,
       SS_TEXT | DT_LEFT | DT_VCENTER, 0, 0, 0, 0, hwnd, HWND_TOP, MONEY_LINK_ID,
       NULL, NULL);
#endif

    _PotHWND = WinCreateWindow(hwnd, WC_STATIC, NULL,
       SS_TEXT | DT_CENTER | DT_VCENTER, 0, 0, 0, 0, hwnd, HWND_TOP, POT_ID,
       NULL, NULL);

    _BetHWND = WinCreateWindow(hwnd, WC_STATIC, NULL,
       SS_TEXT | DT_CENTER | DT_VCENTER, 0, 0, 0, 0, hwnd, HWND_TOP, BET_ID,
       NULL, NULL);

    _Button1HWND = WinCreateWindow(hwnd, WC_BUTTON, HitString, NULL,
      0, 0, 0, 0, hwnd, HWND_TOP, BUTTON1_ID, NULL, NULL);

    _Button2HWND = WinCreateWindow(hwnd, WC_BUTTON, StandString, NULL,
      0, 0, 0, 0, hwnd, HWND_TOP, BUTTON2_ID, NULL, NULL);

    _Button3HWND = WinCreateWindow(hwnd, WC_BUTTON, DoubleString, NULL,
      0, 0, 0, 0, hwnd, HWND_TOP, BUTTON3_ID, NULL, NULL);

    _DiscardHWND = WinCreateWindow(hwnd, WC_BUTTON, DiscardString, NULL,
      0, 0, 0, 0, hwnd, HWND_TOP, DISCARD_ID, NULL, NULL);

    _HeartIconHWND = WinCreateWindow(hwnd, WC_STATIC, "", NULL, 0, 0,
       ICON_WIDTH, ICON_HEIGHT, hwnd, HWND_TOP, HEARTICON_ID, NULL, NULL);

    _SpadeIconHWND = WinCreateWindow(hwnd, WC_STATIC, "", NULL, 0, 0,
       ICON_WIDTH, ICON_HEIGHT, hwnd, HWND_TOP, SPADEICON_ID, NULL, NULL);

    _DiamondIconHWND = WinCreateWindow(hwnd, WC_STATIC, "", NULL, 0, 0,
       ICON_WIDTH, ICON_HEIGHT, hwnd, HWND_TOP, DIAMONDICON_ID, NULL, NULL);

    _ClubIconHWND = WinCreateWindow(hwnd, WC_STATIC, "", NULL, 0, 0,
       ICON_WIDTH, ICON_HEIGHT, hwnd, HWND_TOP, CLUBICON_ID, NULL, NULL);

#elif defined(_PLATFORM_WIN32_)
    HINSTANCE instance = (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE);

    _TitleHWND = CreateWindow("STATIC", BlackJackTitle,
       WS_VISIBLE | WS_CHILD | SS_CENTER, 0, 0, 0, 0, hwnd, (HMENU) TITLE_ID,
       instance, NULL);

    _MoneyHWND = CreateWindow("STATIC", NULL, WS_VISIBLE | WS_CHILD | SS_CENTER,
       0, 0, 0, 0, hwnd, (HMENU) MONEY_ID, instance, NULL);

    _PotHWND = CreateWindow("STATIC", NULL, WS_VISIBLE | WS_CHILD | SS_CENTER,
       0, 0, 0, 0, hwnd, (HMENU) POT_ID, instance, NULL);

    _BetHWND = CreateWindow("STATIC", NULL, WS_VISIBLE | WS_CHILD | SS_CENTER,
       0, 0, 0, 0, hwnd, (HMENU) BET_ID, instance, NULL);

    _Button1HWND = CreateWindow("BUTTON", HitString,
       WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 0, 0, 0, 0, hwnd,
       (HMENU) BUTTON1_ID, instance, NULL);

    _Button2HWND = CreateWindow("BUTTON", StandString,
       WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 0, 0, 0, 0, hwnd,
       (HMENU) BUTTON2_ID, instance, NULL);

    _Button3HWND = CreateWindow("BUTTON", DoubleString,
       WS_VISIBLE | WS_CHILD | BS_PUSHBUTTON, 0, 0, 0, 0, hwnd,
       (HMENU) BUTTON3_ID, instance, NULL);

    _DiscardHWND = CreateWindow("BUTTON", DiscardString,
       WS_CHILD | BS_PUSHBUTTON, 0, 0, 0, 0, hwnd,
       (HMENU) DISCARD_ID, instance, NULL);
#endif
}


SOM_Scope void  SOMLINK CardGameResizeEmbeddedBMPParts(CardGame *somSelf,
                                                            Environment *ev,
                                                           ODFacet* facet,
                                                           ODPoint* scale)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameResizeEmbeddedBMPParts");

    ODCanvas *canvas = facet->GetCanvas(ev);
    ODTransform* scaleXform = facet->CreateTransform(ev);
    scaleXform->ScaleBy(ev, scale);

    LONG adjustmentX = 0x10000*_FrameWidthRatio;
    LONG adjustmentY = 0x10000*_FrameHeightRatio;

    ODPoint offset(CARD1_X_POS*adjustmentX, (DEALER_Y_POS)*adjustmentY);

// ODRect's are laid out as (left, top, right, bottom) - on OS/2, we want the
// bottom zero and the top to be the height - on WIN32, since the coordinate
// system is upside-down there, it has to be the other way, with the top zero
// and the bottom equal to the height

#ifdef _PLATFORM_OS2_
    ODRect rect(0, CARD_HEIGHT*adjustmentY, CARD_WIDTH*adjustmentX, 0);
#elif defined(_PLATFORM_WIN32_)
    ODRect rect(0, 0, CARD_WIDTH*adjustmentX, CARD_HEIGHT*adjustmentY);
#endif

    int LastCard = _CurrentGame==STUD_7_POKER ? 7 : 5;

    for (int index=1; index<=LastCard; index++) {
       ODShape *frameShape = facet->CreateShape(ev);
       frameShape->SetRectangle(ev, &rect);
       frameShape->InverseTransform(ev, scaleXform);

       ODFacet *PictPartFacet = _DealerCardFacet[index];

       ODFrame *PictPartFrame = PictPartFacet->GetFrame(ev);
       PictPartFrame->ChangeFrameShape(ev, frameShape, canvas);

       ODShape *clipShape = facet->CreateShape(ev);
       clipShape->CopyFrom(ev, frameShape);

       ODPoint ScaledOffset(offset.x, offset.y);
       scaleXform->InvertPoint(ev, &ScaledOffset);
       ODTransform *externalXform = facet->CreateTransform(ev);
       externalXform->SetOffset(ev, &ScaledOffset);

       PictPartFacet->ChangeGeometry(ev, clipShape, externalXform, canvas);

       offset.x += (CARD_WIDTH+CARD_SPACE)*adjustmentX;
    } /* endfor */

    offset.x = CARD1_X_POS*adjustmentX;
    offset.y = (PLAYER_Y_POS)*adjustmentY;

    for (index=1; index<=LastCard; index++) {
       ODShape *frameShape = facet->CreateShape(ev);
       frameShape->SetRectangle(ev, &rect);
       frameShape->InverseTransform(ev, scaleXform);

       ODFacet *PictPartFacet = _PlayerCardFacet[index];

       ODFrame *PictPartFrame = PictPartFacet->GetFrame(ev);
       PictPartFrame->ChangeFrameShape(ev, frameShape, canvas);

       ODShape *clipShape = facet->CreateShape(ev);
       clipShape->CopyFrom(ev, frameShape);

       ODPoint ScaledOffset(offset.x, offset.y);
       scaleXform->InvertPoint(ev, &ScaledOffset);
       ODTransform *externalXform = facet->CreateTransform(ev);
       externalXform->SetOffset(ev, &ScaledOffset);

       PictPartFacet->ChangeGeometry(ev, clipShape, externalXform, canvas);

       offset.x += (CARD_WIDTH+CARD_SPACE)*adjustmentX;
    } /* endfor */
}


SOM_Scope void  SOMLINK CardGameResizeEmbeddedControls(CardGame *somSelf,
                                                        Environment *ev,
                                                       double frameWidth,
                                                       ODPoint* origin)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameResizeEmbeddedControls");

   LONG x, y, width, height;

/* We want the controls to scale to the whole frame */
   double ControlsWidthRatio;
   ControlsWidthRatio = frameWidth / ((double) DEFAULT5_WIDTH);

/* Frame resizing code */

   x = origin->x+TITLE_X_POS*ControlsWidthRatio;
   y = origin->y+(TITLE_Y_POS)*_FrameHeightRatio;
   width = TITLE_WIDTH*ControlsWidthRatio;
   height = TEXT_HEIGHT*_FrameHeightRatio;

#ifdef _LEFT_TO_PORT_
   WinSetWindowPos(_FrameHWND, HWND_TOP, x, y, width, height,
      SWP_SIZE | SWP_MOVE | SWP_SHOW);
#endif

#ifdef _PLATFORM_WIN32_
// MoveWindow(_FrameHWND, x, y, width, height, kODTrue);
#endif

/* Rectangle/Pot resizing code */

   x = origin->x+RECT_X_POS*ControlsWidthRatio;
   y = origin->y+(TEXT_Y_POS)*_FrameHeightRatio;
   width = RECT_WIDTH*ControlsWidthRatio;

#ifdef _LEFT_TO_PORT_
   WinSetWindowPos(_RectangleHWND, HWND_TOP, x, y, width, height,
      SWP_SIZE | SWP_MOVE | SWP_SHOW);

   WinSetWindowPos(_PotHWND, HWND_TOP, x, y, width, height,
      SWP_SIZE | SWP_MOVE | SWP_SHOW);

   WinShowWindow(_CurrentGame==BLACKJACK ? _PotHWND : _RectangleHWND, kODFalse);
#endif

#ifdef _PLATFORM_WIN32_
// MoveWindow(_RectangleHWND, x, y, width, height, kODTrue);
   MoveWindow(_PotHWND, x, y, width, height, kODTrue);

   if (_CurrentGame==BLACKJACK) {
      ShowWindow(_PotHWND, SW_HIDE);
// } else {
//    ShowWindow(_RectangleHWND, SW_HIDE);
   } /* endif */
#endif

/* Start of Text Repositioning code */

   x = origin->x+TITLE_X_POS*ControlsWidthRatio;
   y = origin->y+(TITLE_Y_POS)*_FrameHeightRatio;

   width  = TITLE_WIDTH*ControlsWidthRatio;

#ifdef _LEFT_TO_PORT_
   WinSetWindowPos(_TitleHWND, HWND_TOP, x, y, width, height,
      SWP_SIZE | SWP_MOVE | SWP_SHOW);
#endif

#ifdef _PLATFORM_WIN32_
   MoveWindow(_TitleHWND, x, y, width, height, kODTrue);
#endif

   width  = TEXT_WIDTH*ControlsWidthRatio;

   x = origin->x;
   y = origin->y+(TEXT_Y_POS)*_FrameHeightRatio;

#ifdef _LEFT_TO_PORT_
   WinSetWindowPos(_MoneyHWND, HWND_TOP, x, y, width, height,
      SWP_SIZE | SWP_MOVE | SWP_SHOW);
#endif

#ifdef _PLATFORM_WIN32_
   MoveWindow(_MoneyHWND, x, y, width, height, kODTrue);
#endif

   x = origin->x+BET_X_POS*ControlsWidthRatio;

#ifdef _LEFT_TO_PORT_
   WinSetWindowPos(_BetHWND, HWND_TOP, x, y, width, height,
      SWP_SIZE | SWP_MOVE | SWP_SHOW);
#endif

#ifdef _PLATFORM_WIN32_
   MoveWindow(_BetHWND, x, y, width, height, kODTrue);
#endif


/* Start of PushButton resizing code */

   width  = BUTTON_WIDTH*ControlsWidthRatio;
   height = BUTTON_HEIGHT*_FrameHeightRatio;

   x = origin->x+BUTTON1_X_POS*ControlsWidthRatio;
   y = origin->y+(BUTTON_Y_POS)*_FrameHeightRatio;

#ifdef _LEFT_TO_PORT_
   WinSetWindowPos(_Button1HWND, HWND_TOP, x, y, width, height,
      SWP_SIZE | SWP_MOVE | (_AllowDiscards ? 0 : SWP_SHOW));
#endif

#ifdef _PLATFORM_WIN32_
   MoveWindow(_Button1HWND, x, y, width, height, kODTrue);
#endif

   x = origin->x+BUTTON2_X_POS*ControlsWidthRatio;

#ifdef _LEFT_TO_PORT_
   WinSetWindowPos(_Button2HWND, HWND_TOP, x, y, width, height,
      SWP_SIZE | SWP_MOVE | (_AllowDiscards ? 0 : SWP_SHOW));
#endif

#ifdef _PLATFORM_WIN32_
   MoveWindow(_Button2HWND, x, y, width, height, kODTrue);
#endif

   x = origin->x+BUTTON3_X_POS*ControlsWidthRatio;

#ifdef _LEFT_TO_PORT_
   WinSetWindowPos(_Button3HWND, HWND_TOP, x, y, width, height,
      SWP_SIZE | SWP_MOVE | (_AllowDiscards ? 0 : SWP_SHOW));
#endif

#ifdef _PLATFORM_WIN32_
   MoveWindow(_Button3HWND, x, y, width, height, kODTrue);
#endif

   x = origin->x+DISCARD_X_POS*ControlsWidthRatio;
   y = origin->y+(DISCARD_Y_POS)*_FrameHeightRatio;

   width  = DISCARD_WIDTH*ControlsWidthRatio;
   height = DISCARD_HEIGHT*_FrameHeightRatio;

#ifdef _LEFT_TO_PORT_
   WinSetWindowPos(_DiscardHWND, HWND_TOP, x, y, width, height,
      SWP_SIZE | SWP_MOVE | (_AllowDiscards ? SWP_SHOW : 0));
#endif

#ifdef _PLATFORM_WIN32_
   MoveWindow(_DiscardHWND, x, y, width, height, kODTrue);
#endif


#ifdef _LEFT_TO_PORT_
/* Start of Icon resizing code */

   y = origin->y+ICON_Y_POS*_FrameHeightRatio;

   x = origin->x+HEARTICON_X_POS*ControlsWidthRatio;

   WinSetWindowPos(_HeartIconHWND, HWND_TOP, x, y, 0, 0, SWP_MOVE | SWP_SHOW);

   x = origin->x+SPADEICON_X_POS*ControlsWidthRatio;

   WinSetWindowPos(_SpadeIconHWND, HWND_TOP, x, y, 0, 0, SWP_MOVE | SWP_SHOW);

   x = origin->x+DIAMONDICON_X_POS*ControlsWidthRatio;

   WinSetWindowPos(_DiamondIconHWND, HWND_TOP, x, y, 0, 0, SWP_MOVE | SWP_SHOW);

   x = origin->x+CLUBICON_X_POS*ControlsWidthRatio;

   WinSetWindowPos(_ClubIconHWND, HWND_TOP, x, y, 0, 0, SWP_MOVE | SWP_SHOW);
#endif

#ifdef _LEFT_TO_PORT_
   // Writing out the Linked data
   width  = (TEXT_WIDTH - 30)*ControlsWidthRatio;
   height = TEXT_HEIGHT*_FrameHeightRatio;

   x = origin->x;
   y = origin->y;

   // If Linking is in action
   if(_Link_2)
     {
      x = origin->x+LINK_X_POS*ControlsWidthRatio;

      WinSetWindowPos(_MoneyLinkHWND, HWND_TOP, x, y, width, height,
         SWP_SIZE | SWP_MOVE | SWP_SHOW);
     }
   else
     {
      x = origin->x+LINK_X_POS*ControlsWidthRatio;

      WinSetWindowPos(_MoneyLinkHWND, HWND_TOP, x, y, width, height,
         SWP_SIZE | SWP_MOVE);
     }
#endif
}


SOM_Scope char*  SOMLINK CardGameDetermineCardBitmapFileName(CardGame *somSelf,
                                                              Environment *ev,
                                                             short index)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameDetermineCardBitmapFileName");

    char *filename = (char *) malloc(256*sizeof(char));

/* Look for CARDBITMAPDIR environment variable for path to                   */
/* card bitmaps - if no such environment variable, default to the "Cards"    */
/* directory in the current directory (note: if running from a template      */
/* dragged to the Desktop, the current directory is the root directory of    */
/* the boot drive).  Note that if you get a bunch of beeps and then get "No  */
/* bitmap selected" where each card should be, then it wasn't able to locate */
/* the location of the card bitmaps.  It is recommended that you add a line  */
/* to your config.sys specifying the location (and then reboot), so that the */
/* cards will be found regardless of where you invoked "docshell.exe" from   */
/* (or from a template).  This especially helps when using the debugger.     */
    char *CardDirectory = getenv("CARDBITMAPDIR");
    if (CardDirectory!=NULL) {
       strcpy(filename, CardDirectory);
       strcat(filename, "\\");
       strcat(filename, kCardBitmapsPath);
    } else {
       CardDirectory = getenv("ODSRC");
       if (CardDirectory!=NULL) {
          strcpy(filename, CardDirectory);
          strcat(filename, "\\");
          strcat(filename, kCardGameSrcPath);
          strcat(filename, kCardBitmapsPath);
       } else {
         strcpy(filename, kCardBitmapsPath);
       }
    } /* endif */

    switch (index) {
    case 0:
       strcat(filename, "Blank.BMP");
       break;
    case 1:
       strcat(filename, "Ace-H.BMP");
       break;
    case 2:
       strcat(filename, "Two-H.BMP");
       break;
    case 3:
       strcat(filename, "Three-H.BMP");
       break;
    case 4:
       strcat(filename, "Four-H.BMP");
       break;
    case 5:
       strcat(filename, "Five-H.BMP");
       break;
    case 6:
       strcat(filename, "Six-H.BMP");
       break;
    case 7:
       strcat(filename, "Seven-H.BMP");
       break;
    case 8:
       strcat(filename, "Eight-H.BMP");
       break;
    case 9:
       strcat(filename, "Nine-H.BMP");
       break;
    case 10:
       strcat(filename, "Ten-H.BMP");
       break;
    case 11:
       strcat(filename, "Jack-H.BMP");
       break;
    case 12:
       strcat(filename, "Queen-H.BMP");
       break;
    case 13:
       strcat(filename, "King-H.BMP");
       break;
    case 14:
       strcat(filename, "Ace-D.BMP");
       break;
    case 15:
       strcat(filename, "Two-D.BMP");
       break;
    case 16:
       strcat(filename, "Three-D.BMP");
       break;
    case 17:
       strcat(filename, "Four-D.BMP");
       break;
    case 18:
       strcat(filename, "Five-D.BMP");
       break;
    case 19:
       strcat(filename, "Six-D.BMP");
       break;
    case 20:
       strcat(filename, "Seven-D.BMP");
       break;
    case 21:
       strcat(filename, "Eight-D.BMP");
       break;
    case 22:
       strcat(filename, "Nine-D.BMP");
       break;
    case 23:
       strcat(filename, "Ten-D.BMP");
       break;
    case 24:
       strcat(filename, "Jack-D.BMP");
       break;
    case 25:
       strcat(filename, "Queen-D.BMP");
       break;
    case 26:
       strcat(filename, "King-D.BMP");
       break;
    case 27:
       strcat(filename, "Ace-S.BMP");
       break;
    case 28:
       strcat(filename, "Two-S.BMP");
       break;
    case 29:
       strcat(filename, "Three-S.BMP");
       break;
    case 30:
       strcat(filename, "Four-S.BMP");
       break;
    case 31:
       strcat(filename, "Five-S.BMP");
       break;
    case 32:
       strcat(filename, "Six-S.BMP");
       break;
    case 33:
       strcat(filename, "Seven-S.BMP");
       break;
    case 34:
       strcat(filename, "Eight-S.BMP");
       break;
    case 35:
       strcat(filename, "Nine-S.BMP");
       break;
    case 36:
       strcat(filename, "Ten-S.BMP");
       break;
    case 37:
       strcat(filename, "Jack-S.BMP");
       break;
    case 38:
       strcat(filename, "Queen-S.BMP");
       break;
    case 39:
       strcat(filename, "King-S.BMP");
       break;
    case 40:
       strcat(filename, "Ace-C.BMP");
       break;
    case 41:
       strcat(filename, "Two-C.BMP");
       break;
    case 42:
       strcat(filename, "Three-C.BMP");
       break;
    case 43:
       strcat(filename, "Four-C.BMP");
       break;
    case 44:
       strcat(filename, "Five-C.BMP");
       break;
    case 45:
       strcat(filename, "Six-C.BMP");
       break;
    case 46:
       strcat(filename, "Seven-C.BMP");
       break;
    case 47:
       strcat(filename, "Eight-C.BMP");
       break;
    case 48:
       strcat(filename, "Nine-C.BMP");
       break;
    case 49:
       strcat(filename, "Ten-C.BMP");
       break;
    case 50:
       strcat(filename, "Jack-C.BMP");
       break;
    case 51:
       strcat(filename, "Queen-C.BMP");
       break;
    case 52:
       strcat(filename, "King-C.BMP");
       break;
    default:
       strcat(filename, "CardBack.BMP");
      break;
    } /* endswitch */

    return(filename);
}


SOM_Scope void  SOMLINK CardGameSetCardBitmap(CardGame *somSelf,
                                               Environment *ev,
                                              short card, short index,
                                              ODBoolean player)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameSetCardBitmap");

    char *filename = _DetermineCardBitmapFileName(ev, card);

    ODFacet *BMPPartFacet = player==DEALER ? _DealerCardFacet[index]
                                           : _PlayerCardFacet[index];

#ifdef _PLATFORM_WIN32_
    HWND hwnd = BMPPartFacet->GetFacetHWND(ev);

    SendMessage(hwnd, SET_DATA, (WPARAM) NEW_BITMAP, (LPARAM) filename);
#endif

#ifdef _LEFT_TO_PORT_
    /* New code for OSA enablement */
    ODPart *BMPPartWrapper = player==DEALER ? _DealerBMPPartWrapper[index]
                                            : _PlayerBMPPartWrapper[index];

    _SendSetDataEvent (ev, BMPPartWrapper, filename);
    /* End new code for OSA enablement */
#endif

    ODCanvas *BMPPartCanvas = BMPPartFacet->GetCanvas(ev);

    BMPPartFacet->Invalidate(ev, kODNULL, BMPPartCanvas);
}


SOM_Scope void  SOMLINK CardGameSetIconHandles(CardGame *somSelf,
                                                 Environment *ev)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameSetIconHandles");

#ifdef _LEFT_TO_PORT_
    HPOINTER IconHandle;

    IconHandle = WinLoadPointer(HWND_DESKTOP, _MyResources, HEARTICON);
    WinSetWindowBits(_HeartIconHWND, QWL_STYLE, SS_ICON, SS_ICON);
    WinSendMsg(_HeartIconHWND, SM_SETHANDLE, (MPARAM) IconHandle, (MPARAM) 0);

    IconHandle = WinLoadPointer(HWND_DESKTOP, _MyResources, SPADEICON);
    WinSetWindowBits(_SpadeIconHWND, QWL_STYLE, SS_ICON, SS_ICON);
    WinSendMsg(_SpadeIconHWND, SM_SETHANDLE, (MPARAM) IconHandle, (MPARAM) 0);

    IconHandle = WinLoadPointer(HWND_DESKTOP, _MyResources, DIAMONDICON);
    WinSetWindowBits(_DiamondIconHWND, QWL_STYLE, SS_ICON, SS_ICON);
    WinSendMsg(_DiamondIconHWND, SM_SETHANDLE, (MPARAM) IconHandle, (MPARAM) 0);

    IconHandle = WinLoadPointer(HWND_DESKTOP, _MyResources, CLUBICON);
    WinSendMsg(_ClubIconHWND, SM_SETHANDLE, (MPARAM) IconHandle, (MPARAM) 0);
    WinSetWindowBits(_ClubIconHWND, QWL_STYLE, SS_ICON, SS_ICON);
#endif
}


SOM_Scope void  SOMLINK CardGameSetTextFields(CardGame *somSelf,
                                                Environment *ev)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameSetTextFields");

    char MoneyString[16];
    sprintf(MoneyString, "Money: %d", _Money);

#ifdef _LEFT_TO_PORT_
    WinSetWindowText(_MoneyHWND, MoneyString);
#endif

#ifdef _PLATFORM_WIN32_
    SetWindowText(_MoneyHWND, MoneyString);
#endif


#ifdef _LEFT_TO_PORT_
// if(_Link_1 && _Link_2)
   if(_Link_2) //     jru had above for some reason
     {
      char MoneyLinkString[16];
      sprintf(MoneyLinkString, "Link: %d", _Money_Link);
      WinSetWindowText(_MoneyLinkHWND, MoneyLinkString);
      _WriteLinkData(ev, kODNULL);
     }
#endif


    char PotString[10];
    sprintf(PotString, "Pot: %d", _Pot);

#ifdef _LEFT_TO_PORT_
    WinSetWindowText(_PotHWND, PotString);
#endif

#ifdef _PLATFORM_WIN32_
    SetWindowText(_PotHWND, PotString);
#endif

    char BetString[9];
    sprintf(BetString, "Bet: %d", _Bet);

#ifdef _LEFT_TO_PORT_
    WinSetWindowText(_BetHWND, BetString);
#endif

#ifdef _PLATFORM_WIN32_
    SetWindowText(_BetHWND, BetString);
#endif
}


SOM_Scope void  SOMLINK CardGameSetTextColors(CardGame *somSelf,
                                                Environment *ev)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameSetTextColors");

#ifdef _LEFT_TO_PORT_
   RGBColor ForegroundColor = CLR_BLUE;

   WinSetPresParam(_FrameHWND, PP_FOREGROUNDCOLORINDEX,
      (ULONG) sizeof(RGBColor), (PVOID) &ForegroundColor);

   RGBColor BackgroundColor = CLR_DARKGRAY;

   WinSetPresParam(_TitleHWND, PP_BACKGROUNDCOLORINDEX,
      (ULONG) sizeof(RGBColor), (PVOID) &BackgroundColor);

   WinSetPresParam(_TitleHWND, PP_FOREGROUNDCOLORINDEX,
      (ULONG) sizeof(RGBColor), (PVOID) &ForegroundColor);

   ForegroundColor = CLR_BLACK;

   WinSetPresParam(_RectangleHWND, PP_FOREGROUNDCOLORINDEX,
      (ULONG) sizeof(RGBColor), (PVOID) &ForegroundColor);

   BackgroundColor = CLR_BLACK;
   ForegroundColor = CLR_GREEN;

   WinSetPresParam(_MoneyHWND, PP_BACKGROUNDCOLORINDEX,
      (ULONG) sizeof(RGBColor), (PVOID) &BackgroundColor);

   WinSetPresParam(_MoneyHWND, PP_FOREGROUNDCOLORINDEX,
      (ULONG) sizeof(RGBColor), (PVOID) &ForegroundColor);

#ifdef _LEFT_TO_PORT_
   // Used if Linking is in process
   if(_Link_2)
     {
      ForegroundColor = CLR_YELLOW;

      WinSetPresParam(_MoneyLinkHWND, PP_BACKGROUNDCOLORINDEX,
         (ULONG) sizeof(RGBColor), (PVOID) &BackgroundColor);

      WinSetPresParam(_MoneyLinkHWND, PP_FOREGROUNDCOLORINDEX,
         (ULONG) sizeof(RGBColor), (PVOID) &ForegroundColor);
     }
#endif

   ForegroundColor = CLR_BLUE;

   WinSetPresParam(_PotHWND, PP_BACKGROUNDCOLORINDEX,
      (ULONG) sizeof(RGBColor), (PVOID) &BackgroundColor);

   WinSetPresParam(_PotHWND, PP_FOREGROUNDCOLORINDEX,
      (ULONG) sizeof(RGBColor), (PVOID) &ForegroundColor);

   ForegroundColor = CLR_RED;

   WinSetPresParam(_BetHWND, PP_BACKGROUNDCOLORINDEX,
      (ULONG) sizeof(RGBColor), (PVOID) &BackgroundColor);

   WinSetPresParam(_BetHWND, PP_FOREGROUNDCOLORINDEX,
      (ULONG) sizeof(RGBColor), (PVOID) &ForegroundColor);
#endif
}


SOM_Scope ODBoolean  SOMLINK CardGameHandlePushButton(CardGame *somSelf,
                                                        Environment *ev,
                                                       ODFacet* facet,
                                                       short button)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameHandlePushButton");

   ODBoolean ReturnValue;

   PartInfoRec *info = (PartInfoRec *) facet->GetFrame(ev)->GetPartInfo(ev);

   HWND hwnd = facet->GetFacetHWND(ev);
   short DealerDiscards;
   char DealerDiscardMsg[25];

   switch (button) {
   case BUTTON1_ID:
      if (_CurrentGame==BLACKJACK) {
         ReturnValue = _Hit(ev);
      } else {
         ReturnValue = _Raise(ev, facet);
      } /* endif */
      break;
   case BUTTON2_ID:
      if (_CurrentGame==BLACKJACK) {
         ReturnValue = _Stand(ev);
      } else {
         ReturnValue = _Call(ev, facet);
      } /* endif */
      break;
   case BUTTON3_ID:
      if (_CurrentGame==BLACKJACK) {
         ReturnValue = _DoubleDown(ev);
      } else {
         ReturnValue = _Fold(ev);
      } /* endif */
      break;
   case DISCARD_ID:
      _StartOfRound = kODTrue;
      _AllowDiscards = kODFalse;
      _BeforeDiscards = kODFalse;
      DealerDiscards = _DetermineDealerDiscards(ev);
      sprintf(DealerDiscardMsg, "Dealer discards %d cards.", DealerDiscards);
      _MessageBox(ev, hwnd, DiscardString, DealerDiscardMsg);
      _ReplaceDiscards(ev);
      _ReDrawButtons(ev, facet, kODFalse);
      ReturnValue = kODTrue;
      break;
   default:
      ReturnValue = kODFalse;
      DosBeep(500,500);
      break;
   } /* endswitch */

   if (_BeforeDiscards && !ReturnValue && !_PlayerFolded) {
      _AllowDiscards = kODTrue;
      _ReDrawButtons(ev, facet, kODTrue);
      _MessageBox(ev, hwnd, DiscardString, DiscardDetails);
   } /* endif */

   if ((_CurrentGame!=BLACKJACK) && !ReturnValue && !_BeforeDiscards) {
      int MaxCards = _CurrentGame==STUD_7_POKER ? 7 : 5;
      if ((_PlayerCardCount<MaxCards) && !_DealerFolded && !_PlayerFolded) {
         _StartOfRound = kODTrue;

         _DealerCardCount++;
         if (_DealerCardCount<7) {
            _SetCardBitmap(ev, _DealerCard[_DealerCardCount], _DealerCardCount,
               DEALER);
         } else {
            _SetCardBitmap(ev, DISCARD, 7, DEALER);
         } /* endif */

         _PlayerCardCount++;
         _SetCardBitmap(ev, _PlayerCard[_PlayerCardCount], _PlayerCardCount,
            PLAYER);
      } else {
         _ShowDealerCards = kODTrue;
      } /* endif */
   } else {
      if (button!=DISCARD_ID) {
         _StartOfRound = kODFalse;
      } /* endif */
   } /* endif */

   if (_ShowDealerCards) {
      _GameOver(ev, facet);
   } /* endif */

   return(ReturnValue);
}


SOM_Scope short  SOMLINK CardGameGetNewBet(CardGame *somSelf,
                                            Environment *ev,
                                           ODFacet* facet)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameGetNewBet");

#ifdef _LEFT_TO_PORT_
   short NewBet = WinDlgBox(HWND_DESKTOP, facet->GetFacetHWND(ev),
      BetEntryDlgProc, _MyResources, DollarDlgValue, 0);
#endif

#ifdef _PLATFORM_WIN32_
   short NewBet = DialogBox(_MyResources, MAKEINTRESOURCE(DollarDlgValue),
      facet->GetFacetHWND(ev), (DLGPROC) BetEntryDlgProc);
#endif

    return(NewBet);
}


SOM_Scope ODBoolean  SOMLINK CardGamePlaceBet(CardGame *somSelf,
                                               Environment *ev,
                                              ODFacet* facet)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGamePlaceBet");

   ODBoolean ReturnValue = kODFalse;

   short NewBet = _GetNewBet(ev, facet);

   if (NewBet>0) {
      if (_CurrentGame==BLACKJACK) {
         _NextBet = NewBet;
      } else {
         _Ante = NewBet;
      } /* endif */
      ReturnValue = kODTrue;
   } /* endif */

   return(ReturnValue);
}


SOM_Scope ODBoolean  SOMLINK CardGameHit(CardGame *somSelf,
                                           Environment *ev)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameHit");

   ODBoolean ReturnValue = kODTrue;

   _PlayerCardCount++;
   short CurrentCard = _PlayerCard[_PlayerCardCount];

   _SetCardBitmap(ev, CurrentCard, _PlayerCardCount, PLAYER);

   _PlayerSum += _DetermineCardValue(ev, CurrentCard, PLAYER);

   if ((_PlayerSum>=21) || (_PlayerHasAce && (_PlayerSum==11)) ||
       (_PlayerCardCount==5)) {
      _Stand(ev);
   } /* endif */

   return(ReturnValue);
}


SOM_Scope ODBoolean  SOMLINK CardGameStand(CardGame *somSelf,
                                             Environment *ev)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameStand");

   ODBoolean ReturnValue = kODTrue;

   _ShowDealerCards = kODTrue;

   return(ReturnValue);
}


SOM_Scope ODBoolean  SOMLINK CardGameDoubleDown(CardGame *somSelf,
                                                  Environment *ev)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameDoubleDown");

   ODBoolean ReturnValue = kODTrue;

#ifdef _LEFT_TO_PORT_
   _PushToUndoStack(ev, _Money, kCardGameDouble);
#endif

   _Money -= _Bet;
   _Bet *= 2;

   ReturnValue = _Hit(ev);

   if (ReturnValue) {
      ReturnValue = _Stand(ev);
   } /* endif */

   return(ReturnValue);
}


SOM_Scope ODBoolean  SOMLINK CardGameRaise(CardGame *somSelf,
                                            Environment *ev,
                                           ODFacet* facet)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameRaise");

    ODBoolean ReturnValue = kODFalse;

    short RaiseAmount = _GetNewBet(ev, facet);

    _Bet += RaiseAmount;
    _Pot += _Bet;

#ifdef _LEFT_TO_PORT_
    _PushToUndoStack(ev, _Money, kCardGameBet);
#endif

    _Money -= _Bet;
    _Bet = RaiseAmount;

    short DealerBet = _DetermineDealerBet(ev);

    char Message[20];
    if (_DealerFolded) {
       strcpy(Message, DealerFoldMsg);
    } else {
       if (DealerBet>0) {
          _Bet += DealerBet;
          sprintf(Message, "%s%d", DealerRaises, DealerBet);
          ReturnValue = kODTrue;
       } else {
          strcpy(Message, DealerCalls);
       } /* endif */
    } /* endif */

    _Pot += _Bet;
    _SetTextFields(ev);

    _MessageBox(ev, facet->GetFacetHWND(ev), DealerPlay, Message);

    _Bet = DealerBet;
    _SetTextFields(ev);

    return(ReturnValue);
}


SOM_Scope ODBoolean  SOMLINK CardGameCall(CardGame *somSelf,
                                           Environment *ev, ODFacet* facet)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameCall");

    ODBoolean ReturnValue = kODFalse;

    _Pot += _Bet;

#ifdef _LEFT_TO_PORT_
    _PushToUndoStack(ev, _Money, kCardGameBet);
#endif

    _Money -= _Bet;
    _Bet = 0;

    short DealerBet = 0;
    if (_StartOfRound) {
       DealerBet = _DetermineDealerBet(ev);
       char Message[20];
       if (DealerBet>0) {
          _Bet += DealerBet;
          _Pot += _Bet;
          sprintf(Message, "%s%d", DealerRaises, DealerBet);
          ReturnValue = kODTrue;
       } else {
          strcpy(Message, DealerCalls);
       } /* endif */
       _SetTextFields(ev);
       _MessageBox(ev, facet->GetFacetHWND(ev), DealerPlay, Message);
    } /* endif */

    _Bet = DealerBet;
    _SetTextFields(ev);

    return(ReturnValue);
}


SOM_Scope ODBoolean  SOMLINK CardGameFold(CardGame *somSelf,
                                           Environment *ev)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameFold");

    ODBoolean ReturnValue = kODFalse;

    _PlayerFolded = kODTrue;

    if (_CurrentGame==DRAW_POKER) {
       _DealerCardCount = 5;
    } /* endif */

    return(ReturnValue);
}


SOM_Scope short  SOMLINK CardGameRandomNumber(CardGame *somSelf,
                                                Environment *ev)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameRandomNumber");

    short ReturnValue;

    double fraction = double ((double) rand() / (double) RAND_MAX);

    ReturnValue = (short) (rand()%52+1);

    return(ReturnValue);
}


SOM_Scope short  SOMLINK CardGameDetermineCardSuit(CardGame *somSelf,
                                                    Environment *ev,
                                                   short index)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameDetermineCardSuit");

    short suit = (short) ((index - 1) / 13) + 1;

    return(suit);
}


SOM_Scope short  SOMLINK CardGameDetermineCardNumber(CardGame *somSelf,
                                                      Environment *ev,
                                                     short index)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameDetermineCardNumber");

    short CardValue;
    if (index==1) { /* -1 % 13 != 12 ??? */
       CardValue = 14;
    } else {
       CardValue = (index - 2) % 13 + 2;
    } /* endif */

    return(CardValue);
}


SOM_Scope short  SOMLINK CardGameDetermineCardValue(CardGame *somSelf,
                                                      Environment *ev,
                                                     short index,
                                                     short who)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameDetermineCardValue");

    short CardValue = _DetermineCardNumber(ev, index);

    if (CardValue==14) {
       CardValue = 1;
       if (who==DEALER) {
          _DealerHasAce = kODTrue;
       } else {
          _PlayerHasAce = kODTrue;
       } /* endif */
    } else {
       if (CardValue>10) {
          CardValue=10;
       } /* endif */
    } /* endif */

    return(CardValue);
}


SOM_Scope short  SOMLINK CardGameDetermineValueOfHand(CardGame *somSelf,
                                                       Environment *ev,
                                                      ODBoolean player,
                                                      short count)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameDetermineValueOfHand");

    short ReturnValue = HIGH_CARD;
    short Cards[6];    //  0 position not used
    short Number[15];  //  0, 1 positions not used
    short Suit[5];     //  0 position not used
    short HighCard = 0;
    short NextHighestCard = 0;
    int MaxCards = _CurrentGame==STUD_7_POKER ? 7 : 5;

    for (int index=2; index<=14; index++) { /* initialize Number array */
       Number[index] = 0;
    } /* endfor */

    for (index=1; index<=4; index++) { /* initialize Suit array */
       Suit[index] = 0;
    } /* endfor */

    for (index=1; index<=count; index++) { /* initialize Cards array */
       Cards[index] = player ? _PlayerCard[index] : _DealerCard[index];
    } /* endfor */

    for (index=count+1; index<=MaxCards; index++) {
       Cards[index] = DISCARD;
    } /* endfor */

    for (index=1; index<=MaxCards; index++) { /* Fill in Number array */
       short CurrentCard = _DetermineCardNumber(ev, Cards[index]);
       if (CurrentCard>HighCard) {
          NextHighestCard = HighCard;
          HighCard = CurrentCard;
       } else {
          if (CurrentCard>NextHighestCard) {
             NextHighestCard = CurrentCard;
          } /* endif */
       } /* endif */
       if (CurrentCard!=DISCARD) {
          Number[CurrentCard]++;
       } /* endif */
    } /* endfor */

/* Determine pair, three-of-a-kind, full house, four-of-a-kind, or straight */
    short Consecutives = 0;
    short LastCard = 0;
    for (index=2; index<=14; index++) {
       if (Number[index]>0) {
          if (LastCard!=index-1) {
             Consecutives = 0;
          } /* endif */
          Consecutives++;
          if (Consecutives==5) {
             ReturnValue = STRAIGHT;
          } /* endif */
          LastCard = index;
       } /* endif */

       if (Number[index]==2) {
          if (ReturnValue==PAIR) {
             ReturnValue = TWO_PAIR;
             HighCard = index;
          } else {
             if (ReturnValue==THREE_OF_KIND) {
                ReturnValue = FULL_HOUSE;
             } else {
                ReturnValue = PAIR;
                HighCard = index;
             } /* endif */
          } /* endif */
          HighCard = index;
       } /* endif */

       if (Number[index]==3) {
          if (ReturnValue==PAIR) {
             ReturnValue = FULL_HOUSE;
          } else {
             ReturnValue = THREE_OF_KIND;
          } /* endif */
          HighCard = index;
       } /* endif */

       if (Number[index]==4) {
          ReturnValue = FOUR_OF_KIND;
          HighCard = index;
       } /* endif */
    } /* endfor */

    for (index=1; index<=MaxCards; index++) { /* Fill in Suit array */
       if (Cards[index]!=DISCARD) {
          Suit[_DetermineCardSuit(ev, Cards[index])]++;
       } /* endif */
    } /* endfor */

/* Determine flush, straight flush, or royal flush */
    for (index=1; index<=4; index++) {
       if (Suit[index]==5) {
          if (ReturnValue==STRAIGHT) {
             if (HighCard==ACE) {
                ReturnValue = ROYAL_FLUSH;
                HighCard = 0;
             } else {
                ReturnValue = STRAIGHT_FLUSH;
             } /* endif */
          } else {
             HighCard = 0;
             ReturnValue = FLUSH;
          } /* endif */
       } /* endif */
    } /* endfor */

    return(ReturnValue+HighCard*ACE+NextHighestCard);
}


SOM_Scope short  SOMLINK CardGameDetermineDealerDiscards(CardGame *somSelf,
                                                          Environment *ev)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameDetermineDealerDiscards");

    short ReturnValue;

    short CurrentCard = 0;
    short HighCard = 0;
    short NextHighestCard = 0;

    short HandValue = _DetermineValueOfHand(ev, DEALER, _PlayerCardCount)/100;

    short Number[15];
    for (int index=2; index<=14; index++) { /* initialize Number array */
       Number[index] = 0;
    } /* endfor */

    short Suit[5];
    for (index=1; index<=4; index++) { /* initialize Suit array */
       Suit[index] = 0;
    } /* endfor */

    for (index=1; index<=5; index++) { /* Fill in Number array */
       CurrentCard = _DetermineCardNumber(ev, _DealerCard[index]);
       if (CurrentCard>HighCard) {
          NextHighestCard = HighCard;
          HighCard = CurrentCard;
       } else {
          if (CurrentCard>NextHighestCard) {
             NextHighestCard = CurrentCard;
          } /* endif */
       } /* endif */
       Number[CurrentCard]++;
    } /* endfor */

    ODBoolean AlmostFlush = kODFalse;
    ODBoolean AlmostStraight = kODFalse;
    short Consecutives = 0;
    short LastCard = 0;

    for (index=2; index<=14; index++) { /* Try for straight? */
       if (Number[index]>0) {
          if (LastCard!=index-1) {
             Consecutives = 0;
          } /* endif */
          Consecutives++;
          if ((Consecutives==4) && (HandValue<PAIR)) {
             AlmostStraight = kODTrue;
             for (int index2=1; index2<=5; index2++) {
                CurrentCard = _DetermineCardNumber(ev, _DealerCard[index2]);
                if ((CurrentCard<index-3) || (CurrentCard>index)) {
                   _DealerCard[index2] = DISCARD;
                } /* endif */
             } /* endfor */
          } /* endif */
          LastCard = index;
       } /* endif */
    } /* endfor */

    for (index=1; index<=5; index++) { /* Fill in Suit array */
       CurrentCard = _DealerCard[index];
       if (CurrentCard!=DISCARD) {
          Suit[_DetermineCardSuit(ev, CurrentCard)]++;
       } /* endif */
    } /* endfor */

    for (index=1; index<=5; index++) { /* Try for flush? */
       if ((Suit[index]==4) && (HandValue<PAIR)) {
          AlmostFlush = kODTrue;
          for (int index2=1; index2<=5; index2++) {
             if (_DetermineCardSuit(ev, _DealerCard[index2])!=index) {
                _DealerCard[index2] = DISCARD;
             } /* endif */
          } /* endfor */
       } /* endif */
    } /* endfor */

    switch (HandValue-HandValue%1000) {
    case HIGH_CARD:
       if (!AlmostFlush && !AlmostStraight) {
          for (index=1; index<=5; index++) {
             if ((_DealerCard[index]!=HighCard) &&
                (_DealerCard[index]!=NextHighestCard)) {
                   _DealerCard[index] = DISCARD;
             } /* endif */
          } /* endfor */
          ReturnValue = 3;
       } else {
          ReturnValue = 1;
       } /* endif */
       break;
    case PAIR:
       for (index=1; index<=5; index++) {
          CurrentCard = _DetermineCardNumber(ev, _DealerCard[index]);
          if (Number[CurrentCard]<2) {
             _DealerCard[index] = DISCARD;
          } /* endif */
       } /* endfor */
       ReturnValue = 3;
       break;
    case TWO_PAIR:
       for (index=1; index<=5; index++) {
          CurrentCard = _DetermineCardNumber(ev, _DealerCard[index]);
          if (Number[CurrentCard]<2) {
             _DealerCard[index] = DISCARD;
          } /* endif */
       } /* endfor */
       ReturnValue = 1;
       break;
    case THREE_OF_KIND:
       for (index=1; index<=5; index++) {
          CurrentCard = _DetermineCardNumber(ev, _DealerCard[index]);
          if (Number[CurrentCard]<3) {
             _DealerCard[index] = DISCARD;
          } /* endif */
       } /* endfor */
       ReturnValue = 2;
       break;
    default:
       ReturnValue = 0;
      break;
    } /* endswitch */

    for (index=1; index<=5; index++) {
       if (_DealerCard[index]==DISCARD) {
          ODBoolean Continue;
          short NewCard;
          do {
             Continue = kODFalse;
             NewCard = _RandomNumber(ev);
             for (int index2=1; index2<=5; index2++) {
                if (NewCard==_DealerCard[index2]) {
                   Continue = kODTrue;
                } /* endif */
                if (NewCard==_PlayerCard[index2]) {
                   Continue = kODTrue;
                } /* endif */
                if (NewCard==_Discards[index2]) {
                   Continue = kODTrue;
                } /* endif */
             } /* endfor */
          } while ( Continue ); /* enddo */
          _Discards[index+5] = _DealerCard[index];
          _DealerCard[index] = NewCard;
       } /* endif */
    } /* endfor */
    return(ReturnValue);
}


SOM_Scope short  SOMLINK CardGameDetermineDealerBet(CardGame *somSelf,
                                                     Environment *ev)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameDetermineDealerBet");

    short ReturnValue = 0;

    short DealerHand = _DetermineValueOfHand(ev, DEALER, _PlayerCardCount);
    short PlayerHand = 0;
    short DealerBet = DealerHand/100;

    if (_CurrentGame==STUD_5_POKER) { /* Account for visible Player cards */
       short PlayerCard1 = _PlayerCard[1];
       _PlayerCard[1] = DISCARD;
       PlayerHand = _DetermineValueOfHand(ev, PLAYER, _PlayerCardCount);
       _PlayerCard[1] = PlayerCard1;
    } /* endif */

    if (_CurrentGame==STUD_7_POKER) { /* Account for visible Player cards */
       short PlayerCard1 = _PlayerCard[1];
       short PlayerCard2 = _PlayerCard[2];
       short PlayerCard7 = _PlayerCard[7];
       _PlayerCard[1] = DISCARD;
       _PlayerCard[2] = DISCARD;
       _PlayerCard[7] = DISCARD;
       PlayerHand = _DetermineValueOfHand(ev, PLAYER, _PlayerCardCount);
       _PlayerCard[1] = PlayerCard1;
       _PlayerCard[2] = PlayerCard2;
       _PlayerCard[7] = PlayerCard7;
    } /* endif */

    short BluffAmount = 0;

    if (_RandomNumber(ev)<=BLUFF_THRESHOLD) {
       int count = 50;
       while (BluffAmount==0) {
          if (_RandomNumber(ev)>count) {
             BluffAmount = count;
          } else {
             count -= 10;
             if (count==0) {
                count = 50;
             } /* endif */
          } /* endif */
       } /* endwhile */
    } /* endif */

    if ((DealerBet<10) && (_Bet-(DealerBet+BluffAmount)>=50)) {
       _DealerFolded = kODTrue;
    } /* endif */

    if ((DealerHand>PlayerHand) && (DealerBet>_Bet+2)) {
       ReturnValue = DealerBet-_Bet+BluffAmount;
    } /* endif */

    return(ReturnValue);
}


SOM_Scope void  SOMLINK CardGameReplaceDiscards(CardGame *somSelf,
                                                 Environment *ev)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameReplaceDiscards");

    for (int index=1; index<=5; index++) {
       if (_PlayerCard[index]==DISCARD) {
          ODBoolean Continue;
          short NewCard;
          do {
             Continue = kODFalse;
             NewCard = _RandomNumber(ev);
             for (int index2=1; index2<=5; index2++) {
                if (NewCard==_DealerCard[index2]) {
                   Continue = kODTrue;
                } /* endif */
                if (NewCard==_PlayerCard[index2]) {
                   Continue = kODTrue;
                } /* endif */
                if (NewCard==_Discards[index2]) {
                   Continue = kODTrue;
                } /* endif */
                if (NewCard==_Discards[index2+5]) {
                   Continue = kODTrue;
                } /* endif */
             } /* endfor */
          } while ( Continue ); /* enddo */
          _PlayerCard[index] = NewCard;
          _SetCardBitmap(ev, NewCard, index, PLAYER);
       } /* endif */
    } /* endfor */
}


SOM_Scope void  SOMLINK CardGameReDrawButtons(CardGame *somSelf,
                                               Environment *ev,
                                              ODFacet* facet,
                                              ODBoolean discard)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameReDrawButtons");

#ifdef _LEFT_TO_PORT_
    WinShowWindow(_Button1HWND, !discard);
    WinShowWindow(_Button2HWND, !discard);
    WinShowWindow(_Button3HWND, !discard);
    WinShowWindow(_DiscardHWND, discard);
#endif

#ifdef _PLATFORM_WIN32_
    ShowWindow(_Button1HWND, !discard);
    ShowWindow(_Button2HWND, !discard);
    ShowWindow(_Button3HWND, !discard);
    ShowWindow(_DiscardHWND, discard);
#endif

    if (!discard) {
       ODCanvas *canvas = facet->GetCanvas(ev);

#if 0
       RECTL newRect = {DISCARD_X_POS*_FrameWidthRatio,
                        DISCARD_Y_POS*_FrameHeightRatio,
                        DISCARD_WIDTH*_FrameWidthRatio,
                        DISCARD_HEIGHT*_FrameHeightRatio};
       ODRect buttonRect(newRect);

       ODShape *buttonShape = facet->CreateShape(ev);
       buttonShape->SetRectangle(ev, &buttonRect);

       facet->Invalidate(ev, buttonShape, canvas);
#else
/*      Above code didn't work for some reason - need to revisit */
       facet->Invalidate(ev, kODNULL, canvas);
#endif
    } /* endif */
}


SOM_Scope void  SOMLINK CardGameGameOver(CardGame *somSelf,
                                           Environment *ev, ODFacet* facet)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameGameOver");

   int index;
   ODPlatformWindow hwnd = facet->GetFacetHWND(ev);

   switch (_CurrentGame) {
   case BLACKJACK:
   case STUD_5_POKER:
      _SetCardBitmap(ev, _DealerCard[1], 1, DEALER);
      break;
   case STUD_7_POKER:
      _SetCardBitmap(ev, _DealerCard[1], 1, DEALER);
      _SetCardBitmap(ev, _DealerCard[2], 2, DEALER);
      if (_DealerCardCount==7) {
         _SetCardBitmap(ev, _DealerCard[7], 7, DEALER);
      } /* endif */
      break;
   case DRAW_POKER:
      for (index=1; index<=5; index++) {
         _SetCardBitmap(ev, _DealerCard[index], index, DEALER);
      } /* endfor */
      break;
   } /* endswitch */

   if (_CurrentGame==BLACKJACK) {
      while ((!_DealerHasAce && (_DealerSum<=16)) || (_DealerHasAce &&
       ((_DealerSum<=6) || ((_DealerSum>11) && (_DealerSum<=16))))) {
         _DealerCardCount++;
         short CurrentCard = _DealerCard[_DealerCardCount];
         _SetCardBitmap(ev, CurrentCard, _DealerCardCount, DEALER);
         _DealerSum += _DetermineCardValue(ev, CurrentCard, DEALER);
      } /* endwhile */

//    facet->Invalidate(ev, kODNULL);

      if (_DealerHasAce && (_DealerSum<=11)) {
         _DealerSum += 10;
      } /* endif */

      if (_PlayerHasAce && (_PlayerSum<=11)) {
         _PlayerSum += 10;
      } /* endif */

      if ((_PlayerSum<=21) && (_PlayerSum==_DealerSum)) {
         _SetTextFields(ev);
         _MessageBox(ev, hwnd, GameOverString, BJackTieMsg);
      } else {
         if ((_PlayerSum<=21) && ((_DealerSum>21) || (_PlayerCardCount==5)
          || (_PlayerSum>_DealerSum))) {
#ifdef _LEFT_TO_PORT_
            _PushToUndoStack(ev, _Money, kCardGameBet);
#endif
            _Money += _Bet;
            _SetTextFields(ev);
            _MessageBox(ev, hwnd, GameOverString, VictoryMessage);
         } else {
#ifdef _LEFT_TO_PORT_
            _PushToUndoStack(ev, _Money, kCardGameBet);
#endif
            _Money -= _Bet;
            _SetTextFields(ev);
            _MessageBox(ev, hwnd, GameOverString, DefeatMessage);
            if (_Money<=0) {
               _Bankrupt(ev, hwnd);
            } /* endif */
         } /* endif */
      } /* endif */
      _Bet = _NextBet;
   } else {
//    facet->Invalidate(ev, kODNULL);

      short DealerHand = _DealerFolded ? 0 :
         _DetermineValueOfHand(ev, DEALER, _CurrentGame==STUD_7_POKER ? 7 : 5);
      short PlayerHand = _PlayerFolded ? 0 :
         _DetermineValueOfHand(ev, PLAYER, _CurrentGame==STUD_7_POKER ? 7 : 5);

      if (PlayerHand>DealerHand) {
#ifdef _LEFT_TO_PORT_
         _PushToUndoStack(ev, _Money, kCardGameBet);
#endif
         _Money += _Pot;
         _Bet = 0;
         _SetTextFields(ev);
         _MessageBox(ev, hwnd, GameOverString, VictoryMessage);
      } else {
         if (PlayerHand==DealerHand) {
#ifdef _LEFT_TO_PORT_
            _PushToUndoStack(ev, _Money, kCardGameBet);
#endif
            _Money += _Pot/2;
            _Bet = 0;
            _SetTextFields(ev);
            _MessageBox(ev, hwnd, GameOverString, PokerTieMsg);
         } else {
            _Bet = 0;
            _SetTextFields(ev);
            _MessageBox(ev, hwnd, GameOverString, DefeatMessage);
            if (_Money<=0) {
               _Bankrupt(ev, hwnd);
            } /* endif */
         } /* endif */
      } /* endif */
      _Pot = 0;
   } /* endif */

// facet->Invalidate(ev, kODNULL);
   _NewGame(ev, facet);
}


SOM_Scope void  SOMLINK CardGameNewGame(CardGame *somSelf,
                                          Environment *ev, ODFacet* facet)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameNewGame");

   short LastGame = _CurrentGame;
   _ChangeGame(ev, facet);

   ODCanvas *canvas = facet->GetCanvas(ev);  //   See comment below

   if ((_CurrentGame==STUD_7_POKER) && (_CurrentGame!=LastGame)) {
         _CreateEmbeddedBMPParts(ev, facet, CARDS_6_TO_7);
         _SizeFrame(ev, facet);
   } /* endif */
   if ((_CurrentGame!=STUD_7_POKER) && (LastGame==STUD_7_POKER)) {
         _RemoveEmbeddedBMPParts(ev, facet, CARDS_6_TO_7);
         _SizeFrame(ev, facet);
   } /* endif */

   _StartOfRound = kODTrue;
   _ShowDealerCards = kODFalse;

   ODBoolean Repeat;
   short NewCard;

   int MaxCards = _CurrentGame==STUD_7_POKER ? 7 : 5;

   for (int index = 1; index<=MaxCards; index++) {
      do { /* Disallow same card twice */
         Repeat = kODFalse;
         NewCard = _RandomNumber(ev);
         for (int index2 = index-1; index2>0; index2--) {
            if (NewCard == _DealerCard[index2]) {
               Repeat = kODTrue;
            } /* endif */
         } /* endfor */
      } while ( Repeat ); /* enddo */
      if (index<=_DealerCardCount) {
         _DealerSum += _DetermineCardValue(ev, NewCard, DEALER);
      } /* endif */
      _DealerCard[index] = NewCard;
   } /* endfor */

   for (index = 1; index<=MaxCards; index++) {
      do { /* Disallow same card twice */
         Repeat = kODFalse;
         NewCard = _RandomNumber(ev);
         for (int index2 = index-1; index2>0; index2--) {
            if (NewCard == _PlayerCard[index2]) {
               Repeat = kODTrue;
            } /* endif */
         } /* endfor */
         for (index2=MaxCards; index2>0; index2--) {
            if (NewCard == _DealerCard[index2]) {
               Repeat = kODTrue;
            } /* endif */
         } /* endfor */
      } while ( Repeat ); /* enddo */
      if (index<=_PlayerCardCount) {
         _PlayerSum += _DetermineCardValue(ev, NewCard, PLAYER);
      } /* endif */
      _PlayerCard[index] = NewCard;
   } /* endfor */

   _SetNewHands(ev);

   if (_PlayerHasAce && (_PlayerSum==11) && (_CurrentGame==BLACKJACK)) {
      _GeometryChanged(ev, facet, kODFalse, kODTrue);
      _ShowDealerCards = kODTrue;
      _GameOver(ev, facet);
   } /* endif */
}


SOM_Scope void  SOMLINK CardGameChangeGame(CardGame *somSelf,
                                            Environment *ev,
                                           ODFacet* facet)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameChangeGame");

    short index;
    _CurrentGame = _NextGame;

    switch (_CurrentGame) {
    case DRAW_POKER:
       _DealerCardCount = 0;
       _PlayerCardCount = 5;

#ifdef _LEFT_TO_PORT_
       _PushToUndoStack(ev, _Money, kCardGameAnte);
#endif

       _Money -= _Ante;
       _Pot = 2*_Ante;
       _Bet = 0;
       _BeforeDiscards = kODTrue;
       _AllowDiscards = kODFalse;
       _DiscardCount = 0;
       for (index=1; index<=5; index++) {
          _Discards[index] = DISCARD;
       } /* endfor */
       _DealerFolded = kODFalse;
       _PlayerFolded = kODFalse;

#ifdef _LEFT_TO_PORT_
       WinSetWindowText(_TitleHWND, PokerTitle);
       WinShowWindow(_FrameHWND, kODTrue);
       WinSetWindowText(_Button1HWND, RaiseString);
       WinSetWindowText(_Button2HWND, CallString);
       WinSetWindowText(_Button3HWND, DropString);
       WinShowWindow(_RectangleHWND, kODFalse);
       WinShowWindow(_PotHWND, kODTrue);
#endif

#ifdef _PLATFORM_WIN32_
       SetWindowText(_TitleHWND, PokerTitle);
       ShowWindow(_FrameHWND, kODTrue);
       SetWindowText(_Button1HWND, RaiseString);
       SetWindowText(_Button2HWND, CallString);
       SetWindowText(_Button3HWND, DropString);
       ShowWindow(_RectangleHWND, kODFalse);
       ShowWindow(_PotHWND, kODTrue);
#endif
       break;
    case STUD_5_POKER:
       _DealerCardCount = 2;
       _PlayerCardCount = 2;

#ifdef _LEFT_TO_PORT_
       _PushToUndoStack(ev, _Money, kCardGameAnte);
#endif

       _Money -= _Ante;
       _Pot = 2*_Ante;
       _Bet = 0;
       _DealerFolded = kODFalse;
       _PlayerFolded = kODFalse;

#ifdef _LEFT_TO_PORT_
       WinSetWindowText(_TitleHWND, PokerTitle);
       WinShowWindow(_FrameHWND, kODTrue);
       WinSetWindowText(_Button1HWND, RaiseString);
       WinSetWindowText(_Button2HWND, CallString);
       WinSetWindowText(_Button3HWND, DropString);
       WinShowWindow(_RectangleHWND, kODFalse);
       WinShowWindow(_PotHWND, kODTrue);
#endif

#ifdef _PLATFORM_WIN32_
       SetWindowText(_TitleHWND, PokerTitle);
       ShowWindow(_FrameHWND, kODTrue);
       SetWindowText(_Button1HWND, RaiseString);
       SetWindowText(_Button2HWND, CallString);
       SetWindowText(_Button3HWND, DropString);
       ShowWindow(_RectangleHWND, kODFalse);
       ShowWindow(_PotHWND, kODTrue);
#endif
       break;
    case STUD_7_POKER:
       _DealerCardCount = 3;
       _PlayerCardCount = 3;

#ifdef _LEFT_TO_PORT_
       _PushToUndoStack(ev, _Money, kCardGameAnte);
#endif

       _Money -= _Ante;
       _Pot = 2*_Ante;
       _Bet = 0;
       _DealerFolded = kODFalse;
       _PlayerFolded = kODFalse;

#ifdef _LEFT_TO_PORT_
       WinSetWindowText(_TitleHWND, PokerTitle);
       WinShowWindow(_FrameHWND, kODTrue);
       WinSetWindowText(_Button1HWND, RaiseString);
       WinSetWindowText(_Button2HWND, CallString);
       WinSetWindowText(_Button3HWND, DropString);
       WinShowWindow(_RectangleHWND, kODFalse);
       WinShowWindow(_PotHWND, kODTrue);
#endif

#ifdef _PLATFORM_WIN32_
       SetWindowText(_TitleHWND, PokerTitle);
       ShowWindow(_FrameHWND, kODTrue);
       SetWindowText(_Button1HWND, RaiseString);
       SetWindowText(_Button2HWND, CallString);
       SetWindowText(_Button3HWND, DropString);
       ShowWindow(_RectangleHWND, kODFalse);
       ShowWindow(_PotHWND, kODTrue);
#endif
       break;
    default:
       _DealerCardCount = 2;
       _PlayerCardCount = 2;
       _Bet = _NextBet;
       _DealerHasAce = kODFalse;
       _PlayerHasAce = kODFalse;
       _DealerSum = 0;
       _PlayerSum = 0;

#ifdef _LEFT_TO_PORT_
       WinSetWindowText(_TitleHWND, BlackJackTitle);
       WinShowWindow(_FrameHWND, kODTrue);
       WinSetWindowText(_Button1HWND, HitString);
       WinSetWindowText(_Button2HWND, StandString);
       WinSetWindowText(_Button3HWND, DoubleString);
       WinShowWindow(_RectangleHWND, kODTrue);
       WinShowWindow(_PotHWND, kODFalse);
#endif

#ifdef _PLATFORM_WIN32_
       SetWindowText(_TitleHWND, BlackJackTitle);
       ShowWindow(_FrameHWND, kODTrue);
       SetWindowText(_Button1HWND, HitString);
       SetWindowText(_Button2HWND, StandString);
       SetWindowText(_Button3HWND, DoubleString);
       ShowWindow(_RectangleHWND, kODTrue);
       ShowWindow(_PotHWND, kODFalse);
#endif
      break;
    } /* endswitch */

    _SetTextFields(ev);

//    _SetMenuItemStates(ev, facet->GetWindow(ev)->GetMenuBar(ev));
//    _SetMenuItemStates(ev, _MySession->GetWindowState(ev)->CopyBaseMenuBar(ev));
}


SOM_Scope void  SOMLINK CardGameSetNewHands(CardGame *somSelf,
                                             Environment *ev)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameSetNewHands");

    int index;
    int MaxCards = 5;

    switch (_CurrentGame) {
    case BLACKJACK:
    case STUD_5_POKER:
       _SetCardBitmap(ev, DISCARD, 1, DEALER);
       _SetCardBitmap(ev, _DealerCard[2], 2, DEALER);
       for (index=3; index<=5; index++) {
          _SetCardBitmap(ev, BLANK, index, DEALER); /* Set Blanks */
       } /* endfor */
       break;
    case STUD_7_POKER:
       MaxCards = 7;
       _SetCardBitmap(ev, DISCARD, 1, DEALER);
       _SetCardBitmap(ev, DISCARD, 2, DEALER);
       _SetCardBitmap(ev, _DealerCard[3], 3, DEALER);
       for (index=4; index<=7; index++) {
          _SetCardBitmap(ev, BLANK, index, DEALER); /* Set Blanks */
       } /* endfor */
       break;
    case DRAW_POKER:
       for (index=1; index<=5; index++) {
          _SetCardBitmap(ev, DISCARD, index, DEALER); /* Set CardBacks */
       } /* endfor */
       break;
    } /* endswitch */

    for (index=1; index<=_PlayerCardCount; index++) {
       _SetCardBitmap(ev, _PlayerCard[index], index, PLAYER);
    } /* endfor */

    for (index=_PlayerCardCount+1; index<=MaxCards; index++) {
       _SetCardBitmap(ev, BLANK, index, PLAYER); /* Set Blanks */
    } /* endfor */
}


SOM_Scope void  SOMLINK CardGameRemoveEmbeddedBMPParts(CardGame *somSelf,
                                                            Environment *ev,
                                                           ODFacet* facet,
                                                           ODBoolean FirstFive)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameRemoveEmbeddedBMPParts");

    int index;
    int FirstCard, LastCard;

    if (FirstFive) {
       FirstCard = 1;
       LastCard = 5;
    } else {
       FirstCard = 6;
       LastCard = 7;
    } /* endif */

    ODFacet *PictPartFacet;
    ODFrame *PictPartFrame;

    for (index=FirstCard; index<=LastCard; index++) {
       PictPartFacet = _DealerCardFacet[index];
       PictPartFrame = PictPartFacet->GetFrame(ev);
       facet->RemoveFacet(ev, PictPartFacet);
       PictPartFrame->Remove(ev);
    } /* endfor */

    for (index=FirstCard; index<=LastCard; index++) {
       PictPartFacet = _PlayerCardFacet[index];
       PictPartFrame = PictPartFacet->GetFrame(ev);
       facet->RemoveFacet(ev, PictPartFacet);
       PictPartFrame->Remove(ev);
    } /* endfor */
}


SOM_Scope void  SOMLINK CardGameRemoveEmbeddedControls(CardGame *somSelf,
                                                        Environment *ev)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameRemoveEmbeddedControls");

#ifdef _LEFT_TO_PORT_
    WinDestroyWindow(_TitleHWND);
    WinDestroyWindow(_FrameHWND);
    WinDestroyWindow(_RectangleHWND);
    WinDestroyWindow(_PotHWND);
    WinDestroyWindow(_MoneyHWND);
    WinDestroyWindow(_MoneyLinkHWND);
    WinDestroyWindow(_BetHWND);
    WinDestroyWindow(_Button1HWND);
    WinDestroyWindow(_Button2HWND);
    WinDestroyWindow(_Button3HWND);
    WinDestroyWindow(_DiscardHWND);
    WinDestroyWindow(_HeartIconHWND);
    WinDestroyWindow(_SpadeIconHWND);
    WinDestroyWindow(_DiamondIconHWND);
    WinDestroyWindow(_ClubIconHWND);
#endif

#ifdef _PLATFORM_WIN32_
    DestroyWindow(_TitleHWND);
    DestroyWindow(_FrameHWND);
    DestroyWindow(_RectangleHWND);
    DestroyWindow(_PotHWND);
    DestroyWindow(_MoneyHWND);
    DestroyWindow(_BetHWND);
    DestroyWindow(_Button1HWND);
    DestroyWindow(_Button2HWND);
    DestroyWindow(_Button3HWND);
    DestroyWindow(_DiscardHWND);
    DestroyWindow(_HeartIconHWND);
    DestroyWindow(_SpadeIconHWND);
    DestroyWindow(_DiamondIconHWND);
    DestroyWindow(_ClubIconHWND);
#endif
}


SOM_Scope void  SOMLINK CardGameBankrupt(CardGame *somSelf,  Environment *ev,
                                         ODPlatformWindow hwnd)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameBankrupt");

    _MessageBox(ev, hwnd, BankruptTitle, BankruptMsg);

#ifdef _LEFT_TO_PORT_
    _PushToUndoStack(ev, _Money, kCardGameBankrupt);
#endif

    _Money = 500;
    _SetTextFields(ev);
}


#ifdef _LEFT_TO_PORT_
SOM_Scope void  SOMLINK CardGameSendSetDataEvent(CardGame *somSelf,
                                                  Environment *ev,
                                                 ODPart* thePart,
                                                 char* filename)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameSendSetDataEvent");

    ODError       rc = noErr;
    ODOSAEvent    *theOSAEvent;
    ODObjectSpec  *theObjSpec;
    ODAddressDesc *AddrDesc;
    ODSShort      ReturnID;

    ODMessageInterface* MsgIntf = _MySession->GetMessageInterface(ev);
    /***************************************************************************/
    /* Construct an OSA Event for sending the SetData event to myself.         */
    /* - Create the address descriptor specifying kODAppShell (this doc)       */
    /* - Create the object specifier using the part wrapper passed in.         */
    /* - If necessary, use this object specifier as container for a more com-  */
    /*   plex object specifier and then stick the whole thing in the direct    */
    /*   object parameter of the event.                                        */
    /***************************************************************************/
    MsgIntf->CreatePartAddrDesc(ev, &AddrDesc, kODAppShell);

    MsgIntf->CreatePartObjSpec(ev, &theObjSpec, thePart);

    ReturnID = MsgIntf->CreateEvent(ev, kAECoreSuite, kAESetData, AddrDesc,
       kAnyTransactionID, &theOSAEvent);

    AEDesc tempOSAEvent = NULLDESC;
    AEDesc tempObjSpec = NULLDESC;
    ODDescToAEDesc((ODDesc *) theOSAEvent, &tempOSAEvent);
    ODDescToAEDesc((ODDesc *) theObjSpec, &tempObjSpec );
    AEPutParamDesc(&tempOSAEvent, keyDirectObject, &tempObjSpec);

    /***************************************************************************/
    /* Add data to the keyAEData parameter.                                    */
    /***************************************************************************/
    AEDesc theDataDesc = NULLDESC;
    AECreateDesc (typeIntlText, filename, strlen (filename) + 1, &theDataDesc);
    AEPutParamDesc(&tempOSAEvent, keyAEData, &theDataDesc);

  // Update event with tempOSAEvent
    AEDescToODDesc(&tempOSAEvent, (ODDesc *) theOSAEvent);

    /***************************************************************************/
    /* Send the event.  Expect no reply; use normal priority; use default      */
    /* timeout; no idle function; no reply filter.                             */
    /***************************************************************************/
//    AEDesc reply;
//    AEDesc reply = NULLDESC;
//    ODOSAEvent *theReply = new ODOSAEvent;
//    AEDescToODDesc(&reply, (ODDesc *) theReply);
    ODOSAEvent *theReply = new ODOSAEvent;
    theReply->InitODOSAEvent(ev);

    MsgIntf->Send(ev, _fDisplayFrame, thePart, theOSAEvent, theReply, kAEWaitReply,
       kAENormalPriority, kAEDefaultTimeout);

    /***************************************************************************/
    /* Dispose of the all descriptor records that form the OSA Event.          */
    /***************************************************************************/
    AEDisposeDesc (&theDataDesc);
    AEDisposeDesc (&tempOSAEvent);
    AEDisposeDesc (&tempObjSpec);

    return;
}


// Added for Linking - JRU
SOM_Scope void  SOMLINK CardGameInitiateLinking(CardGame *somSelf,
                                             Environment *ev,
                                            ODFacet* facet, ODEventData* event)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameInitiateLinking");

   DRAGIMAGE dimg;
   HBITMAP   hbm;

   memset(&dimg, 0, sizeof(DRAGIMAGE));

   // Initialize the DRAGIMAGE structure
   dimg.cb = sizeof(DRAGIMAGE);
   dimg.hImage = WinLoadPointer(HWND_DESKTOP,
                                _MyResources,
                                LinkPointer);

   dimg.fl = DRG_ICON;

   // Setting up the Drag and Drop Object for Linking
   ODDragAndDrop* pDrgDrp = _MySession->GetDragAndDrop(ev);
   pDrgDrp->Clear(ev);

   // Setting up the LinkSpec object
   ODLinkSpec* linkSpec =
      _GetStorageUnit(ev)->GetDraft(ev)->CreateLinkSpec(ev,
                                                        (ODPart*)somSelf,
                                                        (ODByteArray*)kODNULL);
  // Write the link spec to the Drag and Drop SU
  if(linkSpec)
  {
   // Getting the Storage Unit to be used with this Drag and Drop
   ODStorageUnit* StorageDrgDrp = pDrgDrp->GetContentStorageUnit(ev);

   // Adding the values to the Drp&Drp SU for Linking
   StorageDrgDrp->AddProperty(ev, kODPropLinkSpec);
   StorageDrgDrp->AddValue(ev, kODLinkSpec);

   linkSpec->WriteLinkSpec(ev, StorageDrgDrp);

   // Disposing of my LinkSpec
   delete linkSpec;
  } else {
   _MessageBox(ev, facet->GetFacetHWND(ev), "Linking Error!",
      "Error creating Link Spec!");
  } /* endif */

   ODFrame *frame = facet->GetFrame(ev);
   frame->SetDragging(ev, kODTrue);

   ODPart* destPart;
   ODDropResult dropResult;

   // Setting up Data Structures used by the Drag and Drop operation
   ODByteArray dragImgBA = CreateByteArrayStruct(&dimg, sizeof(DRAGIMAGE));
   ODByteArray eventBA = CreateByteArrayStruct(&event, sizeof(ODEventData*));

   // Starting the Drag and Drop Process
   dropResult = pDrgDrp->StartDrag(ev,
                                   frame,
                                   0,
                                   &dragImgBA,
                                   &destPart,
                                   &eventBA);

   DisposeByteArrayStruct(&dragImgBA);
   DisposeByteArrayStruct(&eventBA);

   frame->SetDragging(ev, kODFalse);

   // The Start of the link
   if(dropResult != kODDropFail)
     {
      _Link_1 = kODTrue;

      // Changing the Link Status of my Frame even though it is
      // meant for Embedded frames.  I'm mostly doing this to ensure
      // that the interface works.
      _fDisplayFrame->ChangeLinkStatus(ev, kODInLinkSource);
     }

}


SOM_Scope void  SOMLINK CardGamePutThatLinkDown(CardGame *somSelf,
                                                 Environment *ev,
                                                ODFacet* facet,
                                                ODStorageUnit* StorageDrgDrp,
                                                ODPasteAsResult* resultPasteAs)
{
   CardGameData *somThis = CardGameGetData(somSelf);
   CardGameMethodDebug("CardGame","CardGamePutThatLinkDown");

   FILE* LinkErr;

   ODDragAndDrop* DrgDrp = _MySession->GetDragAndDrop(ev);

   ODDraft* myDraft = _GetStorageUnit(ev)->GetDraft(ev);

/*
   // This seems to fail when I use the SU from this code
   // There may be a probelm with Prying into the SU while it's
   // being pryed into from the code that called this.  Defect?
   // Workaround: pass the SU in and use that.
   ODStorageUnit* StorageDrgDrp;
   StorageDrgDrp = DrgDrp->GetContentStorageUnit(ev);
   fprintf(LinkErr, "Get Content StorageUnit \n");
   fflush(LinkErr);
*/

   ODLinkSpec* linkSpec = myDraft->CreateLinkSpec(ev,
                                                 (ODPart*)somSelf,
                                                 (ODByteArray*)kODNULL);

   // Read the link spec from the drop
   StorageDrgDrp->Focus(ev,
                       (ODPropertyName)kODPropLinkSpec,
                       kODPosSame,
                       kODLinkSpec,
                       0,
                       kODPosUndefined);


   // Reading in the Link Spec data from the SU
   linkSpec->ReadLinkSpec(ev, StorageDrgDrp);

   //Establish the link
   ODLink* link = myDraft->AcquireLink(ev, 0, linkSpec);

   if(link != kODNULL)
     {
// Neither of these are in here, the Docs say to use the 1st version
//      _fLinkInfo.change = kODChangeUnknown; // not yet updated
//      _fLinkInfo.change = kODUnknownChange; // not yet updated
//    find out: how to do this?
// This is my solution - JRU
      _fLinkInfo.creationTime = time(kODNULL);
      _fLinkInfo.kind = resultPasteAs->selectedKind;
      _fLinkInfo.autoUpdate = resultPasteAs->autoUpdateSetting;
      // Add link and linkInfo to the content model of this part.
      _fLinkPtr = link;

      // Register for updates
      if(_fLinkInfo.autoUpdate)
        {
         link->RegisterDependent(ev,
                                 somSelf,
                                 _fLinkInfo.change);

         WinShowWindow(_MoneyLinkHWND, kODTrue);

         // Changing the Link Status of my Frame even though is is
         // meant for Embedded frames.  I'm mostly doing this to ensure
         // that the interface works.
         _fDisplayFrame->ChangeLinkStatus(ev, kODInLinkDestination);
        }
      else
      // Manually update now
        {
         _LinkUpdated(ev, link, link->GetUpdateID(ev));
         _MessageBox(ev, _fDisplayFacet->GetFacetHWND(ev),
                     "Creating Links", "Linking Manually");
        }
     }

   delete linkSpec;
}


SOM_Scope void  SOMLINK CardGameWriteLinkData(CardGame *somSelf,
                                               Environment *ev,
                                              ODFacet* facet)
{
   CardGameData *somThis = CardGameGetData(somSelf);
   CardGameMethodDebug("CardGame","CardGameWriteLinkData");

   ODULong TheTwo[2] = { 0, 0};
   ODLinkKey linkKey;
   ODLinkSource* linkSource = _fLinkSourcePtr;
   ODUpdateID updateID = _MySession->UniqueUpdateID(ev);
   ODDraft* myDraft = _GetStorageUnit(ev)->GetDraft(ev);
   ODBoolean  fLockSuccess = kODFalse;

   while(!fLockSuccess)
     {
      if(linkSource->Lock(ev, 0, &linkKey))
        {
         fLockSuccess = kODTrue;

         //Remove the current updateID from the link
         linkSource->Clear(ev, updateID, linkKey);

         ODStorageUnit* linkContentSU =
                   linkSource->GetContentStorageUnit(ev, linkKey);

         //Begin a transaction if objects are cloned into the link
         ODDraftKey draftKey = 0;

         //For each value in the link,
         //if the property/value exist,focus - else create it
         if( linkContentSU->Exists(ev, kODPropContents, kCardGameLinkData, 0) )
           {
            linkContentSU->Focus(ev,
                                 kODPropContents,
                                 0,
                                 kCardGameLinkData,
                                 1,
                                 kODPosUndefined);
           }
         else
           {
            linkContentSU->AddProperty(ev, kODPropContents);
            linkContentSU->AddValue(ev, (ODValueType) kCardGameLinkData);
           }

         //write new value
         TheTwo[0] = _Money;
         StorageUnitSetValue(linkContentSU, ev, sizeof(ODULong) * 2, &TheTwo);
         _CurrentUpdateID = updateID;

         //Inform the link that it has changed, so destination can update.
         //The updateID parameter should be the change causing the link
         //to update.
//        linkSource->ContentChanged(ev, updateID, linkKey);
         linkSource->Unlock(ev, linkKey);
        }
      else /* unsuccessful lock */
        {
         ULONG TimeInterval; /* interval in milliseconds */
         APIRET rc;
         TimeInterval = 1000; /* one second */

         rc = DosSleep(TimeInterval);

         if (rc != 0)
           {
            /* ERROR_TS_WAKEUP */
           }
     } /* end unsuccessful lock    */
   } /* end while unsuccesful lock */

}


SOM_Scope void  SOMLINK CardGamePushToUndoStack(CardGame *somSelf,
                                                 Environment *ev,
                                                ODUShort Value,
                                                ODULong Type)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGamePushToUndoStack");

    ODULong TheTwo[2];

    // Filling in the info for the Undo Stack Data
    TheTwo[0] = Value;
    TheTwo[1] = Type;

    ODIText*  undoActionName;
    ODIText*  redoActionName;
    ODUndo *myUndo = _MySession->GetUndo(ev);

    // Setting up the Undo/Redo Text strings
    switch(Type)
      {
       case kCardGameAnte:
          undoActionName = CreateIText(0, 0, "Undo Ante");
          redoActionName = CreateIText(0, 0, "Redo Ante");
          break;

       case kCardGameDouble:
          undoActionName = CreateIText(0, 0, "Undo DoubleUp");
          redoActionName = CreateIText(0, 0, "Redo DoubleUp");
          break;

       case kCardGameBet:
          undoActionName = CreateIText(0, 0, "Undo Bet");
          redoActionName = CreateIText(0, 0, "Redo Bet");
          break;

       case kCardGameBankrupt:
          undoActionName = CreateIText(0, 0, "Undo Bankrupt Help");
          redoActionName = CreateIText(0, 0, "Redo Bankrupt Help");
          break;

      }

    // Creating the ODByteArray for the ODActionData type
    ODActionData *MyData = CreateByteArray(&TheTwo, sizeof(TheTwo));
    // Shoving the data onto the Undo/Redo Stack
    myUndo->AddActionToHistory(ev, somSelf, MyData, kODSingleAction,
                                    (ODName*) undoActionName,
                                    (ODName*) redoActionName);

}
#endif


SOM_Scope void  SOMLINK CardGamesomInit(CardGame *somSelf)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGamesomInit");

    CardGame_parent_SimplePart_somInit(somSelf);

   _CurrentGame = BLACKJACK;

   _EnableHelpItems = kODFalse;

   _DealerCard[0] = DISCARD;
   _PlayerCard[0] = DISCARD;

   _DealerSum = 0;
   _PlayerSum = 0;

   _Money = 500;
   _Bet = 5;
   _NextBet = 5;
   _Ante = 2;

#ifdef _LEFT_TO_PORT_
   // Used for run-time linking indicators
   _InLink = kODFalse;
   _Link_Server = kODFalse;
   _Link_1 = kODFalse;
   _Link_2 = kODFalse;
   _Money_Link = 0;

   _ViewExtension = kODNULL;
   _MyNoteBook = kODNULL;
#endif
}


SOM_Scope ODShape*  SOMLINK CardGameRequestFrameShape(CardGame *somSelf,
                                                       Environment *ev,
                                                      ODFrame* embeddedFrame,
                                                      ODShape* frameShape)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameRequestFrameShape");

/* Ignore requests for new frame shapes from embedded Picture Parts */
    ODShape *oldShape = embeddedFrame->AcquireFrameShape(ev, kODNULL);
    frameShape->CopyFrom(ev, oldShape);
    ODReleaseObject(ev, oldShape);

    return(frameShape);
}


SOM_Scope void  SOMLINK CardGameFacetAdded(CardGame *somSelf,
                                             Environment *ev,
                                            ODFacet* facet)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameFacetAdded");

    _CreateEmbeddedBMPParts(ev, facet, CARDS_1_TO_5);
    if (_CurrentGame==STUD_7_POKER) {
       _CreateEmbeddedBMPParts(ev, facet, CARDS_6_TO_7);
    } /* endif */

    _CreateEmbeddedControls(ev, facet->GetFacetHWND(ev));

    _SetIconHandles(ev);
    _SetTextColors(ev);
    _SetTextFields(ev);

#ifdef _LEFT_TO_PORT_
   // Added for Linking to make CardGame Droppable - JRU
   facet->GetFrame(ev)->SetDroppable(ev, kODTrue);
   _fDisplayFacet = facet;
   _fDisplayFrame = facet->GetFrame(ev);

   // Simply testing the API
   _fDisplayFrame->ChangeLinkStatus(ev, kODNotInLink);
#endif

   _SizeFrame(ev, facet);
//     We really should bring back the game from storage, rather than always
//     start a new one.  Oh well, that would be a bunch more game logic to
//     return to the proper state of the game that was saved, and wouldn't
//     be any better a testcase, so we'll put that off for now.
   _NewGame(ev, facet);

#ifdef _LEFT_TO_PORT_
//                Prepare bitmaps for use when this facet's frame is shown as
//                a small or large icon (we don't support thumbnail right now;
//                that's a lot more work, since instead of being a static
//                representation, it is actually a scaled down image of our
//                current contents, which isn't really feasible with all of
//                our embedded controls).
    HPOINTER MyIcon = NULLHANDLE;
    MyIcon = WinLoadPointer(HWND_DESKTOP, _MyResources, GAMEICON);

    POINTERINFO info;
    WinQueryPointerInfo(MyIcon, &info);
    _SmallIcon = info.hbmMiniColor;
    _LargeIcon = info.hbmColor;

/*     Store bitmap dimensions for use later during Draw() */
    BITMAPINFOHEADER2 header;
    header.cbFix = sizeof(BITMAPINFOHEADER2);
    GpiQueryBitmapInfoHeader(_SmallIcon, &header);

    SIZEL dimensions = {header.cx, header.cy};
    GpiSetBitmapDimension(_SmallIcon, &dimensions);

    GpiQueryBitmapInfoHeader(_LargeIcon, &header);

    dimensions.cx = header.cx; dimensions.cy = header.cy;
    GpiSetBitmapDimension(_LargeIcon, &dimensions);
#endif
}


SOM_Scope void  SOMLINK CardGameFacetRemoved(CardGame *somSelf,
                                              Environment *ev,
                                             ODFacet* facet)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameFacetRemoved");

    if (_CurrentGame==STUD_7_POKER) {
       _RemoveEmbeddedBMPParts(ev, facet, CARDS_6_TO_7);
    } /* endif */

    _RemoveEmbeddedBMPParts(ev, facet, CARDS_1_TO_5);

    _RemoveEmbeddedControls(ev);

#ifdef _LEFT_TO_PORT_
    GpiDeleteBitmap(_SmallIcon);
    GpiDeleteBitmap(_LargeIcon);
#endif
}


SOM_Scope void  SOMLINK CardGameGeometryChanged(CardGame *somSelf,
                                                 Environment *ev,
                                                ODFacet* facet,
                                                ODBoolean clipShapeChanged,
                                                ODBoolean externalTransformChanged)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameGeometryChanged");

    ODFrame *frame = facet->GetFrame(ev);
    ODTypeToken viewType = frame->GetViewType(ev);

    if (viewType==_ViewAsFrame) {
       ODCanvas *canvas = facet->GetCanvas(ev);
       ODTransform *contentXform = facet->AcquireContentTransform(ev, canvas);

#ifdef _LEFT_TO_PORT_
/* Begin Window Clipping */
       ODShape* aggClipShape = facet->AcquireAggregateClipShape(ev, canvas);

       ODShape* clipShape = facet->CreateShape(ev);
       clipShape->CopyFrom(ev, aggClipShape);
       clipShape->Transform(ev, contentXform);
       ODReleaseObject(ev, aggClipShape);

       HWND hwnd = facet->GetFacetHWND(ev);

       WinSetClipRegion(hwnd, clipShape->GetRegion(ev));
/* End Window Clipping */
#endif

/* Determine frameRect */
       ODShape *frameShape = ODCopyAndRelease(ev, frame->AcquireFrameShape(ev, canvas));
       frameShape->Transform(ev, contentXform);

       ODRect frameODRect;
       frameShape->GetBoundingBox(ev, &frameODRect);

#ifdef _LEFT_TO_PORT_
       RECTL frameRect;
       frameODRect.AsRECTL(frameRect);
#endif

#ifdef _PLATFORM_WIN32_
       RECT frameRect;
       frameODRect.AsWinRect(frameRect);
#endif

       double width = (double) _CurrentGame==STUD_7_POKER ? DEFAULT7_WIDTH :
                      DEFAULT5_WIDTH;

#ifdef _LEFT_TO_PORT_
       _FrameWidthRatio = ((double) (frameRect.xRight-frameRect.xLeft)) / width;

       _FrameHeightRatio = ((double) (frameRect.yTop-frameRect.yBottom)) /
                           ((double) DEFAULT_HEIGHT);
#endif

#ifdef _PLATFORM_WIN32_
       _FrameWidthRatio = ((double) (frameRect.right-frameRect.left)) / width;

       _FrameHeightRatio = ((double) (frameRect.bottom-frameRect.top)) /
                           ((double) DEFAULT_HEIGHT);
#endif

       ODTransform *frameXform = facet->AcquireFrameTransform(ev, canvas);
       ODPoint* scale = new ODPoint;
       frameXform->GetScale(ev, scale);
       frameXform->Release(ev);

       _ResizeEmbeddedBMPParts(ev, facet, scale);

/* Determine facet's origin relative to DocShell's origin */
       ODPoint origin(0, 0);
       contentXform->TransformPoint(ev, &origin);
       ODReleaseObject(ev, contentXform);

       origin.x /= 0x10000; /* Conversion of 16:16 value to 32:0 value */
       origin.y /= 0x10000;

#ifdef _LEFT_TO_PORT_
       width = (double) (frameRect.xRight-frameRect.xLeft);
#endif

#ifdef _PLATFORM_WIN32_
       width = (double) (frameRect.right-frameRect.left);
#endif

       _ResizeEmbeddedControls(ev, width, &origin);
    } /* endif */
}


SOM_Scope void  SOMLINK CardGameViewTypeChanged(CardGame *somSelf,
                                                 Environment *ev,
                                                ODFrame* frame)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameViewTypeChanged");

    ODFrameFacetIterator *iter = frame->CreateFacetIterator(ev);
    ODFacet *facet = iter->First(ev); //     Single facet hack!
    delete iter;

    if (facet==kODNULL) {
       DosBeep(250,100);
       return;
    } /* endif */

    ODCanvas *canvas = facet->GetCanvas(ev);

    ODTypeToken viewType = frame->GetViewType(ev);
    if (viewType==_ViewAsFrame) {
       frame->ChangeUsedShape(ev, kODNULL, canvas);
    } else {
       HWND facetHWND = facet->GetFacetHWND(ev);

#ifdef _LEFT_TO_PORT_
       RECTL usedRECTL = {0, 0, 0, 0};

       if (viewType==_ViewAsSmallIcon) {
          usedRECTL.xRight = SMALLICONSIZE;
          usedRECTL.yTop = SMALLICONSIZE;
       } else {
          if (viewType==_ViewAsLargeIcon) {
          usedRECTL.xRight = LARGEICONSIZE;
          usedRECTL.yTop = LARGEICONSIZE;
          } else {
#endif
             _MessageBox(ev, facetHWND, "Error!",
                "Card Game doesn't support this view type");
             frame->ChangeViewType(ev, _ViewAsFrame);
             return;
#ifdef _LEFT_TO_PORT_
          } /* endif */
       } /* endif */

       for (int index=FRAME_ID; index<GAMEICON_ID; index++) {
          HWND hwnd = WinWindowFromID(facetHWND, index);
          WinShowWindow(hwnd, kODFalse);
       } /* endfor */

       ODRect usedODRect(usedRECTL);
       ODShape *usedShape = frame->CreateShape(ev);
       usedShape->SetRectangle(ev, &usedODRect);
       frame->ChangeUsedShape(ev, usedShape, canvas);
#endif
    } /* endif */
}


SOM_Scope void  SOMLINK CardGameDraw(CardGame *somSelf,  Environment *ev,
                                      ODFacet* facet, ODShape* invalidShape)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameDraw");

    ODFrame *frame = facet->GetFrame(ev);
    ODCanvas *biasCanvas = facet->GetCanvas(ev);

    ODTypeToken viewType = frame->GetViewType(ev);

    ODRect frameODRect;
//  ODShape *frameShape = frame->AcquireFrameShape(ev, biasCanvas);
    ODShape *frameShape = frame->AcquireUsedShape(ev, biasCanvas);
    frameShape->GetBoundingBox(ev, &frameODRect);
    frameShape->Release(ev);

#ifdef _LEFT_TO_PORT_
    RECTL frameRect;
    frameODRect.AsRECTL(frameRect);

    HPS hpsDraw;
    CFocus f(ev, facet, invalidShape, &hpsDraw); // Set up drawing environment

    if (viewType==_ViewAsFrame) {
       GpiSetColor(hpsDraw, CLR_DARKGRAY);
       POINTL ptl = {frameRect.xRight-1, frameRect.yTop-1};
       GpiBox(hpsDraw, DRO_FILL, &ptl, 0, 0);

       GpiSetColor(hpsDraw, CLR_BLACK);
       GpiBox(hpsDraw, DRO_OUTLINE, &ptl, 0, 0);

       if (biasCanvas->IsDynamic(ev)) {
          HWND facetHWND = facet->GetFacetHWND(ev);
          for (int index=FRAME_ID; index<GAMEICON_ID; index++) {
             HWND hwnd = WinWindowFromID(facetHWND, index);
             WinUpdateWindow(hwnd);
          } /* endfor */
       } /* endif */
    } else {
       POINTL aptl[4];
       aptl[0].x = frameRect.xLeft;
       aptl[0].y = frameRect.yBottom;
       aptl[1].x = frameRect.xRight - 1;
       aptl[1].y = frameRect.yTop - 1;
       aptl[2].x = aptl[2].y = 0;

       SIZEL dimensions;

       if (viewType==_ViewAsSmallIcon) {
          GpiQueryBitmapDimension(_SmallIcon, &dimensions);
          aptl[3].x = dimensions.cx;
          aptl[3].y = dimensions.cy;
          GpiWCBitBlt(hpsDraw, _SmallIcon, 4, aptl, ROP_SRCCOPY, BBO_IGNORE );
       } else {
          if (viewType==_ViewAsLargeIcon) {
             GpiQueryBitmapDimension(_LargeIcon, &dimensions);
             aptl[3].x = dimensions.cx;
             aptl[3].y = dimensions.cy;
             GpiWCBitBlt(hpsDraw, _LargeIcon, 4, aptl, ROP_SRCCOPY, BBO_IGNORE );
          } else {
             DosBeep(250, 50); /* Unsupported View Type */
          } /* endif */
       } /* endif */

       // here we validate all embedded facets so they don't actually get drawn!!
       ODFacetIterator* iter = facet->CreateFacetIterator(ev, kODChildrenOnly,
          kODFrontToBack);
       for (ODFacet* embFacet = iter->First(ev); iter->IsNotComplete(ev);
            embFacet = iter->Next(ev))
          embFacet->Validate(ev, kODNULL, biasCanvas);
       delete iter;
    } /* endif */
#endif

#ifdef _PLATFORM_WIN32_
    RECT frameRect;
    frameODRect.AsWinRect(frameRect);

    HDC hdcDraw;
    CFocus f(facet, invalidShape, &hdcDraw); // Set up drawing environment

    if (viewType==_ViewAsFrame) {
       // Create a solid brush
       HBRUSH hbr = CreateSolidBrush (CLR_DARKGRAY);

       // Fill the rectangle with the brush
       FillRect (hdcDraw, &frameRect, hbr);

       // Get rid of the brush
       DeleteObject (hbr);
    } else {
       Beep(250, 50); /* Unsupported View Type */
    } /* endif */
#endif
}


#ifdef _LEFT_TO_PORT_
// Added for Linking - JRU
SOM_Scope ODDragResult  SOMLINK CardGameDragEnter(CardGame *somSelf,
                                                  Environment *ev,
                                                  ODDragItemIterator* dragInfo,
                                                  ODFacet* facet,
                                                  ODPoint* where)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameDragEnter");

         ODStorageUnit* StorageDrgDrp = dragInfo->First(ev);

         // Checking to ensure the Dragged object is a CardGame link
    // Change This for CardGame
         if(StorageDrgDrp->Exists(ev, kODPropLinkSpec, kODLinkSpec, kODNULL))
                 return MRFROM2SHORT (DOR_DROP, DO_UNKNOWN);
         else
                 return MRFROM2SHORT (DOR_NEVERDROP, DO_UNKNOWN);


//    return (CardGame_parent_SimplePart_DragEnter(somSelf, ev,
//                                                 dragInfo, facet,
//                                                 where));
}


// Added for Linking - JRU
SOM_Scope ODDragResult  SOMLINK CardGameDragWithin(CardGame *somSelf,
                                                   Environment *ev,
                                                   ODDragItemIterator* dragInfo,
                                                   ODFacet* facet,
                                                   ODPoint* where)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameDragWithin");

        ODStorageUnit* StorageDrgDrp = dragInfo->First(ev);

        // Checking to ensure the Dragged object is a CardGame Link
        if(StorageDrgDrp->Exists(ev, kODPropLinkSpec, kODLinkSpec, kODNULL))
                 return MRFROM2SHORT (DOR_DROP, DO_UNKNOWN);
        else
                 return MRFROM2SHORT (DOR_NEVERDROP, DO_UNKNOWN);

//    return (CardGame_parent_SimplePart_DragWithin(somSelf, ev,
//                                                  dragInfo, facet,
//                                                  where));
}


// Added for Linking - JRU
SOM_Scope void  SOMLINK CardGameDragLeave(CardGame *somSelf,
                                           Environment *ev, ODFacet* facet,
                                          ODPoint* where)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameDragLeave");

//    CardGame_parent_SimplePart_DragLeave(somSelf, ev, facet,
//                                        where);
}


// Added for Linking - JRU
SOM_Scope ODDropResult  SOMLINK CardGameDrop(CardGame *somSelf,
                                              Environment *ev,
                                             ODDragItemIterator* dropInfo,
                                             ODFacet* facet,
                                             ODPoint* where)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameDrop");

        ODULong NumBytes;
        ODDraft *draft = _GetStorageUnit(ev)->GetDraft(ev);
        ODStorageUnit* StorageDrgDrp = draft->CreateStorageUnit(ev);
        StorageDrgDrp = dropInfo->First(ev);
        char TheString[60];
        ODCanvas *myCanvas = facet->GetCanvas(ev);

        // Checking to ensure the Dropped object is a Link
        if(StorageDrgDrp->Exists(ev, kODPropLinkSpec, kODLinkSpec, kODNULL))
          {
      ODBoolean canPasteLink = kODTrue;
      ODBoolean canEmbed = kODFalse;
//      Testing the ShowPasteAsDialogbox
//      ODBoolean canPasteLink = kODFalse;
//      ODBoolean canEmbed = kODTrue;
      ODTypeToken viewType = _MySession->Tokenize(ev, kCardGameDataValue);
      ODPasteAsResult resultPasteAs ;
      ODBoolean result   = kODDropFail;

      ODDragAndDrop* pDrgDrp = _MySession->GetDragAndDrop(ev);

      // This Link has already been established, don't acknowledge the drop
      if(_Link_2)
         // Maybe even put up a message box here?
         return kODDropFail;

      result = pDrgDrp->ShowPasteAsDialog(ev, canPasteLink,
                                         canEmbed,
                                         facet,
                                         viewType,
                                         StorageDrgDrp,
                                         &resultPasteAs);

      if(result == kODFalse)  //if the user chooses the "CANCEL" button
         return kODDropFail;

      if (resultPasteAs.pasteLinkSetting == kODTrue) //if the user chooses the "PASTELINK" button
        {
          //Create a Link (Destination)
          _PutThatLinkDown(ev, facet, StorageDrgDrp, &resultPasteAs);

          _Link_2 = kODTrue;
          // If this has already been dragged to and is now dropped on,
          // it will become the Dealer Server for the linked CardGames
          if(_Link_1)
             _Link_Server = kODTrue;

          return kODDropCopy;
        }
      else if (resultPasteAs.pasteLinkSetting == kODFalse)//if the user chooses the "PASTECONTENT" button
        {
         //Do regular paste
         return kODDropMove;
        }

      }

   return kODDropFail;

}


SOM_Scope ODLinkSource*  SOMLINK CardGameCreateLink(CardGame *somSelf,
                                                     Environment *ev,
                                                    ODByteArray* data)
{
   CardGameData *somThis = CardGameGetData(somSelf);
   CardGameMethodDebug("CardGame","CardGameCreateLink");

   //Call a part-specific method to get the link if it already exists
   ODLinkSource* linkSource = _fLinkSourcePtr;

   if (linkSource == kODNULL)
   {
     // Call this part's draft to create both the link source object
     // used by this part, and the link object returned from this
     // method and used by destinations of the link
     linkSource =
         _GetStorageUnit(ev)->GetDraft(ev)->CreateLinkSource(ev, somSelf);

      //Add the link to the content model of this part.
     _fLinkSourcePtr = linkSource;

     _WriteLinkData(ev, _fDisplayFacet);

     if(_fDisplayFrame != kODNULL)
     {
       _fDisplayFrame->Invalidate( ev, kODNULL, kODNULL );
     }

   }

   return linkSource;
}


SOM_Scope void  SOMLINK CardGameLinkUpdated(CardGame *somSelf,
                                             Environment *ev,
                                            ODLink* updatedLink,
                                            ODUpdateID change)
{
   CardGameData *somThis = CardGameGetData(somSelf);
   CardGameMethodDebug("CardGame","CardGameLinkUpdated");

   ODULong TheTwo[2] = {0, 0};
   ODLinkKey linkKey;
   ODLink* link = updatedLink;
//  ODLinkInfo linkInfo = _fLinkInfo;
   ODDraft* myDraft = _GetStorageUnit(ev)->GetDraft(ev);
   ODBoolean  fLockSuccess = kODFalse;

   // Since we are using circular links we need to check against updating
   // for a change that wasn't ours
   if(change == _CurrentUpdateID)
      return;
   else
      _CurrentUpdateID = change;

   while(!fLockSuccess)
     {
      if(link->Lock(ev, 0, &linkKey))
       {
        fLockSuccess = kODTrue;

        //Remove the current content at the destination of the link
        ODStorageUnit* linkContentSU = link->GetContentStorageUnit(ev, linkKey);

        //Begin a transaction if objects are cloned from the link
        ODDraftKey draftKey = 0;

        //Focus to the value type used at this destination
        //Insert content from the link into the destination
        //This is part specific.Do not internalize cloned objects
        //until EndClone has been called
        if( linkContentSU->Exists(ev, kODPropContents, kCardGameLinkData, 0) )
          {
           linkContentSU->Focus(ev,
                                kODPropContents,
                                kODPosUndefined,
                                kCardGameLinkData,
                                0,
                                kODPosUndefined);

           StorageUnitGetValue(linkContentSU, ev, sizeof(ODULong) * 2, (ODValue) &TheTwo);
           // Use the New Value
           _Money_Link = TheTwo[0];

           // Updating the Linked Data so that it is independant of the
           // Normal game update
           char MoneyLinkString[16];
           sprintf(MoneyLinkString, "Link: %d", _Money_Link);
           WinSetWindowText(_MoneyLinkHWND, MoneyLinkString);
          }

        //Update the link info for this destination
        _fLinkInfo.change = link->GetUpdateID(ev);
        _fLinkInfo.changeTime = link->GetChangeTime(ev);


        link->Unlock(ev, linkKey);
       } /* end lock */
      else /* unsuccessful lock */
       {
        ULONG TimeInterval; /* interval in milliseconds */
        APIRET rc;
        TimeInterval = 1000; /* one second */

        rc = DosSleep(TimeInterval);

        if (rc != 0)
          {
           /* ERROR_TS_WAKEUP */
          }
       } /* end unsuccessful lock    */
     } /* end while unsuccessful lock */

  //Propagate changes to source links maintained by this part
  //(...)
  if(_fLinkSourcePtr != kODNULL)
  {
     _WriteLinkData(ev, _fDisplayFacet);
  } /* endif */

/*
   //now display the new info from the updated link
   char TheText[256];
   sprintf(TheText, "Link Data: %d  Change ID: %d", TheTwo[0], _fLinkInfo.change);

   char msg2[50];
   if(_Link_2 && _Link_Server)
      strcpy(msg2, "First Linked CardGame");
   else
      strcpy(msg2, "Second Linked CardGame");

   WinMessageBox(HWND_DESKTOP, HWND_DESKTOP,
                 TheText, msg2, 5, MB_OK);
*/
}


SOM_Scope void  SOMLINK CardGameLinkStatusChanged(CardGame *somSelf,
                                                   Environment *ev,
                                                  ODFrame* frame)
{
   CardGameData *somThis = CardGameGetData(somSelf);
   CardGameMethodDebug("CardGame","CardGameLinkStatusChanged");

   char TitleText[] = "Link Status Message";

   switch(frame->GetLinkStatus(ev))
     {
      case kODInLinkDestination:
         if(_Link_2 && (!_Link_1))
            _MessageBox(ev, HWND_DESKTOP, TitleText, "Link Destination");
         else
         {
            char msg[256];
            sprintf(msg, "Link Status Error 1. Link_1 = %d, Link_2 = %d",
               _Link_1, _Link_2);
            _MessageBox(ev, HWND_DESKTOP, TitleText, msg);
//          _MessageBox(ev, HWND_DESKTOP, TitleText, "Link Status Error 1");
         }
         break;

      case kODInLinkSource:
         if(_Link_1 && (!_Link_2))
            _MessageBox(ev, HWND_DESKTOP, TitleText, "Link Source");
         else
            _MessageBox(ev, HWND_DESKTOP, TitleText, "Link Status Error 2");
         break;

      case kODNotInLink:
         if( (!_Link_2) && (!_Link_1) )
            _MessageBox(ev, HWND_DESKTOP, TitleText, "Not in a Link Yet");
         else
            _MessageBox(ev, HWND_DESKTOP, TitleText, "Link Status Error 3");
         break;

      default:
         _MessageBox(ev, HWND_DESKTOP, TitleText, "Who called This?");
     }

}


SOM_Scope void  SOMLINK CardGameUndoAction(CardGame *somSelf,
                                            Environment *ev,
                                           ODActionData* actionState)
{
   CardGameData *somThis = CardGameGetData(somSelf);
   CardGameMethodDebug("CardGame","CardGameUndoAction");

   ODULong TheTwo[2];
   ODUndo *TheUndoDude = _MySession->GetUndo(ev);

   memcpy(&TheTwo, actionState->_buffer, sizeof(ODULong) * 2);

   _Money = TheTwo[0];

   char MoneyString[16];
   sprintf(MoneyString, "Money: %d", _Money);
   WinSetWindowText(_MoneyHWND, MoneyString);
}


SOM_Scope void  SOMLINK CardGameRedoAction(CardGame *somSelf,
                                            Environment *ev,
                                           ODActionData* actionState)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameRedoAction");

   ODULong TheTwo[2];
   ODUndo *TheUndoDude = _MySession->GetUndo(ev);

   memcpy(&TheTwo, actionState->_buffer, sizeof(ODULong) * 2);

   _Money = TheTwo[0];

   char MoneyString[16];
   sprintf(MoneyString, "Money: %d", _Money);
   WinSetWindowText(_MoneyHWND, MoneyString);
}
#endif


SOM_Scope ODBoolean  SOMLINK CardGameHandleEvent(CardGame *somSelf,
                                                  Environment *ev,
                                                 ODEventData* event,
                                                 ODFrame* frame,
                                                 ODFacet* facet,
                                                 ODEventInfo* eventInfo)
{
   CardGameData *somThis = CardGameGetData(somSelf);
   CardGameMethodDebug("CardGame","CardGameHandleEvent");

   ODBoolean handled = kODFalse;

#ifdef _LEFT_TO_PORT_
// Rearranged for Linking - JRU
   switch(event->msg)
     {
      case WM_COMMAND:
       switch (SHORT1FROMMP(event->mp2))
         {
          case CMDSRC_MENU:
          case CMDSRC_ACCELERATOR:
             handled = _HandleMenuEvent(ev, frame, event);

             if (handled)
               {
//           frame->Invalidate(ev, kODNULL);
                _SetTextFields(ev);
               } /* endif */
             break;

          case CMDSRC_PUSHBUTTON:
             _Activate(ev, facet);

             handled = _HandlePushButton(ev, facet, SHORT1FROMMP(event->mp1));

             if (handled && (_CurrentGame==BLACKJACK)) {
//              frame->Invalidate(ev, kODNULL);
                _SetTextFields(ev);
             } /* endif */
             break;

          default:
             handled = kODFalse;
             break;
         } /* endswitch */
         break;

      // Added for Linking - JRU
      case WM_BEGINDRAG:
         // Check for if the Link from this already exists
         if(!_Link_1)
            // Maybe put a Message Box here? - JRU
            _InitiateLinking(ev, facet, event);
         handled = kODTrue;
         break;

      case WM_CONTEXTMENU:
      case WM_BUTTON1DBLCLK:
      case WM_BUTTON2DBLCLK:
      case WM_BUTTON3DBLCLK:
      case WM_CHAR:
         handled = kODTrue; /*      We don't actually do anything here;     */
                            /*      we just don't want Simple Part's        */
                            /*      behavior, nor do we want to let the     */
                            /*      message get sent to our containing part */
         break;

      default:
         handled = kODFalse
     } /* endswitch */
#endif

#ifdef _PLATFORM_WIN32_
    switch (event->message)
    {
       case WM_COMMAND:
       {
          int button = event->wParam;
          if ((button>=MIN_WINDOW_ID) && (button<=MAX_WINDOW_ID)) {
             _Activate(ev, facet);

             handled = _HandlePushButton(ev, facet, button);

             if (handled && (_CurrentGame==BLACKJACK)) {
//              frame->Invalidate(ev, kODNULL);
                _SetTextFields(ev);
             } /* endif */
          } /* endif */
       }
          break;

      case WM_LBUTTONDOWN:
      {
         ODPoint *where = new ODPoint;
         where->x = LOWORD(event->lParam)*0x10000;
         where->y = HIWORD(event->lParam)*0x10000;
         handled = _HandleMouseDown(ev, facet, where, event);
      }
          break;

      default:
         handled = kODFalse;
     } /* endswitch */
#endif

    if (!handled) {
         handled = CardGame_parent_SimplePart_HandleEvent(somSelf, ev,
                                                          event,
                                                          frame,
                                                          facet,
                                                          eventInfo);
    } /* endif */

    return(handled);
}


SOM_Scope ODBoolean  SOMLINK CardGameHandleMouseDown(CardGame *somSelf,
                                                      Environment *ev,
                                                     ODFacet* facet,
                                                     ODPoint* where,
                                                     ODEventData* event)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameHandleMouseDown");

    ODBoolean handled = kODFalse;
    if (_AllowDiscards) {
       handled = kODTrue;
       ODCanvas *canvas = facet->GetCanvas(ev);
       ODTransform *xform = facet->AcquireWindowContentTransform(ev, canvas);
       xform->InvertPoint(ev, where);

#ifdef _LEFT_TO_PORT_
       POINTL mouse = where->AsPOINTL();
#endif

#ifdef _PLATFORM_WIN32_
       Point mouse = where->AsWinPoint();
#endif

       ODPoint scale;
       xform->GetScale(ev, &scale); /* Convert coordinate systems */
       xform->Release(ev);
       mouse.x = (mouse.x * scale.x) / (_FrameWidthRatio * 0x10000);
       mouse.y = (mouse.y * scale.y) / (_FrameHeightRatio * 0x10000);

       if ((mouse.y > PLAYER_Y_POS) && (mouse.y < PLAYER_Y_POS+CARD_HEIGHT)) {
          int CardLeft = CARD1_X_POS;
          int CardRight = CARD1_X_POS+CARD_WIDTH;
          for (int index=1; index<=5; index++) {
             if ((mouse.x > CardLeft) && (mouse.x < CardRight)) {
                if (_PlayerCard[index]==DISCARD) {
                   _PlayerCard[index] = _Discards[index];
                   _SetCardBitmap(ev, _PlayerCard[index], index, PLAYER);
                   _Discards[index] = DISCARD;
                   _DiscardCount--;
                } else {
                   if (_DiscardCount<MAX_DISCARDS) {
                      _Discards[index] = _PlayerCard[index];
                      _PlayerCard[index] = DISCARD;
                      _SetCardBitmap(ev, DISCARD, index, PLAYER);
                      _DiscardCount++;
                   } else {
                      _MessageBox(ev, facet->GetFacetHWND(ev), DiscardString,
                         MaxDiscardMsg);
                   } /* endif */
                } /* endif */
//              facet->Invalidate(ev, kODNULL);
             } /* endif */
             CardLeft = CardRight+CARD_SPACE;
             CardRight = CardLeft+CARD_WIDTH;
          } /* endfor */
       } /* endif */
    } /* endif */

#ifdef _LEFT_TO_PORT_
    handled = CardGame_parent_SimplePart_HandleMouseDown(somSelf,
                                                       ev, facet,
                                                       where,
                                                       event);
#endif
   return (handled);
}


SOM_Scope ODBoolean  SOMLINK CardGameHandleMenuEvent(CardGame *somSelf,
                                                      Environment *ev,
                                                     ODFrame* focusFrame,
                                                     ODEventData* event)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameHandleMenuEvent");

    ODBoolean handled = kODTrue;

    ODFrameFacetIterator *iter = focusFrame->CreateFacetIterator(ev);
    ODFacet *facet = iter->First(ev);
    delete iter;
    HWND hwnd = facet->GetFacetHWND(ev);

#ifdef _PLATFORM_WIN32_
    switch (event->wParam) {
#endif

#ifdef _LEFT_TO_PORT_
    switch (LONGFROMMP(event->mp1)) {
    case DOC_OAICON:
    case DOC_OATREE:
    case DOC_OADETAILS:
    case VIEW_OAICON:
    case VIEW_OATREE:
    case VIEW_OADETAILS:
       {
         ODULong vType = kODNULL;
         ODCommandID command = LONGFROMMP(event->mp1);
         if(_ViewExtension == kODNULL) {
            _ViewExtension = new ODViewExtension;
//            _ViewExtension->InitViewExtension(ev, _MyWrapper);
            _ViewExtension->InitViewExtension(ev, somSelf);  // InitExtension gets ptr to self not wrapper (27671)
         } /* endif */

         switch (command) {
         case DOC_OAICON:
         case VIEW_OAICON:
            vType = OD_ICONVIEW;
            break;
         case DOC_OATREE:
         case VIEW_OATREE:
            vType = OD_TREEVIEW;
            break;
         case DOC_OADETAILS:
         case VIEW_OADETAILS:
            vType = OD_DETAILSVIEW;
            break;
         } /* endswitch */

//         _ViewExtension->DisplayView(ev, _MyWrapper, vType);
         _ViewExtension->DisplayView(ev, somSelf????, vType);
       }
       break;
    case VIEW_PROPERTIES:
       _MySession->GetInfo(ev)->ShowPartFrameInfo(ev, facet, kODTrue);
       break;
    case VIEW_SASMALLICON:
       focusFrame->ChangeViewType(ev, _ViewAsSmallIcon);
       break;
    case VIEW_SALARGEICON:
       focusFrame->ChangeViewType(ev, _ViewAsLargeIcon);
       break;
    case VIEW_SATHUMBNAIL:
       focusFrame->ChangeViewType(ev, _ViewAsThumbnail);
       break;
    case VIEW_SAFRAME:
       focusFrame->ChangeViewType(ev, _ViewAsFrame);
       break;
#endif
    case MenuBlackJack:
       _NextGame = BLACKJACK;
       _MessageBox(ev, hwnd, GameChange, NewBlackjack);
       break;
    case MenuPoker5Stud:
       _NextGame = STUD_5_POKER;
       _MessageBox(ev, hwnd, GameChange, New5StudPoker);
       break;
    case MenuPoker7Stud:
       _NextGame = STUD_7_POKER;
       _MessageBox(ev, hwnd, GameChange, New7StudPoker);
       break;
    case MenuPokerDraw:
       _NextGame = DRAW_POKER;
       _MessageBox(ev, hwnd, GameChange, NewDrawPoker);
       break;
    case MenuAction1:
       handled = _HandlePushButton(ev, facet, BUTTON1_ID);
       break;
    case MenuAction2:
       handled = _HandlePushButton(ev, facet, BUTTON2_ID);
       break;
    case MenuAction3:
       handled = _HandlePushButton(ev, facet, BUTTON3_ID);
       break;
    case MenuAction4:
       _PlaceBet(ev, facet);
       break;
#ifdef _LEFT_TO_PORT_
    case MenuDescription:
       DosBeep(500, 250);
       handled = kODFalse;
       break;
    case MenuPartInfo:
#if 0 //     See comment in dialog window function's WM_INITDLG section
       {
          HPOINTER MyIcon = NULLHANDLE;
          MyIcon = WinLoadPointer(HWND_DESKTOP, _MyResources, GAMEICON);
          WinDlgBox(HWND_DESKTOP, hwnd, PartInfoDlgProc, _MyResources,
             PartInfoDlgValue, (PVOID) MyIcon);
       }
#endif
       WinDlgBox(HWND_DESKTOP, hwnd, PartInfoDlgProc, _MyResources,
          PartInfoDlgValue, kODNULL);
       break;
#endif

    default:
       DosBeep(500, 250);
       handled = kODFalse;
      break;
    } /* endswitch */

    return(handled);
}


SOM_Scope void  SOMLINK CardGameAdjustMenus(CardGame *somSelf,
                                             Environment *ev,
                                            ODFrame* frame)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameAdjustMenus");

#ifdef _LEFT_TO_PORT_
   ODBoolean IsRoot = frame->IsRoot(ev);

//      Note that following call is only made if we're the root - if you
//      always make the call (passing "IsRoot" variable instead of "kODTrue"),
//      then we end up graying out DOC_OPENAS when we're not the root (instead
//      of letting the root part enable/disable this menu item, as it should).
   if (IsRoot) {
      _MyMenuBar->EnableMenuItem(ev, IDMS_DOCUMENT, DOC_OPENAS, kODTrue);
   } /* endif */

   _MyMenuBar->EnableMenuItem(ev, IDMS_VIEW, VIEW_OPENAS, kODTrue);
   _MyMenuBar->EnableMenuItem(ev, IDMS_VIEW, VIEW_OAICON, kODTrue);
   _MyMenuBar->EnableMenuItem(ev, IDMS_VIEW, VIEW_OATREE, kODTrue);
   _MyMenuBar->EnableMenuItem(ev, IDMS_VIEW, VIEW_OADETAILS, kODTrue);
   _MyMenuBar->EnableMenuItem(ev, IDMS_VIEW, VIEW_OAWINDOW, kODFalse);

   _MyMenuBar->EnableMenuItem(ev, IDMS_VIEW, VIEW_PROPERTIES, kODTrue);

   _MyMenuBar->EnableMenuItem(ev, IDMS_VIEW, VIEW_SHOWAS, !IsRoot);
   _MyMenuBar->EnableMenuItem(ev, IDMS_VIEW, VIEW_SASMALLICON, kODTrue);
   _MyMenuBar->EnableMenuItem(ev, IDMS_VIEW, VIEW_SALARGEICON, kODTrue);
   _MyMenuBar->EnableMenuItem(ev, IDMS_VIEW, VIEW_SATHUMBNAIL, kODFalse);
   _MyMenuBar->EnableMenuItem(ev, IDMS_VIEW, VIEW_SAFRAME, kODTrue);
#endif

   _MyMenuBar->CheckMenuItem(ev, GameMenuID, MenuBlackJack,
      _CurrentGame==BLACKJACK);
   _MyMenuBar->CheckMenuItem(ev, GameMenuID, MenuPoker5Stud,
      _CurrentGame==STUD_5_POKER);
   _MyMenuBar->CheckMenuItem(ev, GameMenuID, MenuPoker7Stud,
      _CurrentGame==STUD_7_POKER);
   _MyMenuBar->CheckMenuItem(ev, GameMenuID, MenuPokerDraw,
      _CurrentGame==DRAW_POKER);

   _MyMenuBar->EnableMenuItem(ev, ActionsMenuID, MenuAction1, !_AllowDiscards);
   _MyMenuBar->EnableMenuItem(ev, ActionsMenuID, MenuAction2, !_AllowDiscards);
   _MyMenuBar->EnableMenuItem(ev, ActionsMenuID, MenuAction3, !_AllowDiscards);

#ifdef _LEFT_TO_PORT_
   _MyMenuBar->EnableMenuItem(ev, IDMS_HELP, MenuDescription,
      _EnableHelpItems);
#endif

   if (_CurrentGame==BLACKJACK) {
      _MyMenuBar->SetMenuItemText(ev, ActionsMenuID, MenuAction1, HitString);
      _MyMenuBar->SetMenuItemText(ev, ActionsMenuID, MenuAction2, StandString);
      _MyMenuBar->SetMenuItemText(ev, ActionsMenuID, MenuAction3,
         DoubleString);
      _MyMenuBar->SetMenuItemText(ev, ActionsMenuID, MenuAction4,
         NextBetString);
   } else {
      _MyMenuBar->SetMenuItemText(ev, ActionsMenuID, MenuAction1, RaiseString);
      _MyMenuBar->SetMenuItemText(ev, ActionsMenuID, MenuAction2, CallString);
      _MyMenuBar->SetMenuItemText(ev, ActionsMenuID, MenuAction3, DropString);
      _MyMenuBar->SetMenuItemText(ev, ActionsMenuID, MenuAction4,
         NextAnteString);
   } /* endif */
}


SOM_Scope void  SOMLINK CardGameFocusAcquired(CardGame *somSelf,
                                               Environment *ev,
                                              ODTypeToken focus,
                                              ODFrame* ownerFrame)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameFocusAcquired");

   if (focus == _MenuFocus) {
//     Here's the old way of doing menus (pre-DevCon8), preserved for posterity
//    ODActiveFrameMenuBar *mb = new ODActiveFrameMenuBar;
//    mb->InitMenuBar(ev, _MySession, _CardGameMenu);
//    mb->SetOwner(ev, ownerFrame);
//    _SetMenuItemStates(ev, mb);
//    ownerFrame->GetWindow(ev)->SetMenuBar(ev, mb);
//    mb->Release(ev);
//    pInfo->mbActive = mb;
      _MyMenuBar->Display(ev);
   } /* endif */
}


SOM_Scope void  SOMLINK CardGameFocusLost(CardGame *somSelf,
                                           Environment *ev, ODTypeToken focus,
                                          ODFrame* ownerFrame)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameFocusLost");

    CardGame_parent_SimplePart_FocusLost(somSelf, ev, focus,
                                         ownerFrame);

/* Deallocate our private menu bar */
// PartInfoRec* pInfo = (PartInfoRec*) ownerFrame->GetPartInfo(ev);
// ODActiveFrameMenuBar *mb = pInfo->mbActive;
// mb->Release(ev);
// pInfo->mbActive = kODNULL;
}


SOM_Scope void  SOMLINK CardGameExternalize(CardGame *somSelf,
                                              Environment *ev)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameExternalize");

    // Call parent
    CardGame_parent_SimplePart_Externalize(somSelf, ev);

    ODStorageUnit* su = _GetStorageUnit(ev);
    su->AddProperty(ev, kODPropPart);
    su->AddValue(ev, kODISOStr);
    StorageUnitSetValue(su, ev, strlen(kKindCardGamePart)+1, kKindCardGamePart);

    su->AddProperty(ev, kODPropContents);
    su->AddValue(ev, (ODValueType) kCardGameDataValue);
    StorageUnitSetValue(su, ev, sizeof(short), &_Money);
    StorageUnitSetValue(su, ev, sizeof(short), &_Bet);
    StorageUnitSetValue(su, ev, sizeof(short), &_Ante);

    StorageUnitSetValue(su, ev, sizeof(short), &_NextGame);

//     Note that we only since we always start a new game when embedded or
//     re-opened as part of a pre-existing document, we don't bother storing
//     all of our current data - only what's necessary to start the new game.
}


SOM_Scope void  SOMLINK CardGameInitPartFromStorage(CardGame *somSelf,
                                                     Environment *ev,
                                                    ODStorageUnit* storageUnit,
                                                    ODPart* partWrapper)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameInitPartFromStorage");

    ODSUAddPropValue(ev, storageUnit, kODPropContents, kKindCardGamePart);

    CardGame_parent_SimplePart_InitPartFromStorage(somSelf,
                                                    ev,
                                                    storageUnit,
                                                    partWrapper);


    _MyWrapper = partWrapper;

    _CommonInitCardGame(ev);

    storageUnit->Focus(ev, kODPropContents, kODPosUndefined,
       kCardGameDataValue, 0, kODPosUndefined);

    StorageUnitGetValue(storageUnit, ev, sizeof(short), &_Money);
    StorageUnitGetValue(storageUnit, ev, sizeof(short), &_Bet);
    StorageUnitGetValue(storageUnit, ev, sizeof(short), &_Ante);

    StorageUnitGetValue(storageUnit, ev, sizeof(short), &_NextGame);

//     Note that we only since we always start a new game when embedded or
//     re-opened as part of a pre-existing document, we don't bother storing
//     all of our current data - only what's necessary to start the new game.
}


SOM_Scope void  SOMLINK CardGameInitPart(CardGame *somSelf,  Environment *ev,
                                         ODStorageUnit* storageUnit,
                                         ODPart* partWrapper)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameInitPart");

    ODSUAddPropValue(ev, storageUnit, kODPropContents, kKindCardGamePart);

    CardGame_parent_SimplePart_InitPart(somSelf,
                                        ev,
                                        storageUnit,
                                        partWrapper);

    _MyWrapper = partWrapper;

    _CommonInitCardGame(ev);

    if(!storageUnit->Exists(ev, kODPropPreferredKind, kODISOStr, 0))
    {
        storageUnit->AddProperty(ev, kODPropPreferredKind)->AddValue(ev, kODISOStr);
        StorageUnitSetValue(storageUnit, ev, strlen(kKindCardGamePart) + 1, kKindCardGamePart);
    }

#ifdef _LEFT_TO_PORT_
    // code to support custom Part icons (for the OD Templates folder)
    ULONG  cbIconSize;                /* Size of icon data returned          */
    PBYTE  pIconData = NULL;          /* Scratch ptr to a block of icon data */

    if ( !DosQueryResourceSize( _MyResources, RT_POINTER, GAMEICON, &cbIconSize) &&
         !DosGetResource( _MyResources, RT_POINTER, GAMEICON, (PPVOID)&pIconData) ) {

       ODSUForceFocus(ev, storageUnit, kODPropIconFamily, kODIconFamily);
       StorageUnitSetValue( storageUnit, ev, cbIconSize, (ODValue)pIconData );

       DosFreeResource(pIconData);
    } /* endif */
#endif
}


#ifdef _LEFT_TO_PORT_
SOM_Scope ODEmbeddedFramesIterator*  SOMLINK CardGameCreateEmbeddedFramesIterator(CardGame *somSelf,
                                                                                   Environment *ev,
                                                                                  ODFrame* frame)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameCreateEmbeddedFramesIterator");

   EmbeddedCardIterator *embCardIter = new EmbeddedCardIterator;
   embCardIter->InitEmbeddedFramesIterator(ev, _MyWrapper);

   short index;
   short MaxCards = _CurrentGame==STUD_7_POKER ? 7 : 5;

   for (index=1; index<=MaxCards; index++) {
      embCardIter->Add(ev, _DealerCardFacet[index]->GetFrame(ev));
   } /* endfor */

   for (index=1; index<=MaxCards; index++) {
      embCardIter->Add(ev, _PlayerCardFacet[index]->GetFrame(ev));
   } /* endfor */

   return(embCardIter);
}


SOM_Scope ODBoolean  SOMLINK CardGameHasExtension(CardGame *somSelf,
                                                   Environment *ev,
                                                  ODType extensionName)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameHasExtension");

    ODBoolean ReturnValue;
    if (!strcmp(extensionName, kODSettingsExtension)) {
       ReturnValue = kODTrue;
    } else {
       ReturnValue = CardGame_parent_SimplePart_HasExtension(somSelf, ev,
                                                             extensionName);
    } /* endif */

    return(ReturnValue);
}


SOM_Scope ODExtension*  SOMLINK CardGameAcquireExtension(CardGame *somSelf,
                                                          Environment *ev,
                                                         ODType extensionName)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameAcquireExtension");

   ODExtension *ReturnValue;
   if (!strcmp(extensionName, kODSettingsExtension)) {
      if (_MyNoteBook==kODNULL) {
         _MyNoteBook = new CardGameNotebook;
//         _MyNoteBook->InitSettingsExtension( ev, _MyWrapper);
         _MyNoteBook->InitSettingsExtension( ev, somSelf); // Extension Init gets somSelf (27671)
      } /* endif */
      _MyNoteBook->Acquire(ev);
      ReturnValue = (ODExtension *) _MyNoteBook;
   } else {
      ReturnValue = CardGame_parent_SimplePart_AcquireExtension(somSelf, ev,
                                                                extensionName);
   } /* endif */

   return(ReturnValue);
}


SOM_Scope void  SOMLINK CardGameReleaseExtension(CardGame *somSelf,
                                                  Environment *ev,
                                                 ODExtension* extension)
{
    CardGameData *somThis = CardGameGetData(somSelf);
    CardGameMethodDebug("CardGame","CardGameReleaseExtension");

    if (extension==kODNULL) {
       return; /* Probably should raise an exception */
    } /* endif */

    if (extension==_MyNoteBook) {

       // Note to next coder - ReleaseExtension is to be called from the
       // extension when a Release call has reduced the ref count to 0 thus
       // the following old logic is incorrect and I believe the 2 lines
       // is all that is required.  Since the extension is not implemented
       // in OD 1.1, I am not able to test.  - TRM
       delete _MyNoteBook ;       // delete the extension object
       _MyNoteBook = kODNULL ;    // clear our reference to it.

//??       ODBoolean NeedToClearVariable = kODFalse;
//??       if (_MyNoteBook->GetRefCount(ev)==1) { /* is it about to be deleted? */
//??          NeedToClearVariable = kODTrue;
//??       } /* endif */
//??
//??       _MyNoteBook->Release(ev);
//??
//??       if (NeedToClearVariable) { /* Get rid of pointer to deleted object */
//??          _MyNoteBook = kODNULL;
//??       } /* endif */
    } else {
       CardGame_parent_SimplePart_ReleaseExtension(somSelf, ev,
                                                   extension);
    } /* endif */
}
#endif


SOM_Scope ISOString  SOMLINK M_CardGameclsGetODPartHandlerName(M_CardGame *somSelf,
                                                                Environment *ev)
{
    /* M_CardGameData *somThis = M_CardGameGetData(somSelf); */
    M_CardGameMethodDebug("M_CardGame","M_CardGameclsGetODPartHandlerName");

    char * handlerName = (char *) SOMMalloc(strlen(kPartHandlerName)+1);
    strcpy(handlerName, kPartHandlerName);
    return (ISOString) handlerName;
}


SOM_Scope string  SOMLINK M_CardGameclsGetODPartHandlerDisplayName(M_CardGame *somSelf,
                                                                    Environment *ev)
{
    /* M_CardGameData *somThis = M_CardGameGetData(somSelf); */
    M_CardGameMethodDebug("M_CardGame","M_CardGameclsGetODPartHandlerDisplayName");

   string displayName = (char *) SOMMalloc(strlen(kPartHandlerDisplayName)+1);
   strcpy(displayName, kPartHandlerDisplayName);
   return displayName;
}


SOM_Scope _IDL_SEQUENCE_PartKindInfo  SOMLINK M_CardGameclsGetODPartKinds(M_CardGame *somSelf,
                                                                           Environment *ev)
{
    /* M_CardGameData *somThis = M_CardGameGetData(somSelf); */
    M_CardGameMethodDebug("M_CardGame","M_CardGameclsGetODPartKinds");

   _IDL_SEQUENCE_PartKindInfo CardGameInfo;

   // Create structure PartKindInfo  and allocate memory for variable
   PartKindInfo * info = (PartKindInfo *) SOMMalloc(sizeof(PartKindInfo));
   info->partKindName = (ISOString) SOMMalloc(strlen(kKindCardGamePart)+1);
   info->partKindDisplayName = (string)SOMMalloc(strlen(kCardGameKindDisplayName)+1);
   info->filenameTypes = (string)SOMMalloc(strlen("")+1);
   info->filenameFilters =  (string)SOMMalloc(strlen("")+1);
   info->objectID = (string)SOMMalloc(strlen("")+1);
   info->categories =  (string)SOMMalloc(strlen(kSampleCategory)+1);
   // TAH 10-04-95 - DR3 addition
   info->categoryDisplayName = (string) SOMMalloc(strlen(kSampleCategoryDisplayName)+1);

   // Copy the information into the structure
   strcpy(info->partKindName , kKindCardGamePart);
   strcpy(info->partKindDisplayName, kCardGameKindDisplayName);
   strcpy(info->filenameTypes, "");
   strcpy(info->filenameFilters, "");
   strcpy(info->objectID, "");
   strcpy(info->categories, kSampleCategory);
   // TAH 10-04-95 - DR3 addition
   strcpy(info->categoryDisplayName, kSampleCategoryDisplayName);

   CardGameInfo._maximum = 1;
   CardGameInfo._length = 1;
   CardGameInfo._buffer = info;
   return CardGameInfo;
}


SOM_Scope string  SOMLINK M_CardGameclsGetOLE2ClassId(M_CardGame *somSelf,
                                                       Environment *ev)
{
    /* M_CardGameData *somThis = M_CardGameGetData(somSelf); */
    M_CardGameMethodDebug("M_CardGame","M_CardGameclsGetOLE2ClassId");

    // OLE2 Class ID is determined by running the tool UUIDGEN.EXE
    // or GUIDGEN.EXE found in the IBM VAC++ SDK\BIN directory
    // this tool is gauranteed to generate a unique ID based on your
    // network address and the time of day (DCE Standard)


    string OLE2 = "{33d0eae0-2ed4-11d0-b268-08005a49d940}";
    string OLE2ClassId = (string)SOMMalloc(strlen(OLE2)+1);
    strcpy(OLE2ClassId,OLE2);

    return OLE2ClassId;
}


SOM_Scope string  SOMLINK M_CardGameclsGetWindowsIconFileName(M_CardGame *somSelf,
                                                               Environment *ev)
{
    /* M_CardGameData *somThis = M_CardGameGetData(somSelf); */
    M_CardGameMethodDebug("M_CardGame","M_CardGameclsGetWindowsIconFileName");

    string fileName = (string) SOMMalloc (strlen("")+1);
    fileName = "";
    return fileName;
}

