// 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/include/fwl/theme/scrollbartp.h"

#include "xfa/include/fwl/basewidget/fwl_scrollbar.h"
#include "xfa/include/fwl/core/fwl_widget.h"

#define FWL_SCROLL_PawLen 12.5f

CFWL_ScrollBarTP::CFWL_ScrollBarTP() {
  m_pThemeData = new SBThemeData;
  SetThemeData(0);
}
CFWL_ScrollBarTP::~CFWL_ScrollBarTP() {
  if (m_pThemeData) {
    delete m_pThemeData;
    m_pThemeData = NULL;
  }
}
FX_BOOL CFWL_ScrollBarTP::IsValidWidget(IFWL_Widget* pWidget) {
  if (!pWidget)
    return FALSE;
  return pWidget->GetClassID() == FWL_CLASSHASH_ScrollBar;
}
void* CFWL_ScrollBarTP::GetCapacity(CFWL_ThemePart* pThemePart,
                                    FX_DWORD dwCapacity) {
  if (dwCapacity == FWL_CAPACITY_SCB_Size) {
    m_fValue = 5;
    return &m_fValue;
  }
  return CFWL_WidgetTP::GetCapacity(pThemePart, dwCapacity);
}
FX_DWORD CFWL_ScrollBarTP::SetThemeID(IFWL_Widget* pWidget,
                                      FX_DWORD dwThemeID,
                                      FX_BOOL bChildren) {
  if (m_pThemeData) {
    SetThemeData(FWL_GetThemeColor(dwThemeID));
  }
  return CFWL_WidgetTP::SetThemeID(pWidget, dwThemeID, bChildren);
}
FX_BOOL CFWL_ScrollBarTP::DrawBackground(CFWL_ThemeBackground* pParams) {
  if (!pParams)
    return FALSE;
  IFWL_Widget* pWidget = pParams->m_pWidget;
  FWLTHEME_STATE eState = FWLTHEME_STATE_Normal;
  switch (pParams->m_dwStates & 0x03) {
    case FWL_PARTSTATE_SCB_Hovered: {
      eState = FWLTHEME_STATE_Hover;
      break;
    }
    case FWL_PARTSTATE_SCB_Pressed: {
      eState = FWLTHEME_STATE_Pressed;
      break;
    }
    case FWL_PARTSTATE_SCB_Disabled: {
      eState = FWLTHEME_STATE_Disabale;
      break;
    }
  }
  CFX_Graphics* pGraphics = pParams->m_pGraphics;
  CFX_RectF* pRect = &pParams->m_rtPart;
  FX_BOOL bVert = pWidget->GetStylesEx();
  switch (pParams->m_iPart) {
    case FWL_PART_SCB_ForeArrow: {
      DrawMaxMinBtn(pGraphics, pRect,
                    bVert ? FWLTHEME_DIRECTION_Up : FWLTHEME_DIRECTION_Left,
                    eState, &pParams->m_matrix);
      break;
    }
    case FWL_PART_SCB_BackArrow: {
      DrawMaxMinBtn(pGraphics, pRect,
                    bVert ? FWLTHEME_DIRECTION_Down : FWLTHEME_DIRECTION_Right,
                    eState, &pParams->m_matrix);
      break;
    }
    case FWL_PART_SCB_Thumb: {
      DrawThumbBtn(pGraphics, pRect, bVert, eState, TRUE, &pParams->m_matrix);
      break;
    }
    case FWL_PART_SCB_LowerTrack: {
      DrawTrack(pGraphics, pRect, bVert, eState, TRUE, &pParams->m_matrix);
      break;
    }
    case FWL_PART_SCB_UpperTrack: {
      DrawTrack(pGraphics, pRect, bVert, eState, FALSE, &pParams->m_matrix);
      break;
    }
    default: {}
  }
  return TRUE;
}
#ifdef THEME_XPSimilar
void CFWL_ScrollBarTP::DrawThumbBtn(CFX_Graphics* pGraphics,
                                    const CFX_RectF* pRect,
                                    FX_BOOL bVert,
                                    FWLTHEME_STATE eState,
                                    FX_BOOL bPawButton,
                                    CFX_Matrix* pMatrix) {
  if (eState < FWLTHEME_STATE_Normal || eState > FWLTHEME_STATE_Disabale) {
    return;
  }
  CFX_Path path;
  path.Create();
  CFX_RectF rect(*pRect);
  if (bVert) {
    rect.Deflate(1, 0);
    if (rect.IsEmpty(0.1f)) {
      return;
    }
    path.AddRectangle(rect.left, rect.top, rect.width, rect.height);
    DrawAxialShading(pGraphics, rect.left, rect.top, rect.right(), rect.top,
                     m_pThemeData->clrBtnBK[eState - 1][0],
                     m_pThemeData->clrBtnBK[eState - 1][1], &path,
                     FXFILL_WINDING, pMatrix);
    CFX_Color rcStroke;
    rcStroke.Set(m_pThemeData->clrBtnBorder[eState - 1]);
    pGraphics->SaveGraphState();
    pGraphics->SetStrokeColor(&rcStroke);
    pGraphics->StrokePath(&path, pMatrix);
    pGraphics->RestoreGraphState();
  } else {
    rect.Deflate(0, 1);
    if (rect.IsEmpty(0.1f)) {
      return;
    }
    path.AddRectangle(rect.left, rect.top, rect.width, rect.height);
    DrawAxialShading(pGraphics, rect.left, rect.top, rect.left, rect.bottom(),
                     m_pThemeData->clrBtnBK[eState - 1][0],
                     m_pThemeData->clrBtnBK[eState - 1][1], &path,
                     FXFILL_WINDING, pMatrix);
    CFX_Color rcStroke;
    rcStroke.Set(m_pThemeData->clrBtnBorder[eState - 1]);
    pGraphics->SaveGraphState();
    pGraphics->SetStrokeColor(&rcStroke);
    pGraphics->StrokePath(&path, pMatrix);
    pGraphics->RestoreGraphState();
  }
}
void CFWL_ScrollBarTP::DrawPaw(CFX_Graphics* pGraphics,
                               const CFX_RectF* pRect,
                               FX_BOOL bVert,
                               FWLTHEME_STATE eState,
                               CFX_Matrix* pMatrix) {
  CFX_Path path;
  path.Create();
  if (bVert) {
    FX_FLOAT fPawLen = FWL_SCROLL_PawLen;
    if (pRect->width / 2 <= fPawLen) {
      fPawLen = (pRect->width - 6) / 2;
    }
    FX_FLOAT fX = pRect->left + pRect->width / 4;
    FX_FLOAT fY = pRect->top + pRect->height / 2;
    path.MoveTo(fX, fY - 4);
    path.LineTo(fX + fPawLen, fY - 4);
    path.MoveTo(fX, fY - 2);
    path.LineTo(fX + fPawLen, fY - 2);
    path.MoveTo(fX, fY);
    path.LineTo(fX + fPawLen, fY);
    path.MoveTo(fX, fY + 2);
    path.LineTo(fX + fPawLen, fY + 2);
    CFX_Color clrLight(m_pThemeData->clrPawColorLight[eState - 1]);
    pGraphics->SetLineWidth(1);
    pGraphics->SetStrokeColor(&clrLight);
    pGraphics->StrokePath(&path);
    fX++;
    path.Clear();
    path.MoveTo(fX, fY - 3);
    path.LineTo(fX + fPawLen, fY - 3);
    path.MoveTo(fX, fY - 1);
    path.LineTo(fX + fPawLen, fY - 1);
    path.MoveTo(fX, fY + 1);
    path.LineTo(fX + fPawLen, fY + 1);
    path.MoveTo(fX, fY + 3);
    path.LineTo(fX + fPawLen, fY + 3);
    CFX_Color clrDark(m_pThemeData->clrPawColorDark[eState - 1]);
    pGraphics->SetLineWidth(1);
    pGraphics->SetStrokeColor(&clrDark);
    pGraphics->StrokePath(&path, pMatrix);
  } else {
    FX_FLOAT fPawLen = FWL_SCROLL_PawLen;
    if (pRect->height / 2 <= fPawLen) {
      fPawLen = (pRect->height - 6) / 2;
    }
    FX_FLOAT fX = pRect->left + pRect->width / 2;
    FX_FLOAT fY = pRect->top + pRect->height / 4;
    path.MoveTo(fX - 4, fY);
    path.LineTo(fX - 4, fY + fPawLen);
    path.MoveTo(fX - 2, fY);
    path.LineTo(fX - 2, fY + fPawLen);
    path.MoveTo(fX, fY);
    path.LineTo(fX, fY + fPawLen);
    path.MoveTo(fX + 2, fY);
    path.LineTo(fX + 2, fY + fPawLen);
    CFX_Color clrLight(m_pThemeData->clrPawColorLight[eState - 1]);
    pGraphics->SetLineWidth(1);
    pGraphics->SetStrokeColor(&clrLight);
    pGraphics->StrokePath(&path, pMatrix);
    fY++;
    path.Clear();
    path.MoveTo(fX - 3, fY);
    path.LineTo(fX - 3, fY + fPawLen);
    path.MoveTo(fX - 1, fY);
    path.LineTo(fX - 1, fY + fPawLen);
    path.MoveTo(fX + 1, fY);
    path.LineTo(fX + 1, fY + fPawLen);
    path.MoveTo(fX + 3, fY);
    path.LineTo(fX + 3, fY + fPawLen);
    CFX_Color clrDark(m_pThemeData->clrPawColorDark[eState - 1]);
    pGraphics->SetLineWidth(1);
    pGraphics->SetStrokeColor(&clrDark);
    pGraphics->StrokePath(&path, pMatrix);
  }
}
void CFWL_ScrollBarTP::DrawTrack(CFX_Graphics* pGraphics,
                                 const CFX_RectF* pRect,
                                 FX_BOOL bVert,
                                 FWLTHEME_STATE eState,
                                 FX_BOOL bLowerTrack,
                                 CFX_Matrix* pMatrix) {
  if (eState < FWLTHEME_STATE_Normal || eState > FWLTHEME_STATE_Disabale) {
    return;
  }
  pGraphics->SaveGraphState();
  CFX_Color colorLine(ArgbEncode(255, 238, 237, 229));
  CFX_Path path;
  path.Create();
  FX_FLOAT fRight = pRect->right();
  FX_FLOAT fBottom = pRect->bottom();
  if (bVert) {
    path.AddRectangle(pRect->left, pRect->top, 1, pRect->height);
    path.AddRectangle(fRight - 1, pRect->top, 1, pRect->height);
  } else {
    path.AddRectangle(pRect->left, pRect->top, pRect->width, 1);
    path.AddRectangle(pRect->left, fBottom - 1, pRect->width, 1);
  }
  pGraphics->SetFillColor(&colorLine);
  pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
  path.Clear();
  path.AddRectangle(pRect->left + 1, pRect->top, pRect->width - 2,
                    pRect->height);
  FX_FLOAT x1 = bVert ? pRect->left + 1 : pRect->left;
  FX_FLOAT y1 = bVert ? pRect->top : pRect->top + 1;
  FX_FLOAT x2 = bVert ? fRight - 1 : pRect->left;
  FX_FLOAT y2 = bVert ? pRect->top : fBottom - 1;
  pGraphics->RestoreGraphState();
  DrawAxialShading(pGraphics, x1, y1, x2, y2, m_pThemeData->clrTrackBKStart,
                   m_pThemeData->clrTrackBKEnd, &path, FXFILL_WINDING, pMatrix);
}
void CFWL_ScrollBarTP::DrawMaxMinBtn(CFX_Graphics* pGraphics,
                                     const CFX_RectF* pRect,
                                     FWLTHEME_DIRECTION eDict,
                                     FWLTHEME_STATE eState,
                                     CFX_Matrix* pMatrix) {
  DrawTrack(pGraphics, pRect,
            eDict == FWLTHEME_DIRECTION_Up || eDict == FWLTHEME_DIRECTION_Down,
            eState, TRUE, pMatrix);
  CFX_RectF rtArrowBtn(*pRect);
  rtArrowBtn.Deflate(1, 1, 1, 1);
  DrawArrowBtn(pGraphics, &rtArrowBtn, eDict, eState, pMatrix);
}
#else
void CFWL_ScrollBarTP::DrawThumbBtn(CFX_Graphics* pGraphics,
                                    const CFX_RectF* pRect,
                                    FX_BOOL bVert,
                                    FWLTHEME_STATE eState,
                                    FX_BOOL bPawButton,
                                    CFX_Matrix* pMatrix) {
  if (pRect->IsEmpty()) {
    return;
  }
  CFX_RectF rtThumb(*pRect);
  FX_FLOAT fWidth = 2;
  Draw3DRect(pGraphics, FWLTHEME_EDGE_Raised, fWidth, pRect,
             FWLTHEME_COLOR_EDGELT1, FWLTHEME_COLOR_EDGELT2,
             FWLTHEME_COLOR_EDGERB1, FWLTHEME_COLOR_EDGERB2, pMatrix);
  CFX_Path path;
  path.Create();
  path.AddRectangle(pRect->left + fWidth, pRect->top + fWidth,
                    pRect->width - 2 * fWidth, pRect->height - 2 * fWidth);
  pGraphics->SaveGraphState();
  CFX_Color crFill(FWLTHEME_COLOR_Background);
  pGraphics->SetFillColor(&crFill);
  pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
  pGraphics->RestoreGraphState();
}
void CFWL_ScrollBarTP::DrawTrack(CFX_Graphics* pGraphics,
                                 const CFX_RectF* pRect,
                                 FX_BOOL bVert,
                                 FWLTHEME_STATE eState,
                                 FX_BOOL bLowerTrack,
                                 CFX_Matrix* pMatrix) {
  if (pRect->IsEmpty()) {
    return;
  }
  CFX_Path path;
  path.Create();
  path.AddRectangle(pRect->left, pRect->top, pRect->width, pRect->height);
  pGraphics->SaveGraphState();
  CFX_Color clrFill(0xFFF0F0F0);
  pGraphics->SetFillColor(&clrFill);
  pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
  pGraphics->RestoreGraphState();
}
void CFWL_ScrollBarTP::DrawMaxMinBtn(CFX_Graphics* pGraphics,
                                     const CFX_RectF* pRect,
                                     FWLTHEME_DIRECTION eDict,
                                     FWLTHEME_STATE eState,
                                     CFX_Matrix* pMatrix) {
  CFX_RectF rtThumb(*pRect);
  FX_FLOAT fWidth = eState == FWLTHEME_STATE_Pressed ? 1.0f : 2.0f;
  FWLTHEME_EDGE eType = eState == FWLTHEME_STATE_Pressed ? FWLTHEME_EDGE_Flat
                                                         : FWLTHEME_EDGE_Raised;
  Draw3DRect(pGraphics, eType, fWidth, pRect, FWLTHEME_COLOR_EDGELT1,
             FWLTHEME_COLOR_EDGELT2, FWLTHEME_COLOR_EDGERB1,
             FWLTHEME_COLOR_EDGERB2, pMatrix);
  CFX_Path path;
  path.Create();
  path.AddRectangle(pRect->left + fWidth, pRect->top + fWidth,
                    pRect->width - 2 * fWidth, pRect->height - 2 * fWidth);
  pGraphics->SaveGraphState();
  CFX_Color crFill(FWLTHEME_COLOR_Background);
  pGraphics->SetFillColor(&crFill);
  pGraphics->FillPath(&path, FXFILL_WINDING, pMatrix);
  pGraphics->RestoreGraphState();
  DrawArrow(pGraphics, pRect, eDict,
            eState == FWLTHEME_STATE_Disabale ? 0xFFA0A0A0 : 0xFF000000,
            eState == FWLTHEME_STATE_Pressed, pMatrix);
}
#endif
void CFWL_ScrollBarTP::SetThemeData(FX_DWORD dwID) {
  m_pThemeData->clrPawColorLight[3] = ArgbEncode(0xff, 208, 223, 172);
  m_pThemeData->clrPawColorDark[3] = ArgbEncode(0xff, 140, 157, 115);
  m_pThemeData->clrBtnBK[3][0] = ArgbEncode(0xff, 164, 180, 139);
  m_pThemeData->clrBtnBK[3][1] = ArgbEncode(0xff, 141, 157, 115);
  m_pThemeData->clrBtnBorder[3] = ArgbEncode(0xff, 236, 233, 216);
  if (dwID) {
    m_pThemeData->clrPawColorLight[0] = ArgbEncode(0xff, 208, 223, 172);
    m_pThemeData->clrPawColorDark[0] = ArgbEncode(0xff, 140, 157, 115);
    m_pThemeData->clrBtnBK[0][0] = ArgbEncode(0xff, 162, 179, 141);
    m_pThemeData->clrBtnBK[0][1] = ArgbEncode(0xff, 149, 167, 117);
    m_pThemeData->clrBtnBorder[0] = ArgbEncode(0xff, 142, 153, 125);
    m_pThemeData->clrPawColorLight[1] = ArgbEncode(0xff, 235, 245, 212);
    m_pThemeData->clrPawColorDark[1] = ArgbEncode(0xff, 182, 198, 142);
    m_pThemeData->clrBtnBK[1][0] = ArgbEncode(0xff, 200, 213, 170);
    m_pThemeData->clrBtnBK[1][1] = ArgbEncode(0xff, 195, 208, 150);
    m_pThemeData->clrBtnBorder[1] = ArgbEncode(0xff, 189, 203, 150);
    m_pThemeData->clrPawColorLight[2] = ArgbEncode(0xff, 208, 223, 172);
    m_pThemeData->clrPawColorDark[2] = ArgbEncode(0xff, 140, 157, 115);
    m_pThemeData->clrBtnBK[2][0] = ArgbEncode(0xff, 164, 180, 139);
    m_pThemeData->clrBtnBK[2][1] = ArgbEncode(0xff, 141, 157, 115);
    m_pThemeData->clrBtnBorder[2] = ArgbEncode(0xff, 128, 146, 102);
    m_pThemeData->clrTrackBKStart = ArgbEncode(0xff, 243, 241, 236);
    m_pThemeData->clrTrackBKEnd = ArgbEncode(0xff, 254, 254, 251);
  } else {
    m_pThemeData->clrPawColorLight[0] = ArgbEncode(0xff, 238, 244, 254);
    m_pThemeData->clrPawColorDark[0] = ArgbEncode(0xff, 140, 176, 248);
    m_pThemeData->clrBtnBK[0][0] = ArgbEncode(0xff, 197, 213, 252);
    m_pThemeData->clrBtnBK[0][1] = ArgbEncode(0xff, 182, 205, 251);
    m_pThemeData->clrBtnBorder[0] = ArgbEncode(0xff, 148, 176, 221);
    m_pThemeData->clrPawColorLight[1] = ArgbEncode(0xff, 252, 253, 255);
    m_pThemeData->clrPawColorDark[1] = ArgbEncode(0xff, 156, 197, 255);
    m_pThemeData->clrBtnBK[1][0] = ArgbEncode(0xff, 216, 232, 255);
    m_pThemeData->clrBtnBK[1][1] = ArgbEncode(0xff, 204, 225, 255);
    m_pThemeData->clrBtnBorder[1] = ArgbEncode(0xff, 218, 230, 254);
    m_pThemeData->clrPawColorLight[2] = ArgbEncode(0xff, 207, 221, 253);
    m_pThemeData->clrPawColorDark[2] = ArgbEncode(0xff, 131, 158, 216);
    m_pThemeData->clrBtnBK[2][0] = ArgbEncode(0xff, 167, 190, 245);
    m_pThemeData->clrBtnBK[2][1] = ArgbEncode(0xff, 146, 179, 249);
    m_pThemeData->clrBtnBorder[2] = ArgbEncode(0xff, 124, 159, 211);
    m_pThemeData->clrTrackBKStart = ArgbEncode(0xff, 243, 241, 236);
    m_pThemeData->clrTrackBKEnd = ArgbEncode(0xff, 254, 254, 251);
  }
}
