/**
 * @file Application.h
 *
 */

#pragma once

#ifdef _WIN32
#include <windows.h>
#endif

#include <Raym/Object.h>

namespace Raym
{

class Application : public Object
{
private:
#ifdef _WIN32
    HINSTANCE   _instance;      //
    HWND        _wnd;           //
    HMENU       _menu;
    UINT_PTR    _timer;
    UINT        _counter;
#endif

    bool addNotifyIcon();
    void deleteNotifyIcon();

protected:
    Application();
    ~Application();

public:
    static Application *alloc();
#ifdef _WIN32
    virtual Application *init(HINSTANCE hInstance, int nCmdShow, LPCWSTR className);
#endif
    virtual int start();

    virtual void systemWillSuspend() = 0;
    virtual void systemResumed() = 0;
    virtual void detectIdle() = 0;
    virtual void detectNonIdle() = 0;
    virtual bool canTerminate() = 0;

    void resetCounter();
    void sleep();
    void suspend();
    void shutdown();
    bool setWakeSchedule(int year, int month, int day, int hour, int min);
    void resetWakeSchedule();
#ifdef _WIN32
    LRESULT WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam);
#endif

    // misc
    static const char *GetHomeDirectory();
    static const char *GetExecutePath();
    static const char *GetPublicDirectory();

#ifdef _WIN32
    // Win32 アプリケーションのエントリポイント
    static int main(Application *(*allocator)(), LPCWSTR className, HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow);
#endif
};

} // Raym

#define ApplicationMain(APPCLASS, APPNAME, ...) Raym::Application::main((Raym::Application *(*)())APPCLASS::alloc, APPNAME, __VA_ARGS__)
