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

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "xfa/fwl/cfwl_monthcalendar.h"

#include <algorithm>
#include <memory>
#include <utility>

#include "core/fxcrt/cfx_datetime.h"
#include "third_party/base/check.h"
#include "third_party/base/notreached.h"
#include "third_party/base/stl_util.h"
#include "xfa/fde/cfde_textout.h"
#include "xfa/fwl/cfwl_datetimepicker.h"
#include "xfa/fwl/cfwl_messagemouse.h"
#include "xfa/fwl/cfwl_notedriver.h"
#include "xfa/fwl/cfwl_themebackground.h"
#include "xfa/fwl/cfwl_themetext.h"
#include "xfa/fwl/ifwl_themeprovider.h"

#define MONTHCAL_HSEP_HEIGHT 1
#define MONTHCAL_HMARGIN 3
#define MONTHCAL_VMARGIN 2
#define MONTHCAL_ROWS 9
#define MONTHCAL_COLUMNS 7
#define MONTHCAL_HEADER_BTN_VMARGIN 7
#define MONTHCAL_HEADER_BTN_HMARGIN 5

namespace {

WideString GetAbbreviatedDayOfWeek(int day) {
  switch (day) {
    case 0:
      return L"Sun";
    case 1:
      return L"Mon";
    case 2:
      return L"Tue";
    case 3:
      return L"Wed";
    case 4:
      return L"Thu";
    case 5:
      return L"Fri";
    case 6:
      return L"Sat";
    default:
      NOTREACHED();
      return L"";
  }
}

WideString GetMonth(int month) {
  switch (month) {
    case 0:
      return L"January";
    case 1:
      return L"February";
    case 2:
      return L"March";
    case 3:
      return L"April";
    case 4:
      return L"May";
    case 5:
      return L"June";
    case 6:
      return L"July";
    case 7:
      return L"August";
    case 8:
      return L"September";
    case 9:
      return L"October";
    case 10:
      return L"November";
    case 11:
      return L"December";
    default:
      NOTREACHED();
      return L"";
  }
}

}  // namespace

CFWL_MonthCalendar::CFWL_MonthCalendar(CFWL_App* app,
                                       const Properties& properties,
                                       CFWL_Widget* pOuter)
    : CFWL_Widget(app, properties, pOuter) {}

CFWL_MonthCalendar::~CFWL_MonthCalendar() = default;

FWL_Type CFWL_MonthCalendar::GetClassID() const {
  return FWL_Type::MonthCalendar;
}

CFX_RectF CFWL_MonthCalendar::GetAutosizedWidgetRect() {
  CFX_SizeF fs = CalcSize();
  CFX_RectF rect(0, 0, fs.width, fs.height);
  InflateWidgetRect(rect);
  return rect;
}

void CFWL_MonthCalendar::Update() {
  if (IsLocked())
    return;

  if (!m_bInitialized) {
    InitDate();
    m_bInitialized = true;
  }
  ClearDateItem();
  ResetDateItem();
  Layout();
}

void CFWL_MonthCalendar::DrawWidget(CFGAS_GEGraphics* pGraphics,
                                    const CFX_Matrix& matrix) {
  if (!pGraphics)
    return;

  if (HasBorder())
    DrawBorder(pGraphics, CFWL_ThemePart::Part::kBorder, matrix);

  DrawBackground(pGraphics, matrix);
  DrawHeadBK(pGraphics, matrix);
  DrawLButton(pGraphics, matrix);
  DrawRButton(pGraphics, matrix);
  DrawSeparator(pGraphics, matrix);
  DrawDatesInBK(pGraphics, matrix);
  DrawDatesInCircle(pGraphics, matrix);
  DrawCaption(pGraphics, matrix);
  DrawWeek(pGraphics, matrix);
  DrawDatesIn(pGraphics, matrix);
  DrawDatesOut(pGraphics, matrix);
  DrawToday(pGraphics, matrix);
}

void CFWL_MonthCalendar::SetSelect(int32_t iYear,
                                   int32_t iMonth,
                                   int32_t iDay) {
  ChangeToMonth(iYear, iMonth);
  AddSelDay(iDay);
}

void CFWL_MonthCalendar::DrawBackground(CFGAS_GEGraphics* pGraphics,
                                        const CFX_Matrix& mtMatrix) {
  CFWL_ThemeBackground params(this, pGraphics);
  params.m_iPart = CFWL_ThemePart::Part::kBackground;
  params.m_PartRect = m_ClientRect;
  params.m_matrix = mtMatrix;
  GetThemeProvider()->DrawBackground(params);
}

void CFWL_MonthCalendar::DrawHeadBK(CFGAS_GEGraphics* pGraphics,
                                    const CFX_Matrix& mtMatrix) {
  CFWL_ThemeBackground params(this, pGraphics);
  params.m_iPart = CFWL_ThemePart::Part::kHeader;
  params.m_PartRect = m_HeadRect;
  params.m_matrix = mtMatrix;
  GetThemeProvider()->DrawBackground(params);
}

void CFWL_MonthCalendar::DrawLButton(CFGAS_GEGraphics* pGraphics,
                                     const CFX_Matrix& mtMatrix) {
  CFWL_ThemeBackground params(this, pGraphics);
  params.m_iPart = CFWL_ThemePart::Part::kLBtn;
  params.m_dwStates = m_iLBtnPartStates;
  params.m_PartRect = m_LBtnRect;
  params.m_matrix = mtMatrix;
  GetThemeProvider()->DrawBackground(params);
}

void CFWL_MonthCalendar::DrawRButton(CFGAS_GEGraphics* pGraphics,
                                     const CFX_Matrix& mtMatrix) {
  CFWL_ThemeBackground params(this, pGraphics);
  params.m_iPart = CFWL_ThemePart::Part::kRBtn;
  params.m_dwStates = m_iRBtnPartStates;
  params.m_PartRect = m_RBtnRect;
  params.m_matrix = mtMatrix;
  GetThemeProvider()->DrawBackground(params);
}

void CFWL_MonthCalendar::DrawCaption(CFGAS_GEGraphics* pGraphics,
                                     const CFX_Matrix& mtMatrix) {
  CFWL_ThemeText textParam(this, pGraphics);
  textParam.m_iPart = CFWL_ThemePart::Part::kCaption;
  textParam.m_wsText = GetHeadText(m_iCurYear, m_iCurMonth);
  m_HeadSize = CalcTextSize(textParam.m_wsText, false);
  CalcHeadSize();
  textParam.m_PartRect = m_HeadTextRect;
  textParam.m_dwTTOStyles.single_line_ = true;
  textParam.m_iTTOAlign = FDE_TextAlignment::kCenter;
  textParam.m_matrix = mtMatrix;
  GetThemeProvider()->DrawText(textParam);
}

void CFWL_MonthCalendar::DrawSeparator(CFGAS_GEGraphics* pGraphics,
                                       const CFX_Matrix& mtMatrix) {
  CFWL_ThemeBackground params(this, pGraphics);
  params.m_iPart = CFWL_ThemePart::Part::kHSeparator;
  params.m_PartRect = m_HSepRect;
  params.m_matrix = mtMatrix;
  GetThemeProvider()->DrawBackground(params);
}

void CFWL_MonthCalendar::DrawDatesInBK(CFGAS_GEGraphics* pGraphics,
                                       const CFX_Matrix& mtMatrix) {
  CFWL_ThemeBackground params(this, pGraphics);
  params.m_iPart = CFWL_ThemePart::Part::kDateInBK;
  params.m_matrix = mtMatrix;

  IFWL_ThemeProvider* pTheme = GetThemeProvider();
  int32_t iCount = pdfium::CollectionSize<int32_t>(m_DateArray);
  for (int32_t j = 0; j < iCount; j++) {
    DATEINFO* pDataInfo = m_DateArray[j].get();
    if (pDataInfo->dwStates & FWL_ITEMSTATE_MCD_Selected) {
      params.m_dwStates |= CFWL_PartState_Selected;
      if (pDataInfo->dwStates & FWL_ITEMSTATE_MCD_Flag) {
        params.m_dwStates |= CFWL_PartState_Flagged;
      }
    } else if (j == m_iHovered - 1) {
      params.m_dwStates |= CFWL_PartState_Hovered;
    } else if (pDataInfo->dwStates & FWL_ITEMSTATE_MCD_Flag) {
      params.m_dwStates = CFWL_PartState_Flagged;
      pTheme->DrawBackground(params);
    }
    params.m_PartRect = pDataInfo->rect;
    pTheme->DrawBackground(params);
    params.m_dwStates = 0;
  }
}

void CFWL_MonthCalendar::DrawWeek(CFGAS_GEGraphics* pGraphics,
                                  const CFX_Matrix& mtMatrix) {
  CFWL_ThemeText params(this, pGraphics);
  params.m_iPart = CFWL_ThemePart::Part::kWeek;
  params.m_iTTOAlign = FDE_TextAlignment::kCenter;
  params.m_dwTTOStyles.single_line_ = true;
  params.m_matrix = mtMatrix;

  IFWL_ThemeProvider* pTheme = GetThemeProvider();
  CFX_RectF rtDayOfWeek;
  for (int32_t i = 0; i < 7; ++i) {
    rtDayOfWeek = CFX_RectF(
        m_WeekRect.left + i * (m_CellSize.width + MONTHCAL_HMARGIN * 2),
        m_WeekRect.top, m_CellSize);

    params.m_PartRect = rtDayOfWeek;
    params.m_wsText = GetAbbreviatedDayOfWeek(i);
    pTheme->DrawText(params);
  }
}

void CFWL_MonthCalendar::DrawToday(CFGAS_GEGraphics* pGraphics,
                                   const CFX_Matrix& mtMatrix) {
  CFWL_ThemeText params(this, pGraphics);
  params.m_iPart = CFWL_ThemePart::Part::kToday;
  params.m_iTTOAlign = FDE_TextAlignment::kCenterLeft;
  params.m_wsText = GetTodayText(m_iYear, m_iMonth, m_iDay);
  m_TodaySize = CalcTextSize(params.m_wsText, false);
  CalcTodaySize();
  params.m_PartRect = m_TodayRect;
  params.m_dwTTOStyles.single_line_ = true;
  params.m_matrix = mtMatrix;
  GetThemeProvider()->DrawText(params);
}

void CFWL_MonthCalendar::DrawDatesIn(CFGAS_GEGraphics* pGraphics,
                                     const CFX_Matrix& mtMatrix) {
  CFWL_ThemeText params(this, pGraphics);
  params.m_iPart = CFWL_ThemePart::Part::kDatesIn;
  params.m_iTTOAlign = FDE_TextAlignment::kCenter;
  params.m_matrix = mtMatrix;

  IFWL_ThemeProvider* pTheme = GetThemeProvider();
  int32_t iCount = pdfium::CollectionSize<int32_t>(m_DateArray);
  for (int32_t j = 0; j < iCount; j++) {
    DATEINFO* pDataInfo = m_DateArray[j].get();
    params.m_wsText = pDataInfo->wsDay;
    params.m_PartRect = pDataInfo->rect;
    params.m_dwStates = pDataInfo->dwStates;
    if (j + 1 == m_iHovered)
      params.m_dwStates |= CFWL_PartState_Hovered;

    params.m_dwTTOStyles.single_line_ = true;
    pTheme->DrawText(params);
  }
}

void CFWL_MonthCalendar::DrawDatesOut(CFGAS_GEGraphics* pGraphics,
                                      const CFX_Matrix& mtMatrix) {
  CFWL_ThemeText params(this, pGraphics);
  params.m_iPart = CFWL_ThemePart::Part::kDatesOut;
  params.m_iTTOAlign = FDE_TextAlignment::kCenter;
  params.m_matrix = mtMatrix;
  GetThemeProvider()->DrawText(params);
}

void CFWL_MonthCalendar::DrawDatesInCircle(CFGAS_GEGraphics* pGraphics,
                                           const CFX_Matrix& mtMatrix) {
  if (m_iMonth != m_iCurMonth || m_iYear != m_iCurYear)
    return;

  if (m_iDay < 1 || m_iDay > pdfium::CollectionSize<int32_t>(m_DateArray))
    return;

  DATEINFO* pDate = m_DateArray[m_iDay - 1].get();
  if (!pDate)
    return;

  CFWL_ThemeBackground params(this, pGraphics);
  params.m_iPart = CFWL_ThemePart::Part::kDateInCircle;
  params.m_PartRect = pDate->rect;
  params.m_matrix = mtMatrix;
  GetThemeProvider()->DrawBackground(params);
}

CFX_SizeF CFWL_MonthCalendar::CalcSize() {
  float fMaxWeekW = 0.0f;
  float fMaxWeekH = 0.0f;
  for (int i = 0; i < 7; ++i) {
    CFX_SizeF sz = CalcTextSize(GetAbbreviatedDayOfWeek(i), false);
    fMaxWeekW = (fMaxWeekW >= sz.width) ? fMaxWeekW : sz.width;
    fMaxWeekH = (fMaxWeekH >= sz.height) ? fMaxWeekH : sz.height;
  }
  float fDayMaxW = 0.0f;
  float fDayMaxH = 0.0f;
  for (int day = 10; day <= 31; day++) {
    CFX_SizeF sz = CalcTextSize(WideString::Format(L"%d", day), false);
    fDayMaxW = (fDayMaxW >= sz.width) ? fDayMaxW : sz.width;
    fDayMaxH = (fDayMaxH >= sz.height) ? fDayMaxH : sz.height;
  }
  m_CellSize.width =
      static_cast<int>(0.5 + (fMaxWeekW >= fDayMaxW ? fMaxWeekW : fDayMaxW));
  m_CellSize.height = fMaxWeekH >= fDayMaxH ? fMaxWeekH : fDayMaxH;

  CFX_SizeF fs;
  fs.width = m_CellSize.width * MONTHCAL_COLUMNS +
             MONTHCAL_HMARGIN * MONTHCAL_COLUMNS * 2 +
             MONTHCAL_HEADER_BTN_HMARGIN * 2;

  float fMonthMaxW = 0.0f;
  float fMonthMaxH = 0.0f;
  for (int i = 0; i < 12; ++i) {
    CFX_SizeF sz = CalcTextSize(GetMonth(i), false);
    fMonthMaxW = (fMonthMaxW >= sz.width) ? fMonthMaxW : sz.width;
    fMonthMaxH = (fMonthMaxH >= sz.height) ? fMonthMaxH : sz.height;
  }

  CFX_SizeF szYear = CalcTextSize(GetHeadText(m_iYear, m_iMonth), false);
  fMonthMaxH = std::max(fMonthMaxH, szYear.height);
  m_HeadSize = CFX_SizeF(fMonthMaxW + szYear.width, fMonthMaxH);
  fMonthMaxW =
      m_HeadSize.width + MONTHCAL_HEADER_BTN_HMARGIN * 2 + m_CellSize.width * 2;
  fs.width = std::max(fs.width, fMonthMaxW);

  m_wsToday = GetTodayText(m_iYear, m_iMonth, m_iDay);
  m_TodaySize = CalcTextSize(m_wsToday, false);
  m_TodaySize.height = (m_TodaySize.height >= m_CellSize.height)
                           ? m_TodaySize.height
                           : m_CellSize.height;
  fs.height = m_CellSize.width + m_CellSize.height * (MONTHCAL_ROWS - 2) +
              m_TodaySize.height + MONTHCAL_VMARGIN * MONTHCAL_ROWS * 2 +
              MONTHCAL_HEADER_BTN_VMARGIN * 4;
  return fs;
}

void CFWL_MonthCalendar::CalcHeadSize() {
  float fHeadHMargin = (m_ClientRect.width - m_HeadSize.width) / 2;
  float fHeadVMargin = (m_CellSize.width - m_HeadSize.height) / 2;
  m_HeadTextRect = CFX_RectF(m_ClientRect.left + fHeadHMargin,
                             m_ClientRect.top + MONTHCAL_HEADER_BTN_VMARGIN +
                                 MONTHCAL_VMARGIN + fHeadVMargin,
                             m_HeadSize);
}

void CFWL_MonthCalendar::CalcTodaySize() {
  m_TodayFlagRect = CFX_RectF(
      m_ClientRect.left + MONTHCAL_HEADER_BTN_HMARGIN + MONTHCAL_HMARGIN,
      m_DatesRect.bottom() + MONTHCAL_HEADER_BTN_VMARGIN + MONTHCAL_VMARGIN,
      m_CellSize.width, m_TodaySize.height);
  m_TodayRect = CFX_RectF(
      m_ClientRect.left + MONTHCAL_HEADER_BTN_HMARGIN + m_CellSize.width +
          MONTHCAL_HMARGIN * 2,
      m_DatesRect.bottom() + MONTHCAL_HEADER_BTN_VMARGIN + MONTHCAL_VMARGIN,
      m_TodaySize);
}

void CFWL_MonthCalendar::Layout() {
  m_ClientRect = GetClientRect();

  m_HeadRect = CFX_RectF(
      m_ClientRect.left + MONTHCAL_HEADER_BTN_HMARGIN, m_ClientRect.top,
      m_ClientRect.width - MONTHCAL_HEADER_BTN_HMARGIN * 2,
      m_CellSize.width + (MONTHCAL_HEADER_BTN_VMARGIN + MONTHCAL_VMARGIN) * 2);
  m_WeekRect = CFX_RectF(m_ClientRect.left + MONTHCAL_HEADER_BTN_HMARGIN,
                         m_HeadRect.bottom(),
                         m_ClientRect.width - MONTHCAL_HEADER_BTN_HMARGIN * 2,
                         m_CellSize.height + MONTHCAL_VMARGIN * 2);
  m_LBtnRect = CFX_RectF(m_ClientRect.left + MONTHCAL_HEADER_BTN_HMARGIN,
                         m_ClientRect.top + MONTHCAL_HEADER_BTN_VMARGIN,
                         m_CellSize.width, m_CellSize.width);
  m_RBtnRect = CFX_RectF(m_ClientRect.left + m_ClientRect.width -
                             MONTHCAL_HEADER_BTN_HMARGIN - m_CellSize.width,
                         m_ClientRect.top + MONTHCAL_HEADER_BTN_VMARGIN,
                         m_CellSize.width, m_CellSize.width);
  m_HSepRect = CFX_RectF(
      m_ClientRect.left + MONTHCAL_HEADER_BTN_HMARGIN + MONTHCAL_HMARGIN,
      m_WeekRect.bottom() - MONTHCAL_VMARGIN,
      m_ClientRect.width - (MONTHCAL_HEADER_BTN_HMARGIN + MONTHCAL_HMARGIN) * 2,
      MONTHCAL_HSEP_HEIGHT);
  m_DatesRect = CFX_RectF(m_ClientRect.left + MONTHCAL_HEADER_BTN_HMARGIN,
                          m_WeekRect.bottom(),
                          m_ClientRect.width - MONTHCAL_HEADER_BTN_HMARGIN * 2,
                          m_CellSize.height * (MONTHCAL_ROWS - 3) +
                              MONTHCAL_VMARGIN * (MONTHCAL_ROWS - 3) * 2);

  CalDateItem();
}

void CFWL_MonthCalendar::CalDateItem() {
  bool bNewWeek = false;
  int32_t iWeekOfMonth = 0;
  float fLeft = m_DatesRect.left;
  float fTop = m_DatesRect.top;
  for (const auto& pDateInfo : m_DateArray) {
    if (bNewWeek) {
      iWeekOfMonth++;
      bNewWeek = false;
    }
    pDateInfo->rect = CFX_RectF(
        fLeft +
            pDateInfo->iDayOfWeek * (m_CellSize.width + (MONTHCAL_HMARGIN * 2)),
        fTop + iWeekOfMonth * (m_CellSize.height + (MONTHCAL_VMARGIN * 2)),
        m_CellSize.width + (MONTHCAL_HMARGIN * 2),
        m_CellSize.height + (MONTHCAL_VMARGIN * 2));
    if (pDateInfo->iDayOfWeek >= 6)
      bNewWeek = true;
  }
}

void CFWL_MonthCalendar::InitDate() {
  CFX_DateTime now = CFX_DateTime::Now();

  m_iYear = now.GetYear();
  m_iMonth = now.GetMonth();
  m_iDay = now.GetDay();
  m_iCurYear = m_iYear;
  m_iCurMonth = m_iMonth;

  m_wsToday = GetTodayText(m_iYear, m_iMonth, m_iDay);
  m_wsHead = GetHeadText(m_iCurYear, m_iCurMonth);
  m_dtMin = DATE(1500, 12, 1);
  m_dtMax = DATE(2200, 1, 1);
}

void CFWL_MonthCalendar::ClearDateItem() {
  m_DateArray.clear();
}

void CFWL_MonthCalendar::ResetDateItem() {
  int32_t iDays = FX_DaysInMonth(m_iCurYear, m_iCurMonth);
  int32_t iDayOfWeek =
      CFX_DateTime(m_iCurYear, m_iCurMonth, 1, 0, 0, 0, 0).GetDayOfWeek();
  for (int32_t i = 0; i < iDays; i++) {
    if (iDayOfWeek >= 7)
      iDayOfWeek = 0;

    uint32_t dwStates = 0;
    if (m_iYear == m_iCurYear && m_iMonth == m_iCurMonth && m_iDay == (i + 1))
      dwStates |= FWL_ITEMSTATE_MCD_Flag;
    if (pdfium::Contains(m_SelDayArray, i + 1))
      dwStates |= FWL_ITEMSTATE_MCD_Selected;

    CFX_RectF rtDate;
    m_DateArray.push_back(std::make_unique<DATEINFO>(
        i + 1, iDayOfWeek, dwStates, rtDate, WideString::Format(L"%d", i + 1)));
    iDayOfWeek++;
  }
}

void CFWL_MonthCalendar::NextMonth() {
  int32_t iYear = m_iCurYear;
  int32_t iMonth = m_iCurMonth;
  if (iMonth >= 12) {
    iMonth = 1;
    iYear++;
  } else {
    iMonth++;
  }
  DATE dt(m_iCurYear, m_iCurMonth, 1);
  if (!(dt < m_dtMax))
    return;

  m_iCurYear = iYear, m_iCurMonth = iMonth;
  ChangeToMonth(m_iCurYear, m_iCurMonth);
}

void CFWL_MonthCalendar::PrevMonth() {
  int32_t iYear = m_iCurYear;
  int32_t iMonth = m_iCurMonth;
  if (iMonth <= 1) {
    iMonth = 12;
    iYear--;
  } else {
    iMonth--;
  }

  DATE dt(m_iCurYear, m_iCurMonth, 1);
  if (!(dt > m_dtMin))
    return;

  m_iCurYear = iYear, m_iCurMonth = iMonth;
  ChangeToMonth(m_iCurYear, m_iCurMonth);
}

void CFWL_MonthCalendar::ChangeToMonth(int32_t iYear, int32_t iMonth) {
  m_iCurYear = iYear;
  m_iCurMonth = iMonth;
  m_iHovered = -1;

  ClearDateItem();
  ResetDateItem();
  CalDateItem();
  m_wsHead = GetHeadText(m_iCurYear, m_iCurMonth);
}

void CFWL_MonthCalendar::RemoveSelDay() {
  int32_t iDatesCount = pdfium::CollectionSize<int32_t>(m_DateArray);
  for (int32_t iSelDay : m_SelDayArray) {
    if (iSelDay <= iDatesCount)
      m_DateArray[iSelDay - 1]->dwStates &= ~FWL_ITEMSTATE_MCD_Selected;
  }
  m_SelDayArray.clear();
}

void CFWL_MonthCalendar::AddSelDay(int32_t iDay) {
  DCHECK(iDay > 0);
  if (!pdfium::Contains(m_SelDayArray, iDay))
    return;

  RemoveSelDay();
  if (iDay <= pdfium::CollectionSize<int32_t>(m_DateArray))
    m_DateArray[iDay - 1]->dwStates |= FWL_ITEMSTATE_MCD_Selected;

  m_SelDayArray.push_back(iDay);
}

void CFWL_MonthCalendar::JumpToToday() {
  if (m_iYear != m_iCurYear || m_iMonth != m_iCurMonth) {
    m_iCurYear = m_iYear;
    m_iCurMonth = m_iMonth;
    ChangeToMonth(m_iYear, m_iMonth);
    AddSelDay(m_iDay);
    return;
  }

  if (!pdfium::Contains(m_SelDayArray, m_iDay))
    AddSelDay(m_iDay);
}

WideString CFWL_MonthCalendar::GetHeadText(int32_t iYear, int32_t iMonth) {
  DCHECK(iMonth > 0);
  DCHECK(iMonth < 13);

  static const wchar_t* const pMonth[] = {L"January", L"February", L"March",
                                          L"April",   L"May",      L"June",
                                          L"July",    L"August",   L"September",
                                          L"October", L"November", L"December"};
  return WideString::Format(L"%ls, %d", pMonth[iMonth - 1], iYear);
}

WideString CFWL_MonthCalendar::GetTodayText(int32_t iYear,
                                            int32_t iMonth,
                                            int32_t iDay) {
  return WideString::Format(L"Today, %d/%d/%d", iDay, iMonth, iYear);
}

int32_t CFWL_MonthCalendar::GetDayAtPoint(const CFX_PointF& point) const {
  int i = 1;  // one-based day values.
  for (const auto& pDateInfo : m_DateArray) {
    if (pDateInfo->rect.Contains(point))
      return i;
    ++i;
  }
  return -1;
}

CFX_RectF CFWL_MonthCalendar::GetDayRect(int32_t iDay) {
  if (iDay <= 0 || iDay > pdfium::CollectionSize<int32_t>(m_DateArray))
    return CFX_RectF();

  DATEINFO* pDateInfo = m_DateArray[iDay - 1].get();
  return pDateInfo ? pDateInfo->rect : CFX_RectF();
}

void CFWL_MonthCalendar::OnProcessMessage(CFWL_Message* pMessage) {
  switch (pMessage->GetType()) {
    case CFWL_Message::Type::kSetFocus:
    case CFWL_Message::Type::kKillFocus:
      GetOuter()->GetDelegate()->OnProcessMessage(pMessage);
      break;
    case CFWL_Message::Type::kKey:
      break;
    case CFWL_Message::Type::kMouse: {
      CFWL_MessageMouse* pMouse = static_cast<CFWL_MessageMouse*>(pMessage);
      switch (pMouse->m_dwCmd) {
        case FWL_MouseCommand::LeftButtonDown:
          OnLButtonDown(pMouse);
          break;
        case FWL_MouseCommand::LeftButtonUp:
          OnLButtonUp(pMouse);
          break;
        case FWL_MouseCommand::Move:
          OnMouseMove(pMouse);
          break;
        case FWL_MouseCommand::Leave:
          OnMouseLeave(pMouse);
          break;
        default:
          break;
      }
      break;
    }
    default:
      break;
  }
  // Dst target could be |this|, continue only if not destroyed by above.
  if (pMessage->GetDstTarget())
    CFWL_Widget::OnProcessMessage(pMessage);
}

void CFWL_MonthCalendar::OnDrawWidget(CFGAS_GEGraphics* pGraphics,
                                      const CFX_Matrix& matrix) {
  DrawWidget(pGraphics, matrix);
}

void CFWL_MonthCalendar::OnLButtonDown(CFWL_MessageMouse* pMsg) {
  if (m_LBtnRect.Contains(pMsg->m_pos)) {
    m_iLBtnPartStates = CFWL_PartState_Pressed;
    PrevMonth();
    RepaintRect(m_ClientRect);
  } else if (m_RBtnRect.Contains(pMsg->m_pos)) {
    m_iRBtnPartStates |= CFWL_PartState_Pressed;
    NextMonth();
    RepaintRect(m_ClientRect);
  } else if (m_TodayRect.Contains(pMsg->m_pos)) {
    JumpToToday();
    RepaintRect(m_ClientRect);
  }
}

void CFWL_MonthCalendar::OnLButtonUp(CFWL_MessageMouse* pMsg) {
  if (m_LBtnRect.Contains(pMsg->m_pos)) {
    m_iLBtnPartStates = 0;
    RepaintRect(m_LBtnRect);
    return;
  }
  if (m_RBtnRect.Contains(pMsg->m_pos)) {
    m_iRBtnPartStates = 0;
    RepaintRect(m_RBtnRect);
    return;
  }
  if (m_TodayRect.Contains(pMsg->m_pos))
    return;

  int32_t iOldSel = 0;
  if (!m_SelDayArray.empty())
    iOldSel = m_SelDayArray[0];

  int32_t iCurSel = GetDayAtPoint(pMsg->m_pos);
  if (iCurSel > 0) {
    DATEINFO* pDateInfo = m_DateArray[iCurSel - 1].get();
    CFX_RectF rtInvalidate(pDateInfo->rect);
    if (iOldSel > 0 &&
        iOldSel <= pdfium::CollectionSize<int32_t>(m_DateArray)) {
      pDateInfo = m_DateArray[iOldSel - 1].get();
      rtInvalidate.Union(pDateInfo->rect);
    }
    AddSelDay(iCurSel);
    CFWL_DateTimePicker* pDateTime =
        static_cast<CFWL_DateTimePicker*>(GetOuter());
    pDateTime->ProcessSelChanged(m_iCurYear, m_iCurMonth, iCurSel);
    pDateTime->HideMonthCalendar();
  }
}

void CFWL_MonthCalendar::OnMouseMove(CFWL_MessageMouse* pMsg) {
  bool bRepaint = false;
  CFX_RectF rtInvalidate;
  if (m_DatesRect.Contains(pMsg->m_pos)) {
    int32_t iHover = GetDayAtPoint(pMsg->m_pos);
    bRepaint = m_iHovered != iHover;
    if (bRepaint) {
      if (m_iHovered > 0)
        rtInvalidate = GetDayRect(m_iHovered);
      if (iHover > 0) {
        CFX_RectF rtDay = GetDayRect(iHover);
        if (rtInvalidate.IsEmpty())
          rtInvalidate = rtDay;
        else
          rtInvalidate.Union(rtDay);
      }
    }
    m_iHovered = iHover;
  } else {
    bRepaint = m_iHovered > 0;
    if (bRepaint)
      rtInvalidate = GetDayRect(m_iHovered);

    m_iHovered = -1;
  }
  if (bRepaint && !rtInvalidate.IsEmpty())
    RepaintRect(rtInvalidate);
}

void CFWL_MonthCalendar::OnMouseLeave(CFWL_MessageMouse* pMsg) {
  if (m_iHovered <= 0)
    return;

  CFX_RectF rtInvalidate = GetDayRect(m_iHovered);
  m_iHovered = -1;
  if (!rtInvalidate.IsEmpty())
    RepaintRect(rtInvalidate);
}

CFWL_MonthCalendar::DATEINFO::DATEINFO(int32_t day,
                                       int32_t dayofweek,
                                       uint32_t dwSt,
                                       CFX_RectF rc,
                                       const WideString& wsday)
    : iDay(day),
      iDayOfWeek(dayofweek),
      dwStates(dwSt),
      rect(rc),
      wsDay(wsday) {}

CFWL_MonthCalendar::DATEINFO::~DATEINFO() = default;
