/*
 *
 *    Copyright (c) 2023 Project CHIP 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.
 */

#include "qrcode.h"

#include <imgui.h>

#include <Options.h> // examples/platform/linux/Options.h
#include <app/server/OnboardingCodesUtil.h>
#include <setup_payload/QRCodeSetupPayloadGenerator.h>
#include <setup_payload/SetupPayload.h>

namespace example {
namespace Ui {
namespace Windows {
namespace {

inline ImVec2 operator+(const ImVec2 & a, const ImVec2 & b)
{
    return ImVec2(a.x + b.x, a.y + b.y);
}

} // namespace

void QRCode::LoadInitialState()
{
    chip::PayloadContents payload = LinuxDeviceOptions::GetInstance().payload;
    if (!payload.isValidQRCodePayload())
    {
        return;
    }

    char payloadBuffer[chip::QRCodeBasicSetupPayloadGenerator::kMaxQRCodeBase38RepresentationLength + 1];
    chip::MutableCharSpan qrCode(payloadBuffer);

    CHIP_ERROR err = GetQRCode(qrCode, payload);
    if (err != CHIP_NO_ERROR)
    {
        ChipLogError(AppServer, "Failed to load QR code: %" CHIP_ERROR_FORMAT, err.Format());
        return;
    }

    if (qrCode.size() > kMaxQRBufferSize)
    {
        ChipLogError(AppServer, "Insufficient qr code buffer size to encode");
        return;
    }

    uint8_t tempAndData[kMaxQRBufferSize];
    memcpy(tempAndData, qrCode.data(), qrCode.size());

    mHasQRCode = qrcodegen_encodeBinary(tempAndData, qrCode.size(), mQRData, qrcodegen_Ecc_MEDIUM, qrcodegen_VERSION_MIN,
                                        qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true);

    if (!mHasQRCode)
    {
        ChipLogError(AppServer, "Failed to encode QR code");
        return;
    }
}

void QRCode::Render()
{
    ImGui::Begin("QR Code.");
    if (!mHasQRCode)
    {
        ImGui::Text("MISSING/ERROR!");
        ImGui::End();
        return;
    }

    ImDrawList * drawList = ImGui::GetWindowDrawList();

    constexpr int kBorderSize    = 35;
    constexpr int kMinWindowSize = 200;
    const int kQRCodeSize        = qrcodegen_getSize(mQRData);

    ImVec2 pos  = ImGui::GetWindowPos();
    ImVec2 size = ImGui::GetWindowSize();

    if (size.y < kMinWindowSize)
    {
        size = ImVec2(kMinWindowSize, kMinWindowSize);
        ImGui::SetWindowSize(size);
    }

    // Fill the entire window white, then figure out borders
    drawList->AddRectFilled(pos, pos + size, IM_COL32_WHITE);

    // add a border
    if (size.x >= 2 * kBorderSize && size.y >= 2 * kBorderSize)
    {
        size.x -= 2 * kBorderSize;
        size.y -= 2 * kBorderSize;
        pos.x += kBorderSize;
        pos.y += kBorderSize;
    }

    // create a square rectangle: keep only the smaller side and adjust the
    // other
    if (size.x > size.y)
    {
        pos.x += (size.x - size.y) / 2;
        size.x = size.y;
    }
    else if (size.y > size.x)
    {
        pos.y += (size.y - size.x) / 2;
        size.y = size.x;
    }

    const ImVec2 squareSize = ImVec2(size.x / static_cast<float>(kQRCodeSize), size.y / static_cast<float>(kQRCodeSize));

    for (int y = 0; y < kQRCodeSize; ++y)
    {
        for (int x = 0; x < kQRCodeSize; ++x)
        {
            if (qrcodegen_getModule(mQRData, x, y))
            {
                ImVec2 placement =
                    ImVec2(pos.x + static_cast<float>(x) * squareSize.x, pos.y + static_cast<float>(y) * squareSize.y);
                drawList->AddRectFilled(placement, placement + squareSize, IM_COL32_BLACK);
            }
        }
    }

    ImGui::End();
}

} // namespace Windows
} // namespace Ui
} // namespace example
