/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
 *     Copyright 2018 Couchbase, Inc.
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */
#pragma once

#include <array>
#include <gsl/gsl>
#include <optional>
#include <type_traits>

namespace couchbase::protocol
{

/**
 * Helper code for encode and decode of LEB128 values.
 * - mcbp encodes collection-ID as an unsigned LEB128
 * - see https://en.wikipedia.org/wiki/LEB128
 */

struct Leb128NoThrow {
};

/**
 * decode_unsigned_leb128 returns the decoded T and a const_byte_buffer
 * initialised with the data following the leb128 data. This form of the decode
 * does not throw for invalid input and the caller should always check
 * second.data() for success or error (see returns info).
 *
 * @param buf buffer containing a leb128 encoded value (of size T)
 * @returns On error a std::pair where first is set to 0 and second is nullptr/0
 *          const_byte_buffer. On success a std::pair where first is the decoded
 *          value and second is a buffer initialised with the data following the
 *          leb128 data.
 */
template<class T>
typename std::enable_if_t<std::is_unsigned_v<T>, std::pair<T, std::string_view>>
decode_unsigned_leb128(std::string_view buf, struct Leb128NoThrow /* unused */)
{
    T rv = static_cast<uint8_t>(buf[0]) & 0x7fULL;
    size_t end = 0;
    if ((static_cast<uint8_t>(buf[0]) & 0x80ULL) == 0x80ULL) {
        T shift = 7;
        // shift in the remaining data
        for (end = 1; end < buf.size(); end++) {
            rv |= (static_cast<uint8_t>(buf[end]) & 0x7fULL) << shift;
            if ((static_cast<uint8_t>(buf[end]) & 0x80ULL) == 0) {
                break; // no more
            }
            shift += 7;
        }

        // We should of stopped for a stop byte, not the end of the buffer
        if (end == buf.size()) {
            return { 0, std::string_view{} };
        }
    }
    // Return the decoded value and a buffer for any remaining data
    return { rv, std::string_view{ buf.data() + end + 1, buf.size() - (end + 1) } };
}

/**
 * decode_unsigned_leb128 returns the decoded T and a const_byte_buffer
 * initialised with the data following the leb128 data. This form of the decode
 * throws for invalid input.
 *
 * @param buf buffer containing a leb128 encoded value (of size T)
 * @returns std::pair first is the decoded value and second a buffer for the
 *          remaining data (size will be 0 for no more data)
 * @throws std::invalid_argument if buf[0] does not encode a leb128 value with
 *         a stop byte.
 */
template<class T>
typename std::enable_if_t<std::is_unsigned_v<T>, std::pair<T, std::string_view>>
decode_unsigned_leb128(std::string_view buf)
{
    if (buf.size() > 0) {
        auto rv = decode_unsigned_leb128<T>(buf, Leb128NoThrow());
        if (rv.second.data()) {
            return rv;
        }
    }
    throw std::invalid_argument("decode_unsigned_leb128: invalid buf size:" + std::to_string(buf.size()));
}

/**
 * @return a buffer to the data after the leb128 prefix
 */
template<class T>
typename std::enable_if_t<std::is_unsigned_v<T>, std::string_view>
skip_unsigned_leb128(std::string_view buf)
{
    return decode_unsigned_leb128<T>(buf).second;
}

// Empty, non specialised version of the decoder class
template<class T, class Enable = void>
class unsigned_leb128
{
};

/**
 * For encoding a unsigned T leb128, class constructs from a T value and
 * provides a const_byte_buffer for access to the encoded
 */
template<class T>
class unsigned_leb128<T, typename std::enable_if_t<std::is_unsigned_v<T>>>
{
  public:
    explicit unsigned_leb128(T in)
    {
        while (in > 0) {
            auto byte = gsl::narrow_cast<uint8_t>(in & 0x7fULL);
            in >>= 7;

            // In has more data?
            if (in > 0) {
                byte |= 0x80;
                encodedData[encodedSize - 1U] = byte;
                // Increase the size
                encodedSize++;
            } else {
                encodedData[encodedSize - 1U] = byte;
            }
        }
    }

    [[nodiscard]] std::string get() const
    {
        return { begin(), end() };
    }

    [[nodiscard]] const uint8_t* begin() const
    {
        return encodedData.data();
    }

    [[nodiscard]] const uint8_t* end() const
    {
        return encodedData.data() + encodedSize;
    }

    [[nodiscard]] const uint8_t* data() const
    {
        return encodedData.data();
    }

    [[nodiscard]] size_t size() const
    {
        return encodedSize;
    }

    constexpr static size_t getMaxSize()
    {
        return maxSize;
    }

  private:
    // Larger T may need a larger array
    static_assert(sizeof(T) <= 8, "Class is only valid for uint 8/16/64");

    // value is large enough to store ~0 as leb128
    static constexpr size_t maxSize = sizeof(T) + (((sizeof(T) + 1) / 8) + 1);
    std::array<uint8_t, maxSize> encodedData{};
    uint8_t encodedSize{ 1 };
};

} // namespace couchbase::protocol


#pragma once

#include <gsl/string_span>
#include <string>

#include "params.h"

namespace particles {

class ParserParams {
public:

	static PartSysParam* Parse(PartSysParamId id,
							   gsl::cstring_span<> value,
	                           float emitterLifespan,
	                           float particleLifespan,
	                           bool& success);

	static PartSysParam* Parse(gsl::cstring_span<> value,
	                           float defaultValue,
	                           float parentLifespan,
	                           bool& success);

	static PartSysParamKeyframes* ParseKeyframes(gsl::cstring_span<> value, float parentLifespan);

	static PartSysParamRandom* ParseRandom(gsl::cstring_span<> value);

	static PartSysParamSpecial* ParseSpecial(gsl::cstring_span<> value);

	static PartSysParamConstant* ParseConstant(gsl::cstring_span<> value, float defaultValue, bool& success);

};

}


//**************************************************************************\
//* This file is property of and copyright by the ALICE Project            *\
//* ALICE Experiment at CERN, All rights reserved.                         *\
//*                                                                        *\
//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no>        *\
//*                  for The ALICE HLT Project.                            *\
//*                                                                        *\
//* Permission to use, copy, modify and distribute this software and its   *\
//* documentation strictly for non-commercial purposes is hereby granted   *\
//* without fee, provided that the above copyright notice appears in all   *\
//* copies and that both the copyright notice and this permission notice   *\
//* appear in the supporting documentation. The authors make no claims     *\
//* about the suitability of this software for any purpose. It is          *\
//* provided "as is" without express or implied warranty.                  *\
//**************************************************************************

/// \file GPUO2InterfaceConfiguration.h
/// \author David Rohr

#ifndef GPUO2INTERFACECONFIGURATION_H
#define GPUO2INTERFACECONFIGURATION_H

#ifndef HAVE_O2HEADERS
#define HAVE_O2HEADERS
#endif
#ifndef GPUCA_TPC_GEOMETRY_O2
#define GPUCA_TPC_GEOMETRY_O2
#endif
#ifndef GPUCA_O2_INTERFACE
#define GPUCA_O2_INTERFACE
#endif

#include <memory>
#include <array>
#include <vector>
#include <functional>
#include <gsl/gsl>
#include "GPUSettings.h"
#include "GPUDataTypes.h"
#include "GPUHostDataTypes.h"
#include "GPUOutputControl.h"
#include "DataFormatsTPC/Constants.h"

class TH1F;
class TH1D;
class TH2F;

namespace o2
{
namespace tpc
{
class TrackTPC;
class Digit;
} // namespace tpc
namespace gpu
{
class TPCFastTransform;
class GPUReconstruction;
struct GPUSettingsO2;

struct GPUInterfaceQAOutputs {
  const std::vector<TH1F>* hist1;
  const std::vector<TH2F>* hist2;
  const std::vector<TH1D>* hist3;
};

struct GPUInterfaceOutputs : public GPUTrackingOutputs {
  GPUInterfaceQAOutputs qa;
};

// Full configuration structure with all available settings of GPU...
struct GPUO2InterfaceConfiguration {
  GPUO2InterfaceConfiguration() = default;
  ~GPUO2InterfaceConfiguration() = default;
  GPUO2InterfaceConfiguration(const GPUO2InterfaceConfiguration&) = default;

  // Settings for the Interface class
  struct GPUInterfaceSettings {
    int dumpEvents = 0;
    bool outputToExternalBuffers = false;
    float memoryBufferScaleFactor = 1.f;
    // These constants affect GPU memory allocation only and do not limit the CPU processing
    unsigned long maxTPCZS = 8192ul * 1024 * 1024;
    unsigned int maxTPCHits = 1024 * 1024 * 1024;
    unsigned int maxTRDTracklets = 128 * 1024;
    unsigned int maxITSTracks = 96 * 1024;
  };

  GPUSettingsDeviceBackend configDeviceBackend;
  GPUSettingsProcessing configProcessing;
  GPUSettingsGRP configGRP;
  GPUSettingsRec configReconstruction;
  GPUSettingsDisplay configDisplay;
  GPUSettingsQA configQA;
  GPUInterfaceSettings configInterface;
  GPURecoStepConfiguration configWorkflow;
  GPUCalibObjects configCalib;

  GPUSettingsO2 ReadConfigurableParam();

 private:
  friend class GPUReconstruction;
  GPUSettingsO2 ReadConfigurableParam_internal();
};

} // namespace gpu
} // namespace o2

#endif


/*
 * Copyright 2017 RIS.
 * Authored by Ron Dahlgren <ron@red83.net>
 */
#ifndef GLOBALS_H_
#define GLOBALS_H_

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <GL/glew.h>
#include <GLFW/glfw3.h>

#include <unistd.h>
#include <ctype.h>
#include <math.h>
#include <getopt.h>
#include <unistd.h>
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
#include <gsl/gsl_blas.h>
#include <gsl/gsl_matrix.h>
#include <gsl/gsl_vector.h>

typedef int sd_result;

static const sd_result SD_OK = 0;
static const sd_result SD_RENDER_INIT_FAILURE = 1;
static const sd_result SD_WINDOW_CREATION_FAILURE = 2;
static const sd_result SD_NO_FREE_HANDLES = 3;
static const sd_result SD_CHECK_ERRNO = 4;
static const sd_result SD_GEN_ERROR = 5;
static const sd_result SD_SCRIPT_SYNTAX = 6;
static const sd_result SD_SCRIPT_TYPE_ERROR = 7;
static const sd_result SD_SCRIPT_GENERAL_ERROR = 8;
static const sd_result SD_FAILED_TO_READ_NUMBER = 9;

// Transform component indication flags
static const uint8_t XFORM_X_AXIS =         (1 << 0);
static const uint8_t XFORM_Y_AXIS =         (1 << 1);
static const uint8_t XFORM_Z_AXIS =         (1 << 2);
static const uint8_t XFORM_TRANSLATION =    (1 << 3);
static const uint8_t XFORM_TRANSLATION_X =  (1 << 4);
static const uint8_t XFORM_TRANSLATION_Y =  (1 << 5);
static const uint8_t XFORM_TRANSLATION_Z =  (1 << 6);

#endif


#pragma once

#include <gsl.h>
#include <boost/optional.hpp>

#include <mitkPythonService.h>

#include <QObject>
#include <QSet>
#include <QString>
#include <QVariant>
#include <QVariantList>
#include <QVector>

#include <SolidData.h>
#include <FaceIdentifier.h>
#include <ISolverStudyData.h>
#include <MeshData.h>
#include <VesselForestData.h>
#include <PCMRIData.h>

#include "PythonSolverSetupServiceActivator.h"
#include <PythonSolverSetupManager.h>
#include "PythonSolverSetupServiceExports.h"

namespace crimson
{

class   FaceTypeQtWrapper : public QObject
{
    Q_OBJECT
public:
    Q_ENUMS(FaceType);
    enum FaceType {
        ftCapInflow = FaceIdentifier::ftCapInflow,
        ftCapOutflow = FaceIdentifier::ftCapOutflow,
        ftWall = FaceIdentifier::ftWall,

        ftUndefined = FaceIdentifier::ftUndefined
    };
};

class   ArrayDataTypeQtWrapper : public QObject
{
    Q_OBJECT
public:
    Q_ENUMS(ArrayDataType);
    enum class ArrayDataType {
        Int = 0,
        Double = 1,
    };
};

class   PyFaceIdentifier
{
public:
    static PythonQtObjectPtr cppToPy(const FaceIdentifier& cppFaceId)
    {
        auto pythonService = PythonSolverSetupServiceActivator::getPythonService();

        pythonService->Execute("import CRIMSONCore");

        QVariantList parentSolidIndices;
        for (const auto& parentSolidIndex : cppFaceId.parentSolidIndices) {
            parentSolidIndices << QString::fromStdString(parentSolidIndex);
        }

        auto result = PythonQtObjectPtr{pythonService->GetPythonManager()->mainContext().call(
            "CRIMSONCore.FaceIdentifier.FaceIdentifier",
            QVariantList{static_cast<FaceTypeQtWrapper::FaceType>(cppFaceId.faceType), parentSolidIndices})};
        Ensures(!result.isNull());
        return result;
    }

    static boost::optional<FaceIdentifier> pyToCpp(PythonQtObjectPtr pyFaceId)
    {
        FaceIdentifier cppFaceId;

        QVariant faceIdVariant = pyFaceId.getVariable("faceType");
        if (!faceIdVariant.canConvert<int>()) {
            MITK_ERROR << "Face identifier not recognized - wrong faceType (expected int)";
            return boost::none;
        }
        cppFaceId.faceType = static_cast<FaceIdentifier::FaceType>(faceIdVariant.toInt());

        QVariant parentSolidIndicesVariant = pyFaceId.getVariable("parentSolidIndices");
        if (!parentSolidIndicesVariant.canConvert<QVariantList>()) {
            MITK_ERROR << "Face identifier not recognized - wrong parentSolidIndices (expected list of strings)";
            return boost::none;
        }

        for (const auto& parentSolidIndexVariant : parentSolidIndicesVariant.toList()) {
            if (!parentSolidIndexVariant.canConvert<QString>()) {
                MITK_ERROR << "Face identifier not recognized - wrong item in parentSolidIndices (expected string)";
                return boost::none;
            }

            cppFaceId.parentSolidIndices.insert(parentSolidIndexVariant.toString().toStdString());
        }

        return cppFaceId;
    }
};

class   Utils : public QObject
{
    Q_OBJECT
public slots:
    void static_Utils_reloadAll() { crimson::PythonSolverSetupServiceActivator::reloadPythonSolverSetups(true); }

    void static_Utils_logError(QString message) { MITK_ERROR << message.toStdString(); }

    void static_Utils_logWarning(QString message) { MITK_WARN << message.toStdString(); }

    void static_Utils_logInformation(QString message) { MITK_INFO << message.toStdString(); }
};

class   SolidDataQtWrapper : public QObject
{
    Q_OBJECT
public:
	SolidDataQtWrapper()
        : _brep(nullptr)
    {
    }
	SolidDataQtWrapper(gsl::not_null<const SolidData*> brep)
        : _brep(brep)
    {
    }

	SolidDataQtWrapper(const SolidDataQtWrapper& other)
        : _brep(other._brep)
    {
    }

public slots:

    QVector<double> getFaceNormal(PythonQtObjectPtr pyFaceIdentifier) const
    {
        Expects(_brep != nullptr);
        auto cppFaceIdOptional = PyFaceIdentifier::pyToCpp(pyFaceIdentifier);

        if (!cppFaceIdOptional) {
            return {};
        }

        auto normal = _brep->getFaceNormal(cppFaceIdOptional.get());
        return QVector<double>{normal[0], normal[1], normal[2]};
    }

    double getDistanceToFaceEdge(PythonQtObjectPtr pyFaceIdentifier, double x, double y, double z) const
    {
        Expects(_brep != nullptr);
        auto cppFaceIdOptional = PyFaceIdentifier::pyToCpp(pyFaceIdentifier);

        if (!cppFaceIdOptional) {
            return 0;
        }

        auto pos = mitk::Point3D{};
        pos[0] = x;
        pos[1] = y;
        pos[2] = z;
        return _brep->getDistanceToFaceEdge(cppFaceIdOptional.get(), pos);
    }

    PythonQtObjectPtr getFaceIdentifierForModelFace(int faceIndex) const
    {
        Expects(_brep != nullptr);
        auto identifierOpt = _brep->getFaceIdentifierMap().getFaceIdentifierForModelFace(faceIndex);
        return identifierOpt ? PyFaceIdentifier::cppToPy(identifierOpt.get()) : nullptr;
    }

    int getNumberOfModelFaces() const
    {
        Expects(_brep != nullptr);
        return _brep->getFaceIdentifierMap().getNumberOfModelFaces();
    }

    int getNumberOfFaceIdentifiers() const
    {
        Expects(_brep != nullptr);
        return _brep->getFaceIdentifierMap().getNumberOfFaceIdentifiers();
    }

    int faceIdentifierIndex(PythonQtObjectPtr pyFaceIdentifier) const
    {
        Expects(_brep != nullptr);

        auto cppFaceIdOptional = PyFaceIdentifier::pyToCpp(pyFaceIdentifier);

        if (!cppFaceIdOptional) {
            return 0;
        }

        return _brep->getFaceIdentifierMap().faceIdentifierIndex(cppFaceIdOptional.get());
    }

    PythonQtObjectPtr getFaceIdentifier(int uniqueFaceId) const
    {
        Expects(_brep != nullptr);
        return PyFaceIdentifier::cppToPy(_brep->getFaceIdentifierMap().getFaceIdentifier(uniqueFaceId));
    }

    QVector<int> getModelFacesForFaceIdentifier(PythonQtObjectPtr pyFaceIdentifier) const
    {
        Expects(_brep != nullptr);
        auto cppFaceIdOptional = PyFaceIdentifier::pyToCpp(pyFaceIdentifier);

        if (!cppFaceIdOptional) {
            return {};
        }

        return QVector<int>::fromStdVector(_brep->getFaceIdentifierMap().getModelFacesForFaceIdentifier(cppFaceIdOptional.get()));
    }

private:
	const SolidData* _brep;
};

class   MeshDataQtWrapper : public QObject
{
    Q_OBJECT
public:
    MeshDataQtWrapper()
        : _mesh(nullptr)
    {
    }
    MeshDataQtWrapper(gsl::not_null<const MeshData*> mesh)
        : _mesh(mesh)
    {
    }

    MeshDataQtWrapper(const MeshDataQtWrapper& other)
        : _mesh(other._mesh)
    {
    }

public slots:

    int getNNodes() const
    {
        Expects(_mesh != nullptr);
        return _mesh->getNNodes();
    }

    int getNEdges() const
    {
        Expects(_mesh != nullptr);
        return _mesh->getNEdges();
    }

    int getNFaces() const
    {
        Expects(_mesh != nullptr);
        return _mesh->getNFaces();
    }

    int getNElements() const
    {
        Expects(_mesh != nullptr);
        return _mesh->getNElements();
    }

    QVector<double> getNodeCoordinates(int nodeIndex) const
    {
        Expects(_mesh != nullptr);
        auto coords = _mesh->getNodeCoordinates(nodeIndex);
        return QVector<double>{coords[0], coords[1], coords[2]};
    }

    QVector<int> getElementNodeIds(int elementIndex) const
    {
        Expects(_mesh != nullptr);
        return QVector<int>::fromStdVector(_mesh->getElementNodeIds(elementIndex));
    }

    QVector<int> getAdjacentElements(int elementIndex) const
    {
        Expects(_mesh != nullptr);
        return QVector<int>::fromStdVector(_mesh->getAdjacentElements(elementIndex));
    }

    QVector<int> getNodeIdsForFace(PythonQtObjectPtr pyFaceIdentifier) const
    {
        Expects(_mesh != nullptr);
        auto cppFaceIdOptional = PyFaceIdentifier::pyToCpp(pyFaceIdentifier);

        if (!cppFaceIdOptional) {
            return {};
        }

        return QVector<int>::fromStdVector(_mesh->getNodeIdsForFace(cppFaceIdOptional.get()));
    }

    QVariantList getMeshFaceInfoForFace(PythonQtObjectPtr pyFaceIdentifier) const // TODO: QVector<QVector<int>>
    {
        Expects(_mesh != nullptr);
        auto cppFaceIdOptional = PyFaceIdentifier::pyToCpp(pyFaceIdentifier);

        if (!cppFaceIdOptional) {
            return {};
        }

        auto faceInfos = _mesh->getMeshFaceInfoForFace(cppFaceIdOptional.get());

        auto out = QVariantList{};
        out.reserve(faceInfos.size());
        std::transform(
            faceInfos.begin(), faceInfos.end(), std::back_inserter(out),
            [](const crimson::MeshData::MeshFaceInfo& info) {
                return QVariant::fromValue(QVector<int>{info.elementId, info.globalFaceId, info.nodeIds[0], info.nodeIds[1], info.nodeIds[2]});
            });
        return out;
    }

private:
    const MeshData* _mesh;
};

class   VesselForestDataQtWrapper : public QObject
{
    Q_OBJECT
public:
    using UIDToVesselPathDataMap = std::unordered_map<std::string, const VesselPathAbstractData*>;

    VesselForestDataQtWrapper()
        : _vesselForest(nullptr)
    {
    }
    VesselForestDataQtWrapper(gsl::not_null<const VesselForestData*> data, UIDToVesselPathDataMap uidToVesselPathDataMap)
        : _vesselForest(data)
        , _uidToVesselPathDataMap(std::move(uidToVesselPathDataMap))
    {
    }

    VesselForestDataQtWrapper(const VesselForestDataQtWrapper& other)
        : _vesselForest(other._vesselForest)
        , _uidToVesselPathDataMap(other._uidToVesselPathDataMap)
    {
    }
//    VesselForestDataQtWrapper(const VesselForestDataQtWrapper&) = default;

    const UIDToVesselPathDataMap& getUIDToVesselPathDataMap() const { return _uidToVesselPathDataMap; }

public slots:
    QVariantMap getActiveConnectedComponentsMap() const
    {
        Expects(_vesselForest != nullptr);

        auto result = QVariantMap{};
        for (const auto& uidComponentIndexPair : _vesselForest->computeActiveConnectedComponents()) {
            result[QString::fromStdString(uidComponentIndexPair.first)] = uidComponentIndexPair.second;
        }

        return result;
    }

    QVariantList getClosestPoint(PythonQtObjectPtr pyFaceIdentifier, double x, double y, double z) const
    {
        Expects(_vesselForest != nullptr);

        auto closestPathInfo = _getClosestVesselPath(pyFaceIdentifier, x, y, z);
        if (!closestPathInfo.vesselPath) {
            return {};
        }

        return QVariantList{closestPathInfo.distance, closestPathInfo.t};
    }

    QVector<double> getVesselPathCoordinateFrame(PythonQtObjectPtr pyFaceIdentifier, double x, double y, double z) const
    {
        auto closestPathInfo = _getClosestVesselPath(pyFaceIdentifier, x, y, z);
        if (!closestPathInfo.vesselPath) {
            return{};
        }

        auto pt = closestPathInfo.vesselPath->getPosition(closestPathInfo.t);
        auto tangent = closestPathInfo.vesselPath->getTangentVector(closestPathInfo.t);
        auto normal = closestPathInfo.vesselPath->getNormalVector(closestPathInfo.t);

        return QVector<double>{pt[0], pt[1], pt[2], tangent[0], tangent[1], tangent[2], normal[0], normal[1], normal[2]};
    }

private:
    struct ClosestVesselPathInfo {
        const VesselPathAbstractData* vesselPath = nullptr;
        double distance = 0;
        double t = 0;
    };

    ClosestVesselPathInfo _getClosestVesselPath(PythonQtObjectPtr pyFaceIdentifier, double x, double y, double z) const
    {
        auto cppFaceIdOptional = PyFaceIdentifier::pyToCpp(pyFaceIdentifier);

        if (!cppFaceIdOptional) {
            return {};
        }

        auto&& parentSolidIndices = cppFaceIdOptional->parentSolidIndices;

        auto result = ClosestVesselPathInfo{};

        auto pos = mitk::Point3D{};
        mitk::FillVector3D(pos, x, y, z);
        for (const auto& vesselUID : parentSolidIndices) {
            auto closestPointRequestResult = _uidToVesselPathDataMap.at(vesselUID)->getClosestPoint(pos);

            auto d = closestPointRequestResult.closestPoint.EuclideanDistanceTo(pos);
            if (result.vesselPath == nullptr || d < result.distance) {
                result.vesselPath = _uidToVesselPathDataMap.at(vesselUID);
                result.t = closestPointRequestResult.t;
                result.distance = d;
            }
        }

        return result;
    }

    const VesselForestData* _vesselForest;
    UIDToVesselPathDataMap _uidToVesselPathDataMap;
};

class   PCMRIDataQtWrapper : public QObject
{
	Q_OBJECT
public:
	PCMRIDataQtWrapper()
		: _pcmriData(nullptr)
	{
	}
	PCMRIDataQtWrapper(gsl::not_null<const PCMRIData*> pcmriData)
		: _pcmriData(pcmriData)
	{
	}

	PCMRIDataQtWrapper(const PCMRIDataQtWrapper& other)
		: _pcmriData(other._pcmriData)
	{
	}

public slots:

	QVector<double> getTimepoints() const
	{
		Expects(_pcmriData != nullptr);
		return QVector<double>::fromStdVector(_pcmriData->getTimepoints());
	}

	QVector<double> getFlowWaveform() const
	{
		Expects(_pcmriData != nullptr);
		return QVector<double>::fromStdVector(_pcmriData->getFlowWaveform());
	}

	QVector<double> getSingleMappedPCMRIvector(int pointIndex, int timepointIndex) const
	{
		Expects(_pcmriData != nullptr);
		auto coords = _pcmriData->getSingleMappedPCMRIvector(pointIndex, timepointIndex);
		return QVector<double>{coords[0], coords[1], coords[2]};
	}

private:
	const PCMRIData* _pcmriData;
};
}

Q_DECLARE_METATYPE(crimson::SolidDataQtWrapper)
Q_DECLARE_METATYPE(crimson::MeshDataQtWrapper)
Q_DECLARE_METATYPE(crimson::VesselForestDataQtWrapper)
Q_DECLARE_METATYPE(crimson::PCMRIDataQtWrapper)


/**
 * @copyright (c) 2012- King Abdullah University of Science and
 *                      Technology (KAUST). All rights reserved.
 **/

/**
 * @file testing/testing_helper.h

 * KBLAS is a high performance CUDA library for subset of BLAS
 *    and LAPACK routines optimized for NVIDIA GPUs.
 * KBLAS is provided by KAUST.
 *
 * @version 3.0.0
 * @author Wajih Halim Boukaram
 * @author Ali Charara
 * @date 2018-11-14
 **/

#ifndef __TESTING_HELPER_H__
#define __TESTING_HELPER_H__

#include <cuda.h>
#include <cuda_runtime.h>
#include <cuda_runtime_api.h>
#include <cublas_v2.h>
#include <kblas.h>
#include <cusolverDn.h>

#ifdef USE_MAGMA
#include <magma_v2.h>
#endif
#ifdef USE_MKL
#include <mkl.h>
#else
#include <cblas.h>		//TODO: if MKL not set we need to use other libs
#include <lapacke.h>
#endif
#ifdef USE_OPENMP
#include <omp.h>
#endif
#include <kblas.h>

#ifdef __cplusplus
extern "C" {
#endif

inline int iDivUp( int a, int b ) { return (a % b != 0) ? (a / b + 1) : (a / b); }

#define kmin(a,b) ((a)>(b)?(b):(a))
#define kmax(a,b) ((a)<(b)?(b):(a))
int kblas_roundup(int x, int y);

////////////////////////////////////////////////////////////
// Error checking
////////////////////////////////////////////////////////////
#define check_error(ans) { gpuAssert((ans), __FILE__, __LINE__); }
void gpuAssert(cudaError_t code, const char *file, int line);

#define check_cublas_error(ans) { gpuCublasAssert((ans), __FILE__, __LINE__); }
void gpuCublasAssert(cublasStatus_t code, const char *file, int line);

#define check_kblas_error(ans) { gpuKblasAssert((ans), __FILE__, __LINE__); }
void gpuKblasAssert(int code, const char *file, int line);

#define check_cusolver_error(ans) { gpuCusolverAssert((ans), __FILE__, __LINE__); }
void gpuCusolverAssert(cusolverStatus_t code, const char *file, int line);

////////////////////////////////////////////////////////////
// Timers and related stuff
////////////////////////////////////////////////////////////
double gettime(void);

struct GPU_Timer;
typedef GPU_Timer* GPU_Timer_t;

GPU_Timer_t newGPU_Timer(cudaStream_t stream);
void deleteGPU_Timer(GPU_Timer_t timer);
void gpuTimerTic(GPU_Timer_t timer);
void gpuTimerRecordEnd(GPU_Timer_t timer);
double gpuTimerToc(GPU_Timer_t timer);

void avg_and_stdev(double* values, int num_vals, double* avg, double* std_dev, int warmup);

////////////////////////////////////////////////////////////
// Generate array of pointers from a strided array
////////////////////////////////////////////////////////////
void generateDArrayOfPointers(double* original_array, double** array_of_arrays, int stride, int num_arrays, cudaStream_t stream);
void generateSArrayOfPointers(float* original_array, float** array_of_arrays, int stride, int num_arrays, cudaStream_t stream);
void generateDArrayOfPointersHost(double* original_array, double** array_of_arrays, int stride, int num_arrays);
void generateSArrayOfPointersHost(float* original_array, float** array_of_arrays, int stride, int num_arrays);

// Reductions
int getMaxElement(int* a, size_t elements, cudaStream_t stream);
int getMinElement(int* a, size_t elements, cudaStream_t stream);

////////////////////////////////////////////////////////////
// Allocations
////////////////////////////////////////////////////////////
#define TESTING_MALLOC_CPU( ptr, T, size)                       \
{			\
  if ( (ptr = (T*) malloc( (size)*sizeof( T ) ) ) == NULL) {    \
    fprintf( stderr, "!!!! malloc_cpu failed for: %s\n", #ptr ); \
    exit(-1);                                                   \
  } \
}
#define TESTING_MALLOC_DEV( ptr, T, size) check_error( cudaMalloc( (void**)&ptr, (size)*sizeof(T) ) )
#define TESTING_MALLOC_PIN( ptr, T, size) check_error( cudaHostAlloc ( (void**)&ptr, (size)*sizeof( T ), cudaHostAllocPortable  ))

#define TESTING_FREE_CPU(ptr)	{ if( (ptr) ) free( (ptr) ); }
#define TESTING_FREE_DEV(ptr)	check_error( cudaFree( (ptr) ) );

////////////////////////////////////////////////////////////
// Data generation
////////////////////////////////////////////////////////////
void generateDrandom(double* random_data, long num_elements, int num_ops);
void generateSrandom(float* random_data, long num_elements, int num_ops);
void srand_matrix(long rows, long cols, float* A, long LDA);
void drand_matrix(long rows, long cols, double* A, long LDA);
void crand_matrix(long rows, long cols, cuFloatComplex* A, long LDA);
void zrand_matrix(long rows, long cols, cuDoubleComplex* A, long LDA);

void smatrix_make_hpd(int N, float* A, int lda);
void dmatrix_make_hpd(int N, double* A, int lda);
void cmatrix_make_hpd(int N, cuFloatComplex* A, int lda);
void zmatrix_make_hpd(int N, cuDoubleComplex* A, int lda);

void generateRandDimensions(int minDim, int maxDim, int* randDims, int seed, int num_ops);
void fillIntArray(int* array_vals, int value, int num_elements);

void fillGPUIntArray(int* array_vals, int value, int num_elements, cudaStream_t stream);
void copyGPUPointerArray(void** originalPtrs, void** copyPtrs, int num_ptrs, cudaStream_t stream);

// set cond = 0 to use exp decay
void generateDrandomMatrices(
	double* M_strided, int stride_M, double* svals_strided, int stride_S, int rows, int cols,
	double cond, double exp_decay, int seed, int num_ops, int threads
);
void generateSrandomMatrices(
	float* M_strided, int stride_M, float* svals_strided, int stride_S, int rows, int cols,
	float cond, float exp_decay, int seed, int num_ops, int threads
);

// Mode = 0: use provided singualr values
// Mode = 1: sets singular values to random numbers in the range (1/cond, 1)
// Mode = 2: generate singular values such that S(i) = exp(-exp_decay * i);
//	     	 where exp_decay is a random value between exp_decay_min and exp_decay_max
void generateDrandomMatricesArray(
	double** M_ptrs, int* ldm_array, double** svals_ptrs, int *rows_array, int *cols_array,
	int mode, double cond, double exp_decay_min, double exp_decay_max, int seed, int num_ops, int threads
);
void generateSrandomMatricesArray(
	float** M_ptrs, int* ldm_array, float** svals_ptrs, int *rows_array, int *cols_array,
	int mode, float cond, float exp_decay_min, float exp_decay_max, int seed, int num_ops, int threads
);

void generateSsingular_values(float** svals_ptrs, int rank, float min_sval, float max_sval, int seed, int batchCount);
void generateDsingular_values(double** svals_ptrs, int rank, double min_sval, double max_sval, int seed, int batchCount);

////////////////////////////////////////////////////////////
// Result checking
////////////////////////////////////////////////////////////
// Vectors
float sget_max_error(float* ref, float *res, int n, int inc);
double dget_max_error(double* ref, double *res, int n, int inc);
float cget_max_error(cuFloatComplex* ref, cuFloatComplex *res, int n, int inc);
double zget_max_error(cuDoubleComplex* ref, cuDoubleComplex *res, int n, int inc);
// Matrices
float sget_max_error_matrix(float* ref, float *res, long m, long n, long lda);
double dget_max_error_matrix(double* ref, double *res, long m, long n, long lda);
float cget_max_error_matrix(cuFloatComplex* ref, cuFloatComplex *res, long m, long n, long lda);
double zget_max_error_matrix(cuDoubleComplex* ref, cuDoubleComplex *res, long m, long n, long lda);

double dget_max_error_matrix_uplo(double* ref, double *res, long m, long n, long lda, char uplo);
// float sget_max_error_matrix_uplo(float* ref, float *res, long m, long n, long lda, char uplo);
// double dget_max_error_matrix_symm(double* ref, double *res, long m, long n, long lda, char uplo);

#define printMatrix(m, n, A, lda, out) { \
  for(int r = 0; r < (m); r++){ \
    for(int c = 0; c < (n); c++){ \
      fprintf((out), "%.7e  ", (A)[r + c * (lda)]); \
    } \
    fprintf((out), "\n"); \
  } \
  fprintf((out), "\n"); \
}

////////////////////////////////////////////////////////////
// Command line parser
////////////////////////////////////////////////////////////
#define MAX_NTEST 1000

typedef struct kblas_opts
{
	// matrix size
	int ntest;
	int msize[ MAX_NTEST ];
	int nsize[ MAX_NTEST ];
	int ksize[ MAX_NTEST ];
	int rsize[ MAX_NTEST ];

	// scalars
	int devices[MAX_NGPUS];
	int nstream;
	int ngpu;
	int niter;
	int nruns;
	double      tolerance;
	int check;
	int verbose;
	int nb;
	int db;
	int custom;
	int warmup;
	int time;
	int lapack;
	int magma;
	int svd;
	int cuda;
	int nonUniform;
	//int bd[KBLAS_BACKDOORS];
	int batchCount;
	int strided;
	int btest, batch[MAX_NTEST];
	int rtest, rank[MAX_NTEST];
	int omp_numthreads;
  char LR;//Low rank format
  int version;

	// lapack flags
	char uplo;
	char transA;
	char transB;
	char side;
	char diag;
} kblas_opts;

int parse_opts(int argc, char** argv, kblas_opts *opts);

#ifdef __cplusplus
}
#endif

#ifdef __cplusplus

#define kmin(a,b) ((a)>(b)?(b):(a))
#define kmax(a,b) ((a)<(b)?(b):(a))

#include "kblas_operators.h"
template<class T, class T_complex>
T get_magnitude(T_complex a){ return sqrt(a.x * a.x + a.y * a.y); }
template<class T>
T get_magnitude(T ax, T ay){ return sqrt(ax * ax + ay * ay); }

template<typename T>
bool kblas_laisnan(T val1, T val2){
  return val1 != val2;
}

template<typename T>
bool kblas_isnan(T val){
  return kblas_laisnan(val,val);
}

inline float Xabs(float a){return fabs(a);}
inline double Xabs(double a){return fabs(a);}
inline float Xabs(cuFloatComplex a){return get_magnitude<float,cuFloatComplex>(a);}
inline double Xabs(cuDoubleComplex a){return get_magnitude<double,cuDoubleComplex>(a);}

template<class T>
void matrix_make_hpd(int N, T* A, int lda, T diag)
{
  ssize_t ldas = ssize_t(lda);
  for(ssize_t i = 0; i < ssize_t(N); i++)
  {
    A[i + i * ldas] = A[i + i * ldas] + diag;
    for(ssize_t j = 0; j < i; j++){
      A[j + i*ldas] = A[i + j*ldas];
    }
  }
}

template<typename T, typename R>
R kblas_lange(char type, int M, int N, T* arr, int lda){
  R value = make_zero<R>();
  R temp;
  for(int j = 0; j < N; j++){
    for(int i = 0; i < M; i++){
      temp = Xabs(arr[i + j * lda]);
      if( kblas_isnan(temp) ){
        value = temp;
        printf("NAN encountered (%d,%d)\n", i, j);
        return value;
      }
      if( value < temp)
        value = temp;
    }
  }
  return value;
}

template<typename T>
void kblasXaxpy (int n, T alpha, const T *x, int incx, T *y, int incy){
  int ix = 0, iy = 0;
  if(incx < 0) ix = 1 - n * incx;
  if(incy < 0) iy = 1 - n * incy;
  for(int i = 0; i < n; i++, ix+=incx, iy+=incy){
    y[iy] += alpha * x[ix];
  }
}

template<class T>
void hilbertMatrix(int m, int n, T* A, int lda, T scal){
  for(int r = 0; r < m; r++){
    for(int c = 0; c < n; c++){
      A[r + c*lda] = T(scal)/T(r+c+1);
    }
  }
}

#endif //__cplusplus

#ifdef DBG_MSG
#define ECHO_I(_val) printf("%s(%d) ", #_val, (_val));fflush( stdout )
#define ECHO_f(_val) printf("%s(%e) ", #_val, (_val));fflush( stdout )
#define ECHO_p(_val) printf("%s(%p) ", #_val, (_val));fflush( stdout )
#define ECHO_LN printf("\n");fflush( stdout )
#else
#define ECHO_I(_val)
#define ECHO_f(_val)
#define ECHO_p(_val)
#define ECHO_LN
#endif

#endif // __TESTING_HELPER_H__


//          Copyright Jean Pierre Cimalando 2019.
// Distributed under the Boost Software License, Version 1.0.
//    (See accompanying file LICENSE.md or copy at
//          http://www.boost.org/LICENSE_1_0.txt)

#pragma once
#include "keystate.h"
#include "instruments/synth_fx.h"
#include <gsl/gsl>
#include <string>
#include <vector>
#include <bitset>

struct Player_Song_Metadata {
    std::string name;
    std::string author;
    std::vector<std::string> text;
    char format[32] = {};
    unsigned track_count = 0;
};

struct Player_State {
    Keyboard_State kb;
    unsigned repeat_mode = 0;
    double time_position = 0;
    double duration = 0;
    double tempo = 0;
    unsigned speed = 100;
    std::string file_path;
    Player_Song_Metadata song_metadata;
    std::bitset<16> channel_enabled;
    float audio_levels[10] {};
    int fx_parameters[Synth_Fx::Parameter_Count] {};
};


// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

#pragma once

#include <gsl/span>

namespace onnxruntime {
namespace contrib {

template <typename T>
class IAttentionMechanism {
 public:
  virtual ~IAttentionMechanism() = default;

  virtual void PrepareMemory(
    const gsl::span<const T>& memory,
    const gsl::span<const int>& memory_sequence_lengths) = 0;

  virtual void Compute(
    const gsl::span<const T>& query,
    const gsl::span<const T>& prev_alignment,
    const gsl::span<T>& output,
    const gsl::span<T>& alignment) const = 0;

  virtual const gsl::span<const T> Values() const = 0;

  virtual const gsl::span<const T> Keys() const = 0;

  virtual int GetMaxMemorySteps() const = 0;

  virtual bool NeedPrevAlignment() const = 0;
};

}
}


/*
ODE: a program to get optime Runge-Kutta and multi-steps methods.

Copyright 2011-2019, Javier Burguete Tolosa.

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

	1. Redistributions of source code must retain the above copyright notice,
		this list of conditions and the following disclaimer.

	2. Redistributions in binary form must reproduce the above copyright notice,
		this list of conditions and the following disclaimer in the
		documentation and/or other materials provided with the distribution.

THIS SOFTWARE IS PROVIDED BY Javier Burguete Tolosa ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL Javier Burguete Tolosa OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/

/**
 * \file utils.c
 * \brief Source file with util functions.
 * \author Javier Burguete Tolosa.
 * \copyright Copyright 2011-2019.
 */
#define _GNU_SOURCE
#include <stdio.h>
#include <math.h>
#include <libxml/parser.h>
#include <glib.h>
#include <libintl.h>
#include <gsl/gsl_rng.h>
#include "config.h"
#include "utils.h"

gchar *error_message = NULL;    ///< error message string.

/**
 * Function to print an error message.
 */
void
show_error (const char *message)        ///< error message string.
{
  printf ("%s\n%s\n", _("ERROR!"), message);
}

/**
 * Function to get an integer number of a XML node property.
 *
 * \return Integer number value.
 */
int
xml_node_get_int (xmlNode * node,       ///< XML node.
                  const xmlChar * prop, ///< XML property.
                  int *error_code)      ///< Error code.
{
  int i = 0;
  xmlChar *buffer;
  buffer = xmlGetProp (node, prop);
  if (!buffer)
    *error_code = 1;
  else
    {
      if (sscanf ((char *) buffer, "%d", &i) != 1)
        *error_code = 2;
      else
        *error_code = 0;
      xmlFree (buffer);
    }
  return i;
}

/**
 * Function to get an unsigned integer number of a XML node property.
 *
 * \return Unsigned integer number value.
 */
unsigned int
xml_node_get_uint (xmlNode * node,      ///< XML node.
                   const xmlChar * prop,        ///< XML property.
                   int *error_code)     ///< Error code.
{
  unsigned int i = 0;
  xmlChar *buffer;
  buffer = xmlGetProp (node, prop);
  if (!buffer)
    *error_code = 1;
  else
    {
      if (sscanf ((char *) buffer, "%u", &i) != 1)
        *error_code = 2;
      else
        *error_code = 0;
      xmlFree (buffer);
    }
  return i;
}

/**
 * Function to get an unsigned integer number of a XML node property with a
 *   default value.
 *
 * \return Unsigned integer number value.
 */
unsigned int
xml_node_get_uint_with_default (xmlNode * node, ///< XML node.
                                const xmlChar * prop,   ///< XML property.
                                unsigned int default_value,
                                ///< default value.
                                int *error_code)        ///< Error code.
{
  unsigned int i;
  if (xmlHasProp (node, prop))
    i = xml_node_get_uint (node, prop, error_code);
  else
    {
      i = default_value;
      *error_code = 0;
    }
  return i;
}

/**
 * Function to get an long double number of a XML node property.
 *
 * \return Long double number value.
 */
long double
xml_node_get_float (xmlNode * node,     ///< XML node.
                    const xmlChar * prop,       ///< XML property.
                    int *error_code)    ///< Error code.
{
  long double x = 0.L;
  xmlChar *buffer;
  buffer = xmlGetProp (node, prop);
  if (!buffer)
    *error_code = 1;
  else
    {
      if (sscanf ((char *) buffer, "%Lg", &x) != 1)
        *error_code = 2;
      else
        *error_code = 0;
      xmlFree (buffer);
    }
  return x;
}

/**
 * Function to read the minimum, the interval and the random function type of a
 * variable on a XML node.
 *
 * \return 1 on success, 0 on error.
 */
int
read_variable (xmlNode * node,  ///< XML node.
               long double *minimum,    ///< minimum value.
               long double *interval,   ///< interval value.
               unsigned int *type,      ///< random function type.
               unsigned int n)  ///< variable number.
{
  char number[16];
  gchar *buffer;
  xmlChar *prop;
  int code;

  if (!node)
    {
      error_message = g_strdup (_("No XML node"));
      goto exit_on_error;
    }
  if (xmlStrcmp (node->name, XML_VARIABLE))
    {
      error_message = g_strdup (_("Bad XML node"));
      goto exit_on_error;
    }
  minimum[n] = xml_node_get_float (node, XML_MINIMUM, &code);
  if (code)
    {
      error_message = g_strdup (_("Bad minimum"));
      goto exit_on_error;
    }
  interval[n] = xml_node_get_float (node, XML_INTERVAL, &code);
  if (code)
    {
      error_message = g_strdup (_("Bad interval"));
      goto exit_on_error;
    }
  prop = xmlGetProp (node, XML_TYPE);
  if (!prop || !xmlStrcmp (prop, XML_RANDOM))
    type[n] = RANDOM_TYPE_UNIFORM;
  else if (!xmlStrcmp (prop, XML_BOTTOM))
    type[n] = RANDOM_TYPE_BOTTOM;
  else if (!xmlStrcmp (prop, XML_EXTREME))
    type[n] = RANDOM_TYPE_EXTREME;
  else if (!xmlStrcmp (prop, XML_TOP))
    type[n] = RANDOM_TYPE_TOP;
  else if (!xmlStrcmp (prop, XML_REGULAR))
    type[n] = RANDOM_TYPE_REGULAR;
  else if (!xmlStrcmp (prop, XML_ORTHOGONAL))
    type[n] = RANDOM_TYPE_ORTHOGONAL;
  else
    {
      xmlFree (prop);
      error_message = g_strdup (_("Bad random type function"));
      goto exit_on_error;
    }
  xmlFree (prop);
  return 1;

exit_on_error:
  snprintf (number, 16, "%u", n + 1);
  buffer = error_message;
  error_message
    = g_strconcat (_("Variable"), " ", number, ":\n", error_message, NULL);
  g_free (buffer);
  return 0;
}

/**
 * Function to set the precision in a maxima program file.
 */
void
print_maxima_precision (FILE * file)    ///< maxima program file.
{
  fprintf (file, "fpprec:%u;\nfpprintprec:fpprec;\n", MAXIMA_PRECISION);
}


#ifndef OPENMC_TALLIES_FILTER_COLLISIONS_H
#define OPENMC_TALLIES_FILTER_COLLISIONS_H

#include <vector>
#include <unordered_map>
#include <gsl/gsl>

#include "openmc/tallies/filter.h"

namespace openmc {

//==============================================================================
//! Bins the incident neutron energy.
//==============================================================================

class CollisionFilter : public Filter {
public:
  //----------------------------------------------------------------------------
  // Constructors, destructors

  ~CollisionFilter() = default;

  //----------------------------------------------------------------------------
  // Methods

  std::string type() const override { return "collision"; }

  void from_xml(pugi::xml_node node) override;

  void get_all_bins(const Particle& p, TallyEstimator estimator,
    FilterMatch& match) const override;

  void to_statepoint(hid_t filter_group) const override;

  std::string text_label(int bin) const override;

  //----------------------------------------------------------------------------
  // Accessors

  const std::vector<int>& bins() const { return bins_; }
  void set_bins(gsl::span<const int> bins);

protected:
  //----------------------------------------------------------------------------
  // Data members

  std::vector<int> bins_;

  std::unordered_map<int,int> map_;

};

} // namespace openmc
#endif // OPENMC_TALLIES_FILTER_COLLISIONS_H


/****************************************************************************
 *                                                                          *
 *  Author : lukasz.iwaszkiewicz@gmail.com                                  *
 *  ~~~~~~~~                                                                *
 *  License : see COPYING file for details.                                 *
 *  ~~~~~~~~~                                                               *
 ****************************************************************************/

#pragma once
#include <chrono>
#include <cstdint>
#include <gsl/gsl>
#include <iostream>
#include <vector>

namespace tp {
class CanFrame;

/**
 * @brief The TimeProvider struct
 * TODO if I'm not mistaken, those classes ought to have 100µs resolutiuon instead of 1ms (1000µs).
 */
struct ChronoTimeProvider {
        long operator() () const
        {
                using namespace std::chrono;
                system_clock::time_point now = system_clock::now ();
                auto duration = now.time_since_epoch ();
                return duration_cast<milliseconds> (duration).count ();
        }
};

struct CoutPrinter {
        template <typename T> void operator() (T &&a) { std::cout << std::forward<T> (a) << std::endl; }
};

/**
 * Buffer for all input and ouptut operations
 */
using IsoMessage = std::vector<uint8_t>;

} // namespace tp


#pragma once

#include <gsl/gsl>
#include <DirectXMath.h>
#include <vector>
#include <memory>
#include <string>
#include <cstdint>

namespace Library
{
	class Model;
	class Bone;
	class Keyframe;
	class OutputStreamHelper;
	class InputStreamHelper;

	struct BoneAnimationData final
	{
		std::uint32_t BoneIndex{ 0 };
		std::vector<std::shared_ptr<Keyframe>> Keyframes;
	};

    class BoneAnimation final
    {
    public:
		BoneAnimation(Model& model, InputStreamHelper& streamHelper);
		BoneAnimation(Model& model, const BoneAnimationData& boneAnimationData);
		BoneAnimation(Model& model, BoneAnimationData&& boneAnimationData);
		BoneAnimation(const BoneAnimation&) = default;
		BoneAnimation(BoneAnimation&& rhs) = default;
		BoneAnimation& operator=(const BoneAnimation& rhs) = default;
		BoneAnimation& operator=(BoneAnimation&& rhs) = default;
		~BoneAnimation() = default;

		Bone& GetBone();
		std::vector<std::shared_ptr<Keyframe>>& Keyframes();

		std::uint32_t GetTransform(float time, DirectX::XMFLOAT4X4& transform) const;
		void GetTransformAtKeyframe(std::uint32_t keyframeIndex, DirectX::XMFLOAT4X4& transform) const;
		void GetInteropolatedTransform(float time, DirectX::XMFLOAT4X4& transform) const;

		void Save(OutputStreamHelper& streamHelper);

    private:
		void Load(InputStreamHelper& streamHelper);
		std::uint32_t FindKeyframeIndex(float time) const;

		Model* mModel;
		std::weak_ptr<Bone> mBone;
		std::vector<std::shared_ptr<Keyframe>> mKeyframes;
    };
}


/* vector/gsl_vector_uint.h
 *
 * Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007 Gerard Jungman, Brian Gough
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU 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
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 */

#ifndef __GSL_VECTOR_UINT_H__
#define __GSL_VECTOR_UINT_H__

#if !defined( GSL_FUN )
#  if !defined( GSL_DLL )
#    define GSL_FUN extern
#  elif defined( BUILD_GSL_DLL )
#    define GSL_FUN extern __declspec(dllexport)
#  else
#    define GSL_FUN extern __declspec(dllimport)
#  endif
#endif

#include <stdlib.h>
#include <gsl/gsl_types.h>
#include <gsl/gsl_errno.h>
#include <gsl/gsl_inline.h>
#include <gsl/gsl_check_range.h>
#include <gsl/gsl_block_uint.h>

#undef __BEGIN_DECLS
#undef __END_DECLS
#ifdef __cplusplus
# define __BEGIN_DECLS extern "C" {
# define __END_DECLS }
#else
# define __BEGIN_DECLS /* empty */
# define __END_DECLS /* empty */
#endif

__BEGIN_DECLS

typedef struct
{
  size_t size;
  size_t stride;
  unsigned int *data;
  gsl_block_uint *block;
  int owner;
}
gsl_vector_uint;

typedef struct
{
  gsl_vector_uint vector;
} _gsl_vector_uint_view;

typedef _gsl_vector_uint_view gsl_vector_uint_view;

typedef struct
{
  gsl_vector_uint vector;
} _gsl_vector_uint_const_view;

typedef const _gsl_vector_uint_const_view gsl_vector_uint_const_view;

/* Allocation */

GSL_FUN gsl_vector_uint *gsl_vector_uint_alloc (const size_t n);
GSL_FUN gsl_vector_uint *gsl_vector_uint_calloc (const size_t n);

GSL_FUN gsl_vector_uint *gsl_vector_uint_alloc_from_block (gsl_block_uint * b,
                                                     const size_t offset,
                                                     const size_t n,
                                                     const size_t stride);

GSL_FUN gsl_vector_uint *gsl_vector_uint_alloc_from_vector (gsl_vector_uint * v,
                                                      const size_t offset,
                                                      const size_t n,
                                                      const size_t stride);

GSL_FUN void gsl_vector_uint_free (gsl_vector_uint * v);

/* Views */

GSL_FUN _gsl_vector_uint_view
gsl_vector_uint_view_array (unsigned int *v, size_t n);

GSL_FUN _gsl_vector_uint_view
gsl_vector_uint_view_array_with_stride (unsigned int *base,
                                         size_t stride,
                                         size_t n);

GSL_FUN _gsl_vector_uint_const_view
gsl_vector_uint_const_view_array (const unsigned int *v, size_t n);

GSL_FUN _gsl_vector_uint_const_view
gsl_vector_uint_const_view_array_with_stride (const unsigned int *base,
                                               size_t stride,
                                               size_t n);

GSL_FUN _gsl_vector_uint_view
gsl_vector_uint_subvector (gsl_vector_uint *v,
                            size_t i,
                            size_t n);

GSL_FUN _gsl_vector_uint_view
gsl_vector_uint_subvector_with_stride (gsl_vector_uint *v,
                                        size_t i,
                                        size_t stride,
                                        size_t n);

GSL_FUN _gsl_vector_uint_const_view
gsl_vector_uint_const_subvector (const gsl_vector_uint *v,
                                  size_t i,
                                  size_t n);

GSL_FUN _gsl_vector_uint_const_view
gsl_vector_uint_const_subvector_with_stride (const gsl_vector_uint *v,
                                              size_t i,
                                              size_t stride,
                                              size_t n);

/* Operations */

GSL_FUN void gsl_vector_uint_set_zero (gsl_vector_uint * v);
GSL_FUN void gsl_vector_uint_set_all (gsl_vector_uint * v, unsigned int x);
GSL_FUN int gsl_vector_uint_set_basis (gsl_vector_uint * v, size_t i);

GSL_FUN int gsl_vector_uint_fread (FILE * stream, gsl_vector_uint * v);
GSL_FUN int gsl_vector_uint_fwrite (FILE * stream, const gsl_vector_uint * v);
GSL_FUN int gsl_vector_uint_fscanf (FILE * stream, gsl_vector_uint * v);
GSL_FUN int gsl_vector_uint_fprintf (FILE * stream, const gsl_vector_uint * v,
                              const char *format);

GSL_FUN int gsl_vector_uint_memcpy (gsl_vector_uint * dest, const gsl_vector_uint * src);

GSL_FUN int gsl_vector_uint_reverse (gsl_vector_uint * v);

GSL_FUN int gsl_vector_uint_swap (gsl_vector_uint * v, gsl_vector_uint * w);
GSL_FUN int gsl_vector_uint_swap_elements (gsl_vector_uint * v, const size_t i, const size_t j);

GSL_FUN unsigned int gsl_vector_uint_max (const gsl_vector_uint * v);
GSL_FUN unsigned int gsl_vector_uint_min (const gsl_vector_uint * v);
GSL_FUN void gsl_vector_uint_minmax (const gsl_vector_uint * v, unsigned int * min_out, unsigned int * max_out);

GSL_FUN size_t gsl_vector_uint_max_index (const gsl_vector_uint * v);
GSL_FUN size_t gsl_vector_uint_min_index (const gsl_vector_uint * v);
GSL_FUN void gsl_vector_uint_minmax_index (const gsl_vector_uint * v, size_t * imin, size_t * imax);

GSL_FUN int gsl_vector_uint_add (gsl_vector_uint * a, const gsl_vector_uint * b);
GSL_FUN int gsl_vector_uint_sub (gsl_vector_uint * a, const gsl_vector_uint * b);
GSL_FUN int gsl_vector_uint_mul (gsl_vector_uint * a, const gsl_vector_uint * b);
GSL_FUN int gsl_vector_uint_div (gsl_vector_uint * a, const gsl_vector_uint * b);
GSL_FUN int gsl_vector_uint_scale (gsl_vector_uint * a, const unsigned int x);
GSL_FUN int gsl_vector_uint_add_constant (gsl_vector_uint * a, const double x);
GSL_FUN int gsl_vector_uint_axpby (const unsigned int alpha, const gsl_vector_uint * x, const unsigned int beta, gsl_vector_uint * y);
GSL_FUN unsigned int gsl_vector_uint_sum (const gsl_vector_uint * a);

GSL_FUN int gsl_vector_uint_equal (const gsl_vector_uint * u,
                            const gsl_vector_uint * v);

GSL_FUN int gsl_vector_uint_isnull (const gsl_vector_uint * v);
GSL_FUN int gsl_vector_uint_ispos (const gsl_vector_uint * v);
GSL_FUN int gsl_vector_uint_isneg (const gsl_vector_uint * v);
GSL_FUN int gsl_vector_uint_isnonneg (const gsl_vector_uint * v);

GSL_FUN INLINE_DECL unsigned int gsl_vector_uint_get (const gsl_vector_uint * v, const size_t i);
GSL_FUN INLINE_DECL void gsl_vector_uint_set (gsl_vector_uint * v, const size_t i, unsigned int x);
GSL_FUN INLINE_DECL unsigned int * gsl_vector_uint_ptr (gsl_vector_uint * v, const size_t i);
GSL_FUN INLINE_DECL const unsigned int * gsl_vector_uint_const_ptr (const gsl_vector_uint * v, const size_t i);

#ifdef HAVE_INLINE

INLINE_FUN
unsigned int
gsl_vector_uint_get (const gsl_vector_uint * v, const size_t i)
{
#if GSL_RANGE_CHECK
  if (GSL_RANGE_COND(i >= v->size))
    {
      GSL_ERROR_VAL ("index out of range", GSL_EINVAL, 0);
    }
#endif
  return v->data[i * v->stride];
}

INLINE_FUN
void
gsl_vector_uint_set (gsl_vector_uint * v, const size_t i, unsigned int x)
{
#if GSL_RANGE_CHECK
  if (GSL_RANGE_COND(i >= v->size))
    {
      GSL_ERROR_VOID ("index out of range", GSL_EINVAL);
    }
#endif
  v->data[i * v->stride] = x;
}

INLINE_FUN
unsigned int *
gsl_vector_uint_ptr (gsl_vector_uint * v, const size_t i)
{
#if GSL_RANGE_CHECK
  if (GSL_RANGE_COND(i >= v->size))
    {
      GSL_ERROR_NULL ("index out of range", GSL_EINVAL);
    }
#endif
  return (unsigned int *) (v->data + i * v->stride);
}

INLINE_FUN
const unsigned int *
gsl_vector_uint_const_ptr (const gsl_vector_uint * v, const size_t i)
{
#if GSL_RANGE_CHECK
  if (GSL_RANGE_COND(i >= v->size))
    {
      GSL_ERROR_NULL ("index out of range", GSL_EINVAL);
    }
#endif
  return (const unsigned int *) (v->data + i * v->stride);
}
#endif /* HAVE_INLINE */

__END_DECLS

#endif /* __GSL_VECTOR_UINT_H__ */


#ifndef __RNG_H__
#define __RNG_H__
#include <gsl/gsl_rng.h>
extern const gsl_rng_type *rng_T;
extern gsl_rng *rng_R;
#endif


// Copyright 2019 John McFarlane
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#ifndef WSS_BOARD_PREMIUMS_H
#define WSS_BOARD_PREMIUMS_H

#include <gsl/string_span>

#include "board.h"

enum class premium {
    normal,
    dl,
    tl,
    dw,
    tw
};

constexpr std::array<int, 5> letter_multipliers {
        1,
        2,
        3,
        1,
        1
};

constexpr std::array<int, 5> word_multipliers {
        1,
        1,
        1,
        2,
        3
};

auto load_board_premiums(gsl::cstring_span<> filename)
-> std::optional<board<premium>>;

#endif //WSS_BOARD_PREMIUMS_H


#ifndef __e23673_LIBRARIES_H
#define __e23673_LIBRARIES_H

#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <limits.h>

/* GNU Scientific library: */
#include <gsl/gsl_rng.h>

#include "parsing.h"
#include "dev_random.h"
#include "mersenne_twister.h"
#include "random_numbers.h"

#endif


#pragma once

#include <gsl\gsl>
#include <winrt\Windows.Foundation.h>
#include <d3d11.h>
#include "DrawableGameComponent.h"
#include "MatrixHelper.h"
#include "PointLight.h"

namespace Rendering
{
	class EnvironmentMappingMaterial;

	class EnvironmentMappingDemo final : public Library::DrawableGameComponent
	{
	public:
		EnvironmentMappingDemo(Library::Game& game, const std::shared_ptr<Library::Camera>& camera);
		EnvironmentMappingDemo(const EnvironmentMappingDemo&) = delete;
		EnvironmentMappingDemo(EnvironmentMappingDemo&&) = default;
		EnvironmentMappingDemo& operator=(const EnvironmentMappingDemo&) = default;
		EnvironmentMappingDemo& operator=(EnvironmentMappingDemo&&) = default;
		~EnvironmentMappingDemo();

		float AmbientLightIntensity() const;
		void SetAmbientLightIntensity(float intensity);

		float EnvironmentIntensity() const;
		void SetEnvironmentIntensity(float intensity);

		float ReflectionAmount() const;
		void SetReflectionAmount(float amount);

		virtual void Initialize() override;
		virtual void Draw(const Library::GameTime& gameTime) override;

	private:
		inline static const float RotationRate{ DirectX::XM_PI };

		std::shared_ptr<EnvironmentMappingMaterial> mMaterial;
		DirectX::XMFLOAT4X4 mWorldMatrix{ Library::MatrixHelper::Identity };
		winrt::com_ptr<ID3D11Buffer> mVertexBuffer;
		winrt::com_ptr<ID3D11Buffer> mIndexBuffer;
		std::uint32_t mIndexCount{ 0 };
		bool mUpdateMaterial{ true };
	};
}