// Copyright 2017 The Dawn Authors
//
// 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.

// Enable this before including any headers as we want inttypes.h to define
// format macros such as PRId64 that are used in picojson.
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif

#include "../SampleUtils.h"

#include "common/Assert.h"
#include "common/Math.h"
#include "common/Constants.h"
#include "utils/ComboRenderPipelineDescriptor.h"
#include "utils/DawnHelpers.h"
#include "utils/SystemUtils.h"

#include <bitset>
#define GLM_FORCE_DEPTH_ZERO_TO_ONE
#include <glm/mat4x4.hpp>
#include <glm/gtc/matrix_inverse.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>

#define TINYGLTF_LOADER_IMPLEMENTATION
#define STB_IMAGE_IMPLEMENTATION
#define PICOJSON_ASSERT ASSERT
#undef __STDC_FORMAT_MACROS
#include <tinygltfloader/tiny_gltf_loader.h>

#include "GLFW/glfw3.h"

#include "Camera.inl"

namespace gl {
    enum {
        Triangles = 0x0004,
        UnsignedShort = 0x1403,
        UnsignedInt = 0x1405,
        Float = 0x1406,
        RGBA = 0x1908,
        Nearest = 0x2600,
        Linear = 0x2601,
        NearestMipmapNearest = 0x2700,
        LinearMipmapNearest = 0x2701,
        NearestMipmapLinear = 0x2702,
        LinearMipmapLinear = 0x2703,
        ArrayBuffer = 0x8892,
        ElementArrayBuffer = 0x8893,
        FragmentShader = 0x8B30,
        VertexShader = 0x8B31,
        FloatVec2 = 0x8B50,
        FloatVec3 = 0x8B51,
        FloatVec4 = 0x8B52,
    };
}

struct MaterialInfo {
    dawn::RenderPipeline pipeline;
    dawn::BindGroup bindGroup0;
    std::map<uint32_t, std::string> slotSemantics;
};

struct u_transform_block {
    glm::mat4 modelViewProj;
    glm::mat4 modelInvTr;
};

dawn::Device device;
dawn::Queue queue;
dawn::SwapChain swapchain;
dawn::TextureView depthStencilView;

dawn::Buffer defaultBuffer;
std::map<std::string, dawn::Buffer> buffers;
std::map<std::string, dawn::CommandBuffer> commandBuffers;
std::map<uint32_t, std::string> slotSemantics = {{0, "POSITION"}, {1, "NORMAL"}, {2, "TEXCOORD_0"}};

std::map<std::string, dawn::Sampler> samplers;
std::map<std::string, dawn::TextureView> textures;

tinygltf::Scene scene;
glm::mat4 projection = glm::perspective(glm::radians(60.f), 640.f/480, 0.1f, 2000.f);
Camera camera;

// Helpers
namespace {
    std::string getFilePathExtension(const std::string &FileName) {
        if (FileName.find_last_of(".") != std::string::npos) {
            return FileName.substr(FileName.find_last_of(".") + 1);
        }
        return "";
    }

    bool techniqueParameterTypeToVertexFormat(int type, dawn::VertexFormat *format) {
        switch (type) {
            case gl::FloatVec2:
                *format = dawn::VertexFormat::Float2;
                return true;
            case gl::FloatVec3:
                *format = dawn::VertexFormat::Float3;
                return true;
            case gl::FloatVec4:
                *format = dawn::VertexFormat::Float4;
                return true;
            default:
                return false;
        }
    }
}

// Initialization
namespace {
    void initBuffers() {
        dawn::BufferDescriptor descriptor;
        descriptor.size = 256;
        descriptor.usage = dawn::BufferUsageBit::Vertex | dawn::BufferUsageBit::Index;
        defaultBuffer = device.CreateBuffer(&descriptor);

        for (const auto& bv : scene.bufferViews) {
            const auto& iBufferViewID = bv.first;
            const auto& iBufferView = bv.second;

            dawn::BufferUsageBit usage = dawn::BufferUsageBit::None;
            switch (iBufferView.target) {
                case gl::ArrayBuffer:
                    usage |= dawn::BufferUsageBit::Vertex;
                    break;
                case gl::ElementArrayBuffer:
                    usage |= dawn::BufferUsageBit::Index;
                    break;
                case 0:
                    fprintf(stderr, "TODO: buffer view has no target; skipping\n");
                    continue;
                default:
                    fprintf(stderr, "unsupported buffer view target %d\n", iBufferView.target);
                    continue;
            }
            const auto& iBuffer = scene.buffers.at(iBufferView.buffer);

            size_t iBufferViewSize =
                iBufferView.byteLength ? iBufferView.byteLength :
                (iBuffer.data.size() - iBufferView.byteOffset);
            auto oBuffer = utils::CreateBufferFromData(device, &iBuffer.data.at(iBufferView.byteOffset), static_cast<uint32_t>(iBufferViewSize), usage);
            buffers[iBufferViewID] = std::move(oBuffer);
        }
    }

    const MaterialInfo& getMaterial(const std::string& iMaterialID, size_t stridePos, size_t strideNor, size_t strideTxc) {
        static std::map<std::tuple<std::string, size_t, size_t, size_t>, MaterialInfo> materials;
        auto key = make_tuple(iMaterialID, stridePos, strideNor, strideTxc);
        auto materialIterator = materials.find(key);
        if (materialIterator != materials.end()) {
            return materialIterator->second;
        }

        const auto& iMaterial = scene.materials.at(iMaterialID);
        const auto& iTechnique = scene.techniques.at(iMaterial.technique);

        bool hasTexture = false;
        std::string iTextureID;
        {
            auto it = iMaterial.values.find("diffuse");
            if (it != iMaterial.values.end() && !it->second.string_value.empty()) {
                hasTexture = true;
                iTextureID = it->second.string_value;
            }
        }

        auto oVSModule = utils::CreateShaderModule(device, dawn::ShaderStage::Vertex, R"(
            #version 450

            layout(push_constant) uniform u_transform_block {
                mat4 modelViewProj;
                mat4 modelInvTr;
            } u_transform;

            layout(location = 0) in vec4 a_position;
            layout(location = 1) in vec3 a_normal;
            layout(location = 2) in vec2 a_texcoord;

            layout(location = 0) out vec3 v_normal;
            layout(location = 1) out vec2 v_texcoord;

            void main() {
                v_normal = (u_transform.modelInvTr * vec4(normalize(a_normal), 0)).rgb;
                v_texcoord = a_texcoord;
                gl_Position = u_transform.modelViewProj * a_position;
            })");

        auto oFSSourceTextured = R"(
            #version 450

            layout(set = 0, binding = 0) uniform sampler u_samp;
            layout(set = 0, binding = 1) uniform texture2D u_tex;

            layout(location = 0) in vec3 v_normal;
            layout(location = 1) in vec2 v_texcoord;

            layout(location = 0) out vec4 fragcolor;

            void main() {
                const vec3 lightdir = normalize(vec3(-1, -2, 3));
                vec3 normal = normalize(v_normal);
                float diffuse = abs(dot(lightdir, normal));
                float diffamb = diffuse * 0.85 + 0.15;
                vec3 albedo = texture(sampler2D(u_tex, u_samp), v_texcoord).rgb;
                fragcolor = vec4(diffamb * albedo, 1);
            })";
        auto oFSSourceUntextured = R"(
            #version 450

            layout(location = 0) in vec3 v_normal;
            layout(location = 1) in vec2 v_texcoord;

            layout(location = 0) out vec4 fragcolor;

            void main() {
                const vec3 lightdir = normalize(vec3(-1, -2, 3));
                vec3 normal = normalize(v_normal);
                float diffuse = abs(dot(lightdir, normal));
                float diffamb = diffuse * 0.85 + 0.15;
                fragcolor = vec4(vec3(diffamb), 1);
            })";

        auto oFSModule = utils::CreateShaderModule(device, dawn::ShaderStage::Fragment, hasTexture ? oFSSourceTextured : oFSSourceUntextured);

        utils::ComboRenderPipelineDescriptor descriptor(device);
        descriptor.cInputState.indexFormat = dawn::IndexFormat::Uint16;
        uint32_t numAttributes = 0;
        uint32_t numInputs = 0;
        std::bitset<3> slotsSet;
        for (const auto& a : iTechnique.attributes) {
            const auto iAttributeName = a.first;
            const auto iParameter = iTechnique.parameters.at(a.second);
            dawn::VertexFormat format;
            if (!techniqueParameterTypeToVertexFormat(iParameter.type, &format)) {
                fprintf(stderr, "unsupported technique parameter type %d\n", iParameter.type);
                continue;
            }
            descriptor.cInputState.cAttributes[numAttributes].format = format;

            if (iParameter.semantic == "POSITION") {
                descriptor.cInputState.cInputs[numInputs].stride = static_cast<uint32_t>(stridePos);
                numAttributes++;
                numInputs++;
                slotsSet.set(0);
            } else if (iParameter.semantic == "NORMAL") {
                descriptor.cInputState.cAttributes[numAttributes].shaderLocation = 1;
                descriptor.cInputState.cAttributes[numAttributes].inputSlot = 1;
                descriptor.cInputState.cInputs[numInputs].inputSlot = 1;
                descriptor.cInputState.cInputs[numInputs].stride = static_cast<uint32_t>(strideNor);
                numAttributes++;
                numInputs++;
                slotsSet.set(1);
            } else if (iParameter.semantic == "TEXCOORD_0") {
                descriptor.cInputState.cAttributes[numAttributes].shaderLocation = 2;
                descriptor.cInputState.cAttributes[numAttributes].inputSlot = 2;
                descriptor.cInputState.cInputs[numInputs].inputSlot = 2;
                descriptor.cInputState.cInputs[numInputs].stride = static_cast<uint32_t>(strideTxc);
                numAttributes++;
                numInputs++;
                slotsSet.set(2);
            } else {
                fprintf(stderr, "unsupported technique attribute semantic %s\n", iParameter.semantic.c_str());
            }
        }
        for (uint32_t i = 0; i < slotsSet.size(); i++) {
            if (slotsSet[i]) {
                continue;
            }
            descriptor.cInputState.cAttributes[numAttributes].shaderLocation = i;
            descriptor.cInputState.cAttributes[numAttributes].inputSlot = i;
            descriptor.cInputState.cAttributes[numAttributes].format = dawn::VertexFormat::Float4;

            descriptor.cInputState.cInputs[numInputs].inputSlot = i;

            numAttributes++;
            numInputs++;
        }
        descriptor.cInputState.numAttributes = numAttributes;
        descriptor.cInputState.numInputs = numInputs;

        constexpr dawn::ShaderStageBit kNoStages{};
        dawn::BindGroupLayout bindGroupLayout = utils::MakeBindGroupLayout(
            device, {
                        {0, hasTexture ? dawn::ShaderStageBit::Fragment : kNoStages,
                         dawn::BindingType::Sampler},
                        {1, hasTexture ? dawn::ShaderStageBit::Fragment : kNoStages,
                         dawn::BindingType::SampledTexture},
                    });

        auto pipelineLayout = utils::MakeBasicPipelineLayout(device, &bindGroupLayout);

        descriptor.layout = pipelineLayout;
        descriptor.cVertexStage.module = oVSModule;
        descriptor.cFragmentStage.module = oFSModule;
        descriptor.depthStencilState = &descriptor.cDepthStencilState;
        descriptor.cDepthStencilState.format = dawn::TextureFormat::D32FloatS8Uint;
        descriptor.cColorStates[0]->format = GetPreferredSwapChainTextureFormat();
        descriptor.cDepthStencilState.depthWriteEnabled = true;
        descriptor.cDepthStencilState.depthCompare = dawn::CompareFunction::Less;

        dawn::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);

        dawn::BindGroup bindGroup;

        if (hasTexture) {
            const auto& textureView = textures[iTextureID];
            const auto& iSamplerID = scene.textures[iTextureID].sampler;
            bindGroup = utils::MakeBindGroup(device, bindGroupLayout, {
                {0, samplers[iSamplerID]},
                {1, textureView}
            });
        } else {
            bindGroup = utils::MakeBindGroup(device, bindGroupLayout, {});
        }

        MaterialInfo material = {
            pipeline,
            bindGroup,
            std::map<uint32_t, std::string>(),
        };
        materials[key] = std::move(material);
        return materials.at(key);
    }

    void initSamplers() {
        for (const auto& s : scene.samplers) {
            const auto& iSamplerID = s.first;
            const auto& iSampler = s.second;

            dawn::SamplerDescriptor desc = utils::GetDefaultSamplerDescriptor();
            // TODO: wrap modes

            switch (iSampler.magFilter) {
                case gl::Nearest:
                    desc.magFilter = dawn::FilterMode::Nearest;
                    break;
                case gl::Linear:
                    desc.magFilter = dawn::FilterMode::Linear;
                    break;
                default:
                    fprintf(stderr, "unsupported magFilter %d\n", iSampler.magFilter);
                    break;
            }
            switch (iSampler.minFilter) {
                case gl::Nearest:
                case gl::NearestMipmapNearest:
                case gl::NearestMipmapLinear:
                    desc.minFilter = dawn::FilterMode::Nearest;
                    break;
                case gl::Linear:
                case gl::LinearMipmapNearest:
                case gl::LinearMipmapLinear:
                    desc.minFilter = dawn::FilterMode::Linear;
                    break;
                default:
                    fprintf(stderr, "unsupported minFilter %d\n", iSampler.magFilter);
                    break;
            }
            switch (iSampler.minFilter) {
                case gl::NearestMipmapNearest:
                case gl::LinearMipmapNearest:
                    desc.mipmapFilter = dawn::FilterMode::Nearest;
                    break;
                case gl::NearestMipmapLinear:
                case gl::LinearMipmapLinear:
                    desc.mipmapFilter = dawn::FilterMode::Linear;
                    break;
            }

            samplers[iSamplerID] = device.CreateSampler(&desc);
        }
    }

    void initTextures() {
        for (const auto& t : scene.textures) {
            const auto& iTextureID = t.first;
            const auto& iTexture = t.second;
            const auto& iImage = scene.images[iTexture.source];

            dawn::TextureFormat format = dawn::TextureFormat::R8G8B8A8Unorm;
            switch (iTexture.format) {
                case gl::RGBA:
                    format = dawn::TextureFormat::R8G8B8A8Unorm;
                    break;
                default:
                    fprintf(stderr, "unsupported texture format %d\n", iTexture.format);
                    continue;
            }

            dawn::TextureDescriptor descriptor;
            descriptor.dimension = dawn::TextureDimension::e2D;
            descriptor.size.width = iImage.width;
            descriptor.size.height = iImage.height;
            descriptor.size.depth = 1;
            descriptor.arrayLayerCount = 1;
            descriptor.sampleCount = 1;
            descriptor.format = format;
            descriptor.mipLevelCount = 1;
            descriptor.usage = dawn::TextureUsageBit::TransferDst | dawn::TextureUsageBit::Sampled;
            auto oTexture = device.CreateTexture(&descriptor);
                // TODO: release this texture

            const uint8_t* origData = iImage.image.data();
            const uint8_t* data = nullptr;
            std::vector<uint8_t> newData;

            uint32_t width = static_cast<uint32_t>(iImage.width);
            uint32_t height = static_cast<uint32_t>(iImage.height);
            uint32_t rowSize = width * 4;
            uint32_t rowPitch = Align(rowSize, kTextureRowPitchAlignment);

            if (iImage.component == 3 || iImage.component == 4) {
                if (rowSize != rowPitch || iImage.component == 3) {
                    newData.resize(rowPitch * height);
                    uint32_t pixelsPerRow = rowPitch / 4;
                    for (uint32_t y = 0; y < height; ++y) {
                        for (uint32_t x = 0; x < width; ++x) {
                            size_t oldIndex = x + y * height;
                            size_t newIndex = x + y * pixelsPerRow;
                            if (iImage.component == 4) {
                                newData[4 * newIndex + 0] = origData[4 * oldIndex + 0];
                                newData[4 * newIndex + 1] = origData[4 * oldIndex + 1];
                                newData[4 * newIndex + 2] = origData[4 * oldIndex + 2];
                                newData[4 * newIndex + 3] = origData[4 * oldIndex + 3];
                            } else if (iImage.component == 3) {
                                newData[4 * newIndex + 0] = origData[3 * oldIndex + 0];
                                newData[4 * newIndex + 1] = origData[3 * oldIndex + 1];
                                newData[4 * newIndex + 2] = origData[3 * oldIndex + 2];
                                newData[4 * newIndex + 3] = 255;
                            }
                        }
                    }
                    data = newData.data();
                } else {
                    data = origData;
                }
            } else {
                fprintf(stderr, "unsupported image.component %d\n", iImage.component);
            }

            dawn::Buffer staging = utils::CreateBufferFromData(device, data, rowPitch * iImage.height, dawn::BufferUsageBit::TransferSrc);
            dawn::BufferCopyView bufferCopyView =
                utils::CreateBufferCopyView(staging, 0, rowPitch, 0);
            dawn::TextureCopyView textureCopyView =
                utils::CreateTextureCopyView(oTexture, 0, 0, {0, 0, 0});
            dawn::Extent3D copySize = {iImage.width, iImage.height, 1};

            dawn::CommandEncoder encoder = device.CreateCommandEncoder();
            encoder.CopyBufferToTexture(&bufferCopyView, &textureCopyView, &copySize);

            dawn::CommandBuffer cmdbuf = encoder.Finish();
            queue.Submit(1, &cmdbuf);

            textures[iTextureID] = oTexture.CreateDefaultView();
        }
    }

    void init() {
        device = CreateCppDawnDevice();

        queue = device.CreateQueue();
        swapchain = GetSwapChain(device);
        swapchain.Configure(GetPreferredSwapChainTextureFormat(),
                            dawn::TextureUsageBit::OutputAttachment, 640, 480);

        depthStencilView = CreateDefaultDepthStencilView(device);

        initBuffers();
        initSamplers();
        initTextures();
    }
}

// Drawing
namespace {
    void drawMesh(dawn::RenderPassEncoder& pass, const tinygltf::Mesh& iMesh, const glm::mat4& model) {
        for (const auto& iPrim : iMesh.primitives) {
            if (iPrim.mode != gl::Triangles) {
                fprintf(stderr, "unsupported primitive mode %d\n", iPrim.mode);
                continue;
            }

            u_transform_block transforms = {
                (projection * camera.view() * model),
                glm::inverseTranspose(model),
            };

            size_t strides[3] = {0};
            for (const auto& s : slotSemantics) {
                if (s.first < 3) {
                    auto it = iPrim.attributes.find(s.second);
                    if (it == iPrim.attributes.end()) {
                        continue;
                    }
                    const auto& iAccessorName = it->second;
                    strides[s.first] = scene.accessors.at(iAccessorName).byteStride;
                }
            }
            const MaterialInfo& material = getMaterial(iPrim.material, strides[0], strides[1], strides[2]);
            pass.SetPipeline(material.pipeline);
            pass.SetBindGroup(0, material.bindGroup0, 0, nullptr);
            pass.SetPushConstants(dawn::ShaderStageBit::Vertex,
                    0, sizeof(u_transform_block) / sizeof(uint32_t),
                    reinterpret_cast<const uint32_t*>(&transforms));

            uint32_t vertexCount = 0;
            for (const auto& s : slotSemantics) {
                uint32_t slot = s.first;
                auto it = iPrim.attributes.find(s.second);
                if (it == iPrim.attributes.end()) {
                    uint64_t zero = 0;
                    pass.SetVertexBuffers(slot, 1, &defaultBuffer, &zero);
                    continue;
                }
                const auto& iAccessor = scene.accessors.at(it->second);
                if (iAccessor.componentType != gl::Float ||
                        (iAccessor.type != TINYGLTF_TYPE_VEC4 && iAccessor.type != TINYGLTF_TYPE_VEC3 && iAccessor.type != TINYGLTF_TYPE_VEC2)) {
                    fprintf(stderr, "unsupported vertex accessor component type %d and type %d\n", iAccessor.componentType, iAccessor.type);
                    continue;
                }

                if (vertexCount == 0) {
                    vertexCount = static_cast<uint32_t>(iAccessor.count);
                }
                const auto& oBuffer = buffers.at(iAccessor.bufferView);
                uint64_t iBufferOffset = static_cast<uint64_t>(iAccessor.byteOffset);
                pass.SetVertexBuffers(slot, 1, &oBuffer, &iBufferOffset);
            }

            if (!iPrim.indices.empty()) {
                const auto& iIndices = scene.accessors.at(iPrim.indices);
                // DrawElements
                if (iIndices.componentType != gl::UnsignedShort || iIndices.type != TINYGLTF_TYPE_SCALAR) {
                    fprintf(stderr, "unsupported index accessor component type %d and type %d\n", iIndices.componentType, iIndices.type);
                    continue;
                }
                const auto& oIndicesBuffer = buffers.at(iIndices.bufferView);
                pass.SetIndexBuffer(oIndicesBuffer, static_cast<uint32_t>(iIndices.byteOffset));
                pass.DrawIndexed(static_cast<uint32_t>(iIndices.count), 1, 0, 0, 0);
            } else {
                // DrawArrays
                pass.Draw(vertexCount, 1, 0, 0);
            }
        }
    }

    void drawNode(dawn::RenderPassEncoder& pass, const tinygltf::Node& node, const glm::mat4& parent = glm::mat4()) {
        glm::mat4 model;
        if (node.matrix.size() == 16) {
            model = glm::make_mat4(node.matrix.data());
        } else {
            if (node.scale.size() == 3) {
                glm::vec3 scale = glm::make_vec3(node.scale.data());
                model = glm::scale(model, scale);
            }
            if (node.rotation.size() == 4) {
                glm::quat rotation = glm::make_quat(node.rotation.data());
                model = glm::mat4_cast(rotation) * model;
            }
            if (node.translation.size() == 3) {
                glm::vec3 translation = glm::make_vec3(node.translation.data());
                model = glm::translate(model, translation);
            }
        }
        model = parent * model;

        for (const auto& meshID : node.meshes) {
            drawMesh(pass, scene.meshes[meshID], model);
        }
        for (const auto& child : node.children) {
            drawNode(pass, scene.nodes.at(child), model);
        }
    }

    void frame() {
        dawn::Texture backbuffer = swapchain.GetNextTexture();

        const auto& defaultSceneNodes = scene.scenes.at(scene.defaultScene);
        dawn::CommandEncoder encoder = device.CreateCommandEncoder();
        {
            utils::ComboRenderPassDescriptor renderPass({backbuffer.CreateDefaultView()},
                                                        depthStencilView);
            dawn::RenderPassEncoder pass = encoder.BeginRenderPass(&renderPass);
            for (const auto& n : defaultSceneNodes) {
                const auto& node = scene.nodes.at(n);
                drawNode(pass, node);
            }
            pass.EndPass();
        }

        dawn::CommandBuffer commands = encoder.Finish();
        queue.Submit(1, &commands);

        swapchain.Present(backbuffer);
        DoFlush();
    }
}

// Mouse camera control
namespace {
    bool buttons[GLFW_MOUSE_BUTTON_LAST + 1] = {0};

    void mouseButtonCallback(GLFWwindow*, int button, int action, int) {
        buttons[button] = (action == GLFW_PRESS);
    }

    void cursorPosCallback(GLFWwindow*, double mouseX, double mouseY) {
        static double oldX, oldY;
        float dX = static_cast<float>(mouseX - oldX);
        float dY = static_cast<float>(mouseY - oldY);
        oldX = mouseX;
        oldY = mouseY;

        if (buttons[2] || (buttons[0] && buttons[1])) {
            camera.pan(-dX * 0.002f, dY * 0.002f);
        } else if (buttons[0]) {
            camera.rotate(dX * 0.01f, dY * 0.01f);
        } else if (buttons[1]) {
            camera.zoom(dY * -0.005f);
        }
    }

    void scrollCallback(GLFWwindow*, double, double yoffset) {
        camera.zoom(static_cast<float>(yoffset) * 0.04f);
    }
}

int main(int argc, const char* argv[]) {
    if (!InitSample(argc, argv)) {
        return 1;
    }
    if (argc < 2) {
        fprintf(stderr, "Usage: %s model.gltf [... Dawn Options]\n", argv[0]);
        return 1;
    }

    tinygltf::TinyGLTFLoader loader;
    std::string err;
    std::string input_filename(argv[1]);
    std::string ext = getFilePathExtension(input_filename);

    bool ret = false;
    if (ext.compare("glb") == 0) {
        // assume binary glTF.
        ret = loader.LoadBinaryFromFile(&scene, &err, input_filename.c_str());
    } else {
        // assume ascii glTF.
        ret = loader.LoadASCIIFromFile(&scene, &err, input_filename.c_str());
    }
    if (!err.empty()) {
        fprintf(stderr, "ERR: %s\n", err.c_str());
    }
    if (!ret) {
        fprintf(stderr, "Failed to load .glTF : %s\n", argv[1]);
        exit(-1);
    }

    init();

    GLFWwindow* window = GetGLFWWindow();
    glfwSetMouseButtonCallback(window, mouseButtonCallback);
    glfwSetCursorPosCallback(window, cursorPosCallback);
    glfwSetScrollCallback(window, scrollCallback);

    while (!ShouldQuit()) {
        frame();
        utils::USleep(16000);
    }

    // TODO release stuff
}
