/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
 *
 * The contents of this file are subject to the Netscape Public
 * License Version 1.1 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a copy of
 * the License at http://www.mozilla.org/NPL/
 *
 * Software distributed under the License is distributed on an "AS
 * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * rights and limitations under the License.
 *
 * The Original Code is mozilla.org code.
 *
 * The Initial Developer of the Original Code is Netscape
 * Communications Corporation.  Portions created by Netscape are
 * Copyright (C) 1998 Netscape Communications Corporation. All
 * Rights Reserved.
 *
 * Contributor(s): 
 */

#include "nsIProperties.idl"

typedef unsigned long PRIntervalTime;

interface nsIStopwatch;
interface nsILog;

////////////////////////////////////////////////////////////////////////////////
// nsIStopwatchService

[scriptable, uuid(0aeb95e0-be2c-11d3-93bd-000064657374)]
interface nsIStopwatchService : nsIProperties
{
    nsIStopwatch createStopwatch(in string name,
                                 in string countUnits, 
                                 in boolean perThread);
    void describeTimings(in nsILog output);
};

%{C++
#define NS_STOPWATCHSERVICE_CID                      \
{ /* 10231fc0-be2c-11d3-93bd-000064657374 */         \
    0x10231fc0,                                      \
    0xbe2c,                                          \
    0x11d3,                                          \
    {0x93, 0xbd, 0x00, 0x00, 0x64, 0x65, 0x73, 0x74} \
}

#define NS_STOPWATCHSERVICE_PROGID        "component://netscape/stopwatch-service"
#define NS_STOPWATCHSERVICE_CLASSNAME     "Stopwatch Service"
%}

////////////////////////////////////////////////////////////////////////////////
// nsIStopwatch

[scriptable, uuid(32c89070-b98b-11d3-93bb-00104ba0fd40)]
interface nsIStopwatch : nsISupports
{
    void init(in string name,
              in string countUnits, 
              in boolean perThread);

    readonly attribute string name;

    void start();

    void stop(in double count, out PRIntervalTime elapsed);

    void reset();

    /**
     * @param realTimeSamples - units countUnits
     * @param realTimeMean - units milliseconds
     * @param realTimeStdDev - units milliseconds
     */
    void getRealTimeStats(out double realTimeSamples,
                          out double realTimeMean,
                          out double realTimeStdDev);

    /**
     * @param cpuTimeSamples - units countUnits
     * @param cpuTimeMean - units milliseconds
     * @param cpuTimeStdDev - units milliseconds
     */
    void getCPUTimeStats(out double cpuTimeSamples,
                         out double cpuTimeMean,
                         out double cpuTimeStdDev);

    void describe(in nsILog log, in string msg);
};

%{C++

////////////////////////////////////////////////////////////////////////////////

#define NS_STOPWATCH_CID                             \
{ /* 46fa0bc0-b98b-11d3-93bb-00104ba0fd40 */         \
    0x46fa0bc0,                                      \
    0xb98b,                                          \
    0x11d3,                                          \
    {0x93, 0xbb, 0x00, 0x10, 0x4b, 0xa0, 0xfd, 0x40} \
}
#define NS_STOPWATCH_PROGID        "component://netscape/stopwatch"
#define NS_STOPWATCH_CLASSNAME     "Stopwatch"

////////////////////////////////////////////////////////////////////////////////

#if (defined(DEBUG) || defined(NS_DEBUG)) && !defined(WIN16)
// enable STOPWATCH by default
#define NS_ENABLE_STOPWATCH
#endif

#ifdef NS_DISABLE_STOPWATCH
// override, if you want DEBUG, but *not* STOPWATCH (for some reason)
#undef NS_ENABLE_STOPWATCH
#endif

#ifdef NS_ENABLE_STOPWATCH

#define NS_DECL_STOPWATCH(_name)                nsIStopwatch* _name
#define NS_INIT_STOPWATCH(_stopwatch, _countUnits, _perThread)                   \
    PR_BEGIN_MACRO                                                               \
    if (_stopwatch == nsnull) {                                                  \
        nsresult _rv;                                                            \
        static NS_DEFINE_CID(kStopwatchServiceCID, NS_STOPWATCHSERVICE_CID);     \
        NS_WITH_SERVICE(nsIStopwatchService, _serv, kStopwatchServiceCID, &_rv); \
        if (NS_SUCCEEDED(_rv)) {                                                 \
            _rv = _serv->CreateStopwatch(#_stopwatch,  _countUnits, _perThread,  \
                                         &_stopwatch);                           \
            PR_ASSERT(NS_SUCCEEDED(_rv));                                        \
        }                                                                        \
    }                                                                            \
    PR_END_MACRO

#define NS_STOPWATCH_START(_sw)                 ((_sw)->Start())
#define NS_STOPWATCH_STOP(_sw, _cnt, _elapsed)  ((_sw)->Stop(_cnt, _elapsed))
#define NS_STOPWATCH_RESET(_sw)                 ((_sw)->Reset())
#define NS_STOPWATCH_GETREALTIMESTATS(_sw, _samples, _mean, _sd) \
    ((_sw)->GetRealTimeStats(_samples, _mean, _sd))
#define NS_STOPWATCH_GETCPUTIMESTATS(_sw, _samples, _mean, _sd) \
    ((_sw)->GetCPUTimeStats(_samples, _mean, _sd))
#define NS_STOPWATCH_DESCRIBE(_sw, _log, _msg)  ((_sw)->Describe(_log, _msg))

#else // !NS_ENABLE_STOPWATCH

#define NS_DECL_STOPWATCH(_name)                void _not_used() // something that can be used with extern
#define NS_INIT_STOPWATCH(_stopwatch, _countUnits, _perThread)    NS_OK

#define NS_STOPWATCH_START(_sw)                 NS_OK
#define NS_STOPWATCH_STOP(_sw, _cnt, _elapsed) (*(_elapsed) = 0)
#define NS_STOPWATCH_RESET(_sw)                 NS_OK
#define NS_STOPWATCH_GETREALTIMESTATS(_sw, _samples, _mean, _sd) \
    (*(_samples) = 0, *(_mean) = 0, *(_sd) = 0)
#define NS_STOPWATCH_GETCPUTIMESTATS(_sw, _samples, _mean, _sd) \
    (*(_samples) = 0, *(_mean) = 0, *(_sd) = 0)
#define NS_STOPWATCH_DESCRIBE(_sw, _log, _msg)  NS_OK

#endif // !NS_ENABLE_STOPWATCH

////////////////////////////////////////////////////////////////////////////////

%}
