#import <OmniTimer/OTTimer.h>

// This can be defined when building the framework to enable checking of nesting
// of timers.  For the least error in timing measurements, though, this should
// be turned off.
#define OT_DEBUG_NESTING


typedef struct _OTTimerNode {
    struct _OTTimerNode           *parentNode;
    const char                    *name;
    unsigned int                   childCount;
    struct _OTTimerNode          **children;
    OTStamp                        sum;
    OTStamp                        lastStart;
    unsigned int                   startCount;
} OTTimerNode;

#ifdef OT_DEBUG_NESTING
extern void OTIllegalNestingBreak();

extern OTTimerNode *_OTCurrentNode;
extern void  OTIllegalNesting(const OTTimerNode *node, const char *operation);
extern void  OTPrintTimerName(const OTTimerNode *node);
#endif

extern void         OTEnable(int yn);

extern OTTimerNode *OTTimerNodeCreate(const char *name, OTTimerNode *parentNode);
extern void         OTTimerNodeDestroy(OTTimerNode *node);

extern void OTReportResults(OTTimerNode *root);


static inline void OTNodeStart(OTTimerNode *node)
{
#ifdef OT_DEBUG_NESTING
    if (_OTCurrentNode != node->parentNode)
        OTIllegalNesting(node, "start");
    _OTCurrentNode = node;
#endif
    OTReadCounter(&node->lastStart);
    node->startCount++;
}

static inline void OTNodeStop(OTTimerNode *node)
{
    OTAddDeltaSinceStart(&node->lastStart, &node->sum);
#ifdef OT_DEBUG_NESTING
    if (_OTCurrentNode != node)
        OTIllegalNesting(node, "stop");
    _OTCurrentNode = node->parentNode;
#endif
}
