/*
 * Copyright (C) 2015 The Android Open Source Project
 * Copyright (C) 2019 The LineageOS Project
 *
 * 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 "device.h"

#define ARRAY_SIZE(A) (sizeof(A) / sizeof(*(A)))

// *** Main menu ***
static const menu_type_t MAIN_MENU_TYPE = MT_GRID;
static const MenuItem MAIN_MENU_ITEMS[] = {
  MenuItem("Reboot", "ic_reboot", "ic_reboot_sel"),
  MenuItem("Apply update", "ic_system_update", "ic_system_update_sel"),
  MenuItem("Factory reset", "ic_factory_reset", "ic_factory_reset_sel"),
  MenuItem("Advanced", "ic_options_advanced", "ic_options_advanced_sel"),
};
static const MenuItemVector main_menu_items_ =
    MenuItemVector(MAIN_MENU_ITEMS, MAIN_MENU_ITEMS + ARRAY_SIZE(MAIN_MENU_ITEMS));
static const Device::BuiltinAction MAIN_MENU_ACTIONS[] = {
  Device::REBOOT,
  Device::APPLY_UPDATE,
  Device::WIPE_MENU,
  Device::ADVANCED_MENU,
};
static const Device::MenuActionVector main_menu_actions_ =
    Device::MenuActionVector(MAIN_MENU_ACTIONS, MAIN_MENU_ACTIONS + ARRAY_SIZE(MAIN_MENU_ACTIONS));
static_assert(ARRAY_SIZE(MAIN_MENU_ITEMS) == ARRAY_SIZE(MAIN_MENU_ACTIONS),
              "MAIN_MENU_ITEMS and MAIN_MENU_ACTIONS should have the same length.");

// *** Wipe menu ***
static const menu_type_t WIPE_MENU_TYPE = MT_LIST;
static const MenuItem WIPE_MENU_ITEMS[] = {
  MenuItem("Wipe data / factory reset"),
#ifndef AB_OTA_UPDATER
  MenuItem("Wipe cache"),
#endif
  MenuItem("Wipe system"),
};
static const MenuItemVector wipe_menu_items_ =
    MenuItemVector(WIPE_MENU_ITEMS, WIPE_MENU_ITEMS + ARRAY_SIZE(WIPE_MENU_ITEMS));
static const Device::BuiltinAction WIPE_MENU_ACTIONS[] = {
  Device::WIPE_DATA,
#ifndef AB_OTA_UPDATER
  Device::WIPE_CACHE,
#endif
  Device::WIPE_SYSTEM,
};
static const Device::MenuActionVector wipe_menu_actions_ =
    Device::MenuActionVector(WIPE_MENU_ACTIONS, WIPE_MENU_ACTIONS + ARRAY_SIZE(WIPE_MENU_ACTIONS));
static_assert(ARRAY_SIZE(WIPE_MENU_ITEMS) == ARRAY_SIZE(WIPE_MENU_ACTIONS),
              "WIPE_MENU_ITEMS and WIPE_MENU_ACTIONS should have the same length.");

// *** Advanced menu
static const menu_type_t ADVANCED_MENU_TYPE = MT_LIST;

static const MenuItem ADVANCED_MENU_ITEMS[] = {
#ifdef DOWNLOAD_MODE
  MenuItem("Reboot to download mode"),
#else
  MenuItem("Reboot to bootloader"),
#endif
  MenuItem("Reboot to recovery"),
  MenuItem("Mount system"),
  MenuItem("View logs"),
#ifdef SHOW_TESTS
  MenuItem("Run graphics test"),
  MenuItem("Run locale test"),
#endif
  MenuItem("Power off"),
};
static const MenuItemVector advanced_menu_items_ =
    MenuItemVector(ADVANCED_MENU_ITEMS, ADVANCED_MENU_ITEMS + ARRAY_SIZE(ADVANCED_MENU_ITEMS));

static const Device::BuiltinAction ADVANCED_MENU_ACTIONS[] = {
  Device::REBOOT_BOOTLOADER,
  Device::REBOOT_RECOVERY,
  Device::MOUNT_SYSTEM,
  Device::VIEW_RECOVERY_LOGS,
#ifdef SHOW_TESTS
  Device::RUN_GRAPHICS_TEST,
  Device::RUN_LOCALE_TEST,
#endif
  Device::SHUTDOWN,
};
static const Device::MenuActionVector advanced_menu_actions_ = Device::MenuActionVector(
    ADVANCED_MENU_ACTIONS, ADVANCED_MENU_ACTIONS + ARRAY_SIZE(ADVANCED_MENU_ACTIONS));

static_assert(ARRAY_SIZE(ADVANCED_MENU_ITEMS) == ARRAY_SIZE(ADVANCED_MENU_ACTIONS),
              "ADVANCED_MENU_ITEMS and ADVANCED_MENU_ACTIONS should have the same length.");

Device::Device(RecoveryUI* ui) : ui_(ui) {
  GoHome();
}

Device::BuiltinAction Device::InvokeMenuItem(int menu_position) {
  if (menu_position < 0) {
    if (menu_position == Device::kGoBack || menu_position == Device::kGoHome) {
      // Assume only two menu levels, so back is equivalent to home.
      GoHome();
    }
    return NO_ACTION;
  }
  BuiltinAction action = menu_actions_.at(menu_position);
  switch (action) {
    case WIPE_MENU:
      menu_is_main_ = false;
      menu_type_ = WIPE_MENU_TYPE;
      menu_items_ = wipe_menu_items_;
      menu_actions_ = wipe_menu_actions_;
      break;
    case ADVANCED_MENU:
      menu_is_main_ = false;
      menu_type_ = ADVANCED_MENU_TYPE;
      menu_items_ = advanced_menu_items_;
      menu_actions_ = advanced_menu_actions_;
      break;
    default:
      break;  // Fall through
  }
  return action;
}

void Device::GoHome() {
  menu_is_main_ = true;
  menu_type_ = MAIN_MENU_TYPE;
  menu_items_ = main_menu_items_;
  menu_actions_ = main_menu_actions_;
}

int Device::HandleMenuKey(int key, bool visible) {
  if (!visible) {
    return kNoAction;
  }

  switch (key) {
    case KEY_RIGHTSHIFT:
    case KEY_DOWN:
    case KEY_VOLUMEDOWN:
    case KEY_MENU:
      return kHighlightDown;

    case KEY_LEFTSHIFT:
    case KEY_UP:
    case KEY_VOLUMEUP:
    case KEY_SEARCH:
      return kHighlightUp;

    case KEY_SCROLLUP:
      return kScrollUp;
    case KEY_SCROLLDOWN:
      return kScrollDown;

    case KEY_ENTER:
    case KEY_POWER:
    case BTN_MOUSE:
    case KEY_SEND:
      return kInvokeItem;

    case KEY_HOME:
    case KEY_HOMEPAGE:
      return kGoHome;

    case KEY_BACKSPACE:
    case KEY_BACK:
      return kGoBack;

    case KEY_REFRESH:
      return kRefresh;

    default:
      // If you have all of the above buttons, any other buttons
      // are ignored. Otherwise, any button cycles the highlight.
      return ui_->HasThreeButtons() ? kNoAction : kHighlightDown;
  }
}
