/*
 * Copyright (C) 2011 The Android Open Source 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 "screen_ui.h"

#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <linux/input.h>
#include <pthread.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#include <memory>
#include <string>
#include <unordered_map>
#include <vector>

#include <android-base/logging.h>
#include <android-base/properties.h>
#include <android-base/stringprintf.h>
#include <android-base/strings.h>
#include <minui/minui.h>

#include "device.h"
#include "ui.h"

// Return the current time as a double (including fractions of a second).
static double now() {
  struct timeval tv;
  gettimeofday(&tv, nullptr);
  return tv.tv_sec + tv.tv_usec / 1000000.0;
}

Menu::Menu(bool scrollable, size_t max_items, size_t max_length, const char* const* headers,
           const char* const* items, int initial_selection)
    : scrollable_(scrollable),
      max_display_items_(max_items),
      max_item_length_(max_length),
      text_headers_(headers),
      menu_start_(0),
      selection_(initial_selection) {
  CHECK_LE(max_items, static_cast<size_t>(std::numeric_limits<int>::max()));

  // It's fine to have more entries than text_rows_ if scrollable menu is supported.
  size_t max_items_count = scrollable_ ? std::numeric_limits<int>::max() : max_display_items_;
  for (size_t i = 0; i < max_items_count && items[i] != nullptr; ++i) {
    text_items_.emplace_back(items[i], strnlen(items[i], max_item_length_));
  }

  CHECK(!text_items_.empty());
}

const char* const* Menu::text_headers() const {
  return text_headers_;
}

std::string Menu::TextItem(size_t index) const {
  CHECK_LT(index, text_items_.size());

  return text_items_[index];
}

size_t Menu::MenuStart() const {
  return menu_start_;
}

size_t Menu::MenuEnd() const {
  return std::min(ItemsCount(), menu_start_ + max_display_items_);
}

size_t Menu::ItemsCount() const {
  return text_items_.size();
}

bool Menu::ItemsOverflow(std::string* cur_selection_str) const {
  if (!scrollable_ || ItemsCount() <= max_display_items_) {
    return false;
  }

  *cur_selection_str =
      android::base::StringPrintf("Current item: %d/%zu", selection_ + 1, ItemsCount());
  return true;
}

// TODO(xunchang) modify the function parameters to button up & down.
int Menu::Select(int sel) {
  CHECK_LE(ItemsCount(), static_cast<size_t>(std::numeric_limits<int>::max()));
  int count = ItemsCount();

  // Wraps the selection at boundary if the menu is not scrollable.
  if (!scrollable_) {
    if (sel < 0) {
      selection_ = count - 1;
    } else if (sel >= count) {
      selection_ = 0;
    } else {
      selection_ = sel;
    }

    return selection_;
  }

  if (sel < 0) {
    selection_ = 0;
  } else if (sel >= count) {
    selection_ = count - 1;
  } else {
    if (static_cast<size_t>(sel) < menu_start_) {
      menu_start_--;
    } else if (static_cast<size_t>(sel) >= MenuEnd()) {
      menu_start_++;
    }
    selection_ = sel;
  }

  return selection_;
}

ScreenRecoveryUI::ScreenRecoveryUI() : ScreenRecoveryUI(false) {}

ScreenRecoveryUI::ScreenRecoveryUI(bool scrollable_menu)
    : kMarginWidth(RECOVERY_UI_MARGIN_WIDTH),
      kMarginHeight(RECOVERY_UI_MARGIN_HEIGHT),
      kAnimationFps(RECOVERY_UI_ANIMATION_FPS),
      kDensity(static_cast<float>(android::base::GetIntProperty("ro.sf.lcd_density", 160)) / 160.f),
      currentIcon(NONE),
      progressBarType(EMPTY),
      progressScopeStart(0),
      progressScopeSize(0),
      progress(0),
      pagesIdentical(false),
      text_cols_(0),
      text_rows_(0),
      text_(nullptr),
      text_col_(0),
      text_row_(0),
      show_text(false),
      show_text_ever(false),
      scrollable_menu_(scrollable_menu),
      file_viewer_text_(nullptr),
      intro_frames(0),
      loop_frames(0),
      current_frame(0),
      intro_done(false),
      stage(-1),
      max_stage(-1),
      locale_(""),
      rtl_locale_(false),
      updateMutex(PTHREAD_MUTEX_INITIALIZER) {}

GRSurface* ScreenRecoveryUI::GetCurrentFrame() const {
  if (currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) {
    return intro_done ? loopFrames[current_frame] : introFrames[current_frame];
  }
  return error_icon;
}

GRSurface* ScreenRecoveryUI::GetCurrentText() const {
  switch (currentIcon) {
    case ERASING:
      return erasing_text;
    case ERROR:
      return error_text;
    case INSTALLING_UPDATE:
      return installing_text;
    case NO_COMMAND:
      return no_command_text;
    case NONE:
      abort();
  }
}

int ScreenRecoveryUI::PixelsFromDp(int dp) const {
  return dp * kDensity;
}

// Here's the intended layout:

//          | portrait    large        landscape      large
// ---------+-------------------------------------------------
//      gap |
// icon     |                   (200dp)
//      gap |    68dp      68dp             56dp      112dp
// text     |                    (14sp)
//      gap |    32dp      32dp             26dp       52dp
// progress |                     (2dp)
//      gap |

// Note that "baseline" is actually the *top* of each icon (because that's how our drawing routines
// work), so that's the more useful measurement for calling code. We use even top and bottom gaps.

enum Layout { PORTRAIT = 0, PORTRAIT_LARGE = 1, LANDSCAPE = 2, LANDSCAPE_LARGE = 3, LAYOUT_MAX };
enum Dimension { TEXT = 0, ICON = 1, DIMENSION_MAX };
static constexpr int kLayouts[LAYOUT_MAX][DIMENSION_MAX] = {
  { 32,  68, },  // PORTRAIT
  { 32,  68, },  // PORTRAIT_LARGE
  { 26,  56, },  // LANDSCAPE
  { 52, 112, },  // LANDSCAPE_LARGE
};

int ScreenRecoveryUI::GetAnimationBaseline() const {
  return GetTextBaseline() - PixelsFromDp(kLayouts[layout_][ICON]) - gr_get_height(loopFrames[0]);
}

int ScreenRecoveryUI::GetTextBaseline() const {
  return GetProgressBaseline() - PixelsFromDp(kLayouts[layout_][TEXT]) -
         gr_get_height(installing_text);
}

int ScreenRecoveryUI::GetProgressBaseline() const {
  int elements_sum = gr_get_height(loopFrames[0]) + PixelsFromDp(kLayouts[layout_][ICON]) +
                     gr_get_height(installing_text) + PixelsFromDp(kLayouts[layout_][TEXT]) +
                     gr_get_height(progressBarFill);
  int bottom_gap = (ScreenHeight() - elements_sum) / 2;
  return ScreenHeight() - bottom_gap - gr_get_height(progressBarFill);
}

// Clear the screen and draw the currently selected background icon (if any).
// Should only be called with updateMutex locked.
void ScreenRecoveryUI::draw_background_locked() {
  pagesIdentical = false;
  gr_color(0, 0, 0, 255);
  gr_clear();
  if (currentIcon != NONE) {
    if (max_stage != -1) {
      int stage_height = gr_get_height(stageMarkerEmpty);
      int stage_width = gr_get_width(stageMarkerEmpty);
      int x = (ScreenWidth() - max_stage * gr_get_width(stageMarkerEmpty)) / 2;
      int y = ScreenHeight() - stage_height - kMarginHeight;
      for (int i = 0; i < max_stage; ++i) {
        GRSurface* stage_surface = (i < stage) ? stageMarkerFill : stageMarkerEmpty;
        DrawSurface(stage_surface, 0, 0, stage_width, stage_height, x, y);
        x += stage_width;
      }
    }

    GRSurface* text_surface = GetCurrentText();
    int text_x = (ScreenWidth() - gr_get_width(text_surface)) / 2;
    int text_y = GetTextBaseline();
    gr_color(255, 255, 255, 255);
    DrawTextIcon(text_x, text_y, text_surface);
  }
}

// Draws the animation and progress bar (if any) on the screen. Does not flip pages. Should only be
// called with updateMutex locked.
void ScreenRecoveryUI::draw_foreground_locked() {
  if (currentIcon != NONE) {
    GRSurface* frame = GetCurrentFrame();
    int frame_width = gr_get_width(frame);
    int frame_height = gr_get_height(frame);
    int frame_x = (ScreenWidth() - frame_width) / 2;
    int frame_y = GetAnimationBaseline();
    DrawSurface(frame, 0, 0, frame_width, frame_height, frame_x, frame_y);
  }

  if (progressBarType != EMPTY) {
    int width = gr_get_width(progressBarEmpty);
    int height = gr_get_height(progressBarEmpty);

    int progress_x = (ScreenWidth() - width) / 2;
    int progress_y = GetProgressBaseline();

    // Erase behind the progress bar (in case this was a progress-only update)
    gr_color(0, 0, 0, 255);
    DrawFill(progress_x, progress_y, width, height);

    if (progressBarType == DETERMINATE) {
      float p = progressScopeStart + progress * progressScopeSize;
      int pos = static_cast<int>(p * width);

      if (rtl_locale_) {
        // Fill the progress bar from right to left.
        if (pos > 0) {
          DrawSurface(progressBarFill, width - pos, 0, pos, height, progress_x + width - pos,
                      progress_y);
        }
        if (pos < width - 1) {
          DrawSurface(progressBarEmpty, 0, 0, width - pos, height, progress_x, progress_y);
        }
      } else {
        // Fill the progress bar from left to right.
        if (pos > 0) {
          DrawSurface(progressBarFill, 0, 0, pos, height, progress_x, progress_y);
        }
        if (pos < width - 1) {
          DrawSurface(progressBarEmpty, pos, 0, width - pos, height, progress_x + pos, progress_y);
        }
      }
    }
  }
}

void ScreenRecoveryUI::SetColor(UIElement e) const {
  switch (e) {
    case INFO:
      gr_color(249, 194, 0, 255);
      break;
    case HEADER:
      gr_color(247, 0, 6, 255);
      break;
    case MENU:
    case MENU_SEL_BG:
      gr_color(0, 106, 157, 255);
      break;
    case MENU_SEL_BG_ACTIVE:
      gr_color(0, 156, 100, 255);
      break;
    case MENU_SEL_FG:
      gr_color(255, 255, 255, 255);
      break;
    case LOG:
      gr_color(196, 196, 196, 255);
      break;
    case TEXT_FILL:
      gr_color(0, 0, 0, 160);
      break;
    default:
      gr_color(255, 255, 255, 255);
      break;
  }
}

void ScreenRecoveryUI::SelectAndShowBackgroundText(const std::vector<std::string>& locales_entries,
                                                   size_t sel) {
  SetLocale(locales_entries[sel]);
  std::vector<std::string> text_name = { "erasing_text", "error_text", "installing_text",
                                         "installing_security_text", "no_command_text" };
  std::unordered_map<std::string, std::unique_ptr<GRSurface, decltype(&free)>> surfaces;
  for (const auto& name : text_name) {
    GRSurface* text_image = nullptr;
    LoadLocalizedBitmap(name.c_str(), &text_image);
    if (!text_image) {
      Print("Failed to load %s\n", name.c_str());
      return;
    }
    surfaces.emplace(name, std::unique_ptr<GRSurface, decltype(&free)>(text_image, &free));
  }

  pthread_mutex_lock(&updateMutex);
  gr_color(0, 0, 0, 255);
  gr_clear();

  int text_y = kMarginHeight;
  int text_x = kMarginWidth;
  int line_spacing = gr_sys_font()->char_height;  // Put some extra space between images.
  // Write the header and descriptive texts.
  SetColor(INFO);
  std::string header = "Show background text image";
  text_y += DrawTextLine(text_x, text_y, header, true);
  std::string locale_selection = android::base::StringPrintf(
      "Current locale: %s, %zu/%zu", locales_entries[sel].c_str(), sel, locales_entries.size());
  // clang-format off
  std::vector<std::string> instruction = {
    locale_selection,
    "Use volume up/down to switch locales and power to exit."
  };
  // clang-format on
  text_y += DrawWrappedTextLines(text_x, text_y, instruction);

  // Iterate through the text images and display them in order for the current locale.
  for (const auto& p : surfaces) {
    text_y += line_spacing;
    SetColor(LOG);
    text_y += DrawTextLine(text_x, text_y, p.first, false);
    gr_color(255, 255, 255, 255);
    gr_texticon(text_x, text_y, p.second.get());
    text_y += gr_get_height(p.second.get());
  }
  // Update the whole screen.
  gr_flip();
  pthread_mutex_unlock(&updateMutex);
}

void ScreenRecoveryUI::CheckBackgroundTextImages(const std::string& saved_locale) {
  // Load a list of locales embedded in one of the resource files.
  std::vector<std::string> locales_entries = get_locales_in_png("installing_text");
  if (locales_entries.empty()) {
    Print("Failed to load locales from the resource files\n");
    return;
  }
  size_t selected = 0;
  SelectAndShowBackgroundText(locales_entries, selected);

  FlushKeys();
  while (true) {
    int key = WaitKey();
    if (key == KEY_POWER || key == KEY_ENTER) {
      break;
    } else if (key == KEY_UP || key == KEY_VOLUMEUP) {
      selected = (selected == 0) ? locales_entries.size() - 1 : selected - 1;
      SelectAndShowBackgroundText(locales_entries, selected);
    } else if (key == KEY_DOWN || key == KEY_VOLUMEDOWN) {
      selected = (selected == locales_entries.size() - 1) ? 0 : selected + 1;
      SelectAndShowBackgroundText(locales_entries, selected);
    }
  }

  SetLocale(saved_locale);
}

int ScreenRecoveryUI::ScreenWidth() const {
  return gr_fb_width();
}

int ScreenRecoveryUI::ScreenHeight() const {
  return gr_fb_height();
}

void ScreenRecoveryUI::DrawSurface(GRSurface* surface, int sx, int sy, int w, int h, int dx,
                                   int dy) const {
  gr_blit(surface, sx, sy, w, h, dx, dy);
}

int ScreenRecoveryUI::DrawHorizontalRule(int y) const {
  gr_fill(0, y + 4, ScreenWidth(), y + 6);
  return 8;
}

void ScreenRecoveryUI::DrawHighlightBar(int x, int y, int width, int height) const {
  gr_fill(x, y, x + width, y + height);
}

void ScreenRecoveryUI::DrawFill(int x, int y, int w, int h) const {
  gr_fill(x, y, w, h);
}

void ScreenRecoveryUI::DrawTextIcon(int x, int y, GRSurface* surface) const {
  gr_texticon(x, y, surface);
}

int ScreenRecoveryUI::DrawTextLine(int x, int y, const std::string& line, bool bold) const {
  gr_text(gr_sys_font(), x, y, line.c_str(), bold);
  return char_height_ + 4;
}

int ScreenRecoveryUI::DrawTextLines(int x, int y, const std::vector<std::string>& lines) const {
  int offset = 0;
  for (const auto& line : lines) {
    offset += DrawTextLine(x, y + offset, line, false);
  }
  return offset;
}

int ScreenRecoveryUI::DrawWrappedTextLines(int x, int y,
                                           const std::vector<std::string>& lines) const {
  int offset = 0;
  for (const auto& line : lines) {
    size_t next_start = 0;
    while (next_start < line.size()) {
      std::string sub = line.substr(next_start, text_cols_ + 1);
      if (sub.size() <= text_cols_) {
        next_start += sub.size();
      } else {
        // Line too long and must be wrapped to text_cols_ columns.
        size_t last_space = sub.find_last_of(" \t\n");
        if (last_space == std::string::npos) {
          // No space found, just draw as much as we can.
          sub.resize(text_cols_);
          next_start += text_cols_;
        } else {
          sub.resize(last_space);
          next_start += last_space + 1;
        }
      }
      offset += DrawTextLine(x, y + offset, sub, false);
    }
  }
  return offset;
}

// Redraws everything on the screen. Does not flip pages. Should only be called with updateMutex
// locked.
void ScreenRecoveryUI::draw_screen_locked() {
  if (!show_text) {
    draw_background_locked();
    draw_foreground_locked();
    return;
  }

  gr_color(0, 0, 0, 255);
  gr_clear();

  // clang-format off
  static std::vector<std::string> REGULAR_HELP = {
    "Use volume up/down and power.",
  };
  static std::vector<std::string> LONG_PRESS_HELP = {
    "Any button cycles highlight.",
    "Long-press activates.",
  };
  // clang-format on
  draw_menu_and_text_buffer_locked(HasThreeButtons() ? REGULAR_HELP : LONG_PRESS_HELP);
}

// Draws the menu and text buffer on the screen. Should only be called with updateMutex locked.
void ScreenRecoveryUI::draw_menu_and_text_buffer_locked(
    const std::vector<std::string>& help_message) {
  int y = kMarginHeight;
  if (menu_) {
    static constexpr int kMenuIndent = 4;
    int x = kMarginWidth + kMenuIndent;

    SetColor(INFO);
    y += DrawTextLine(x, y, "Android Recovery", true);
    std::string recovery_fingerprint =
        android::base::GetProperty("ro.bootimage.build.fingerprint", "");
    for (const auto& chunk : android::base::Split(recovery_fingerprint, ":")) {
      y += DrawTextLine(x, y, chunk, false);
    }

    y += DrawTextLines(x, y, help_message);

    auto convert_to_vector = [](const char* const* items) -> std::vector<std::string> {
      if (items == nullptr) return {};

      std::vector<std::string> result;
      for (size_t i = 0; items[i] != nullptr; ++i) {
        result.emplace_back(items[i]);
      }
      return result;
    };

    // Draw menu header.
    SetColor(HEADER);
    if (!menu_->scrollable()) {
      y += DrawWrappedTextLines(x, y, convert_to_vector(menu_->text_headers()));
    } else {
      y += DrawTextLines(x, y, convert_to_vector(menu_->text_headers()));
      // Show the current menu item number in relation to total number if items don't fit on the
      // screen.
      std::string cur_selection_str;
      if (menu_->ItemsOverflow(&cur_selection_str)) {
        y += DrawTextLine(x, y, cur_selection_str, true);
      }
    }

    // Draw menu items.
    SetColor(MENU);
    // Do not draw the horizontal rule for wear devices.
    if (!menu_->scrollable()) {
      y += DrawHorizontalRule(y) + 4;
    }
    for (size_t i = menu_->MenuStart(); i < menu_->MenuEnd(); ++i) {
      bool bold = false;
      if (i == static_cast<size_t>(menu_->selection())) {
        // Draw the highlight bar.
        SetColor(IsLongPress() ? MENU_SEL_BG_ACTIVE : MENU_SEL_BG);

        int bar_height = char_height_ + 4;
        DrawHighlightBar(0, y - 2, ScreenWidth(), bar_height);

        // Bold white text for the selected item.
        SetColor(MENU_SEL_FG);
        bold = true;
      }

      y += DrawTextLine(x, y, menu_->TextItem(i), bold);

      SetColor(MENU);
    }
    y += DrawHorizontalRule(y);
  }

  // Display from the bottom up, until we hit the top of the screen, the bottom of the menu, or
  // we've displayed the entire text buffer.
  SetColor(LOG);
  int row = text_row_;
  size_t count = 0;
  for (int ty = ScreenHeight() - kMarginHeight - char_height_; ty >= y && count < text_rows_;
       ty -= char_height_, ++count) {
    DrawTextLine(kMarginWidth, ty, text_[row], false);
    --row;
    if (row < 0) row = text_rows_ - 1;
  }
}

// Redraw everything on the screen and flip the screen (make it visible).
// Should only be called with updateMutex locked.
void ScreenRecoveryUI::update_screen_locked() {
  draw_screen_locked();
  gr_flip();
}

// Updates only the progress bar, if possible, otherwise redraws the screen.
// Should only be called with updateMutex locked.
void ScreenRecoveryUI::update_progress_locked() {
  if (show_text || !pagesIdentical) {
    draw_screen_locked();  // Must redraw the whole screen
    pagesIdentical = true;
  } else {
    draw_foreground_locked();  // Draw only the progress bar and overlays
  }
  gr_flip();
}

// Keeps the progress bar updated, even when the process is otherwise busy.
void* ScreenRecoveryUI::ProgressThreadStartRoutine(void* data) {
  reinterpret_cast<ScreenRecoveryUI*>(data)->ProgressThreadLoop();
  return nullptr;
}

void ScreenRecoveryUI::ProgressThreadLoop() {
  double interval = 1.0 / kAnimationFps;
  while (true) {
    double start = now();
    pthread_mutex_lock(&updateMutex);

    bool redraw = false;

    // update the installation animation, if active
    // skip this if we have a text overlay (too expensive to update)
    if ((currentIcon == INSTALLING_UPDATE || currentIcon == ERASING) && !show_text) {
      if (!intro_done) {
        if (current_frame == intro_frames - 1) {
          intro_done = true;
          current_frame = 0;
        } else {
          ++current_frame;
        }
      } else {
        current_frame = (current_frame + 1) % loop_frames;
      }

      redraw = true;
    }

    // move the progress bar forward on timed intervals, if configured
    int duration = progressScopeDuration;
    if (progressBarType == DETERMINATE && duration > 0) {
      double elapsed = now() - progressScopeTime;
      float p = 1.0 * elapsed / duration;
      if (p > 1.0) p = 1.0;
      if (p > progress) {
        progress = p;
        redraw = true;
      }
    }

    if (redraw) update_progress_locked();

    pthread_mutex_unlock(&updateMutex);
    double end = now();
    // minimum of 20ms delay between frames
    double delay = interval - (end - start);
    if (delay < 0.02) delay = 0.02;
    usleep(static_cast<useconds_t>(delay * 1000000));
  }
}

void ScreenRecoveryUI::LoadBitmap(const char* filename, GRSurface** surface) {
  int result = res_create_display_surface(filename, surface);
  if (result < 0) {
    LOG(ERROR) << "couldn't load bitmap " << filename << " (error " << result << ")";
  }
}

void ScreenRecoveryUI::LoadLocalizedBitmap(const char* filename, GRSurface** surface) {
  int result = res_create_localized_alpha_surface(filename, locale_.c_str(), surface);
  if (result < 0) {
    LOG(ERROR) << "couldn't load bitmap " << filename << " (error " << result << ")";
  }
}

static char** Alloc2d(size_t rows, size_t cols) {
  char** result = new char*[rows];
  for (size_t i = 0; i < rows; ++i) {
    result[i] = new char[cols];
    memset(result[i], 0, cols);
  }
  return result;
}

// Choose the right background string to display during update.
void ScreenRecoveryUI::SetSystemUpdateText(bool security_update) {
  if (security_update) {
    LoadLocalizedBitmap("installing_security_text", &installing_text);
  } else {
    LoadLocalizedBitmap("installing_text", &installing_text);
  }
  Redraw();
}

bool ScreenRecoveryUI::InitTextParams() {
  if (gr_init() < 0) {
    return false;
  }

  gr_font_size(gr_sys_font(), &char_width_, &char_height_);
  text_rows_ = (ScreenHeight() - kMarginHeight * 2) / char_height_;
  text_cols_ = (ScreenWidth() - kMarginWidth * 2) / char_width_;
  return true;
}

bool ScreenRecoveryUI::Init(const std::string& locale) {
  RecoveryUI::Init(locale);

  if (!InitTextParams()) {
    return false;
  }

  // Are we portrait or landscape?
  layout_ = (gr_fb_width() > gr_fb_height()) ? LANDSCAPE : PORTRAIT;
  // Are we the large variant of our base layout?
  if (gr_fb_height() > PixelsFromDp(800)) ++layout_;

  text_ = Alloc2d(text_rows_, text_cols_ + 1);
  file_viewer_text_ = Alloc2d(text_rows_, text_cols_ + 1);

  text_col_ = text_row_ = 0;

  // Set up the locale info.
  SetLocale(locale);

  LoadBitmap("icon_error", &error_icon);

  LoadBitmap("progress_empty", &progressBarEmpty);
  LoadBitmap("progress_fill", &progressBarFill);

  LoadBitmap("stage_empty", &stageMarkerEmpty);
  LoadBitmap("stage_fill", &stageMarkerFill);

  // Background text for "installing_update" could be "installing update"
  // or "installing security update". It will be set after UI init according
  // to commands in BCB.
  installing_text = nullptr;
  LoadLocalizedBitmap("erasing_text", &erasing_text);
  LoadLocalizedBitmap("no_command_text", &no_command_text);
  LoadLocalizedBitmap("error_text", &error_text);

  LoadAnimation();

  pthread_create(&progress_thread_, nullptr, ProgressThreadStartRoutine, this);

  return true;
}

void ScreenRecoveryUI::LoadAnimation() {
  std::unique_ptr<DIR, decltype(&closedir)> dir(opendir("/res/images"), closedir);
  dirent* de;
  std::vector<std::string> intro_frame_names;
  std::vector<std::string> loop_frame_names;

  while ((de = readdir(dir.get())) != nullptr) {
    int value, num_chars;
    if (sscanf(de->d_name, "intro%d%n.png", &value, &num_chars) == 1) {
      intro_frame_names.emplace_back(de->d_name, num_chars);
    } else if (sscanf(de->d_name, "loop%d%n.png", &value, &num_chars) == 1) {
      loop_frame_names.emplace_back(de->d_name, num_chars);
    }
  }

  intro_frames = intro_frame_names.size();
  loop_frames = loop_frame_names.size();

  // It's okay to not have an intro.
  if (intro_frames == 0) intro_done = true;
  // But you must have an animation.
  if (loop_frames == 0) abort();

  std::sort(intro_frame_names.begin(), intro_frame_names.end());
  std::sort(loop_frame_names.begin(), loop_frame_names.end());

  introFrames = new GRSurface*[intro_frames];
  for (size_t i = 0; i < intro_frames; i++) {
    LoadBitmap(intro_frame_names.at(i).c_str(), &introFrames[i]);
  }

  loopFrames = new GRSurface*[loop_frames];
  for (size_t i = 0; i < loop_frames; i++) {
    LoadBitmap(loop_frame_names.at(i).c_str(), &loopFrames[i]);
  }
}

void ScreenRecoveryUI::SetBackground(Icon icon) {
  pthread_mutex_lock(&updateMutex);

  currentIcon = icon;
  update_screen_locked();

  pthread_mutex_unlock(&updateMutex);
}

void ScreenRecoveryUI::SetProgressType(ProgressType type) {
  pthread_mutex_lock(&updateMutex);
  if (progressBarType != type) {
    progressBarType = type;
  }
  progressScopeStart = 0;
  progressScopeSize = 0;
  progress = 0;
  update_progress_locked();
  pthread_mutex_unlock(&updateMutex);
}

void ScreenRecoveryUI::ShowProgress(float portion, float seconds) {
  pthread_mutex_lock(&updateMutex);
  progressBarType = DETERMINATE;
  progressScopeStart += progressScopeSize;
  progressScopeSize = portion;
  progressScopeTime = now();
  progressScopeDuration = seconds;
  progress = 0;
  update_progress_locked();
  pthread_mutex_unlock(&updateMutex);
}

void ScreenRecoveryUI::SetProgress(float fraction) {
  pthread_mutex_lock(&updateMutex);
  if (fraction < 0.0) fraction = 0.0;
  if (fraction > 1.0) fraction = 1.0;
  if (progressBarType == DETERMINATE && fraction > progress) {
    // Skip updates that aren't visibly different.
    int width = gr_get_width(progressBarEmpty);
    float scale = width * progressScopeSize;
    if ((int)(progress * scale) != (int)(fraction * scale)) {
      progress = fraction;
      update_progress_locked();
    }
  }
  pthread_mutex_unlock(&updateMutex);
}

void ScreenRecoveryUI::SetStage(int current, int max) {
  pthread_mutex_lock(&updateMutex);
  stage = current;
  max_stage = max;
  pthread_mutex_unlock(&updateMutex);
}

void ScreenRecoveryUI::PrintV(const char* fmt, bool copy_to_stdout, va_list ap) {
  std::string str;
  android::base::StringAppendV(&str, fmt, ap);

  if (copy_to_stdout) {
    fputs(str.c_str(), stdout);
  }

  pthread_mutex_lock(&updateMutex);
  if (text_rows_ > 0 && text_cols_ > 0) {
    for (const char* ptr = str.c_str(); *ptr != '\0'; ++ptr) {
      if (*ptr == '\n' || text_col_ >= text_cols_) {
        text_[text_row_][text_col_] = '\0';
        text_col_ = 0;
        text_row_ = (text_row_ + 1) % text_rows_;
      }
      if (*ptr != '\n') text_[text_row_][text_col_++] = *ptr;
    }
    text_[text_row_][text_col_] = '\0';
    update_screen_locked();
  }
  pthread_mutex_unlock(&updateMutex);
}

void ScreenRecoveryUI::Print(const char* fmt, ...) {
  va_list ap;
  va_start(ap, fmt);
  PrintV(fmt, true, ap);
  va_end(ap);
}

void ScreenRecoveryUI::PrintOnScreenOnly(const char *fmt, ...) {
  va_list ap;
  va_start(ap, fmt);
  PrintV(fmt, false, ap);
  va_end(ap);
}

void ScreenRecoveryUI::PutChar(char ch) {
  pthread_mutex_lock(&updateMutex);
  if (ch != '\n') text_[text_row_][text_col_++] = ch;
  if (ch == '\n' || text_col_ >= text_cols_) {
    text_col_ = 0;
    ++text_row_;
  }
  pthread_mutex_unlock(&updateMutex);
}

void ScreenRecoveryUI::ClearText() {
  pthread_mutex_lock(&updateMutex);
  text_col_ = 0;
  text_row_ = 0;
  for (size_t i = 0; i < text_rows_; ++i) {
    memset(text_[i], 0, text_cols_ + 1);
  }
  pthread_mutex_unlock(&updateMutex);
}

void ScreenRecoveryUI::ShowFile(FILE* fp) {
  std::vector<off_t> offsets;
  offsets.push_back(ftello(fp));
  ClearText();

  struct stat sb;
  fstat(fileno(fp), &sb);

  bool show_prompt = false;
  while (true) {
    if (show_prompt) {
      PrintOnScreenOnly("--(%d%% of %d bytes)--",
                        static_cast<int>(100 * (double(ftello(fp)) / double(sb.st_size))),
                        static_cast<int>(sb.st_size));
      Redraw();
      while (show_prompt) {
        show_prompt = false;
        int key = WaitKey();
        if (key == KEY_POWER || key == KEY_ENTER) {
          return;
        } else if (key == KEY_UP || key == KEY_VOLUMEUP) {
          if (offsets.size() <= 1) {
            show_prompt = true;
          } else {
            offsets.pop_back();
            fseek(fp, offsets.back(), SEEK_SET);
          }
        } else {
          if (feof(fp)) {
            return;
          }
          offsets.push_back(ftello(fp));
        }
      }
      ClearText();
    }

    int ch = getc(fp);
    if (ch == EOF) {
      while (text_row_ < text_rows_ - 1) PutChar('\n');
      show_prompt = true;
    } else {
      PutChar(ch);
      if (text_col_ == 0 && text_row_ >= text_rows_ - 1) {
        show_prompt = true;
      }
    }
  }
}

void ScreenRecoveryUI::ShowFile(const std::string& filename) {
  std::unique_ptr<FILE, decltype(&fclose)> fp(fopen(filename.c_str(), "re"), fclose);
  if (!fp) {
    Print("  Unable to open %s: %s\n", filename.c_str(), strerror(errno));
    return;
  }

  char** old_text = text_;
  size_t old_text_col = text_col_;
  size_t old_text_row = text_row_;

  // Swap in the alternate screen and clear it.
  text_ = file_viewer_text_;
  ClearText();

  ShowFile(fp.get());

  text_ = old_text;
  text_col_ = old_text_col;
  text_row_ = old_text_row;
}

void ScreenRecoveryUI::StartMenu(const char* const* headers, const char* const* items,
                                 int initial_selection) {
  pthread_mutex_lock(&updateMutex);
  if (text_rows_ > 0 && text_cols_ > 1) {
    menu_ = std::make_unique<Menu>(scrollable_menu_, text_rows_, text_cols_ - 1, headers, items,
                                   initial_selection);
    update_screen_locked();
  }
  pthread_mutex_unlock(&updateMutex);
}

int ScreenRecoveryUI::SelectMenu(int sel) {
  pthread_mutex_lock(&updateMutex);
  if (menu_) {
    int old_sel = menu_->selection();
    sel = menu_->Select(sel);

    if (sel != old_sel) {
      update_screen_locked();
    }
  }
  pthread_mutex_unlock(&updateMutex);
  return sel;
}

void ScreenRecoveryUI::EndMenu() {
  pthread_mutex_lock(&updateMutex);
  if (menu_) {
    menu_.reset();
    update_screen_locked();
  }
  pthread_mutex_unlock(&updateMutex);
}

int ScreenRecoveryUI::ShowMenu(const char* const* headers, const char* const* items,
                               int initial_selection, bool menu_only,
                               const std::function<int(int, bool)>& key_handler) {
  // Throw away keys pressed previously, so user doesn't accidentally trigger menu items.
  FlushKeys();

  StartMenu(headers, items, initial_selection);

  int selected = initial_selection;
  int chosen_item = -1;
  while (chosen_item < 0) {
    int key = WaitKey();
    if (key == -1) {  // WaitKey() timed out.
      if (WasTextEverVisible()) {
        continue;
      } else {
        LOG(INFO) << "Timed out waiting for key input; rebooting.";
        EndMenu();
        return -1;
      }
    }

    bool visible = IsTextVisible();
    int action = key_handler(key, visible);
    if (action < 0) {
      switch (action) {
        case Device::kHighlightUp:
          selected = SelectMenu(--selected);
          break;
        case Device::kHighlightDown:
          selected = SelectMenu(++selected);
          break;
        case Device::kInvokeItem:
          chosen_item = selected;
          break;
        case Device::kNoAction:
          break;
      }
    } else if (!menu_only) {
      chosen_item = action;
    }
  }

  EndMenu();
  return chosen_item;
}

bool ScreenRecoveryUI::IsTextVisible() {
  pthread_mutex_lock(&updateMutex);
  int visible = show_text;
  pthread_mutex_unlock(&updateMutex);
  return visible;
}

bool ScreenRecoveryUI::WasTextEverVisible() {
  pthread_mutex_lock(&updateMutex);
  int ever_visible = show_text_ever;
  pthread_mutex_unlock(&updateMutex);
  return ever_visible;
}

void ScreenRecoveryUI::ShowText(bool visible) {
  pthread_mutex_lock(&updateMutex);
  show_text = visible;
  if (show_text) show_text_ever = true;
  update_screen_locked();
  pthread_mutex_unlock(&updateMutex);
}

void ScreenRecoveryUI::Redraw() {
  pthread_mutex_lock(&updateMutex);
  update_screen_locked();
  pthread_mutex_unlock(&updateMutex);
}

void ScreenRecoveryUI::KeyLongPress(int) {
  // Redraw so that if we're in the menu, the highlight
  // will change color to indicate a successful long press.
  Redraw();
}

void ScreenRecoveryUI::SetLocale(const std::string& new_locale) {
  locale_ = new_locale;
  rtl_locale_ = false;

  if (!new_locale.empty()) {
    size_t underscore = new_locale.find('_');
    // lang has the language prefix prior to '_', or full string if '_' doesn't exist.
    std::string lang = new_locale.substr(0, underscore);

    // A bit cheesy: keep an explicit list of supported RTL languages.
    if (lang == "ar" ||  // Arabic
        lang == "fa" ||  // Persian (Farsi)
        lang == "he" ||  // Hebrew (new language code)
        lang == "iw" ||  // Hebrew (old language code)
        lang == "ur") {  // Urdu
      rtl_locale_ = true;
    }
  }
}
