/*
* Copyright 2016 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/

#include <windows.h>
#include <tchar.h>

#include "include/core/SkTypes.h"
#include "include/private/base/SkMalloc.h"
#include "tools/sk_app/Application.h"
#include "tools/sk_app/win/Window_win.h"
#include "tools/timer/Timer.h"

using sk_app::Application;

static char* tchar_to_utf8(const TCHAR* str) {
#ifdef _UNICODE
    int size = WideCharToMultiByte(CP_UTF8, 0, str, wcslen(str), nullptr, 0, nullptr, nullptr);
    char* str8 = (char*)sk_malloc_throw(size + 1);
    WideCharToMultiByte(CP_UTF8, 0, str, wcslen(str), str8, size, nullptr, nullptr);
    str8[size] = '\0';
    return str8;
#else
    return _strdup(str);
#endif
}

// This file can work with GUI or CONSOLE subsystem types since we define _tWinMain and main().

static int main_common(HINSTANCE hInstance, int show, int argc, char**argv);

int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine,
                       int nCmdShow) {

    // convert from lpCmdLine to argc, argv.
    char* argv[4096];
    int argc = 0;
    TCHAR exename[1024], *next;
    int exenameLen = GetModuleFileName(nullptr, exename, std::size(exename));
    // we're ignoring the possibility that the exe name exceeds the exename buffer
    (void)exenameLen;
    argv[argc++] = tchar_to_utf8(exename);
    TCHAR* arg = _tcstok_s(lpCmdLine, _T(" "), &next);
    while (arg != nullptr) {
        argv[argc++] = tchar_to_utf8(arg);
        arg = _tcstok_s(nullptr, _T(" "), &next);
    }
    int result = main_common(hInstance, nCmdShow, argc, argv);
    for (int i = 0; i < argc; ++i) {
        sk_free(argv[i]);
    }
    return result;
}

int main(int argc, char**argv) {
    return main_common(GetModuleHandle(nullptr), SW_SHOW, argc, argv);
}

static int main_common(HINSTANCE hInstance, int show, int argc, char**argv) {

    Application* app = Application::Create(argc, argv, (void*)hInstance);

    MSG msg;
    memset(&msg, 0, sizeof(msg));

    bool idled = false;

    // Main message loop
    while (WM_QUIT != msg.message) {
        if (PeekMessage(&msg, nullptr, 0, 0, PM_REMOVE)) {
            TranslateMessage(&msg);

            if (WM_PAINT == msg.message) {
                // Ensure that call onIdle at least once per WM_PAINT, or mouse events can
                // overwhelm the message processing loop, and prevent animation from running.
                if (!idled) {
                    app->onIdle();
                }
                idled = false;
            }
            DispatchMessage(&msg);
        } else {
            app->onIdle();
            idled = true;
        }
    }

    delete app;

    return (int)msg.wParam;
}
