#ifndef PROFILER_H_INCLUDED
#define PROFILER_H_INCLUDED

#include <windows.h>
#include <assert.h>

#ifdef ENABLE_PROFILER
class ProfilerSlot
{
public:
  LONG count;
  LONG elapsed;

  ProfilerSlot() : count(0), elapsed(0) {}
};

class Profiler
{
private:
  _TCHAR* name;
  unsigned int numberOfSlots;
  ProfilerSlot* slots;

public:
  Profiler(_TCHAR* name, unsigned int numberOfSlots);
  ~Profiler();

  inline void queryTime(LARGE_INTEGER* pli) { QueryPerformanceCounter(pli); }

  inline void recordEnd(unsigned int slot, LARGE_INTEGER* pStartTime)
  {
    recordElapsed(slot, pStartTime);
    InterlockedIncrement(&slots[slot].count);
  }

  inline void recordElapsed(unsigned int slot, LARGE_INTEGER* pStartTime)
  {
    assert(slot < this->numberOfSlots);
    LARGE_INTEGER currentTime;
    QueryPerformanceCounter(&currentTime);
    InterlockedExchangeAdd(&slots[slot].elapsed, (LONG) (currentTime.QuadPart - pStartTime->QuadPart));
  }
  
  void writeTo(HANDLE hFile);

  /**
   * bytecode profiler.
   */
  static Profiler* const BYTECODE_PROFILER;

  /**
   * unzip seek profiler.
   */
  static Profiler* const UNZIP_SEEK_PROFILER;


  static void writeAllProfiles();

};

#endif

#endif