//----------------------------------------------------------------------
// Copyright (C) 2006-2008 Electronic Arts    
//----------------------------------------------------------------------

#ifndef JOB_UTIL_FOR_EACH_DESC_H
#define JOB_UTIL_FOR_EACH_DESC_H

#include "EAAssert/eaassert.h"
#include "EABase/eabase.h"
#include "job_manager/config.h"

namespace EA { 
    namespace Jobs {

//----------------------------------------------------------------------
enum ForEachDivisionEnum
{ 
    FOR_EACH_DIVISION_NONE,
    FOR_EACH_DIVISION_EVEN,
    FOR_EACH_DIVISION_DYNAMIC
};

class EA_PREFIX_ALIGN(PLATFORM_PREFERRED_ALIGNMENT) ForEachDesc
{
public:
    static size_t const sLargeEnoughToHoldAllKnownDescTypes = 1024;

    void SetDivision(ForEachDivisionEnum forEachDivisionEnum, int jobCount);
    ForEachDivisionEnum GetDivision() const;

    ForEachDesc(uint16_t size, uint16_t ident);

// Internal inter-component API only, stop reading...
    int JobCount() const;

    static uint32_t * GetDynamicCounterEa(uintptr_t forEachDescEa);
    static uint32_t * GetRefCounterEa(uintptr_t forEachDescEa);

    void InitDynamicCounter();
    void InitRefCounter(uint32_t refCount);

    void Copy(ForEachDesc const & forEachDesc);

    bool Verify(uint16_t size, uint16_t ident) const;

    uint16_t            mSize; // used to copy descriptor
    uint16_t            mIdent; // used to identify descriptor type

    ForEachDivisionEnum mForEachDivisionEnum;
    uint32_t            mDynamicCounter;
    int                 mNumJobs;
    uint32_t mutable    mRefCounter;
    uint32_t            mPad0;

    uintptr_t mutable   mAtomicAllocator;
    uintptr_t mutable   mNext;
} EA_POSTFIX_ALIGN(PLATFORM_PREFERRED_ALIGNMENT);

}}

#endif
