// Copyright 2018 The PDFium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "samples/pdfium_test_event_helper.h"

#include <stdio.h>

#include <string>
#include <vector>

#include "public/fpdf_fwlevent.h"
#include "public/fpdfview.h"
#include "testing/fx_string_testhelpers.h"

namespace {

uint32_t GetModifiers(std::string modifiers_string) {
  uint32_t modifiers = 0;
  if (modifiers_string.find("shift") != std::string::npos)
    modifiers |= FWL_EVENTFLAG_ShiftKey;
  if (modifiers_string.find("control") != std::string::npos)
    modifiers |= FWL_EVENTFLAG_ControlKey;
  if (modifiers_string.find("alt") != std::string::npos)
    modifiers |= FWL_EVENTFLAG_AltKey;

  return modifiers;
}

void SendCharCodeEvent(FPDF_FORMHANDLE form,
                       FPDF_PAGE page,
                       const std::vector<std::string>& tokens) {
  if (tokens.size() != 2) {
    fprintf(stderr, "charcode: bad args\n");
    return;
  }

  int charcode = atoi(tokens[1].c_str());
  FORM_OnChar(form, page, charcode, 0);
}

void SendKeyCodeEvent(FPDF_FORMHANDLE form,
                      FPDF_PAGE page,
                      const std::vector<std::string>& tokens) {
  if (tokens.size() < 2 || tokens.size() > 3) {
    fprintf(stderr, "keycode: bad args\n");
    return;
  }

  int keycode = atoi(tokens[1].c_str());
  uint32_t modifiers = tokens.size() >= 3 ? GetModifiers(tokens[2]) : 0;
  FORM_OnKeyDown(form, page, keycode, modifiers);
  FORM_OnKeyUp(form, page, keycode, modifiers);
}

void SendMouseDownEvent(FPDF_FORMHANDLE form,
                        FPDF_PAGE page,
                        const std::vector<std::string>& tokens) {
  if (tokens.size() < 4 && tokens.size() > 5) {
    fprintf(stderr, "mousedown: bad args\n");
    return;
  }

  int x = atoi(tokens[2].c_str());
  int y = atoi(tokens[3].c_str());
  uint32_t modifiers = tokens.size() >= 5 ? GetModifiers(tokens[4]) : 0;

  if (tokens[1] == "left")
    FORM_OnLButtonDown(form, page, modifiers, x, y);
  else if (tokens[1] == "right")
    FORM_OnRButtonDown(form, page, modifiers, x, y);
  else
    fprintf(stderr, "mousedown: bad button name\n");
}

void SendMouseUpEvent(FPDF_FORMHANDLE form,
                      FPDF_PAGE page,
                      const std::vector<std::string>& tokens) {
  if (tokens.size() < 4 && tokens.size() > 5) {
    fprintf(stderr, "mouseup: bad args\n");
    return;
  }

  int x = atoi(tokens[2].c_str());
  int y = atoi(tokens[3].c_str());
  int modifiers = tokens.size() >= 5 ? GetModifiers(tokens[4]) : 0;
  if (tokens[1] == "left")
    FORM_OnLButtonUp(form, page, modifiers, x, y);
  else if (tokens[1] == "right")
    FORM_OnRButtonUp(form, page, modifiers, x, y);
  else
    fprintf(stderr, "mouseup: bad button name\n");
}

void SendMouseDoubleClickEvent(FPDF_FORMHANDLE form,
                               FPDF_PAGE page,
                               const std::vector<std::string>& tokens) {
  if (tokens.size() < 4 && tokens.size() > 5) {
    fprintf(stderr, "mousedoubleclick: bad args\n");
    return;
  }

  int x = atoi(tokens[2].c_str());
  int y = atoi(tokens[3].c_str());
  int modifiers = tokens.size() >= 5 ? GetModifiers(tokens[4]) : 0;
  if (tokens[1] != "left") {
    fprintf(stderr, "mousedoubleclick: bad button name\n");
    return;
  }
  FORM_OnLButtonDoubleClick(form, page, modifiers, x, y);
}

void SendMouseMoveEvent(FPDF_FORMHANDLE form,
                        FPDF_PAGE page,
                        const std::vector<std::string>& tokens) {
  if (tokens.size() != 3) {
    fprintf(stderr, "mousemove: bad args\n");
    return;
  }

  int x = atoi(tokens[1].c_str());
  int y = atoi(tokens[2].c_str());
  FORM_OnMouseMove(form, page, 0, x, y);
}

void SendMouseWheelEvent(FPDF_FORMHANDLE form,
                         FPDF_PAGE page,
                         const std::vector<std::string>& tokens) {
  if (tokens.size() < 5 && tokens.size() > 6) {
    fprintf(stderr, "mousewheel: bad args\n");
    return;
  }

  const FS_POINTF point = {static_cast<float>(atoi(tokens[1].c_str())),
                           static_cast<float>(atoi(tokens[2].c_str()))};
  int delta_x = atoi(tokens[3].c_str());
  int delta_y = atoi(tokens[4].c_str());
  int modifiers = tokens.size() >= 6 ? GetModifiers(tokens[5]) : 0;
  FORM_OnMouseWheel(form, page, modifiers, &point, delta_x, delta_y);
}

void SendFocusEvent(FPDF_FORMHANDLE form,
                    FPDF_PAGE page,
                    const std::vector<std::string>& tokens) {
  if (tokens.size() != 3) {
    fprintf(stderr, "focus: bad args\n");
    return;
  }

  int x = atoi(tokens[1].c_str());
  int y = atoi(tokens[2].c_str());
  FORM_OnFocus(form, page, 0, x, y);
}

}  // namespace

void SendPageEvents(FPDF_FORMHANDLE form,
                    FPDF_PAGE page,
                    const std::string& events,
                    const std::function<void()>& idler) {
  auto lines = StringSplit(events, '\n');
  for (const auto& line : lines) {
    auto command = StringSplit(line, '#');
    if (command[0].empty())
      continue;
    auto tokens = StringSplit(command[0], ',');
    if (tokens[0] == "charcode") {
      SendCharCodeEvent(form, page, tokens);
    } else if (tokens[0] == "keycode") {
      SendKeyCodeEvent(form, page, tokens);
    } else if (tokens[0] == "mousedown") {
      SendMouseDownEvent(form, page, tokens);
    } else if (tokens[0] == "mouseup") {
      SendMouseUpEvent(form, page, tokens);
    } else if (tokens[0] == "mousedoubleclick") {
      SendMouseDoubleClickEvent(form, page, tokens);
    } else if (tokens[0] == "mousemove") {
      SendMouseMoveEvent(form, page, tokens);
    } else if (tokens[0] == "mousewheel") {
      SendMouseWheelEvent(form, page, tokens);
    } else if (tokens[0] == "focus") {
      SendFocusEvent(form, page, tokens);
    } else {
      fprintf(stderr, "Unrecognized event: %s\n", tokens[0].c_str());
    }
    idler();
  }
}
