// @(#) 1.1 com/src/samples/scrtimer/iodtimer.cpp, odscript, od96nt, odnt9712d 1/7/97 08:49:01 [3/21/97 17:43:00]
//#====START_GENERATED_PROLOG======================================
//#
//#
//#   COMPONENT_NAME: odscript
//#
//#   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========================================
//#


//#
//#     File:           timer.idl
//#
//#     Contains:       IDL description of Scriptable Timer Part
//#
//#     Written by:     TRM/SEN
//#

#ifndef SOM_Module_timer_Source
#define SOM_Module_timer_Source
#endif
#define ODS_Timer_Class_Source

#include <windows.h>
#define VARIABLE_MACROS
#include "iodtimer.xih"
#include "oddsemgr.xh"
#include "oddsconn.xh"
#include "somtc.h"


// define a global array of timer object references
ODS_Timer **ODS_Timers = NULL;
int num_ODS_Timers = 0;

//=====================================================================
// This function is the callback service routine invoked by the
// system timer function when the requested time interval has
// expired.
//=====================================================================

void CALLBACK TimerProc(HWND hwnd, UINT  msg, UINT idEvent, DWORD time)

{
  Environment *ev = SOM_CreateLocalEnvironment();
  // locate the timer object for the specified ID and call its
  // 'Trigger Event' method to link to any sinks attached to that timer.
  for (int i = 0; i < num_ODS_Timers; i++) {
    if (ODS_Timers[i]->_get_ID(ev) == (long) idEvent) {
      ODS_Timers[i]->TriggerEvent(ev);
    }
  }

  SOM_DestroyLocalEnvironment(ev);

}
//=====================================================================
// Start - will register with the system timer service to be notified
//    when our specified interval has expired.
//=====================================================================
SOM_Scope void  SOMLINK ODS_TimerStart(ODS_Timer *somSelf,  Environment *ev)
{
    ODS_TimerData *somThis = ODS_TimerGetData(somSelf);
    ODS_TimerMethodDebug("ODS_Timer","Start");
    if (! _fRunning) {
      UINT id = ::SetTimer(NULL, 0, (UINT) somSelf->_get_Interval(ev),
                           (TIMERPROC) TimerProc);

      if (id) {
        somSelf->_set_ID(ev, (long) id);
        _fRunning = TRUE;
        ODS_Timers = (ODS_Timer **) SOMRealloc(ODS_Timers, (num_ODS_Timers+1) * sizeof(ODS_Timer *));
        if (ODS_Timers) {
          ODS_Timers[num_ODS_Timers] = somSelf;
          num_ODS_Timers += 1 ;
        }
      }
    }
}
//=====================================================================
// Stop - Terminates notification from the system timer service and
//    hence terminates raising events
//=====================================================================
SOM_Scope void  SOMLINK ODS_TimerStop(ODS_Timer *somSelf,  Environment *ev)
{
    ODS_TimerData *somThis = ODS_TimerGetData(somSelf);
    ODS_TimerMethodDebug("ODS_Timer","Stop");

    if (_fRunning && somSelf->_get_ID(ev)) {
      ::KillTimer(NULL, (UINT) somSelf->_get_ID(ev));
      _fRunning = FALSE;
      somSelf->_set_ID(ev, 0);
      for (int i = 0; i < num_ODS_Timers; i++) {
        if (ODS_Timers[i] == somSelf) {
          ODS_Timers[i] = ODS_Timers[num_ODS_Timers];
          num_ODS_Timers -= 1 ;
          break;
        }
      }
    }
}
//=====================================================================
// TriggerEvent - invoked from the callback routine when the interval
//    for this object has been reached.
//=====================================================================
SOM_Scope void  SOMLINK ODS_TimerTriggerEvent(ODS_Timer *somSelf,  Environment *ev)
{
    ODS_TimerData *somThis = ODS_TimerGetData(somSelf);
    ODS_TimerMethodDebug("ODS_Timer","TriggerEvent");

    _IDL_SEQUENCE_any  inParms;
    ODDSRESULT         result;
    long               sinkCount ;
    long               sinkNumber ;
    ODDSSinkEnum       *sinkEnum;

    inParms._length  = 0;
    inParms._maximum = 0;
    inParms._buffer = NULL;


    try {

      _fEventManager->PrepareEventFiring(ev, &sinkCount, &sinkEnum);
      for (sinkNumber = 0 ; sinkNumber < sinkCount ; sinkNumber++ )
      {
        _fEventManager->FireEvent(ev, sinkEnum, "TimerEvent",&inParms,&result);
        // ignore any return value, we don't use it in this case
      }
      _fEventManager->StopEventFiring(ev, sinkEnum);
    }

    catch(...)
    {
    }

}

//=====================================================================
// somInit - constructor, initialize all local data and create the
//    event interface manager object for this object.
//=====================================================================
SOM_Scope void  SOMLINK ODS_TimersomInit(ODS_Timer *somSelf)
{
    ODS_TimerData *somThis = ODS_TimerGetData(somSelf);
    ODS_TimerMethodDebug("ODS_Timer","somInit");

    Environment *ev = SOM_CreateLocalEnvironment();

    ODS_Timer_parent_ODDSConnection_somInit(somSelf);

    ODGUID odguid = { 0xf2166380, 0x285d, 0x11d0,
                      {0xa5, 0xc4, 0x00, 0x04, 0xac, 0x32, 0x80, 0xdc}};
    _fODGuid = odguid ;
    _fEventManager =  new ODDSEventMgr(ev, _fODGuid);
    somSelf->_set_Interval(ev, 1000);
    _fRunning = FALSE;
    somSelf->AddEventMgr(ev, _fEventManager);
    SOM_DestroyLocalEnvironment(ev);
}

//=====================================================================
// somUninit - relaease resources and disconnect from system timer
//    service.
//=====================================================================
SOM_Scope void  SOMLINK ODS_TimersomUninit(ODS_Timer *somSelf)
{
    ODS_TimerData *somThis = ODS_TimerGetData(somSelf);
    ODS_TimerMethodDebug("ODS_Timer","somUninit");

    Environment *ev = SOM_CreateLocalEnvironment();

    somSelf->Stop(ev);                   // disconnect from timer service

    if (_fEventManager)                  // release our event manager
    {
      somSelf->DeleteEventMgr(ev,&_fODGuid) ;
      delete _fEventManager ;
    }
    SOM_DestroyLocalEnvironment(ev);

    ODS_Timer_parent_ODDSConnection_somUninit(somSelf);
}





// ----------------------------------------------------------
// constants to define meta information for the class
// ----------------------------------------------------------

const ODType   kHandlerName     = "ODS_Timer";
const ODType   kPresNormal      = "ODS_Timer:Presentation:Normal";
const ODType   kPresPalette     = "ODS_Timer:Presentation:Palette";
const ODType   kKind            = "ODS_Timer";
const ODType   kKindDisplayName = "Timer";
const ODType   kCategory        = "OpenDoc:Category:Sample";
const ODType   kDisplayCatagory = "Sample" ;
const ODType   kWindowsIcon     = "";
const ODType   kClassGUID       = "{da26cc80-59c3-11d0-802c-08005a88887e}";




//=======================================================================
// modify Meta class with part specific name strings. PartHandlerName
//=======================================================================
SOM_Scope ISOString  SOMLINK M_ODS_TimerclsGetODPartHandlerName(M_ODS_Timer *somSelf,
                                                                            Environment *ev)
{
    /* M_ODS_TimerData *somThis = M_ODS_TimerGetData(somSelf); */
    M_ODS_TimerMethodDebug("M_ODS_Timer","M_ODS_TimerclsGetODPartHandlerName");

    string tempName = kHandlerName ;
    string handlerName =  (string) SOMMalloc(strlen(tempName) + 1);
    strcpy(handlerName, tempName);

    return (ISOString) handlerName;
}


//=======================================================================
// modify Meta class with part specific name strings. PartHandlerDisplayName
//=======================================================================
SOM_Scope string  SOMLINK M_ODS_TimerclsGetODPartHandlerDisplayName(M_ODS_Timer *somSelf,
                                                                                Environment *ev)
{
    /* M_ODS_TimerData *somThis = M_ODS_TimerGetData(somSelf); */
    M_ODS_TimerMethodDebug("M_ODS_Timer","M_ODS_TimerclsGetODPartHandlerDisplayName");

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






//=======================================================================
// modify Meta class with part specific name strings. PartKindInfo
//=======================================================================
SOM_Scope _IDL_SEQUENCE_PartKindInfo  SOMLINK M_ODS_TimerclsGetODPartKinds(M_ODS_Timer *somSelf,
                                                                                       Environment *ev)
{
    /* M_ODS_TimerData *somThis = M_ODS_TimerGetData(somSelf); */
    M_ODS_TimerMethodDebug("M_ODS_Timer","M_ODS_TimerclsGetODPartKinds");


    _IDL_SEQUENCE_PartKindInfo ODS_TimerInfo;

    // Create structure PartKindInfo  and allocate memory for variable

    PartKindInfo * info = (PartKindInfo *)SOMMalloc(sizeof(PartKindInfo));

    info->partKindName =     (ISOString)SOMMalloc(strlen(kKind) + 1);
    strcpy(info->partKindName , kKind);

    info->partKindDisplayName = (string)SOMMalloc(strlen(kKindDisplayName)+1);
    strcpy(info->partKindDisplayName, kKindDisplayName);

    info->filenameFilters =     (string)SOMMalloc(strlen("")+1);
    strcpy(info->filenameFilters, "");

    info->filenameTypes =       (string)SOMMalloc(strlen("")+1);
    strcpy(info->filenameTypes, "");

    info->categories =          (string)SOMMalloc(strlen(kCategory) + 1);
    strcpy(info->categories, kCategory);

    info->categoryDisplayName = (string)SOMMalloc(strlen(kDisplayCatagory)+1);
    strcpy(info->categoryDisplayName, kDisplayCatagory);

    info->objectID =            (string)SOMMalloc(strlen("") + 1);
    strcpy(info->objectID, "");

    // Copy the information into the structure


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

    return ODS_TimerInfo;

}

//=======================================================================
// modify Meta class with part specific name strings. OLE2ClassId
//=======================================================================
SOM_Scope string  SOMLINK M_ODS_TimerclsGetOLE2ClassId(M_ODS_Timer *somSelf,
                                                                   Environment *ev)
{
    /* M_ODS_TimerData *somThis = M_ODS_TimerGetData(somSelf); */
    M_ODS_TimerMethodDebug("M_ODS_Timer","M_ODS_TimerclsGetOLE2ClassId");

    string tempClassID = kClassGUID ;
    string classID = (string) SOMMalloc(strlen(tempClassID) + 1);
    strcpy(classID, tempClassID);
    return classID;
}

//=======================================================================
// modify Meta class with part specific name strings. WindowsIconFileName
//=======================================================================
SOM_Scope string  SOMLINK M_ODS_TimerclsGetWindowsIconFileName(M_ODS_Timer *somSelf,
                                                                           Environment *ev)
{
    /* M_ODS_TimerData *somThis = M_ODS_TimerGetData(somSelf); */
    M_ODS_TimerMethodDebug("M_ODS_Timer","M_ODS_TimerclsGetWindowsIconFileName");

    string tempName = kWindowsIcon ;
    string WindowsIconFileName = (string)SOMMalloc(strlen(tempName)+1);
    strcpy(WindowsIconFileName,tempName);

    return WindowsIconFileName;
}
