/*****************************************************************************
 * Copyright (c) 2014-2019 OpenRCT2 developers
 *
 * For a complete list of all authors, please refer to contributors.md
 * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
 *
 * OpenRCT2 is licensed under the GNU General Public License version 3.
 *****************************************************************************/

#include <openrct2-ui/interface/Dropdown.h>
#include <openrct2-ui/interface/Widget.h>
#include <openrct2-ui/windows/Window.h>
#include <openrct2/Game.h>
#include <openrct2/actions/ParkSetResearchFundingAction.hpp>
#include <openrct2/localisation/Localisation.h>
#include <openrct2/management/Finance.h>
#include <openrct2/management/NewsItem.h>
#include <openrct2/management/Research.h>
#include <openrct2/sprites.h>
#include <openrct2/world/Park.h>
#include <openrct2/world/Scenery.h>

// clang-format off
enum {
    WINDOW_RESEARCH_PAGE_DEVELOPMENT,
    WINDOW_RESEARCH_PAGE_FUNDING,
    WINDOW_RESEARCH_PAGE_COUNT
};

enum {
    WIDX_BACKGROUND,
    WIDX_TITLE,
    WIDX_CLOSE,
    WIDX_PAGE_BACKGROUND,
    WIDX_TAB_1,
    WIDX_TAB_2,

    WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP,
    WIDX_LAST_DEVELOPMENT_GROUP,
    WIDX_LAST_DEVELOPMENT_BUTTON,

    WIDX_FUNDING_GROUP = 6,
    WIDX_RESEARCH_FUNDING,
    WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON,
    WIDX_PRIORITIES_GROUP,
    WIDX_TRANSPORT_RIDES,
    WIDX_GENTLE_RIDES,
    WIDX_ROLLER_COASTERS,
    WIDX_THRILL_RIDES,
    WIDX_WATER_RIDES,
    WIDX_SHOPS_AND_STALLS,
    WIDX_SCENERY_AND_THEMING,
};

#pragma region Widgets

static rct_widget window_research_development_widgets[] = {
    { WWT_FRAME,            0,  0,      299,    0,      195,    0xFFFFFFFF,                             STR_NONE },
    { WWT_CAPTION,          0,  1,      298,    1,      14,     STR_RESEARCH_AND_DEVELOPMENT,           STR_WINDOW_TITLE_TIP },
    { WWT_CLOSEBOX,         0,  287,    297,    2,      13,     STR_CLOSE_X,                            STR_CLOSE_WINDOW_TIP },
    { WWT_RESIZE,           1,  0,      299,    43,     195,    0xFFFFFFFF,                             STR_NONE },
    { WWT_TAB,              1,  3,      33,     17,     43,     IMAGE_TYPE_REMAP | SPR_TAB,                   STR_RESEARCH_AND_DEVELOPMENT_TIP },
    { WWT_TAB,              1,  34,     64,     17,     43,     IMAGE_TYPE_REMAP | SPR_TAB,                   STR_FINANCES_RESEARCH_TIP },
    { WWT_GROUPBOX,         2,  3,      292,    47,     116,    STR_CURRENTLY_IN_DEVELOPMENT,           STR_NONE },
    { WWT_GROUPBOX,         2,  3,      292,    124,    188,    STR_LAST_DEVELOPMENT,                   STR_NONE },
    { WWT_FLATBTN,          2,  265,    288,    161,    184,    0xFFFFFFFF,                             STR_RESEARCH_SHOW_DETAILS_TIP },
    { WIDGETS_END },
};

static rct_widget window_research_funding_widgets[] = {
    { WWT_FRAME,            0,  0,      319,    0,      206,    0xFFFFFFFF,                             STR_NONE },
    { WWT_CAPTION,          0,  1,      318,    1,      14,     STR_RESEARCH_FUNDING,                   STR_WINDOW_TITLE_TIP },
    { WWT_CLOSEBOX,         0,  307,    317,    2,      13,     STR_CLOSE_X,                            STR_CLOSE_WINDOW_TIP },
    { WWT_RESIZE,           1,  0,      319,    43,     206,    0xFFFFFFFF,                             STR_NONE },
    { WWT_TAB,              1,  3,      33,     17,     43,     IMAGE_TYPE_REMAP | SPR_TAB,                   STR_RESEARCH_AND_DEVELOPMENT_TIP },
    { WWT_TAB,              1,  34,     64,     17,     43,     IMAGE_TYPE_REMAP | SPR_TAB,                   STR_FINANCES_RESEARCH_TIP },
    { WWT_GROUPBOX,         2,  3,      316,    47,     91,     STR_RESEARCH_FUNDING_,                  STR_NONE },
    { WWT_DROPDOWN,         2,  8,      167,    59,     70,     0xFFFFFFFF,                             STR_SELECT_LEVEL_OF_RESEARCH_AND_DEVELOPMENT },
    { WWT_BUTTON,           2,  156,    166,    60,     69,     STR_DROPDOWN_GLYPH,                     STR_SELECT_LEVEL_OF_RESEARCH_AND_DEVELOPMENT },
    { WWT_GROUPBOX,         2,  3,      316,    96,     202,    STR_RESEARCH_PRIORITIES,                STR_NONE },
    { WWT_CHECKBOX,         2,  8,      311,    108,    119,    STR_RESEARCH_NEW_TRANSPORT_RIDES,       STR_RESEARCH_NEW_TRANSPORT_RIDES_TIP },
    { WWT_CHECKBOX,         2,  8,      311,    121,    132,    STR_RESEARCH_NEW_GENTLE_RIDES,          STR_RESEARCH_NEW_GENTLE_RIDES_TIP },
    { WWT_CHECKBOX,         2,  8,      311,    134,    145,    STR_RESEARCH_NEW_ROLLER_COASTERS,       STR_RESEARCH_NEW_ROLLER_COASTERS_TIP },
    { WWT_CHECKBOX,         2,  8,      311,    147,    158,    STR_RESEARCH_NEW_THRILL_RIDES,          STR_RESEARCH_NEW_THRILL_RIDES_TIP },
    { WWT_CHECKBOX,         2,  8,      311,    160,    171,    STR_RESEARCH_NEW_WATER_RIDES,           STR_RESEARCH_NEW_WATER_RIDES_TIP },
    { WWT_CHECKBOX,         2,  8,      311,    173,    184,    STR_RESEARCH_NEW_SHOPS_AND_STALLS,      STR_RESEARCH_NEW_SHOPS_AND_STALLS_TIP },
    { WWT_CHECKBOX,         2,  8,      311,    186,    197,    STR_RESEARCH_NEW_SCENERY_AND_THEMING,   STR_RESEARCH_NEW_SCENERY_AND_THEMING_TIP },
    { WIDGETS_END },
};

static rct_widget *window_research_page_widgets[] = {
    window_research_development_widgets,
    window_research_funding_widgets
};

#pragma endregion

#pragma region Events

static void window_research_development_mouseup(rct_window *w, rct_widgetindex widgetIndex);
static void window_research_development_update(rct_window *w);
static void window_research_development_invalidate(rct_window *w);
static void window_research_development_paint(rct_window *w, rct_drawpixelinfo *dpi);

static void window_research_funding_mouseup(rct_window *w, rct_widgetindex widgetIndex);
static void window_research_funding_mousedown(rct_window *w, rct_widgetindex widgetIndex, rct_widget* widget);
static void window_research_funding_dropdown(rct_window *w, rct_widgetindex widgetIndex, int32_t dropdownIndex);
static void window_research_funding_update(rct_window *w);
static void window_research_funding_invalidate(rct_window *w);
static void window_research_funding_paint(rct_window *w, rct_drawpixelinfo *dpi);

//
static rct_window_event_list window_research_development_events = {
    nullptr,
    window_research_development_mouseup,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    window_research_development_update,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    window_research_development_invalidate,
    window_research_development_paint,
    nullptr
};

// 0x009890E8
static rct_window_event_list window_research_funding_events = {
    nullptr,
    window_research_funding_mouseup,
    nullptr,
    window_research_funding_mousedown,
    window_research_funding_dropdown,
    nullptr,
    window_research_funding_update,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    nullptr,
    window_research_funding_invalidate,
    window_research_funding_paint,
    nullptr
};

static rct_window_event_list *window_research_page_events[] = {
    &window_research_development_events,
    &window_research_funding_events
};

#pragma endregion

#pragma region Enabled widgets

static uint32_t window_research_page_enabled_widgets[] = {
    (1 << WIDX_CLOSE) |
    (1 << WIDX_TAB_1) |
    (1 << WIDX_TAB_2) |
    (1 << WIDX_LAST_DEVELOPMENT_BUTTON),

    (1 << WIDX_CLOSE) |
    (1 << WIDX_TAB_1) |
    (1 << WIDX_TAB_2) |
    (1 << WIDX_RESEARCH_FUNDING) |
    (1 << WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON) |
    (1 << WIDX_TRANSPORT_RIDES) |
    (1 << WIDX_GENTLE_RIDES) |
    (1 << WIDX_ROLLER_COASTERS) |
    (1 << WIDX_THRILL_RIDES) |
    (1 << WIDX_WATER_RIDES) |
    (1 << WIDX_SHOPS_AND_STALLS) |
    (1 << WIDX_SCENERY_AND_THEMING)
};

#pragma endregion

const int32_t window_research_tab_animation_loops[] = { 16, 16 };

static constexpr const rct_string_id ResearchCategoryNames[] = {
    STR_RESEARCH_CATEGORY_TRANSPORT,
    STR_RESEARCH_CATEGORY_GENTLE,
    STR_RESEARCH_CATEGORY_ROLLERCOASTER,
    STR_RESEARCH_CATEGORY_THRILL,
    STR_RESEARCH_CATEGORY_WATER,
    STR_RESEARCH_CATEGORY_SHOP,
    STR_RESEARCH_CATEGORY_SCENERY_GROUP,
};

static constexpr const rct_string_id ResearchStageNames[] = {
    STR_RESEARCH_STAGE_INITIAL_RESEARCH,
    STR_RESEARCH_STAGE_DESIGNING,
    STR_RESEARCH_STAGE_COMPLETING_DESIGN,
    STR_RESEARCH_STAGE_UNKNOWN,
};
// clang-format on

static void window_research_set_page(rct_window* w, int32_t page);
static void window_research_set_pressed_tab(rct_window* w);
static void window_research_draw_tab_images(rct_drawpixelinfo* dpi, rct_window* w);

rct_window* window_research_open()
{
    rct_window* w;

    w = window_bring_to_front_by_class(WC_RESEARCH);
    if (w == nullptr)
    {
        w = window_create_auto_pos(530, 257, window_research_page_events[0], WC_RESEARCH, WF_10);
        w->widgets = window_research_page_widgets[0];
        w->enabled_widgets = window_research_page_enabled_widgets[0];
        w->number = 0;
        w->page = 0;
        w->frame_no = 0;
        w->disabled_widgets = 0;
        research_update_uncompleted_types();
    }

    w->page = 0;
    w->Invalidate();
    w->width = 300;
    w->height = 196;
    w->Invalidate();

    w->widgets = window_research_page_widgets[0];
    w->enabled_widgets = window_research_page_enabled_widgets[0];
    w->hold_down_widgets = 0;
    w->event_handlers = window_research_page_events[0];
    w->pressed_widgets = 0;
    w->disabled_widgets = 0;
    window_init_scroll_widgets(w);

    return w;
}

#pragma region Development page

/**
 *
 *  rct2: 0x006B6B38
 */
static void window_research_development_mouseup(rct_window* w, rct_widgetindex widgetIndex)
{
    switch (widgetIndex)
    {
        case WIDX_CLOSE:
            window_close(w);
            break;
        case WIDX_TAB_1:
        case WIDX_TAB_2:
            window_research_set_page(w, widgetIndex - WIDX_TAB_1);
            break;
        case WIDX_LAST_DEVELOPMENT_BUTTON:
            news_item_open_subject(NEWS_ITEM_RESEARCH, gResearchLastItem.rawValue);
            break;
    }
}

/**
 *
 *  rct2: 0x0069CBA6
 */
static void window_research_development_update(rct_window* w)
{
    // Tab animation
    if (++w->frame_no >= window_research_tab_animation_loops[w->page])
        w->frame_no = 0;
    widget_invalidate(w, WIDX_TAB_1);
}

/**
 *
 *  rct2: 0x006B6819
 */
static void window_research_development_invalidate(rct_window* w)
{
    if (w->widgets != window_research_page_widgets[WINDOW_RESEARCH_PAGE_DEVELOPMENT])
    {
        w->widgets = window_research_page_widgets[WINDOW_RESEARCH_PAGE_DEVELOPMENT];
        window_init_scroll_widgets(w);
    }

    window_research_set_pressed_tab(w);

    window_research_development_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].type = WWT_EMPTY;
    if (gResearchLastItem.rawValue != RESEARCHED_ITEMS_SEPARATOR)
    {
        uint8_t type = gResearchLastItem.type;
        window_research_development_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].type = WWT_FLATBTN;
        window_research_development_widgets[WIDX_LAST_DEVELOPMENT_BUTTON].image = type == RESEARCH_ENTRY_TYPE_RIDE
            ? SPR_NEW_RIDE
            : SPR_NEW_SCENERY;
    }
}

/**
 *
 *  rct2: 0x006B689B
 */
static void window_research_development_paint(rct_window* w, rct_drawpixelinfo* dpi)
{
    window_draw_widgets(w, dpi);
    window_research_draw_tab_images(dpi, w);

    window_research_development_page_paint(w, dpi, WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP);
}

void window_research_development_page_paint(rct_window* w, rct_drawpixelinfo* dpi, rct_widgetindex baseWidgetIndex)
{
    baseWidgetIndex = baseWidgetIndex - WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP;

    int32_t x = w->x + 10;
    int32_t y = w->y + w->widgets[WIDX_CURRENTLY_IN_DEVELOPMENT_GROUP + baseWidgetIndex].top + 12;
    rct_string_id stringId;

    if (gResearchProgressStage == RESEARCH_STAGE_FINISHED_ALL)
    {
        stringId = STR_RESEARCH_UNKNOWN;
        gfx_draw_string_left_wrapped(dpi, &stringId, x, y, 296, STR_RESEARCH_TYPE_LABEL, COLOUR_BLACK);
        y += 25;

        // Progress
        stringId = STR_RESEARCH_COMPLETED_AL;
        gfx_draw_string_left_wrapped(dpi, &stringId, x, y, 296, STR_RESEARCH_PROGRESS_LABEL, COLOUR_BLACK);
        y += 15;

        set_format_arg(0, rct_string_id, STR_RESEARCH_STAGE_UNKNOWN);
        gfx_draw_string_left(dpi, STR_RESEARCH_EXPECTED_LABEL, gCommonFormatArgs, COLOUR_BLACK, x, y);
    }
    else
    {
        // Research type
        stringId = STR_RESEARCH_UNKNOWN;
        if (gResearchProgressStage != RESEARCH_STAGE_INITIAL_RESEARCH)
        {
            stringId = ResearchCategoryNames[gResearchNextItem.category];
            if (gResearchProgressStage != RESEARCH_STAGE_DESIGNING)
            {
                stringId = research_item_get_name(&gResearchNextItem);
            }
        }
        gfx_draw_string_left_wrapped(dpi, &stringId, x, y, 296, STR_RESEARCH_TYPE_LABEL, COLOUR_BLACK);
        y += 25;

        // Progress
        stringId = ResearchStageNames[gResearchProgressStage];
        gfx_draw_string_left_wrapped(dpi, &stringId, x, y, 296, STR_RESEARCH_PROGRESS_LABEL, COLOUR_BLACK);
        y += 15;

        // Expected
        set_format_arg(0, rct_string_id, STR_RESEARCH_STAGE_UNKNOWN);
        if (gResearchProgressStage != RESEARCH_STAGE_INITIAL_RESEARCH)
        {
            uint16_t expectedDay = gResearchExpectedDay;
            if (expectedDay != 255)
            {
                // TODO: Should probably use game date format setting
                set_format_arg(0, rct_string_id, STR_RESEARCH_EXPECTED_FORMAT);
                set_format_arg(2, rct_string_id, DateDayNames[expectedDay]);
                set_format_arg(4, rct_string_id, DateGameMonthNames[gResearchExpectedMonth]);
            }
        }
        gfx_draw_string_left(dpi, STR_RESEARCH_EXPECTED_LABEL, gCommonFormatArgs, COLOUR_BLACK, x, y);
    }

    // Last development
    x = w->x + 10;
    y = w->y + w->widgets[WIDX_LAST_DEVELOPMENT_GROUP + baseWidgetIndex].top + 12;

    rct_string_id lastDevelopmentFormat;
    if (gResearchLastItem.rawValue != RESEARCHED_ITEMS_SEPARATOR)
    {
        stringId = research_item_get_name(&gResearchLastItem);
        uint8_t type = gResearchLastItem.type;
        lastDevelopmentFormat = (type == RESEARCH_ENTRY_TYPE_RIDE) ? STR_RESEARCH_RIDE_LABEL : STR_RESEARCH_SCENERY_LABEL;

        gfx_draw_string_left_wrapped(dpi, &stringId, x, y, 266, lastDevelopmentFormat, COLOUR_BLACK);
    }
}

#pragma endregion

#pragma region Funding page

/**
 *
 *  rct2: 0x0069DB3F
 */
static void window_research_funding_mouseup(rct_window* w, rct_widgetindex widgetIndex)
{
    switch (widgetIndex)
    {
        case WIDX_CLOSE:
            window_close(w);
            break;
        case WIDX_TAB_1:
        case WIDX_TAB_2:
            window_research_set_page(w, widgetIndex - WIDX_TAB_1);
            break;
        case WIDX_TRANSPORT_RIDES:
        case WIDX_GENTLE_RIDES:
        case WIDX_ROLLER_COASTERS:
        case WIDX_THRILL_RIDES:
        case WIDX_WATER_RIDES:
        case WIDX_SHOPS_AND_STALLS:
        case WIDX_SCENERY_AND_THEMING:
        {
            auto activeResearchTypes = gResearchPriorities;
            activeResearchTypes ^= 1 << (widgetIndex - WIDX_TRANSPORT_RIDES);
            auto gameAction = ParkSetResearchFundingAction(activeResearchTypes, gResearchFundingLevel);
            GameActions::Execute(&gameAction);
            break;
        }
    }
}

/**
 *
 *  rct2: 0x0069DB66
 */
static void window_research_funding_mousedown(rct_window* w, rct_widgetindex widgetIndex, rct_widget* widget)
{
    rct_widget* dropdownWidget;
    int32_t i;

    if (widgetIndex != WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON)
        return;

    dropdownWidget = widget - 1;

    for (i = 0; i < 4; i++)
    {
        gDropdownItemsFormat[i] = STR_DROPDOWN_MENU_LABEL;
        gDropdownItemsArgs[i] = ResearchFundingLevelNames[i];
    }
    window_dropdown_show_text_custom_width(
        w->x + dropdownWidget->left, w->y + dropdownWidget->top, dropdownWidget->bottom - dropdownWidget->top + 1,
        w->colours[1], 0, DROPDOWN_FLAG_STAY_OPEN, 4, dropdownWidget->right - dropdownWidget->left - 3);

    int32_t currentResearchLevel = gResearchFundingLevel;
    dropdown_set_checked(currentResearchLevel, true);
}

/**
 *
 *  rct2: 0x0069DB6D
 */
static void window_research_funding_dropdown(rct_window* w, rct_widgetindex widgetIndex, int32_t dropdownIndex)
{
    if (widgetIndex != WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON || dropdownIndex == -1)
        return;

    auto gameAction = ParkSetResearchFundingAction(gResearchPriorities, dropdownIndex);
    GameActions::Execute(&gameAction);
}

/**
 *
 *  rct2: 0x0069DC23
 */
static void window_research_funding_update(rct_window* w)
{
    // Tab animation
    if (++w->frame_no >= window_research_tab_animation_loops[w->page])
        w->frame_no = 0;
    widget_invalidate(w, WIDX_TAB_2);
}

/**
 *
 *  rct2: 0x0069DA64
 */
static void window_research_funding_invalidate(rct_window* w)
{
    if (w->widgets != window_research_page_widgets[WINDOW_RESEARCH_PAGE_FUNDING])
    {
        w->widgets = window_research_page_widgets[WINDOW_RESEARCH_PAGE_FUNDING];
        window_init_scroll_widgets(w);
    }

    window_research_set_pressed_tab(w);

    if ((gParkFlags & PARK_FLAGS_NO_MONEY) || (gResearchProgressStage == RESEARCH_STAGE_FINISHED_ALL))
    {
        window_research_funding_widgets[WIDX_RESEARCH_FUNDING].type = WWT_EMPTY;
        window_research_funding_widgets[WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON].type = WWT_EMPTY;
    }
    else
    {
        window_research_funding_widgets[WIDX_FUNDING_GROUP].type = WWT_GROUPBOX;
        window_research_funding_widgets[WIDX_RESEARCH_FUNDING].type = WWT_DROPDOWN;
        window_research_funding_widgets[WIDX_RESEARCH_FUNDING_DROPDOWN_BUTTON].type = WWT_BUTTON;

        // Current funding
        int32_t currentResearchLevel = gResearchFundingLevel;
        window_research_funding_widgets[WIDX_RESEARCH_FUNDING].text = ResearchFundingLevelNames[currentResearchLevel];
    }

    // Checkboxes
    uint8_t activeResearchTypes = gResearchPriorities;
    for (int32_t i = 0; i < 7; i++)
    {
        int32_t mask = 1 << i;
        int32_t widgetMask = 1 << (i + WIDX_TRANSPORT_RIDES);

        // Set checkbox disabled if research type is complete
        if (gResearchUncompletedCategories & mask)
        {
            w->disabled_widgets &= ~widgetMask;

            // Set checkbox ticked if research type is active
            if (activeResearchTypes & mask)
                w->pressed_widgets |= widgetMask;
            else
                w->pressed_widgets &= ~widgetMask;
        }
        else
        {
            w->disabled_widgets |= widgetMask;
            w->pressed_widgets &= ~widgetMask;
        }
    }
}

/**
 *
 *  rct2: 0x0069DAF0
 */
static void window_research_funding_paint(rct_window* w, rct_drawpixelinfo* dpi)
{
    window_draw_widgets(w, dpi);
    window_research_draw_tab_images(dpi, w);

    window_research_funding_page_paint(w, dpi, WIDX_RESEARCH_FUNDING);
}

void window_research_funding_page_paint(rct_window* w, rct_drawpixelinfo* dpi, rct_widgetindex baseWidgetIndex)
{
    if (gParkFlags & PARK_FLAGS_NO_MONEY)
        return;

    int32_t currentResearchLevel = gResearchFundingLevel;
    money32 currentResearchCostPerWeek = research_cost_table[currentResearchLevel];
    gfx_draw_string_left(dpi, STR_RESEARCH_COST_PER_MONTH, &currentResearchCostPerWeek, COLOUR_BLACK, w->x + 10, w->y + 77);
}

#pragma endregion

#pragma region Common

/**
 *
 *  rct2: 0x0069CAC5
 */
static void window_research_set_page(rct_window* w, int32_t page)
{
    w->page = page;
    w->frame_no = 0;
    if (w->viewport != nullptr)
    {
        w->viewport->width = 0;
        w->viewport = nullptr;
    }

    w->enabled_widgets = window_research_page_enabled_widgets[page];
    w->hold_down_widgets = 0;
    w->event_handlers = window_research_page_events[page];
    w->widgets = window_research_page_widgets[page];
    w->disabled_widgets = 0;
    w->pressed_widgets = 0;

    w->Invalidate();
    if (w->page == WINDOW_RESEARCH_PAGE_DEVELOPMENT)
    {
        w->width = 300;
        w->height = 196;
    }
    else
    {
        w->width = 320;
        w->height = 207;
    }
    window_event_resize_call(w);
    window_event_invalidate_call(w);

    window_init_scroll_widgets(w);
    w->Invalidate();
}

static void window_research_set_pressed_tab(rct_window* w)
{
    int32_t i;
    for (i = 0; i < WINDOW_RESEARCH_PAGE_COUNT; i++)
        w->pressed_widgets &= ~(1 << (WIDX_TAB_1 + i));
    w->pressed_widgets |= 1LL << (WIDX_TAB_1 + w->page);
}

static void window_research_draw_tab_image(rct_drawpixelinfo* dpi, rct_window* w, int32_t page, int32_t spriteIndex)
{
    rct_widgetindex widgetIndex = WIDX_TAB_1 + page;

    if (!(w->disabled_widgets & (1LL << widgetIndex)))
    {
        if (w->page == page)
        {
            int32_t frame = w->frame_no / 2;
            if (page == WINDOW_RESEARCH_PAGE_DEVELOPMENT)
                frame %= 8;
            spriteIndex += frame;
        }

        gfx_draw_sprite(dpi, spriteIndex, w->x + w->widgets[widgetIndex].left, w->y + w->widgets[widgetIndex].top, 0);
    }
}

static void window_research_draw_tab_images(rct_drawpixelinfo* dpi, rct_window* w)
{
    window_research_draw_tab_image(dpi, w, WINDOW_RESEARCH_PAGE_DEVELOPMENT, SPR_TAB_FINANCES_RESEARCH_0);
    window_research_draw_tab_image(dpi, w, WINDOW_RESEARCH_PAGE_FUNDING, SPR_TAB_FINANCES_SUMMARY_0);
}

#pragma endregion
