// 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 "third_party/base/ptr_util.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 GetCapacityForDay(IFWL_ThemeProvider* pTheme,
                             CFWL_ThemePart& params,
                             uint32_t day) {
  ASSERT(day < 7);

  if (day == 0)
    return L"Sun";
  if (day == 1)
    return L"Mon";
  if (day == 2)
    return L"Tue";
  if (day == 3)
    return L"Wed";
  if (day == 4)
    return L"Thu";
  if (day == 5)
    return L"Fri";
  return L"Sat";
}

WideString GetCapacityForMonth(IFWL_ThemeProvider* pTheme,
                               CFWL_ThemePart& params,
                               uint32_t month) {
  ASSERT(month < 12);

  if (month == 0)
    return L"January";
  if (month == 1)
    return L"February";
  if (month == 2)
    return L"March";
  if (month == 3)
    return L"April";
  if (month == 4)
    return L"May";
  if (month == 5)
    return L"June";
  if (month == 6)
    return L"July";
  if (month == 7)
    return L"August";
  if (month == 8)
    return L"September";
  if (month == 9)
    return L"October";
  if (month == 10)
    return L"November";
  return L"December";
}

}  // namespace

CFWL_MonthCalendar::CFWL_MonthCalendar(
    const CFWL_App* app,
    std::unique_ptr<CFWL_WidgetProperties> properties,
    CFWL_Widget* pOuter)
    : CFWL_Widget(app, std::move(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_pProperties->m_pThemeProvider)
    m_pProperties->m_pThemeProvider = GetAvailableTheme();

  GetCapValue();
  if (!m_bInitialized) {
    InitDate();
    m_bInitialized = true;
  }

  ClearDateItem();
  ResetDateItem();
  Layout();
}

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

  if (!m_pProperties->m_pThemeProvider)
    m_pProperties->m_pThemeProvider = GetAvailableTheme();

  IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider.Get();
  if (HasBorder())
    DrawBorder(pGraphics, CFWL_Part::Border, pTheme, matrix);

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

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

void CFWL_MonthCalendar::DrawBackground(CXFA_Graphics* pGraphics,
                                        IFWL_ThemeProvider* pTheme,
                                        const CFX_Matrix* pMatrix) {
  CFWL_ThemeBackground params;
  params.m_pWidget = this;
  params.m_iPart = CFWL_Part::Background;
  params.m_pGraphics = pGraphics;
  params.m_dwStates = CFWL_PartState_Normal;
  params.m_rtPart = m_rtClient;
  if (pMatrix)
    params.m_matrix.Concat(*pMatrix);
  pTheme->DrawBackground(&params);
}

void CFWL_MonthCalendar::DrawHeadBK(CXFA_Graphics* pGraphics,
                                    IFWL_ThemeProvider* pTheme,
                                    const CFX_Matrix* pMatrix) {
  CFWL_ThemeBackground params;
  params.m_pWidget = this;
  params.m_iPart = CFWL_Part::Header;
  params.m_pGraphics = pGraphics;
  params.m_dwStates = CFWL_PartState_Normal;
  params.m_rtPart = m_rtHead;
  if (pMatrix)
    params.m_matrix.Concat(*pMatrix);
  pTheme->DrawBackground(&params);
}

void CFWL_MonthCalendar::DrawLButton(CXFA_Graphics* pGraphics,
                                     IFWL_ThemeProvider* pTheme,
                                     const CFX_Matrix* pMatrix) {
  CFWL_ThemeBackground params;
  params.m_pWidget = this;
  params.m_iPart = CFWL_Part::LBtn;
  params.m_pGraphics = pGraphics;
  params.m_dwStates = m_iLBtnPartStates;
  params.m_rtPart = m_rtLBtn;
  if (pMatrix)
    params.m_matrix.Concat(*pMatrix);
  pTheme->DrawBackground(&params);
}

void CFWL_MonthCalendar::DrawRButton(CXFA_Graphics* pGraphics,
                                     IFWL_ThemeProvider* pTheme,
                                     const CFX_Matrix* pMatrix) {
  CFWL_ThemeBackground params;
  params.m_pWidget = this;
  params.m_iPart = CFWL_Part::RBtn;
  params.m_pGraphics = pGraphics;
  params.m_dwStates = m_iRBtnPartStates;
  params.m_rtPart = m_rtRBtn;
  if (pMatrix)
    params.m_matrix.Concat(*pMatrix);
  pTheme->DrawBackground(&params);
}

void CFWL_MonthCalendar::DrawCaption(CXFA_Graphics* pGraphics,
                                     IFWL_ThemeProvider* pTheme,
                                     const CFX_Matrix* pMatrix) {
  CFWL_ThemeText textParam;
  textParam.m_pWidget = this;
  textParam.m_iPart = CFWL_Part::Caption;
  textParam.m_dwStates = CFWL_PartState_Normal;
  textParam.m_pGraphics = pGraphics;
  textParam.m_wsText = GetHeadText(m_iCurYear, m_iCurMonth);
  m_szHead = CalcTextSize(textParam.m_wsText,
                          m_pProperties->m_pThemeProvider.Get(), false);
  CalcHeadSize();
  textParam.m_rtPart = m_rtHeadText;
  textParam.m_dwTTOStyles.single_line_ = true;
  textParam.m_iTTOAlign = FDE_TextAlignment::kCenter;
  if (pMatrix)
    textParam.m_matrix.Concat(*pMatrix);
  pTheme->DrawText(&textParam);
}

void CFWL_MonthCalendar::DrawSeperator(CXFA_Graphics* pGraphics,
                                       IFWL_ThemeProvider* pTheme,
                                       const CFX_Matrix* pMatrix) {
  CFWL_ThemeBackground params;
  params.m_pWidget = this;
  params.m_iPart = CFWL_Part::HSeparator;
  params.m_pGraphics = pGraphics;
  params.m_dwStates = CFWL_PartState_Normal;
  params.m_rtPart = m_rtHSep;
  if (pMatrix)
    params.m_matrix.Concat(*pMatrix);
  pTheme->DrawBackground(&params);
}

void CFWL_MonthCalendar::DrawDatesInBK(CXFA_Graphics* pGraphics,
                                       IFWL_ThemeProvider* pTheme,
                                       const CFX_Matrix* pMatrix) {
  CFWL_ThemeBackground params;
  params.m_pWidget = this;
  params.m_iPart = CFWL_Part::DateInBK;
  params.m_pGraphics = pGraphics;
  if (pMatrix)
    params.m_matrix.Concat(*pMatrix);

  int32_t iCount = pdfium::CollectionSize<int32_t>(m_arrDates);
  for (int32_t j = 0; j < iCount; j++) {
    DATEINFO* pDataInfo = m_arrDates[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_rtPart = pDataInfo->rect;
    pTheme->DrawBackground(&params);
    params.m_dwStates = 0;
  }
}

void CFWL_MonthCalendar::DrawWeek(CXFA_Graphics* pGraphics,
                                  IFWL_ThemeProvider* pTheme,
                                  const CFX_Matrix* pMatrix) {
  CFWL_ThemeText params;
  params.m_pWidget = this;
  params.m_iPart = CFWL_Part::Week;
  params.m_pGraphics = pGraphics;
  params.m_dwStates = CFWL_PartState_Normal;
  params.m_iTTOAlign = FDE_TextAlignment::kCenter;
  params.m_dwTTOStyles.single_line_ = true;

  CFX_RectF rtDayOfWeek;
  if (pMatrix)
    params.m_matrix.Concat(*pMatrix);

  for (int32_t i = 0; i < 7; i++) {
    rtDayOfWeek =
        CFX_RectF(m_rtWeek.left + i * (m_szCell.width + MONTHCAL_HMARGIN * 2),
                  m_rtWeek.top, m_szCell);

    params.m_rtPart = rtDayOfWeek;
    params.m_wsText = GetCapacityForDay(pTheme, params, i);
    pTheme->DrawText(&params);
  }
}

void CFWL_MonthCalendar::DrawToday(CXFA_Graphics* pGraphics,
                                   IFWL_ThemeProvider* pTheme,
                                   const CFX_Matrix* pMatrix) {
  CFWL_ThemeText params;
  params.m_pWidget = this;
  params.m_iPart = CFWL_Part::Today;
  params.m_pGraphics = pGraphics;
  params.m_dwStates = CFWL_PartState_Normal;
  params.m_iTTOAlign = FDE_TextAlignment::kCenterLeft;
  params.m_wsText = GetTodayText(m_iYear, m_iMonth, m_iDay);

  m_szToday = CalcTextSize(params.m_wsText,
                           m_pProperties->m_pThemeProvider.Get(), false);
  CalcTodaySize();
  params.m_rtPart = m_rtToday;
  params.m_dwTTOStyles.single_line_ = true;

  if (pMatrix)
    params.m_matrix.Concat(*pMatrix);
  pTheme->DrawText(&params);
}

void CFWL_MonthCalendar::DrawDatesIn(CXFA_Graphics* pGraphics,
                                     IFWL_ThemeProvider* pTheme,
                                     const CFX_Matrix* pMatrix) {
  CFWL_ThemeText params;
  params.m_pWidget = this;
  params.m_iPart = CFWL_Part::DatesIn;
  params.m_pGraphics = pGraphics;
  params.m_dwStates = CFWL_PartState_Normal;
  params.m_iTTOAlign = FDE_TextAlignment::kCenter;
  if (pMatrix)
    params.m_matrix.Concat(*pMatrix);

  int32_t iCount = pdfium::CollectionSize<int32_t>(m_arrDates);
  for (int32_t j = 0; j < iCount; j++) {
    DATEINFO* pDataInfo = m_arrDates[j].get();
    params.m_wsText = pDataInfo->wsDay;
    params.m_rtPart = 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(CXFA_Graphics* pGraphics,
                                      IFWL_ThemeProvider* pTheme,
                                      const CFX_Matrix* pMatrix) {
  CFWL_ThemeText params;
  params.m_pWidget = this;
  params.m_iPart = CFWL_Part::DatesOut;
  params.m_pGraphics = pGraphics;
  params.m_dwStates = CFWL_PartState_Normal;
  params.m_iTTOAlign = FDE_TextAlignment::kCenter;
  if (pMatrix)
    params.m_matrix.Concat(*pMatrix);
  pTheme->DrawText(&params);
}

void CFWL_MonthCalendar::DrawDatesInCircle(CXFA_Graphics* pGraphics,
                                           IFWL_ThemeProvider* pTheme,
                                           const CFX_Matrix* pMatrix) {
  if (m_iMonth != m_iCurMonth || m_iYear != m_iCurYear)
    return;

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

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

  CFWL_ThemeBackground params;
  params.m_pWidget = this;
  params.m_iPart = CFWL_Part::DateInCircle;
  params.m_pGraphics = pGraphics;
  params.m_rtPart = pDate->rect;
  params.m_dwStates = CFWL_PartState_Normal;
  if (pMatrix)
    params.m_matrix.Concat(*pMatrix);
  pTheme->DrawBackground(&params);
}

CFX_SizeF CFWL_MonthCalendar::CalcSize() {
  IFWL_ThemeProvider* pTheme = m_pProperties->m_pThemeProvider.Get();
  if (!pTheme)
    return CFX_SizeF();

  CFWL_ThemePart params;
  params.m_pWidget = this;

  float fMaxWeekW = 0.0f;
  float fMaxWeekH = 0.0f;
  for (uint32_t i = 0; i < 7; ++i) {
    CFX_SizeF sz =
        CalcTextSize(GetCapacityForDay(pTheme, params, i), pTheme, 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), pTheme, false);
    fDayMaxW = (fDayMaxW >= sz.width) ? fDayMaxW : sz.width;
    fDayMaxH = (fDayMaxH >= sz.height) ? fDayMaxH : sz.height;
  }
  m_szCell.width = float((fMaxWeekW >= fDayMaxW) ? (int)(fMaxWeekW + 0.5)
                                                 : (int)(fDayMaxW + 0.5));
  m_szCell.height = (fMaxWeekH >= fDayMaxH) ? fMaxWeekH : fDayMaxH;

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

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

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

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

void CFWL_MonthCalendar::CalcHeadSize() {
  float fHeadHMargin = (m_rtClient.width - m_szHead.width) / 2;
  float fHeadVMargin = (m_szCell.width - m_szHead.height) / 2;
  m_rtHeadText = CFX_RectF(m_rtClient.left + fHeadHMargin,
                           m_rtClient.top + MONTHCAL_HEADER_BTN_VMARGIN +
                               MONTHCAL_VMARGIN + fHeadVMargin,
                           m_szHead);
}

void CFWL_MonthCalendar::CalcTodaySize() {
  m_rtTodayFlag = CFX_RectF(
      m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN + MONTHCAL_HMARGIN,
      m_rtDates.bottom() + MONTHCAL_HEADER_BTN_VMARGIN + MONTHCAL_VMARGIN,
      m_szCell.width, m_szToday.height);
  m_rtToday = CFX_RectF(
      m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN + m_szCell.width +
          MONTHCAL_HMARGIN * 2,
      m_rtDates.bottom() + MONTHCAL_HEADER_BTN_VMARGIN + MONTHCAL_VMARGIN,
      m_szToday);
}

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

  m_rtHead = CFX_RectF(
      m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN, m_rtClient.top,
      m_rtClient.width - MONTHCAL_HEADER_BTN_HMARGIN * 2,
      m_szCell.width + (MONTHCAL_HEADER_BTN_VMARGIN + MONTHCAL_VMARGIN) * 2);
  m_rtWeek = CFX_RectF(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN,
                       m_rtHead.bottom(),
                       m_rtClient.width - MONTHCAL_HEADER_BTN_HMARGIN * 2,
                       m_szCell.height + MONTHCAL_VMARGIN * 2);
  m_rtLBtn = CFX_RectF(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN,
                       m_rtClient.top + MONTHCAL_HEADER_BTN_VMARGIN,
                       m_szCell.width, m_szCell.width);
  m_rtRBtn = CFX_RectF(m_rtClient.left + m_rtClient.width -
                           MONTHCAL_HEADER_BTN_HMARGIN - m_szCell.width,
                       m_rtClient.top + MONTHCAL_HEADER_BTN_VMARGIN,
                       m_szCell.width, m_szCell.width);
  m_rtHSep = CFX_RectF(
      m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN + MONTHCAL_HMARGIN,
      m_rtWeek.bottom() - MONTHCAL_VMARGIN,
      m_rtClient.width - (MONTHCAL_HEADER_BTN_HMARGIN + MONTHCAL_HMARGIN) * 2,
      MONTHCAL_HSEP_HEIGHT);
  m_rtDates = CFX_RectF(m_rtClient.left + MONTHCAL_HEADER_BTN_HMARGIN,
                        m_rtWeek.bottom(),
                        m_rtClient.width - MONTHCAL_HEADER_BTN_HMARGIN * 2,
                        m_szCell.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_rtDates.left;
  float fTop = m_rtDates.top;
  for (const auto& pDateInfo : m_arrDates) {
    if (bNewWeek) {
      iWeekOfMonth++;
      bNewWeek = false;
    }
    pDateInfo->rect = CFX_RectF(
        fLeft +
            pDateInfo->iDayOfWeek * (m_szCell.width + (MONTHCAL_HMARGIN * 2)),
        fTop + iWeekOfMonth * (m_szCell.height + (MONTHCAL_VMARGIN * 2)),
        m_szCell.width + (MONTHCAL_HMARGIN * 2),
        m_szCell.height + (MONTHCAL_VMARGIN * 2));
    if (pDateInfo->iDayOfWeek >= 6)
      bNewWeek = true;
  }
}

void CFWL_MonthCalendar::GetCapValue() {
  if (!m_pProperties->m_pThemeProvider)
    m_pProperties->m_pThemeProvider = GetAvailableTheme();
}

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_arrDates.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::ContainsValue(m_arrSelDays, i + 1))
      dwStates |= FWL_ITEMSTATE_MCD_Selected;

    CFX_RectF rtDate;
    m_arrDates.push_back(pdfium::MakeUnique<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_arrDates);
  for (int32_t iSelDay : m_arrSelDays) {
    if (iSelDay <= iDatesCount)
      m_arrDates[iSelDay - 1]->dwStates &= ~FWL_ITEMSTATE_MCD_Selected;
  }
  m_arrSelDays.clear();
}

void CFWL_MonthCalendar::AddSelDay(int32_t iDay) {
  ASSERT(iDay > 0);
  if (!pdfium::ContainsValue(m_arrSelDays, iDay))
    return;

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

  m_arrSelDays.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::ContainsValue(m_arrSelDays, m_iDay))
    AddSelDay(m_iDay);
}

WideString CFWL_MonthCalendar::GetHeadText(int32_t iYear, int32_t iMonth) {
  ASSERT(iMonth > 0);
  ASSERT(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_arrDates) {
    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_arrDates))
    return CFX_RectF();

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

void CFWL_MonthCalendar::OnProcessMessage(CFWL_Message* pMessage) {
  if (!pMessage)
    return;

  switch (pMessage->GetType()) {
    case CFWL_Message::Type::SetFocus:
    case CFWL_Message::Type::KillFocus:
      GetOuter()->GetDelegate()->OnProcessMessage(pMessage);
      break;
    case CFWL_Message::Type::Key:
      break;
    case CFWL_Message::Type::Mouse: {
      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;
  }
  CFWL_Widget::OnProcessMessage(pMessage);
}

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

void CFWL_MonthCalendar::OnLButtonDown(CFWL_MessageMouse* pMsg) {
  if (m_rtLBtn.Contains(pMsg->m_pos)) {
    m_iLBtnPartStates = CFWL_PartState_Pressed;
    PrevMonth();
    RepaintRect(m_rtClient);
  } else if (m_rtRBtn.Contains(pMsg->m_pos)) {
    m_iRBtnPartStates |= CFWL_PartState_Pressed;
    NextMonth();
    RepaintRect(m_rtClient);
  } else if (m_rtToday.Contains(pMsg->m_pos)) {
    JumpToToday();
    RepaintRect(m_rtClient);
  }
}

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

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

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

void CFWL_MonthCalendar::OnMouseMove(CFWL_MessageMouse* pMsg) {
  bool bRepaint = false;
  CFX_RectF rtInvalidate;
  if (m_rtDates.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() {}
