// 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 "../../include/pdfwindow/PDFWindow.h"
#include "../../include/pdfwindow/PWL_Wnd.h"
#include "../../include/pdfwindow/PWL_ScrollBar.h"
#include "../../include/pdfwindow/PWL_Utils.h"

#define IsFloatZero(f) ((f) < 0.0001 && (f) > -0.0001)
#define IsFloatBigger(fa, fb) ((fa) > (fb) && !IsFloatZero((fa) - (fb)))
#define IsFloatSmaller(fa, fb) ((fa) < (fb) && !IsFloatZero((fa) - (fb)))
#define IsFloatEqual(fa, fb) IsFloatZero((fa) - (fb))

/* ------------------------------- PWL_FLOATRANGE
 * ------------------------------- */

PWL_FLOATRANGE::PWL_FLOATRANGE() {
  Default();
}

PWL_FLOATRANGE::PWL_FLOATRANGE(FX_FLOAT min, FX_FLOAT max) {
  Set(min, max);
}

void PWL_FLOATRANGE::Default() {
  fMin = 0;
  fMax = 0;
}

void PWL_FLOATRANGE::Set(FX_FLOAT min, FX_FLOAT max) {
  if (min > max) {
    fMin = max;
    fMax = min;
  } else {
    fMin = min;
    fMax = max;
  }
}

FX_BOOL PWL_FLOATRANGE::In(FX_FLOAT x) const {
  return (IsFloatBigger(x, fMin) || IsFloatEqual(x, fMin)) &&
         (IsFloatSmaller(x, fMax) || IsFloatEqual(x, fMax));
}

FX_FLOAT PWL_FLOATRANGE::GetWidth() const {
  return fMax - fMin;
}

/* ------------------------------- PWL_SCROLL_PRIVATEDATA
 * ------------------------------- */

PWL_SCROLL_PRIVATEDATA::PWL_SCROLL_PRIVATEDATA() {
  Default();
}

void PWL_SCROLL_PRIVATEDATA::Default() {
  ScrollRange.Default();
  fScrollPos = ScrollRange.fMin;
  fClientWidth = 0;
  fBigStep = 10;
  fSmallStep = 1;
}

void PWL_SCROLL_PRIVATEDATA::SetScrollRange(FX_FLOAT min, FX_FLOAT max) {
  ScrollRange.Set(min, max);

  if (IsFloatSmaller(fScrollPos, ScrollRange.fMin))
    fScrollPos = ScrollRange.fMin;
  if (IsFloatBigger(fScrollPos, ScrollRange.fMax))
    fScrollPos = ScrollRange.fMax;
}

void PWL_SCROLL_PRIVATEDATA::SetClientWidth(FX_FLOAT width) {
  fClientWidth = width;
}

void PWL_SCROLL_PRIVATEDATA::SetSmallStep(FX_FLOAT step) {
  fSmallStep = step;
}

void PWL_SCROLL_PRIVATEDATA::SetBigStep(FX_FLOAT step) {
  fBigStep = step;
}

FX_BOOL PWL_SCROLL_PRIVATEDATA::SetPos(FX_FLOAT pos) {
  if (ScrollRange.In(pos)) {
    fScrollPos = pos;
    return TRUE;
  }
  return FALSE;
}

void PWL_SCROLL_PRIVATEDATA::AddSmall() {
  if (!SetPos(fScrollPos + fSmallStep))
    SetPos(ScrollRange.fMax);
}

void PWL_SCROLL_PRIVATEDATA::SubSmall() {
  if (!SetPos(fScrollPos - fSmallStep))
    SetPos(ScrollRange.fMin);
}

void PWL_SCROLL_PRIVATEDATA::AddBig() {
  if (!SetPos(fScrollPos + fBigStep))
    SetPos(ScrollRange.fMax);
}

void PWL_SCROLL_PRIVATEDATA::SubBig() {
  if (!SetPos(fScrollPos - fBigStep))
    SetPos(ScrollRange.fMin);
}

/* ------------------------------- CPWL_SBButton -------------------------------
 */

CPWL_SBButton::CPWL_SBButton(PWL_SCROLLBAR_TYPE eScrollBarType,
                             PWL_SBBUTTON_TYPE eButtonType) {
  m_eScrollBarType = eScrollBarType;
  m_eSBButtonType = eButtonType;

  m_bMouseDown = FALSE;
}

CPWL_SBButton::~CPWL_SBButton() {}

CFX_ByteString CPWL_SBButton::GetClassName() const {
  return "CPWL_SBButton";
}

void CPWL_SBButton::OnCreate(PWL_CREATEPARAM& cp) {
  cp.eCursorType = FXCT_ARROW;
}

void CPWL_SBButton::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
  CPWL_Wnd::GetThisAppearanceStream(sAppStream);

  if (!IsVisible())
    return;

  CFX_ByteTextBuf sButton;

  CPDF_Rect rectWnd = GetWindowRect();

  if (rectWnd.IsEmpty())
    return;

  sAppStream << "q\n";

  CPDF_Point ptCenter = GetCenterPoint();

  switch (m_eScrollBarType) {
    case SBT_HSCROLL:
      switch (m_eSBButtonType) {
        case PSBT_MIN: {
          CPDF_Point pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f, ptCenter.y);
          CPDF_Point pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f,
                         ptCenter.y + PWL_TRIANGLE_HALFLEN);
          CPDF_Point pt3(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f,
                         ptCenter.y - PWL_TRIANGLE_HALFLEN);

          if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 &&
              rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) {
            sButton << "0 g\n";
            sButton << pt1.x << " " << pt1.y << " m\n";
            sButton << pt2.x << " " << pt2.y << " l\n";
            sButton << pt3.x << " " << pt3.y << " l\n";
            sButton << pt1.x << " " << pt1.y << " l f\n";

            sAppStream << sButton;
          }
        } break;
        case PSBT_MAX: {
          CPDF_Point pt1(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f, ptCenter.y);
          CPDF_Point pt2(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f,
                         ptCenter.y + PWL_TRIANGLE_HALFLEN);
          CPDF_Point pt3(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f,
                         ptCenter.y - PWL_TRIANGLE_HALFLEN);

          if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 &&
              rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) {
            sButton << "0 g\n";
            sButton << pt1.x << " " << pt1.y << " m\n";
            sButton << pt2.x << " " << pt2.y << " l\n";
            sButton << pt3.x << " " << pt3.y << " l\n";
            sButton << pt1.x << " " << pt1.y << " l f\n";

            sAppStream << sButton;
          }
        } break;
        default:
          break;
      }
      break;
    case SBT_VSCROLL:
      switch (m_eSBButtonType) {
        case PSBT_MIN: {
          CPDF_Point pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN,
                         ptCenter.y - PWL_TRIANGLE_HALFLEN * 0.5f);
          CPDF_Point pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN,
                         ptCenter.y - PWL_TRIANGLE_HALFLEN * 0.5f);
          CPDF_Point pt3(ptCenter.x, ptCenter.y + PWL_TRIANGLE_HALFLEN * 0.5f);

          if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 &&
              rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) {
            sButton << "0 g\n";
            sButton << pt1.x << " " << pt1.y << " m\n";
            sButton << pt2.x << " " << pt2.y << " l\n";
            sButton << pt3.x << " " << pt3.y << " l\n";
            sButton << pt1.x << " " << pt1.y << " l f\n";

            sAppStream << sButton;
          }
        } break;
        case PSBT_MAX: {
          CPDF_Point pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN,
                         ptCenter.y + PWL_TRIANGLE_HALFLEN * 0.5f);
          CPDF_Point pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN,
                         ptCenter.y + PWL_TRIANGLE_HALFLEN * 0.5f);
          CPDF_Point pt3(ptCenter.x, ptCenter.y - PWL_TRIANGLE_HALFLEN * 0.5f);

          if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 &&
              rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) {
            sButton << "0 g\n";
            sButton << pt1.x << " " << pt1.y << " m\n";
            sButton << pt2.x << " " << pt2.y << " l\n";
            sButton << pt3.x << " " << pt3.y << " l\n";
            sButton << pt1.x << " " << pt1.y << " l f\n";

            sAppStream << sButton;
          }
        } break;
        default:
          break;
      }
      break;
    default:
      break;
  }

  sAppStream << "Q\n";
}

void CPWL_SBButton::DrawThisAppearance(CFX_RenderDevice* pDevice,
                                       CPDF_Matrix* pUser2Device) {
  if (!IsVisible())
    return;

  CPDF_Rect rectWnd = GetWindowRect();
  if (rectWnd.IsEmpty())
    return;

  CPDF_Point ptCenter = GetCenterPoint();
  int32_t nTransparancy = GetTransparency();

  switch (m_eScrollBarType) {
    case SBT_HSCROLL:
      CPWL_Wnd::DrawThisAppearance(pDevice, pUser2Device);
      switch (m_eSBButtonType) {
        case PSBT_MIN: {
          CPDF_Point pt1(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f, ptCenter.y);
          CPDF_Point pt2(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f,
                         ptCenter.y + PWL_TRIANGLE_HALFLEN);
          CPDF_Point pt3(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f,
                         ptCenter.y - PWL_TRIANGLE_HALFLEN);

          if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 &&
              rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) {
            CFX_PathData path;

            path.SetPointCount(4);
            path.SetPoint(0, pt1.x, pt1.y, FXPT_MOVETO);
            path.SetPoint(1, pt2.x, pt2.y, FXPT_LINETO);
            path.SetPoint(2, pt3.x, pt3.y, FXPT_LINETO);
            path.SetPoint(3, pt1.x, pt1.y, FXPT_LINETO);

            pDevice->DrawPath(&path, pUser2Device, NULL,
                              CPWL_Utils::PWLColorToFXColor(
                                  PWL_DEFAULT_BLACKCOLOR, nTransparancy),
                              0, FXFILL_ALTERNATE);
          }
        } break;
        case PSBT_MAX: {
          CPDF_Point pt1(ptCenter.x + PWL_TRIANGLE_HALFLEN * 0.5f, ptCenter.y);
          CPDF_Point pt2(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f,
                         ptCenter.y + PWL_TRIANGLE_HALFLEN);
          CPDF_Point pt3(ptCenter.x - PWL_TRIANGLE_HALFLEN * 0.5f,
                         ptCenter.y - PWL_TRIANGLE_HALFLEN);

          if (rectWnd.right - rectWnd.left > PWL_TRIANGLE_HALFLEN * 2 &&
              rectWnd.top - rectWnd.bottom > PWL_TRIANGLE_HALFLEN) {
            CFX_PathData path;

            path.SetPointCount(4);
            path.SetPoint(0, pt1.x, pt1.y, FXPT_MOVETO);
            path.SetPoint(1, pt2.x, pt2.y, FXPT_LINETO);
            path.SetPoint(2, pt3.x, pt3.y, FXPT_LINETO);
            path.SetPoint(3, pt1.x, pt1.y, FXPT_LINETO);

            pDevice->DrawPath(&path, pUser2Device, NULL,
                              CPWL_Utils::PWLColorToFXColor(
                                  PWL_DEFAULT_BLACKCOLOR, nTransparancy),
                              0, FXFILL_ALTERNATE);
          }
        } break;
        default:
          break;
      }
      break;
    case SBT_VSCROLL:
      switch (m_eSBButtonType) {
        case PSBT_MIN: {
          // draw border
          CPDF_Rect rcDraw = rectWnd;
          CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw,
                                     ArgbEncode(nTransparancy, 100, 100, 100),
                                     0.0f);

          // draw inner border
          rcDraw = CPWL_Utils::DeflateRect(rectWnd, 0.5f);
          CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw,
                                     ArgbEncode(nTransparancy, 255, 255, 255),
                                     1.0f);

          // draw background

          rcDraw = CPWL_Utils::DeflateRect(rectWnd, 1.0f);

          if (IsEnabled())
            CPWL_Utils::DrawShadow(pDevice, pUser2Device, TRUE, FALSE, rcDraw,
                                   nTransparancy, 80, 220);
          else
            CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcDraw,
                                     ArgbEncode(255, 255, 255, 255));

          // draw arrow

          if (rectWnd.top - rectWnd.bottom > 6.0f) {
            FX_FLOAT fX = rectWnd.left + 1.5f;
            FX_FLOAT fY = rectWnd.bottom;
            CPDF_Point pts[7] = {CPDF_Point(fX + 2.5f, fY + 4.0f),
                                 CPDF_Point(fX + 2.5f, fY + 3.0f),
                                 CPDF_Point(fX + 4.5f, fY + 5.0f),
                                 CPDF_Point(fX + 6.5f, fY + 3.0f),
                                 CPDF_Point(fX + 6.5f, fY + 4.0f),
                                 CPDF_Point(fX + 4.5f, fY + 6.0f),
                                 CPDF_Point(fX + 2.5f, fY + 4.0f)};

            if (IsEnabled())
              CPWL_Utils::DrawFillArea(
                  pDevice, pUser2Device, pts, 7,
                  ArgbEncode(nTransparancy, 255, 255, 255));
            else
              CPWL_Utils::DrawFillArea(pDevice, pUser2Device, pts, 7,
                                       CPWL_Utils::PWLColorToFXColor(
                                           PWL_DEFAULT_HEAVYGRAYCOLOR, 255));
          }
        } break;
        case PSBT_MAX: {
          // draw border
          CPDF_Rect rcDraw = rectWnd;
          CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw,
                                     ArgbEncode(nTransparancy, 100, 100, 100),
                                     0.0f);

          // draw inner border
          rcDraw = CPWL_Utils::DeflateRect(rectWnd, 0.5f);
          CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw,
                                     ArgbEncode(nTransparancy, 255, 255, 255),
                                     1.0f);

          // draw background
          rcDraw = CPWL_Utils::DeflateRect(rectWnd, 1.0f);
          if (IsEnabled())
            CPWL_Utils::DrawShadow(pDevice, pUser2Device, TRUE, FALSE, rcDraw,
                                   nTransparancy, 80, 220);
          else
            CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcDraw,
                                     ArgbEncode(255, 255, 255, 255));

          // draw arrow

          if (rectWnd.top - rectWnd.bottom > 6.0f) {
            FX_FLOAT fX = rectWnd.left + 1.5f;
            FX_FLOAT fY = rectWnd.bottom;

            CPDF_Point pts[7] = {CPDF_Point(fX + 2.5f, fY + 5.0f),
                                 CPDF_Point(fX + 2.5f, fY + 6.0f),
                                 CPDF_Point(fX + 4.5f, fY + 4.0f),
                                 CPDF_Point(fX + 6.5f, fY + 6.0f),
                                 CPDF_Point(fX + 6.5f, fY + 5.0f),
                                 CPDF_Point(fX + 4.5f, fY + 3.0f),
                                 CPDF_Point(fX + 2.5f, fY + 5.0f)};

            if (IsEnabled())
              CPWL_Utils::DrawFillArea(
                  pDevice, pUser2Device, pts, 7,
                  ArgbEncode(nTransparancy, 255, 255, 255));
            else
              CPWL_Utils::DrawFillArea(pDevice, pUser2Device, pts, 7,
                                       CPWL_Utils::PWLColorToFXColor(
                                           PWL_DEFAULT_HEAVYGRAYCOLOR, 255));
          }
        } break;
        case PSBT_POS: {
          // CPWL_Wnd::DrawThisAppearance(pDevice,pUser2Device);

          // draw border
          CPDF_Rect rcDraw = rectWnd;
          CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw,
                                     ArgbEncode(nTransparancy, 100, 100, 100),
                                     0.0f);

          // draw inner border
          rcDraw = CPWL_Utils::DeflateRect(rectWnd, 0.5f);
          CPWL_Utils::DrawStrokeRect(pDevice, pUser2Device, rcDraw,
                                     ArgbEncode(nTransparancy, 255, 255, 255),
                                     1.0f);

          if (IsEnabled()) {
            // draw shadow effect

            CPDF_Point ptTop = CPDF_Point(rectWnd.left, rectWnd.top - 1.0f);
            CPDF_Point ptBottom =
                CPDF_Point(rectWnd.left, rectWnd.bottom + 1.0f);

            ptTop.x += 1.5f;
            ptBottom.x += 1.5f;

            CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom,
                                       ArgbEncode(nTransparancy, 210, 210, 210),
                                       1.0f);

            ptTop.x += 1.0f;
            ptBottom.x += 1.0f;

            CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom,
                                       ArgbEncode(nTransparancy, 220, 220, 220),
                                       1.0f);

            ptTop.x += 1.0f;
            ptBottom.x += 1.0f;

            CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom,
                                       ArgbEncode(nTransparancy, 240, 240, 240),
                                       1.0f);

            ptTop.x += 1.0f;
            ptBottom.x += 1.0f;

            CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom,
                                       ArgbEncode(nTransparancy, 240, 240, 240),
                                       1.0f);

            ptTop.x += 1.0f;
            ptBottom.x += 1.0f;

            CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom,
                                       ArgbEncode(nTransparancy, 210, 210, 210),
                                       1.0f);

            ptTop.x += 1.0f;
            ptBottom.x += 1.0f;

            CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom,
                                       ArgbEncode(nTransparancy, 180, 180, 180),
                                       1.0f);

            ptTop.x += 1.0f;
            ptBottom.x += 1.0f;

            CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom,
                                       ArgbEncode(nTransparancy, 150, 150, 150),
                                       1.0f);

            ptTop.x += 1.0f;
            ptBottom.x += 1.0f;

            CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom,
                                       ArgbEncode(nTransparancy, 150, 150, 150),
                                       1.0f);

            ptTop.x += 1.0f;
            ptBottom.x += 1.0f;

            CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom,
                                       ArgbEncode(nTransparancy, 180, 180, 180),
                                       1.0f);

            ptTop.x += 1.0f;
            ptBottom.x += 1.0f;

            CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptTop, ptBottom,
                                       ArgbEncode(nTransparancy, 210, 210, 210),
                                       1.0f);
          } else {
            CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rcDraw,
                                     ArgbEncode(255, 255, 255, 255));
          }

          // draw friction

          if (rectWnd.Height() > 8.0f) {
            FX_COLORREF crStroke = ArgbEncode(nTransparancy, 120, 120, 120);
            if (!IsEnabled())
              crStroke = CPWL_Utils::PWLColorToFXColor(
                  PWL_DEFAULT_HEAVYGRAYCOLOR, 255);

            FX_FLOAT nFrictionWidth = 5.0f;
            FX_FLOAT nFrictionHeight = 5.5f;

            CPDF_Point ptLeft =
                CPDF_Point(ptCenter.x - nFrictionWidth / 2.0f,
                           ptCenter.y - nFrictionHeight / 2.0f + 0.5f);
            CPDF_Point ptRight =
                CPDF_Point(ptCenter.x + nFrictionWidth / 2.0f,
                           ptCenter.y - nFrictionHeight / 2.0f + 0.5f);

            CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptLeft, ptRight,
                                       crStroke, 1.0f);

            ptLeft.y += 2.0f;
            ptRight.y += 2.0f;

            CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptLeft, ptRight,
                                       crStroke, 1.0f);

            ptLeft.y += 2.0f;
            ptRight.y += 2.0f;

            CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptLeft, ptRight,
                                       crStroke, 1.0f);

            /*
            ptLeft.y += 1.5f;
            ptRight.y += 1.5f;

            CPWL_Utils::DrawStrokeLine(pDevice, pUser2Device, ptLeft, ptRight,
                    ArgbEncode(nTransparancy,150,150,150),1.0f);
                    */
          }
        } break;
        default:
          break;
      }
      break;
    default:
      break;
  }
}

FX_BOOL CPWL_SBButton::OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) {
  CPWL_Wnd::OnLButtonDown(point, nFlag);

  if (CPWL_Wnd* pParent = GetParentWindow())
    pParent->OnNotify(this, PNM_LBUTTONDOWN, 0, (intptr_t)&point);

  m_bMouseDown = TRUE;
  SetCapture();

  return TRUE;
}

FX_BOOL CPWL_SBButton::OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
  CPWL_Wnd::OnLButtonUp(point, nFlag);

  if (CPWL_Wnd* pParent = GetParentWindow())
    pParent->OnNotify(this, PNM_LBUTTONUP, 0, (intptr_t)&point);

  m_bMouseDown = FALSE;
  ReleaseCapture();

  return TRUE;
}

FX_BOOL CPWL_SBButton::OnMouseMove(const CPDF_Point& point, FX_DWORD nFlag) {
  CPWL_Wnd::OnMouseMove(point, nFlag);

  if (CPWL_Wnd* pParent = GetParentWindow()) {
    pParent->OnNotify(this, PNM_MOUSEMOVE, 0, (intptr_t)&point);

    /*
    if (m_bMouseDown && (m_eSBButtonType == PSBT_MIN || m_eSBButtonType ==
    PSBT_MAX))
    {
            if
    (!pParent->OnNotify(this,PNM_LBUTTONDOWN,nFlags,(intptr_t)&point))
                    return FALSE;
    }
    */
  }

  return TRUE;
}

/* ------------------------------- CPWL_ScrollBar
 * ---------------------------------- */

CPWL_ScrollBar::CPWL_ScrollBar(PWL_SCROLLBAR_TYPE sbType)
    : m_sbType(sbType),
      m_pMinButton(NULL),
      m_pMaxButton(NULL),
      m_pPosButton(NULL),
      m_bMouseDown(FALSE),
      m_bMinOrMax(FALSE),
      m_bNotifyForever(TRUE) {}

CPWL_ScrollBar::~CPWL_ScrollBar() {}

CFX_ByteString CPWL_ScrollBar::GetClassName() const {
  return "CPWL_ScrollBar";
}

void CPWL_ScrollBar::OnCreate(PWL_CREATEPARAM& cp) {
  cp.eCursorType = FXCT_ARROW;
}

void CPWL_ScrollBar::RePosChildWnd() {
  CPDF_Rect rcClient = GetClientRect();
  CPDF_Rect rcMinButton, rcMaxButton;
  FX_FLOAT fBWidth = 0;

  switch (m_sbType) {
    case SBT_HSCROLL:
      if (rcClient.right - rcClient.left >
          PWL_SCROLLBAR_BUTTON_WIDTH * 2 + PWL_SCROLLBAR_POSBUTTON_MINWIDTH +
              2) {
        rcMinButton =
            CPDF_Rect(rcClient.left, rcClient.bottom,
                      rcClient.left + PWL_SCROLLBAR_BUTTON_WIDTH, rcClient.top);
        rcMaxButton = CPDF_Rect(rcClient.right - PWL_SCROLLBAR_BUTTON_WIDTH,
                                rcClient.bottom, rcClient.right, rcClient.top);
      } else {
        fBWidth = (rcClient.right - rcClient.left -
                   PWL_SCROLLBAR_POSBUTTON_MINWIDTH - 2) /
                  2;

        if (fBWidth > 0) {
          rcMinButton = CPDF_Rect(rcClient.left, rcClient.bottom,
                                  rcClient.left + fBWidth, rcClient.top);
          rcMaxButton = CPDF_Rect(rcClient.right - fBWidth, rcClient.bottom,
                                  rcClient.right, rcClient.top);
        } else
          SetVisible(FALSE);
      }
      break;
    case SBT_VSCROLL:
      if (IsFloatBigger(rcClient.top - rcClient.bottom,
                        PWL_SCROLLBAR_BUTTON_WIDTH * 2 +
                            PWL_SCROLLBAR_POSBUTTON_MINWIDTH + 2)) {
        rcMinButton =
            CPDF_Rect(rcClient.left, rcClient.top - PWL_SCROLLBAR_BUTTON_WIDTH,
                      rcClient.right, rcClient.top);
        rcMaxButton = CPDF_Rect(rcClient.left, rcClient.bottom, rcClient.right,
                                rcClient.bottom + PWL_SCROLLBAR_BUTTON_WIDTH);
      } else {
        fBWidth = (rcClient.top - rcClient.bottom -
                   PWL_SCROLLBAR_POSBUTTON_MINWIDTH - 2) /
                  2;

        if (IsFloatBigger(fBWidth, 0)) {
          rcMinButton = CPDF_Rect(rcClient.left, rcClient.top - fBWidth,
                                  rcClient.right, rcClient.top);
          rcMaxButton = CPDF_Rect(rcClient.left, rcClient.bottom,
                                  rcClient.right, rcClient.bottom + fBWidth);
        } else
          SetVisible(FALSE);
      }
      break;
  }

  if (m_pMinButton)
    m_pMinButton->Move(rcMinButton, TRUE, FALSE);
  if (m_pMaxButton)
    m_pMaxButton->Move(rcMaxButton, TRUE, FALSE);
  MovePosButton(FALSE);
}

void CPWL_ScrollBar::GetThisAppearanceStream(CFX_ByteTextBuf& sAppStream) {
  CPDF_Rect rectWnd = GetWindowRect();

  if (IsVisible() && !rectWnd.IsEmpty()) {
    CFX_ByteTextBuf sButton;

    sButton << "q\n";
    sButton << "0 w\n"
            << CPWL_Utils::GetColorAppStream(GetBackgroundColor(), TRUE);
    sButton << rectWnd.left << " " << rectWnd.bottom << " "
            << rectWnd.right - rectWnd.left << " "
            << rectWnd.top - rectWnd.bottom << " re b Q\n";

    sAppStream << sButton;
  }
}

void CPWL_ScrollBar::DrawThisAppearance(CFX_RenderDevice* pDevice,
                                        CPDF_Matrix* pUser2Device) {
  CPDF_Rect rectWnd = GetWindowRect();

  if (IsVisible() && !rectWnd.IsEmpty()) {
    CPWL_Utils::DrawFillRect(pDevice, pUser2Device, rectWnd,
                             GetBackgroundColor(), GetTransparency());

    CPWL_Utils::DrawStrokeLine(
        pDevice, pUser2Device,
        CPDF_Point(rectWnd.left + 2.0f, rectWnd.top - 2.0f),
        CPDF_Point(rectWnd.left + 2.0f, rectWnd.bottom + 2.0f),
        ArgbEncode(GetTransparency(), 100, 100, 100), 1.0f);

    CPWL_Utils::DrawStrokeLine(
        pDevice, pUser2Device,
        CPDF_Point(rectWnd.right - 2.0f, rectWnd.top - 2.0f),
        CPDF_Point(rectWnd.right - 2.0f, rectWnd.bottom + 2.0f),
        ArgbEncode(GetTransparency(), 100, 100, 100), 1.0f);
  }
}

FX_BOOL CPWL_ScrollBar::OnLButtonDown(const CPDF_Point& point, FX_DWORD nFlag) {
  CPWL_Wnd::OnLButtonDown(point, nFlag);

  if (HasFlag(PWS_AUTOTRANSPARENT)) {
    if (GetTransparency() != 255) {
      SetTransparency(255);
      InvalidateRect();
    }
  }

  CPDF_Rect rcMinArea, rcMaxArea;

  if (m_pPosButton && m_pPosButton->IsVisible()) {
    CPDF_Rect rcClient = GetClientRect();
    CPDF_Rect rcPosButton = m_pPosButton->GetWindowRect();

    switch (m_sbType) {
      case SBT_HSCROLL:
        rcMinArea = CPDF_Rect(rcClient.left + PWL_SCROLLBAR_BUTTON_WIDTH,
                              rcClient.bottom, rcPosButton.left, rcClient.top);
        rcMaxArea = CPDF_Rect(rcPosButton.right, rcClient.bottom,
                              rcClient.right - PWL_SCROLLBAR_BUTTON_WIDTH,
                              rcClient.top);

        break;
      case SBT_VSCROLL:
        rcMinArea = CPDF_Rect(rcClient.left, rcPosButton.top, rcClient.right,
                              rcClient.top - PWL_SCROLLBAR_BUTTON_WIDTH);
        rcMaxArea = CPDF_Rect(rcClient.left,
                              rcClient.bottom + PWL_SCROLLBAR_BUTTON_WIDTH,
                              rcClient.right, rcPosButton.bottom);
        break;
    }

    rcMinArea.Normalize();
    rcMaxArea.Normalize();

    if (rcMinArea.Contains(point.x, point.y)) {
      m_sData.SubBig();
      MovePosButton(TRUE);
      NotifyScrollWindow();
    }

    if (rcMaxArea.Contains(point.x, point.y)) {
      m_sData.AddBig();
      MovePosButton(TRUE);
      NotifyScrollWindow();
    }
  }

  return TRUE;
}

FX_BOOL CPWL_ScrollBar::OnLButtonUp(const CPDF_Point& point, FX_DWORD nFlag) {
  CPWL_Wnd::OnLButtonUp(point, nFlag);

  if (HasFlag(PWS_AUTOTRANSPARENT)) {
    if (GetTransparency() != PWL_SCROLLBAR_TRANSPARANCY) {
      SetTransparency(PWL_SCROLLBAR_TRANSPARANCY);
      InvalidateRect();
    }
  }

  EndTimer();
  m_bMouseDown = FALSE;

  return TRUE;
}

void CPWL_ScrollBar::OnNotify(CPWL_Wnd* pWnd,
                              FX_DWORD msg,
                              intptr_t wParam,
                              intptr_t lParam) {
  CPWL_Wnd::OnNotify(pWnd, msg, wParam, lParam);

  switch (msg) {
    case PNM_LBUTTONDOWN:
      if (pWnd == m_pMinButton) {
        OnMinButtonLBDown(*(CPDF_Point*)lParam);
      }

      if (pWnd == m_pMaxButton) {
        OnMaxButtonLBDown(*(CPDF_Point*)lParam);
      }

      if (pWnd == m_pPosButton) {
        OnPosButtonLBDown(*(CPDF_Point*)lParam);
      }
      break;
    case PNM_LBUTTONUP:
      if (pWnd == m_pMinButton) {
        OnMinButtonLBUp(*(CPDF_Point*)lParam);
      }

      if (pWnd == m_pMaxButton) {
        OnMaxButtonLBUp(*(CPDF_Point*)lParam);
      }

      if (pWnd == m_pPosButton) {
        OnPosButtonLBUp(*(CPDF_Point*)lParam);
      }
      break;
    case PNM_MOUSEMOVE:
      if (pWnd == m_pMinButton) {
        OnMinButtonMouseMove(*(CPDF_Point*)lParam);
      }

      if (pWnd == m_pMaxButton) {
        OnMaxButtonMouseMove(*(CPDF_Point*)lParam);
      }

      if (pWnd == m_pPosButton) {
        OnPosButtonMouseMove(*(CPDF_Point*)lParam);
      }
      break;
    case PNM_SETSCROLLINFO: {
      if (PWL_SCROLL_INFO* pInfo = (PWL_SCROLL_INFO*)lParam) {
        if (FXSYS_memcmp(&m_OriginInfo, pInfo, sizeof(PWL_SCROLL_INFO)) != 0) {
          m_OriginInfo = *pInfo;
          FX_FLOAT fMax =
              pInfo->fContentMax - pInfo->fContentMin - pInfo->fPlateWidth;
          fMax = fMax > 0.0f ? fMax : 0.0f;
          SetScrollRange(0, fMax, pInfo->fPlateWidth);
          SetScrollStep(pInfo->fBigStep, pInfo->fSmallStep);
        }
      }
    } break;
    case PNM_SETSCROLLPOS: {
      FX_FLOAT fPos = *(FX_FLOAT*)lParam;
      switch (m_sbType) {
        case SBT_HSCROLL:
          fPos = fPos - m_OriginInfo.fContentMin;
          break;
        case SBT_VSCROLL:
          fPos = m_OriginInfo.fContentMax - fPos;
          break;
      }
      SetScrollPos(fPos);
    } break;
  }
}

void CPWL_ScrollBar::CreateButtons(const PWL_CREATEPARAM& cp) {
  PWL_CREATEPARAM scp = cp;
  scp.pParentWnd = this;
  scp.dwBorderWidth = 2;
  scp.nBorderStyle = PBS_BEVELED;

  scp.dwFlags =
      PWS_VISIBLE | PWS_CHILD | PWS_BORDER | PWS_BACKGROUND | PWS_NOREFRESHCLIP;

  if (!m_pMinButton) {
    m_pMinButton = new CPWL_SBButton(m_sbType, PSBT_MIN);
    m_pMinButton->Create(scp);
  }

  if (!m_pMaxButton) {
    m_pMaxButton = new CPWL_SBButton(m_sbType, PSBT_MAX);
    m_pMaxButton->Create(scp);
  }

  if (!m_pPosButton) {
    m_pPosButton = new CPWL_SBButton(m_sbType, PSBT_POS);
    m_pPosButton->SetVisible(FALSE);
    m_pPosButton->Create(scp);
  }
}

FX_FLOAT CPWL_ScrollBar::GetScrollBarWidth() const {
  if (!IsVisible())
    return 0;

  return PWL_SCROLLBAR_WIDTH;
}

void CPWL_ScrollBar::SetScrollRange(FX_FLOAT fMin,
                                    FX_FLOAT fMax,
                                    FX_FLOAT fClientWidth) {
  if (m_pPosButton) {
    m_sData.SetScrollRange(fMin, fMax);
    m_sData.SetClientWidth(fClientWidth);

    if (IsFloatSmaller(m_sData.ScrollRange.GetWidth(), 0.0f)) {
      m_pPosButton->SetVisible(FALSE);
    } else {
      m_pPosButton->SetVisible(TRUE);
      MovePosButton(TRUE);
    }
  }
}

void CPWL_ScrollBar::SetScrollPos(FX_FLOAT fPos) {
  FX_FLOAT fOldPos = m_sData.fScrollPos;

  m_sData.SetPos(fPos);

  if (!IsFloatEqual(m_sData.fScrollPos, fOldPos))
    MovePosButton(TRUE);
}

void CPWL_ScrollBar::SetScrollStep(FX_FLOAT fBigStep, FX_FLOAT fSmallStep) {
  m_sData.SetBigStep(fBigStep);
  m_sData.SetSmallStep(fSmallStep);
}

void CPWL_ScrollBar::MovePosButton(FX_BOOL bRefresh) {
  ASSERT(m_pPosButton != NULL);
  ASSERT(m_pMinButton != NULL);
  ASSERT(m_pMaxButton != NULL);

  if (m_pPosButton->IsVisible()) {
    CPDF_Rect rcClient;
    CPDF_Rect rcPosArea, rcPosButton;

    rcClient = GetClientRect();
    rcPosArea = GetScrollArea();

    FX_FLOAT fLeft, fRight, fTop, fBottom;

    switch (m_sbType) {
      case SBT_HSCROLL:
        fLeft = TrueToFace(m_sData.fScrollPos);
        fRight = TrueToFace(m_sData.fScrollPos + m_sData.fClientWidth);

        if (fRight - fLeft < PWL_SCROLLBAR_POSBUTTON_MINWIDTH)
          fRight = fLeft + PWL_SCROLLBAR_POSBUTTON_MINWIDTH;

        if (fRight > rcPosArea.right) {
          fRight = rcPosArea.right;
          fLeft = fRight - PWL_SCROLLBAR_POSBUTTON_MINWIDTH;
        }

        rcPosButton = CPDF_Rect(fLeft, rcPosArea.bottom, fRight, rcPosArea.top);

        break;
      case SBT_VSCROLL:
        fBottom = TrueToFace(m_sData.fScrollPos + m_sData.fClientWidth);
        fTop = TrueToFace(m_sData.fScrollPos);

        if (IsFloatSmaller(fTop - fBottom, PWL_SCROLLBAR_POSBUTTON_MINWIDTH))
          fBottom = fTop - PWL_SCROLLBAR_POSBUTTON_MINWIDTH;

        if (IsFloatSmaller(fBottom, rcPosArea.bottom)) {
          fBottom = rcPosArea.bottom;
          fTop = fBottom + PWL_SCROLLBAR_POSBUTTON_MINWIDTH;
        }

        rcPosButton = CPDF_Rect(rcPosArea.left, fBottom, rcPosArea.right, fTop);

        break;
    }

    m_pPosButton->Move(rcPosButton, TRUE, bRefresh);
  }
}

void CPWL_ScrollBar::OnMinButtonLBDown(const CPDF_Point& point) {
  m_sData.SubSmall();
  MovePosButton(TRUE);
  NotifyScrollWindow();

  m_bMinOrMax = TRUE;

  EndTimer();
  BeginTimer(100);
}

void CPWL_ScrollBar::OnMinButtonLBUp(const CPDF_Point& point) {}

void CPWL_ScrollBar::OnMinButtonMouseMove(const CPDF_Point& point) {}

void CPWL_ScrollBar::OnMaxButtonLBDown(const CPDF_Point& point) {
  m_sData.AddSmall();
  MovePosButton(TRUE);
  NotifyScrollWindow();

  m_bMinOrMax = FALSE;

  EndTimer();
  BeginTimer(100);
}

void CPWL_ScrollBar::OnMaxButtonLBUp(const CPDF_Point& point) {}

void CPWL_ScrollBar::OnMaxButtonMouseMove(const CPDF_Point& point) {}

void CPWL_ScrollBar::OnPosButtonLBDown(const CPDF_Point& point) {
  m_bMouseDown = TRUE;

  if (m_pPosButton) {
    CPDF_Rect rcPosButton = m_pPosButton->GetWindowRect();

    switch (m_sbType) {
      case SBT_HSCROLL:
        m_nOldPos = point.x;
        m_fOldPosButton = rcPosButton.left;
        break;
      case SBT_VSCROLL:
        m_nOldPos = point.y;
        m_fOldPosButton = rcPosButton.top;
        break;
    }
  }
}

void CPWL_ScrollBar::OnPosButtonLBUp(const CPDF_Point& point) {
  if (m_bMouseDown) {
    if (!m_bNotifyForever)
      NotifyScrollWindow();
  }
  m_bMouseDown = FALSE;
}

void CPWL_ScrollBar::OnPosButtonMouseMove(const CPDF_Point& point) {
  FX_FLOAT fOldScrollPos = m_sData.fScrollPos;

  FX_FLOAT fNewPos = 0;

  switch (m_sbType) {
    case SBT_HSCROLL:
      if (FXSYS_fabs(point.x - m_nOldPos) < 1)
        return;
      fNewPos = FaceToTrue(m_fOldPosButton + point.x - m_nOldPos);
      break;
    case SBT_VSCROLL:
      if (FXSYS_fabs(point.y - m_nOldPos) < 1)
        return;
      fNewPos = FaceToTrue(m_fOldPosButton + point.y - m_nOldPos);
      break;
  }

  if (m_bMouseDown) {
    switch (m_sbType) {
      case SBT_HSCROLL:

        if (IsFloatSmaller(fNewPos, m_sData.ScrollRange.fMin)) {
          fNewPos = m_sData.ScrollRange.fMin;
        }

        if (IsFloatBigger(fNewPos, m_sData.ScrollRange.fMax)) {
          fNewPos = m_sData.ScrollRange.fMax;
        }

        m_sData.SetPos(fNewPos);

        break;
      case SBT_VSCROLL:

        if (IsFloatSmaller(fNewPos, m_sData.ScrollRange.fMin)) {
          fNewPos = m_sData.ScrollRange.fMin;
        }

        if (IsFloatBigger(fNewPos, m_sData.ScrollRange.fMax)) {
          fNewPos = m_sData.ScrollRange.fMax;
        }

        m_sData.SetPos(fNewPos);

        break;
    }

    if (!IsFloatEqual(fOldScrollPos, m_sData.fScrollPos)) {
      MovePosButton(TRUE);

      if (m_bNotifyForever)
        NotifyScrollWindow();
    }
  }
}

void CPWL_ScrollBar::NotifyScrollWindow() {
  if (CPWL_Wnd* pParent = GetParentWindow()) {
    FX_FLOAT fPos;
    switch (m_sbType) {
      case SBT_HSCROLL:
        fPos = m_OriginInfo.fContentMin + m_sData.fScrollPos;
        break;
      case SBT_VSCROLL:
        fPos = m_OriginInfo.fContentMax - m_sData.fScrollPos;
        break;
    }
    pParent->OnNotify(this, PNM_SCROLLWINDOW, (intptr_t)m_sbType,
                      (intptr_t)&fPos);
  }
}

CPDF_Rect CPWL_ScrollBar::GetScrollArea() const {
  CPDF_Rect rcClient = GetClientRect();
  CPDF_Rect rcArea;

  if (!m_pMinButton || !m_pMaxButton)
    return rcClient;

  CPDF_Rect rcMin = m_pMinButton->GetWindowRect();
  CPDF_Rect rcMax = m_pMaxButton->GetWindowRect();

  FX_FLOAT fMinWidth = rcMin.right - rcMin.left;
  FX_FLOAT fMinHeight = rcMin.top - rcMin.bottom;
  FX_FLOAT fMaxWidth = rcMax.right - rcMax.left;
  FX_FLOAT fMaxHeight = rcMax.top - rcMax.bottom;

  switch (m_sbType) {
    case SBT_HSCROLL:
      if (rcClient.right - rcClient.left > fMinWidth + fMaxWidth + 2) {
        rcArea = CPDF_Rect(rcClient.left + fMinWidth + 1, rcClient.bottom,
                           rcClient.right - fMaxWidth - 1, rcClient.top);
      } else {
        rcArea = CPDF_Rect(rcClient.left + fMinWidth + 1, rcClient.bottom,
                           rcClient.left + fMinWidth + 1, rcClient.top);
      }
      break;
    case SBT_VSCROLL:
      if (rcClient.top - rcClient.bottom > fMinHeight + fMaxHeight + 2) {
        rcArea = CPDF_Rect(rcClient.left, rcClient.bottom + fMinHeight + 1,
                           rcClient.right, rcClient.top - fMaxHeight - 1);
      } else {
        rcArea = CPDF_Rect(rcClient.left, rcClient.bottom + fMinHeight + 1,
                           rcClient.right, rcClient.bottom + fMinHeight + 1);
      }
      break;
  }

  rcArea.Normalize();

  return rcArea;
}

FX_FLOAT CPWL_ScrollBar::TrueToFace(FX_FLOAT fTrue) {
  CPDF_Rect rcPosArea;
  rcPosArea = GetScrollArea();

  FX_FLOAT fFactWidth = m_sData.ScrollRange.GetWidth() + m_sData.fClientWidth;
  fFactWidth = fFactWidth == 0 ? 1 : fFactWidth;

  FX_FLOAT fFace = 0;

  switch (m_sbType) {
    case SBT_HSCROLL:
      fFace = rcPosArea.left +
              fTrue * (rcPosArea.right - rcPosArea.left) / fFactWidth;
      break;
    case SBT_VSCROLL:
      fFace = rcPosArea.top -
              fTrue * (rcPosArea.top - rcPosArea.bottom) / fFactWidth;
      break;
  }

  return fFace;
}

FX_FLOAT CPWL_ScrollBar::FaceToTrue(FX_FLOAT fFace) {
  CPDF_Rect rcPosArea;
  rcPosArea = GetScrollArea();

  FX_FLOAT fFactWidth = m_sData.ScrollRange.GetWidth() + m_sData.fClientWidth;
  fFactWidth = fFactWidth == 0 ? 1 : fFactWidth;

  FX_FLOAT fTrue = 0;

  switch (m_sbType) {
    case SBT_HSCROLL:
      fTrue = (fFace - rcPosArea.left) * fFactWidth /
              (rcPosArea.right - rcPosArea.left);
      break;
    case SBT_VSCROLL:
      fTrue = (rcPosArea.top - fFace) * fFactWidth /
              (rcPosArea.top - rcPosArea.bottom);
      break;
  }

  return fTrue;
}

void CPWL_ScrollBar::CreateChildWnd(const PWL_CREATEPARAM& cp) {
  CreateButtons(cp);
}

void CPWL_ScrollBar::TimerProc() {
  PWL_SCROLL_PRIVATEDATA sTemp = m_sData;

  if (m_bMinOrMax)
    m_sData.SubSmall();
  else
    m_sData.AddSmall();

  if (FXSYS_memcmp(&m_sData, &sTemp, sizeof(PWL_SCROLL_PRIVATEDATA)) != 0) {
    MovePosButton(TRUE);
    NotifyScrollWindow();
  }
}
