/* -------------------------------------------------------------------------- *
 *                                   OpenMM                                   *
 * -------------------------------------------------------------------------- *
 * This is part of the OpenMM molecular simulation toolkit.                   *
 * See https://openmm.org/development.                                        *
 *                                                                            *
 * Portions copyright (c) 2019-2022 Stanford University and the Authors.      *
 * Authors: Peter Eastman                                                     *
 * Contributors:                                                              *
 *                                                                            *
 * This program 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 3 of the License, or       *
 * (at your option) any later version.                                        *
 *                                                                            *
 * This program is distributed in the hope that it will be useful,            *
 * but WITHOUT ANY WARRANTY; without even the implied warranty of             *
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              *
 * GNU Lesser General Public License for more details.                        *
 *                                                                            *
 * You should have received a copy of the GNU Lesser General Public License   *
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.      *
 * -------------------------------------------------------------------------- */

#include "openmm/common/ComputeArray.h"
#include "openmm/common/ComputeContext.h"

using namespace OpenMM;

ComputeArray::ComputeArray() : impl(NULL) {
}

ComputeArray::~ComputeArray() {
    if (impl != NULL)
        delete impl;
}

ArrayInterface& ComputeArray::getArray() {
    if (impl == NULL)
        throw OpenMMException("ComputeArray has not been initialized");
    return *impl;
}

void ComputeArray::initialize(ComputeContext& context, size_t size, int elementSize, const std::string& name) {
    if (impl != NULL)
        throw OpenMMException("The array "+getName()+" has already been initialized");
    impl = context.createArray();
    impl->initialize(context, size, elementSize, name);
}

void ComputeArray::resize(size_t size) {
    if (impl == NULL)
        throw OpenMMException("ComputeArray has not been initialized");
    impl->resize(size);
}

bool ComputeArray::isInitialized() const {
    return (impl != NULL);
}

size_t ComputeArray::getSize() const {
    if (impl == NULL)
        throw OpenMMException("ComputeArray has not been initialized");
    return impl->getSize();
}

int ComputeArray::getElementSize() const {
    if (impl == NULL)
        throw OpenMMException("ComputeArray has not been initialized");
    return impl->getElementSize();
}

const std::string& ComputeArray::getName() const {
    if (impl == NULL)
        throw OpenMMException("ComputeArray has not been initialized");
    return impl->getName();
}

ComputeContext& ComputeArray::getContext() {
    if (impl == NULL)
        throw OpenMMException("ComputeArray has not been initialized");
    return impl->getContext();
}

void ComputeArray::uploadSubArray(const void* data, int offset, int elements, bool blocking) {
    if (impl == NULL)
        throw OpenMMException("ComputeArray has not been initialized");
    impl->uploadSubArray(data, offset, elements, blocking);
}

void ComputeArray::download(void* data, bool blocking) const {
    if (impl == NULL)
        throw OpenMMException("ComputeArray has not been initialized");
    impl->download(data, blocking);
}

void ComputeArray::copyTo(ArrayInterface& dest) const {
    if (impl == NULL)
        throw OpenMMException("ComputeArray has not been initialized");
    impl->copyTo(dest);
}