/**
 * MOAB, a Mesh-Oriented datABase, is a software component for creating,
 * storing and accessing finite element mesh data.
 *
 * Copyright 2004 Sandia Corporation.  Under the terms of Contract
 * DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government
 * retains certain rights in this software.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 */

#include "StructuredElementSeq.hpp"
#include "ScdVertexData.hpp"
#include "ScdElementData.hpp"
#include "moab/Interface.hpp"
#include "moab/ReadUtilIface.hpp"
#include "moab/CN.hpp"
#include "Internals.hpp"

namespace moab
{

StructuredElementSeq::StructuredElementSeq( EntityHandle shandle, const int imin, const int jmin, const int kmin,
                                            const int imax, const int jmax, const int kmax, int* is_per )
    : ElementSequence( shandle,
                       ScdElementData::calc_num_entities( shandle, imax - imin, jmax - jmin, kmax - kmin, is_per ),
                       CN::VerticesPerEntity( TYPE_FROM_HANDLE( shandle ) ),
                       new ScdElementData( shandle, imin, jmin, kmin, imax, jmax, kmax, is_per ) )
{
}

StructuredElementSeq::~StructuredElementSeq() {}

ErrorCode StructuredElementSeq::get_connectivity( EntityHandle handle, std::vector< EntityHandle >& connect,
                                                  bool /*topological*/ ) const
{
    int i, j, k;
    ErrorCode rval = get_params( handle, i, j, k );
    if( MB_SUCCESS == rval ) rval = get_params_connectivity( i, j, k, connect );
    return rval;
}

ErrorCode StructuredElementSeq::get_connectivity( EntityHandle handle, EntityHandle const*& connect,
                                                  int& connect_length, bool topo,
                                                  std::vector< EntityHandle >* storage ) const
{
    if( !storage )
    {
        connect        = 0;
        connect_length = 0;
        return MB_STRUCTURED_MESH;
    }

    storage->clear();
    ErrorCode rval = get_connectivity( handle, *storage, topo );
    connect        = &( *storage )[0];
    connect_length = storage->size();
    return rval;
}

ErrorCode StructuredElementSeq::set_connectivity( EntityHandle, EntityHandle const*, int )
{
    return MB_STRUCTURED_MESH;
}

EntityHandle* StructuredElementSeq::get_connectivity_array()
{
    return 0;
}

int StructuredElementSeq::values_per_entity() const
{
    return -1;
}  // never reuse freed handles for structured elements

EntitySequence* StructuredElementSeq::split( EntityHandle here )
{
    return new StructuredElementSeq( *this, here );
}

SequenceData* StructuredElementSeq::create_data_subset( EntityHandle, EntityHandle ) const
{
    return 0;
}

void StructuredElementSeq::get_const_memory_use( unsigned long& bytes_per_entity, unsigned long& sequence_size ) const
{
    sequence_size    = sizeof( *this );
    bytes_per_entity = sdata()->get_memory_use() / sdata()->size();
}

}  // namespace moab
