/*
    File:          $filename:toupper$.CPP

    Description:   Implementation of $partname$

    Written by:    $author$

    Copyright:     (c) $years$ by $company$
                   - all rights reserved

    Generated by:  $toolname$ $toolversion$
*/

#ifndef SOM_Module_$filename$_Source
#define SOM_Module_$filename$_Source
#endif
#define $partname$_Class_Source

#define VARIABLE_MACROS

#include <odall.h>

#ifndef _ODDEBUG_
#include <ODDebug.h>
#endif

#ifndef _TEMPOBJ_
#include <TempObj.h>
#endif

#ifndef _ODMATH_
#include <ODMath.h>
#endif

#ifndef _WINUTILS_
#include <WinUtils.h>
#endif

#ifndef _STDTYPIO_
#include <StdTypIO.h>
#endif

#if defined (_PLATFORM_OS2_)
#include <odos2.h>
#endif

#if defined (_PLATFORM_WIN32_)
#include <storutil.h>
#endif

#if defined (_PLATFORM_AIX_)
#include <Xm/XmAll.h>
#endif


#include <stdio.h>

#include "$filename$.xih"

#include <FocusLib.h>

#include "$filename$.h"

#if (defined(_PLATFORM_OS2_) || defined(_PLATFORM_WIN32_))
#include "$lang_subdir$\$filename$.h"       // The generated message catalog header
#endif

#ifdef _PLATFORM_AIX_
#include "$lang_subdir$/$filename$_msg.h"   // The generated message catalog header
#endif

const ODType kPartHandlerName     = "$partname$";
const ODType kDisplayName         = $displayname$;
const ODType kKind                = $kind$;
const ODType kKindDisplayName     = $kinddisplayname$;
const ODType kCategory            = $category$;
const ODType kCategoryDisplayName = $categorydisplayname$;

const char  *kDebugName           = "$partname$";
const char  *kDebugNameM          = "M_$partname$";

#define FIXED2LONG(f) (((f) + 0x8000) >> 16)

/*
    This is the first method called when an object of this class is created.
    Initialization of all attributes and private variables.

    Implementation: Call parent initializer, initialize attributes
    Return        : None
    Subclassing   : Call first
    Notes         : None
*/

SOM_Scope void SOMLINK somDefaultInit($partname$ *somSelf, somInitCtrl* ctrl)
{
    $partname$Data *somThis; /* set in BeginInitializer */
    somInitCtrl globalCtrl;
    somBooleanVector myMask;
    $partname$MethodDebug(kPartHandlerName,"somDefaultInit");
    $partname$_BeginInitializer_somDefaultInit;

    $partname$_Init_$parentname$_somDefaultInit(somSelf, ctrl);

    // initialization
    _text = NULL;
}

/*
    This is the last method called before this instance of the class is
    destroyed. Release any remaining allocated resources.

    Implementation: Clean up resources, then call parent
    Return        : None
    Subclassing   : Call last (or as your part requires)
    Notes         : None
*/

SOM_Scope void SOMLINK somDestruct($partname$ *somSelf, octet doFree,
                                   somDestructCtrl* ctrl)
{
    $partname$Data *somThis; /* set in BeginDestructor */
    somDestructCtrl globalCtrl;
    somBooleanVector myMask;
    $partname$MethodDebug(kPartHandlerName,"somDestruct");
    $partname$_BeginDestructor;

    // clean up
    if (_text != NULL)
        SOMFree (_text);

    $partname$_EndDestructor;
}



SOM_Scope void  SOMLINK InitPart($partname$ *somSelf,  Environment *ev,
                                 ODStorageUnit* storageUnit, ODPart *partWrapper)
{
    $partname$Data *somThis = $partname$GetData(somSelf);
    $partname$MethodDebug(kPartHandlerName,"InitPart");

    try
    {
       // Call parent's method (which calls our CommonInit)
       $partname$_parent_SimplePart_InitPart(somSelf, ev, storageUnit, partWrapper);

       // Save preferred kind property
       ODSetISOStrProp(ev, storageUnit,
                      kODPropPreferredKind,
                      kODISOStr,
                      kKind);

       _text = (string) SOMMalloc (strlen ("$partname$") + 1);
       strcpy (_text, "$partname$");
    }
    catch(...)
    {
    }
}


SOM_Scope void  SOMLINK CommonInit($partname$ *somSelf,
                                   Environment *ev,
                                   ODPart* partWrapper)
{
    $partname$Data *somThis = $partname$GetData(somSelf);
    $partname$MethodDebug(kPartHandlerName,"CommonInit");

    try
    {
    $partname$_parent_SimplePart_CommonInit(somSelf, ev, partWrapper);
    somThis->fSession = somSelf->GetStorageUnit(ev)->GetSession(ev);

    ODMenuBar *menuBar = somSelf->GetMenuBar(ev);

    if (menuBar) {

       menuBar->Acquire(ev);

#if defined(__IBMCPP__) || defined(_IBMR2)
       nl_catd msgCatalog;       // NLS message catalog handle
       char *menuText;           // pointer for NLS message

       setlocale(LC_MESSAGES, NULL);
       msgCatalog = catopen($filename:toupper$_MSG_CATALOG, 0);
       if(msgCatalog == CATD_ERR)
       {
         PRINT("Could not open message catalog %s\n", $filename:toupper$_MSG_CATALOG);
       }
#else
       char menuText[256];
#endif

       ODPlatformMenuItem *mi = new ODPlatformMenuItem;

       // add a menu separator line to the HELP menu
       mi->id = k$partname$MenuSeparator;
       #if defined(_PLATFORM_WIN32_)
       mi->afAttribute=MF_SEPARATOR;
       #elif defined(_PLATFORM_OS2_)
       mi->afAttribute=CA_TITLESEPARATOR;
       #endif

       menuBar->AddMenuItemLast(ev, IDMS_HELP, kODNULL, mi);

       // add $partname$ Help item to the HELP menu
       mi->id = k$partname$HelpMenu;
       #if (defined(_PLATFORM_OS2_) || defined(_PLATFORM_WIN32_))
       mi->afAttribute=0;           // use default attributes
       #endif
       menuBar->AddMenuItemLast(ev, IDMS_HELP, kODNULL, mi);
       #if defined(__IBMCPP__) || defined(_IBMR2)
       menuText=catgets(msgCatalog, FIRST_MSG_SET, $filename:toupper$_MSG_HELPMENU, $filename:toupper$_DEFMSG_HELPMENU);
       #else
       strcpy (menuText, $filename:toupper$_DEFMSG_HELPMENU);
       #endif
       menuBar->SetMenuItemText(ev, IDMS_HELP, mi->id, menuText);

       // add $partname$ Information item to the HELP menu
       mi->id = k$partname$InfoMenu;
       #if (defined(_PLATFORM_OS2_) || defined(_PLATFORM_WIN32_))
       mi->afAttribute=0;           // use default attributes
       #endif
       menuBar->AddMenuItemLast(ev, IDMS_HELP, kODNULL, mi);
       #if defined(__IBMCPP__) || defined(_IBMR2)
       menuText=catgets(msgCatalog, FIRST_MSG_SET, $filename:toupper$_MSG_INFOMENU, $filename:toupper$_DEFMSG_INFOMENU);
       #else
       strcpy (menuText, $filename:toupper$_DEFMSG_INFOMENU);
       #endif
       menuBar->SetMenuItemText(ev, IDMS_HELP, mi->id, menuText);

       // we can now release the MenuBar
       menuBar->Release(ev);

       delete mi;                        // cleanup menuitem buffer

       #if defined(__IBMCPP__) || defined(_IBMR2)
       catclose(msgCatalog);             // close the message catalog
       #endif
    }  // if menubar

    }
    catch(...)
    {
    }
}


SOM_Scope void  SOMLINK InitPartFromStorage($partname$ *somSelf, Environment *ev,
                                            ODStorageUnit* storageUnit, ODPart *partWrapper)
{
    $partname$Data *somThis = $partname$GetData(somSelf);
    $partname$MethodDebug(kPartHandlerName,"InitPartFromStorage");

    $partname$_parent_$parentname$_InitPartFromStorage(somSelf, ev, storageUnit, partWrapper);
}

SOM_Scope void  SOMLINK DrawFrame($partname$ *somSelf,
                                            Environment *ev,
                                            ODFacet* facet,
                                            ODShape* invalidShape)
{
    $partname$Data *somThis = $partname$GetData(somSelf);
    $partname$MethodDebug(kPartHandlerName,"DrawFrame");

    ODRect frameODRect;
    TempODShape usedShape = facet->GetFrame(ev)->AcquireUsedShape(ev,kODNULL);
    usedShape->GetBoundingBox(ev, &frameODRect);
    HDraw hDraw;

    CFocus f(facet, invalidShape, &hDraw);     // Set up drawing environment
#if defined(_PLATFORM_OS2_)||defined(_PLATFORM_WIN32_)

    Rect frameRect;
#endif
#ifdef _PLATFORM_OS2_
    HAB hab = WinInitialize(0);
    WinSetRect(hab,&frameRect, FixedToInt(frameODRect.left),
                               FixedToInt(frameODRect.bottom),
                               FixedToInt(frameODRect.right),
                               FixedToInt(frameODRect.top));
    Point orig = {0, 0};
    Point pt = {frameRect.xRight, frameRect.yTop};
    GpiSetColor(hDraw, CLR_BLUE);                 // Set the drawing color
    GpiMove(hDraw, &orig);                        // Set the origin from which to draw
    GpiBox(hDraw, DRO_FILL, &pt, 0, 0);           // Draw a color filled rectangle

#elif defined(_PLATFORM_WIN32_)
    SetRect(&frameRect, FixedToInt(frameODRect.left),
                        FixedToInt(frameODRect.top),
                        FixedToInt(frameODRect.right),
                        FixedToInt(frameODRect.bottom));

    HBRUSH hbr = CreateSolidBrush (RGB(0,0,255)); // Create a solid brush
    FillRect (hDraw, &frameRect, hbr);            // Fill the rectangle with the brush
    DeleteObject (hbr);                           // Delete the brush

#elif defined(_PLATFORM_UNIX_)

    // Get the AIX Window canvas
    ODAIXWindowCanvas *aixwincanvas = (ODAIXWindowCanvas *) (facet->GetCanvas(ev)->GetPlatformCanvas(ev, kODAIX));

    // Get the canvas widget
    Widget widget = aixwincanvas->GetWidget(ev);

    // Get the canvas window
    Window window = aixwincanvas->GetWindow(ev);

    // Get the canvas display
    Display *display = aixwincanvas->GetDisplay(ev);

    // Get the widget's dimensions
    Position x, y;
    Dimension width, height;

    // Use the following code when DrawThumbnail is implemented.
    // Set the width and height according to the widget size.
    // XtVaGetValues(widget,
    //              XmNwidth, &width,
    //              XmNheight, &height,
    //              NULL);

    // Use the following code if DrawThumbnail calls DrawFrame.
    // Set the width and height according to the used shape.
    ODFixed xscale, yscale;
    Get72DPIToScreenScale( _fSession, &xscale, &yscale);
    width = FixedToInt((ODFixedMultiply(xscale,
                                      (frameODRect.right - frameODRect.left))));
    height = FixedToInt((ODFixedMultiply(yscale,
                                      (frameODRect.bottom - frameODRect.top))));

    x = 0;
    y = 0;

    // Ensure the fill style is solid
    XSetFillStyle(display, hDraw, FillSolid);

    // Get the screen
    Screen *screen = _fSession->GetWindowState(ev)->GetScreen(ev);

    // Get the default colormap for the screen
    Colormap map = XDefaultColormapOfScreen(screen);

    XColor def, def2;

    Status stat;

    // Color is dark purple
    stat = XAllocNamedColor(display, map, "purple" , &def, &def2);

    // Set foreground color
    XSetForeground(display, hDraw, def.pixel);

    // Fill the rectangle
    XFillRectangle(display,
                   window,
                   hDraw,
                   x, y,
                   width, height);
#endif
}

SOM_Scope ODBoolean  SOMLINK HandleMenuEvent($partname$ *somSelf,
                                              Environment *ev,
                                              ODFrame* focusFrame,
                                              ODEventData* event)
{
    $partname$Data *somThis = $partname$GetData(somSelf);
    $partname$MethodDebug(kDebugName,"HandleMenuEvent");

    ODBoolean handled = kODFalse;

    try
    {

#ifdef _PLATFORM_WIN32_
    ODCommandID command = event->wParam;
#elif defined(_PLATFORM_OS2_)
    ODCommandID command = LONGFROMMP(event->mp1);
#elif defined(_PLATFORM_UNIX_)
    ODMenuItemID command = ((ODMenuEventData *)event)->item;
#endif

      switch (command)
      {
         case VIEW_PROPERTIES:
            {
              ODFrameFacetIterator* facets = focusFrame->CreateFacetIterator(ev);
              _fSession->GetInfo(ev)->ShowPartFrameInfo(ev,facets->First(ev), kODFalse);
              delete facets;
              handled = kODTrue;
            }
            break;
         case VIEW_SASMALLICON:
            focusFrame->SetViewType(ev, _fSession->Tokenize(ev,kODViewAsSmallIcon));
            somSelf->ViewTypeChanged(ev, focusFrame);
            break;
         case VIEW_SALARGEICON:
            focusFrame->SetViewType(ev, _fSession->Tokenize(ev,kODViewAsLargeIcon));
            somSelf->ViewTypeChanged(ev, focusFrame);
            break;
         case VIEW_SATHUMBNAIL:
            focusFrame->SetViewType(ev, _fSession->Tokenize(ev,kODViewAsThumbnail));
            somSelf->ViewTypeChanged(ev, focusFrame);
            break;
         case VIEW_SAFRAME:
            focusFrame->SetViewType(ev, _fSession->Tokenize(ev,kODViewAsFrame));
            somSelf->ViewTypeChanged(ev, focusFrame);
            break;
         case VIEW_OAWINDOW:
         case kODCommandViewAsWin:
            {
              somSelf->Open(ev, focusFrame);
              handled = kODTrue;
            }
            break;
         case kSimplePartHelpMenu:         // Using parent class $parentname$ menu constants
            {
               ODHelp *help = _fSession->GetHelp(ev);
               help->DisplayHelp(ev, $filename:toupper$_HELP_FILE, $filename:toupper$_HELP_PANEL);
               handled = kODTrue;
            }
            break;
         case kSimplePartInfoMenu:         // Using parent class $parentname$ menu constants
            {

               somSelf->DisplayInfoDialog(ev,
                                          $filename:toupper$_MSG_CATALOG,
                                          FIRST_MSG_SET,
                                          $filename:toupper$_MSG_INFOTITLE,
                                          $filename:toupper$_DEFMSG_INFOTITLE,
                                          $filename:toupper$_MSG_INFO,
                                          $filename:toupper$_DEFMSG_INFO);
               handled = kODTrue;
            }
            break;
         default:
            break;
      }
    }
    catch(...)
    {
    }

    return handled;

}


// metaclass methods

SOM_Scope ISOString  SOMLINK clsGetODPartHandlerName(M_$partname$ *somSelf,
                                                     Environment *ev)
{
    /* M_$partname$Data *somThis = M_$partname$GetData(somSelf); */
    M_$partname$MethodDebug(kDebugNameM,"clsGetODPartHandlerName");

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

SOM_Scope string  SOMLINK clsGetODPartHandlerDisplayName(M_$partname$ *somSelf,
                                                         Environment *ev)
{
    /* M_$partname$Data *somThis = M_$partname$GetData(somSelf); */
    M_$partname$MethodDebug(kDebugNameM,"clsGetODPartHandlerDisplayName");

    string displayName = (string) SOMMalloc (strlen (kDisplayName) + 1);
    strcpy (displayName, kDisplayName);
    return (displayName);
}

SOM_Scope _IDL_SEQUENCE_PartKindInfo  SOMLINK clsGetODPartKinds(M_$partname$ *somSelf,
                                                                             Environment *ev)
{
    /* M_$partname$Data *somThis = M_$partname$GetData(somSelf); */
    M_$partname$MethodDebug(kDebugNameM,"clsGetODPartKinds");

    _IDL_SEQUENCE_PartKindInfo kindInfo;

    // Create structure PartKindInfo  and allocate memory for variable
    PartKindInfo *info        = (PartKindInfo *) SOMMalloc (sizeof (PartKindInfo));
    info->partKindName        = (ISOString)      SOMMalloc (strlen (kKind)                + 1);
    info->partKindDisplayName = (string)         SOMMalloc (strlen (kKindDisplayName)     + 1);
    info->filenameFilters     = (string)         SOMMalloc (strlen ("")                   + 1);
    info->filenameTypes       = (string)         SOMMalloc (strlen ("")                   + 1);
    info->categories          = (string)         SOMMalloc (strlen (kCategory)            + 1);
    info->categoryDisplayName = (string)         SOMMalloc (strlen (kCategoryDisplayName) + 1);
    info->objectID            = (string)         SOMMalloc (strlen ("")                   + 1);

    // Copy the information into the structure
    strcpy (info->partKindName,        kKind);
    strcpy (info->partKindDisplayName, kKindDisplayName);
    strcpy (info->filenameFilters,     "");
    strcpy (info->filenameTypes,       "");
    strcpy (info->categories,          kCategory);
    strcpy (info->categoryDisplayName, kCategoryDisplayName);
    strcpy (info->objectID,            "");

    kindInfo._maximum = 1;
    kindInfo._length  = 1;
    kindInfo._buffer  = info;

    return (kindInfo);
}

SOM_Scope string  SOMLINK clsGetOLE2ClassId(M_$partname$ *somSelf,
                                                         Environment *ev)
{
    /* M_$partname$Data *somThis = M_$partname$GetData(somSelf); */
    M_$partname$MethodDebug(kDebugNameM,"clsGetOLE2ClassId");

    string classID = (string) SOMMalloc (1);
    classID[0]     = '\0';
    return (classID);
}

SOM_Scope string  SOMLINK clsGetWindowsIconFileName(M_$partname$ *somSelf,
                                                                 Environment *ev)
{
    /* M_$partname$Data *somThis = M_$partname$GetData(somSelf); */
    M_$partname$MethodDebug(kDebugNameM,"clsGetWindowsIconFileName");

    string fileName = (string) SOMMalloc (1);
    fileName[0]     = '\0';
    return (fileName);
}


#ifdef __IBMC___
  #pragma linkage (SOMInitModule, system)
#endif

SOMEXTERN void SOMLINK SOMInitModule (long majorVersion, long minorVersion,
                                 string className)
{
   $partname$NewClass ($partname$_MajorVersion, $partname$_MinorVersion);
}
