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

#ifndef JOB_UTIL_BATCH_DESC_H
#define JOB_UTIL_BATCH_DESC_H

#include "job_util/for_each_desc.h"
#include "job_manager/config.h"

namespace EA {
    namespace Jobs {

//----------------------------------------------------------------------
EA_PREFIX_ALIGN(PLATFORM_PREFERRED_ALIGNMENT) class BatchDesc : public ForEachDesc
{
public:

    explicit BatchDesc(int numElements);
    explicit BatchDesc(size_t numElements);

    static int const sMaxArrays = 16;
    template <typename T> inline void SetArray(int index, T const * inPtr, T * outPtr = 0);
    void SetArray(int index, void const * inPtr, void * outPtr, int sizeOfEachElement);

    void SetElementsPerBatch(int elementsPerBatch);
    int GetElementsPerBatch() const;

    void SetElementMultiplePerBatch(int elementMultiple);
    int GetElementMultiplePerBatch() const;

    int NumElements() const;


public: // Internal inter-component API only, stop reading...

    static int const sBatchDescIdent = 0x100;
    BatchDesc();

    struct ArrayDesc
    {
        char const * mInPtr;
        char * mOutPtr;
        int mElementSize;
        ArrayDesc() : mInPtr(0), mOutPtr(0), mElementSize(0) {}
    };

    ArrayDesc & GetArrayDesc(int index);

    bool Verify() const;

private:
    ArrayDesc           mArray[sMaxArrays];
    int32_t             mNumElements;
    int32_t             mElementsPerBatch;
    int32_t             mElementMultiplePerBatch;
    int32_t             mMinimumElementsPerBatch;
} EA_POSTFIX_ALIGN(PLATFORM_PREFERRED_ALIGNMENT);

EA_COMPILETIME_ASSERT(sizeof(BatchDesc) % 16 == 0);

template <typename T>
inline void BatchDesc::SetArray(int index, T const * inPtr, T * outPtr)
{
    SetArray(index, inPtr, outPtr, sizeof(T));
}

}}

#endif
