// Change History:
// DART Data Transfer

#ifndef DDP_FIELD_H
#define DDP_FIELD_H

#include  "drs/drs_appl.h"

#include  "ddp/ddp_descr.h"
#include  "ddp/ddp_expdef.h"

////////////////////////////////////////////////////////
// DDP_Field class
////////////////////////////////////////////////////////
class DDP_Field : public DDP_ExportDef, public DDP_Descr
{
private:
    uint Size;
    uint MaxDataSize;
    uint Type;
    uint Width;
    std::string ReoccurGroup;
    uint ApportionLevel;

protected:
    virtual const byte * GetDefLabel() const { return (const byte *)"Field"; }

protected:
    bool get_field_type(byte * buf, uint sz) const;

public:
    uint get_size() const { const byte * group = GetReoccurGroup();
        return group ? GetMaxDataSize() : GetSize(); }
    
public:
    DDP_Field() : DDP_ExportDef(), DDP_Descr(),
        Size(0), MaxDataSize(0), Width(0), Type(), ApportionLevel(0) {}
    DDP_Field(const DDP_Field & rhs);
    DDP_Field(const byte * caption, const byte * sshort = NULL, const byte * id = NULL) :
        DDP_ExportDef(),
        DDP_Descr(caption, sshort, id), Size(0), MaxDataSize(0), Width(0), Type(0) {}
    virtual ~DDP_Field() {}

    virtual const byte * GetUserDefinedName() const { const byte * un = DDP_ExportDef::GetUserDefinedName();
        return un ? un : GetCaption(); }

    void SetSize(uint sz) { Size = sz; }
    void SetMaxDataSize(uint sz) { MaxDataSize = sz; }
    void SetWidth(uint w) { Width = w; }
    void SetType(uint t) { Type = t; }
    void SetReoccurGroup(const byte * group) { if(group) ReoccurGroup = (char *)group;
        else ReoccurGroup.clear(); }
    void SetApportionLevel(uint l) { ApportionLevel = l; }

    uint GetSize() const { return Size; }
    uint GetMaxDataSize() const { return MaxDataSize; }
    uint GetType() const { return Type; }
    uint GetWidth() const { return Width; }
    const byte * GetReoccurGroup() const { return ReoccurGroup.length() ? PORT_c_str(ReoccurGroup) : NULL; }
    uint GetApportionLevel() const { return ApportionLevel; }

    virtual bool Dump(DDP_PrintFile * file, const byte * prefix = NULL) const;

    virtual DDP_ExportDef * NewCopy(const DDP_ExportDef * rhs) const
        { return new DDP_Field(*((const DDP_Field *)rhs)); }
    virtual bool IsNull() const { const byte * c = GetCaption();
        return (!c || !*c); }
};

////////////////////////////////////////////////////////
// DDP_Layout class
////////////////////////////////////////////////////////
class DDP_Layout : public DDP_DescrCollection
{
protected:
    virtual DDP_Field * CreateObject() const { return new DDP_Field; }
    virtual DDP_Field * CreateObject(uint num) const { const DDP_Field * field = (const DDP_Field *)Get(num);
        return field ? new DDP_Field(*field) : NULL; }
    
public:
    virtual ~DDP_Layout() {}
    bool Load(const DRS_Application * appl);

    virtual const DDP_Field * Get(uint num) const {
        return (const DDP_Field *)DDP_DescrCollection::Get(num); }
    virtual const DDP_Field * Get(const byte * str) const {
        return (const DDP_Field *)DDP_DescrCollection::Get(str); }
};

#endif

 