// Copyright (c) The NodeRT Contributors
// All rights reserved.
//
// 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
//
// THIS CODE IS PROVIDED ON AN  *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS
// OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY
// IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
// MERCHANTABLITY OR NON-INFRINGEMENT.
//
// See the Apache Version 2.0 License for specific language governing permissions
// and limitations under the License.

// TODO: Verify that this is is still needed..
#define NTDDI_VERSION 0x06010000

#include <v8.h>
#include "nan.h"
#include <string>
#include <ppltasks.h>
#include "CollectionsConverter.h"
#include "CollectionsWrap.h"
#include "node-async.h"
#include "NodeRtUtils.h"
#include "OpaqueWrapper.h"
#include "WrapperBase.h"

#using <Windows.WinMD>

// this undefs fixes the issues of compiling Windows.Data.Json, Windows.Storag.FileProperties, and Windows.Stroage.Search
// Some of the node header files brings windows definitions with the same names as some of the WinRT methods
#undef DocumentProperties
#undef GetObject
#undef CreateEvent
#undef FindText
#undef SendMessage

const char* REGISTRATION_TOKEN_MAP_PROPERTY_NAME = "__registrationTokenMap__";

using v8::Array;
using v8::String;
using v8::Value;
using v8::Boolean;
using v8::Integer;
using v8::FunctionTemplate;
using v8::Object;
using v8::Local;
using v8::Function;
using v8::Date;
using v8::Number;
using v8::PropertyAttribute;
using v8::Primitive;
using Nan::HandleScope;
using Nan::Persistent;
using Nan::Undefined;
using Nan::True;
using Nan::False;
using Nan::Null;
using Nan::MaybeLocal;
using Nan::EscapableHandleScope;
using Nan::HandleScope;
using Nan::TryCatch;
using namespace concurrency;

namespace NodeRT { namespace Windows { namespace Graphics { namespace DirectX { 



  static void InitDirectXAlphaModeEnum(const Local<Object> exports) {
    HandleScope scope;

    Local<Object> enumObject = Nan::New<Object>();

    Nan::Set(exports, Nan::New<String>("DirectXAlphaMode").ToLocalChecked(), enumObject);
    Nan::Set(enumObject, Nan::New<String>("unspecified").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXAlphaMode::Unspecified)));
    Nan::Set(enumObject, Nan::New<String>("premultiplied").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXAlphaMode::Premultiplied)));
    Nan::Set(enumObject, Nan::New<String>("straight").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXAlphaMode::Straight)));
    Nan::Set(enumObject, Nan::New<String>("ignore").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXAlphaMode::Ignore)));
  }

  static void InitDirectXPixelFormatEnum(const Local<Object> exports) {
    HandleScope scope;

    Local<Object> enumObject = Nan::New<Object>();

    Nan::Set(exports, Nan::New<String>("DirectXPixelFormat").ToLocalChecked(), enumObject);
    Nan::Set(enumObject, Nan::New<String>("unknown").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::Unknown)));
    Nan::Set(enumObject, Nan::New<String>("r32G32B32A32Typeless").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R32G32B32A32Typeless)));
    Nan::Set(enumObject, Nan::New<String>("r32G32B32A32Float").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R32G32B32A32Float)));
    Nan::Set(enumObject, Nan::New<String>("r32G32B32A32UInt").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R32G32B32A32UInt)));
    Nan::Set(enumObject, Nan::New<String>("r32G32B32A32Int").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R32G32B32A32Int)));
    Nan::Set(enumObject, Nan::New<String>("r32G32B32Typeless").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R32G32B32Typeless)));
    Nan::Set(enumObject, Nan::New<String>("r32G32B32Float").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R32G32B32Float)));
    Nan::Set(enumObject, Nan::New<String>("r32G32B32UInt").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R32G32B32UInt)));
    Nan::Set(enumObject, Nan::New<String>("r32G32B32Int").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R32G32B32Int)));
    Nan::Set(enumObject, Nan::New<String>("r16G16B16A16Typeless").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R16G16B16A16Typeless)));
    Nan::Set(enumObject, Nan::New<String>("r16G16B16A16Float").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R16G16B16A16Float)));
    Nan::Set(enumObject, Nan::New<String>("r16G16B16A16UIntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R16G16B16A16UIntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("r16G16B16A16UInt").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R16G16B16A16UInt)));
    Nan::Set(enumObject, Nan::New<String>("r16G16B16A16IntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R16G16B16A16IntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("r16G16B16A16Int").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R16G16B16A16Int)));
    Nan::Set(enumObject, Nan::New<String>("r32G32Typeless").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R32G32Typeless)));
    Nan::Set(enumObject, Nan::New<String>("r32G32Float").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R32G32Float)));
    Nan::Set(enumObject, Nan::New<String>("r32G32UInt").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R32G32UInt)));
    Nan::Set(enumObject, Nan::New<String>("r32G32Int").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R32G32Int)));
    Nan::Set(enumObject, Nan::New<String>("r32G8X24Typeless").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R32G8X24Typeless)));
    Nan::Set(enumObject, Nan::New<String>("d32FloatS8X24UInt").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::D32FloatS8X24UInt)));
    Nan::Set(enumObject, Nan::New<String>("r32FloatX8X24Typeless").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R32FloatX8X24Typeless)));
    Nan::Set(enumObject, Nan::New<String>("x32TypelessG8X24UInt").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::X32TypelessG8X24UInt)));
    Nan::Set(enumObject, Nan::New<String>("r10G10B10A2Typeless").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R10G10B10A2Typeless)));
    Nan::Set(enumObject, Nan::New<String>("r10G10B10A2UIntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R10G10B10A2UIntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("r10G10B10A2UInt").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R10G10B10A2UInt)));
    Nan::Set(enumObject, Nan::New<String>("r11G11B10Float").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R11G11B10Float)));
    Nan::Set(enumObject, Nan::New<String>("r8G8B8A8Typeless").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R8G8B8A8Typeless)));
    Nan::Set(enumObject, Nan::New<String>("r8G8B8A8UIntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R8G8B8A8UIntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("r8G8B8A8UIntNormalizedSrgb").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R8G8B8A8UIntNormalizedSrgb)));
    Nan::Set(enumObject, Nan::New<String>("r8G8B8A8UInt").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R8G8B8A8UInt)));
    Nan::Set(enumObject, Nan::New<String>("r8G8B8A8IntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R8G8B8A8IntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("r8G8B8A8Int").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R8G8B8A8Int)));
    Nan::Set(enumObject, Nan::New<String>("r16G16Typeless").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R16G16Typeless)));
    Nan::Set(enumObject, Nan::New<String>("r16G16Float").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R16G16Float)));
    Nan::Set(enumObject, Nan::New<String>("r16G16UIntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R16G16UIntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("r16G16UInt").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R16G16UInt)));
    Nan::Set(enumObject, Nan::New<String>("r16G16IntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R16G16IntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("r16G16Int").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R16G16Int)));
    Nan::Set(enumObject, Nan::New<String>("r32Typeless").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R32Typeless)));
    Nan::Set(enumObject, Nan::New<String>("d32Float").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::D32Float)));
    Nan::Set(enumObject, Nan::New<String>("r32Float").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R32Float)));
    Nan::Set(enumObject, Nan::New<String>("r32UInt").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R32UInt)));
    Nan::Set(enumObject, Nan::New<String>("r32Int").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R32Int)));
    Nan::Set(enumObject, Nan::New<String>("r24G8Typeless").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R24G8Typeless)));
    Nan::Set(enumObject, Nan::New<String>("d24UIntNormalizedS8UInt").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::D24UIntNormalizedS8UInt)));
    Nan::Set(enumObject, Nan::New<String>("r24UIntNormalizedX8Typeless").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R24UIntNormalizedX8Typeless)));
    Nan::Set(enumObject, Nan::New<String>("x24TypelessG8UInt").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::X24TypelessG8UInt)));
    Nan::Set(enumObject, Nan::New<String>("r8G8Typeless").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R8G8Typeless)));
    Nan::Set(enumObject, Nan::New<String>("r8G8UIntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R8G8UIntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("r8G8UInt").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R8G8UInt)));
    Nan::Set(enumObject, Nan::New<String>("r8G8IntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R8G8IntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("r8G8Int").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R8G8Int)));
    Nan::Set(enumObject, Nan::New<String>("r16Typeless").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R16Typeless)));
    Nan::Set(enumObject, Nan::New<String>("r16Float").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R16Float)));
    Nan::Set(enumObject, Nan::New<String>("d16UIntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::D16UIntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("r16UIntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R16UIntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("r16UInt").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R16UInt)));
    Nan::Set(enumObject, Nan::New<String>("r16IntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R16IntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("r16Int").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R16Int)));
    Nan::Set(enumObject, Nan::New<String>("r8Typeless").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R8Typeless)));
    Nan::Set(enumObject, Nan::New<String>("r8UIntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R8UIntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("r8UInt").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R8UInt)));
    Nan::Set(enumObject, Nan::New<String>("r8IntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R8IntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("r8Int").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R8Int)));
    Nan::Set(enumObject, Nan::New<String>("a8UIntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::A8UIntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("r1UIntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R1UIntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("r9G9B9E5SharedExponent").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R9G9B9E5SharedExponent)));
    Nan::Set(enumObject, Nan::New<String>("r8G8B8G8UIntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R8G8B8G8UIntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("g8R8G8B8UIntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::G8R8G8B8UIntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("bC1Typeless").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::BC1Typeless)));
    Nan::Set(enumObject, Nan::New<String>("bC1UIntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::BC1UIntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("bC1UIntNormalizedSrgb").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::BC1UIntNormalizedSrgb)));
    Nan::Set(enumObject, Nan::New<String>("bC2Typeless").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::BC2Typeless)));
    Nan::Set(enumObject, Nan::New<String>("bC2UIntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::BC2UIntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("bC2UIntNormalizedSrgb").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::BC2UIntNormalizedSrgb)));
    Nan::Set(enumObject, Nan::New<String>("bC3Typeless").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::BC3Typeless)));
    Nan::Set(enumObject, Nan::New<String>("bC3UIntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::BC3UIntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("bC3UIntNormalizedSrgb").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::BC3UIntNormalizedSrgb)));
    Nan::Set(enumObject, Nan::New<String>("bC4Typeless").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::BC4Typeless)));
    Nan::Set(enumObject, Nan::New<String>("bC4UIntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::BC4UIntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("bC4IntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::BC4IntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("bC5Typeless").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::BC5Typeless)));
    Nan::Set(enumObject, Nan::New<String>("bC5UIntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::BC5UIntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("bC5IntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::BC5IntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("b5G6R5UIntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::B5G6R5UIntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("b5G5R5A1UIntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::B5G5R5A1UIntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("b8G8R8A8UIntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::B8G8R8A8UIntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("b8G8R8X8UIntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::B8G8R8X8UIntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("r10G10B10XRBiasA2UIntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::R10G10B10XRBiasA2UIntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("b8G8R8A8Typeless").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::B8G8R8A8Typeless)));
    Nan::Set(enumObject, Nan::New<String>("b8G8R8A8UIntNormalizedSrgb").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::B8G8R8A8UIntNormalizedSrgb)));
    Nan::Set(enumObject, Nan::New<String>("b8G8R8X8Typeless").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::B8G8R8X8Typeless)));
    Nan::Set(enumObject, Nan::New<String>("b8G8R8X8UIntNormalizedSrgb").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::B8G8R8X8UIntNormalizedSrgb)));
    Nan::Set(enumObject, Nan::New<String>("bC6HTypeless").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::BC6HTypeless)));
    Nan::Set(enumObject, Nan::New<String>("bC6H16UnsignedFloat").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::BC6H16UnsignedFloat)));
    Nan::Set(enumObject, Nan::New<String>("bC6H16Float").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::BC6H16Float)));
    Nan::Set(enumObject, Nan::New<String>("bC7Typeless").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::BC7Typeless)));
    Nan::Set(enumObject, Nan::New<String>("bC7UIntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::BC7UIntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("bC7UIntNormalizedSrgb").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::BC7UIntNormalizedSrgb)));
    Nan::Set(enumObject, Nan::New<String>("ayuv").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::Ayuv)));
    Nan::Set(enumObject, Nan::New<String>("y410").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::Y410)));
    Nan::Set(enumObject, Nan::New<String>("y416").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::Y416)));
    Nan::Set(enumObject, Nan::New<String>("nV12").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::NV12)));
    Nan::Set(enumObject, Nan::New<String>("p010").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::P010)));
    Nan::Set(enumObject, Nan::New<String>("p016").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::P016)));
    Nan::Set(enumObject, Nan::New<String>("opaque420").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::Opaque420)));
    Nan::Set(enumObject, Nan::New<String>("yuy2").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::Yuy2)));
    Nan::Set(enumObject, Nan::New<String>("y210").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::Y210)));
    Nan::Set(enumObject, Nan::New<String>("y216").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::Y216)));
    Nan::Set(enumObject, Nan::New<String>("nV11").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::NV11)));
    Nan::Set(enumObject, Nan::New<String>("aI44").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::AI44)));
    Nan::Set(enumObject, Nan::New<String>("iA44").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::IA44)));
    Nan::Set(enumObject, Nan::New<String>("p8").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::P8)));
    Nan::Set(enumObject, Nan::New<String>("a8P8").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::A8P8)));
    Nan::Set(enumObject, Nan::New<String>("b4G4R4A4UIntNormalized").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::B4G4R4A4UIntNormalized)));
    Nan::Set(enumObject, Nan::New<String>("p208").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::P208)));
    Nan::Set(enumObject, Nan::New<String>("v208").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::V208)));
    Nan::Set(enumObject, Nan::New<String>("v408").ToLocalChecked(), Nan::New<Integer>(static_cast<int>(::Windows::Graphics::DirectX::DirectXPixelFormat::V408)));
  }




} } } } 

NAN_MODULE_INIT(init) {
  // We ignore failures for now since it probably means that
  // the initialization already happened for STA, and that's cool

  CoInitializeEx(nullptr, COINIT_MULTITHREADED);

  /*
  if (FAILED(CoInitializeEx(nullptr, COINIT_MULTITHREADED))) {
    Nan::ThrowError(Nan::Error(NodeRT::Utils::NewString(L"error in CoInitializeEx()")));
    return;
  }
  */

      NodeRT::Windows::Graphics::DirectX::InitDirectXAlphaModeEnum(target);
      NodeRT::Windows::Graphics::DirectX::InitDirectXPixelFormatEnum(target);


  NodeRT::Utils::RegisterNameSpace("Windows.Graphics.DirectX", target);
}



NODE_MODULE(binding, init)
