// 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/theme/cfwl_comboboxtp.h"

#include "xfa/fwl/cfwl_combobox.h"
#include "xfa/fwl/cfwl_themebackground.h"
#include "xfa/fwl/cfwl_widget.h"
#include "xfa/fwl/ifwl_themeprovider.h"
#include "xfa/fxgraphics/cxfa_color.h"
#include "xfa/fxgraphics/cxfa_path.h"

CFWL_ComboBoxTP::CFWL_ComboBoxTP() {}

CFWL_ComboBoxTP::~CFWL_ComboBoxTP() {}

void CFWL_ComboBoxTP::DrawBackground(CFWL_ThemeBackground* pParams) {
  if (!pParams)
    return;

  switch (pParams->m_iPart) {
    case CFWL_Part::Border: {
      DrawBorder(pParams->m_pGraphics, &pParams->m_rtPart, &pParams->m_matrix);
      break;
    }
    case CFWL_Part::Background: {
      CXFA_Path path;
      CFX_RectF& rect = pParams->m_rtPart;
      path.AddRectangle(rect.left, rect.top, rect.width, rect.height);
      FX_ARGB argb_color;
      switch (pParams->m_dwStates) {
        case CFWL_PartState_Selected:
          argb_color = FWLTHEME_COLOR_BKSelected;
          break;
        case CFWL_PartState_Disabled:
          argb_color = FWLTHEME_COLOR_EDGERB1;
          break;
        default:
          argb_color = 0xFFFFFFFF;
      }
      pParams->m_pGraphics->SaveGraphState();
      CXFA_Color cr(argb_color);
      pParams->m_pGraphics->SetFillColor(&cr);
      pParams->m_pGraphics->FillPath(&path, FXFILL_WINDING, &pParams->m_matrix);
      pParams->m_pGraphics->RestoreGraphState();
      break;
    }
    case CFWL_Part::DropDownButton: {
      DrawDropDownButton(pParams, pParams->m_dwStates, &pParams->m_matrix);
      break;
    }
    case CFWL_Part::StretchHandler: {
      DrawStrethHandler(pParams, 0, &pParams->m_matrix);
      break;
    }
    default:
      break;
  }
}

void CFWL_ComboBoxTP::DrawStrethHandler(CFWL_ThemeBackground* pParams,
                                        uint32_t dwStates,
                                        CFX_Matrix* pMatrix) {
  CXFA_Path path;
  path.AddRectangle(pParams->m_rtPart.left, pParams->m_rtPart.top,
                    pParams->m_rtPart.width - 1, pParams->m_rtPart.height);
  CXFA_Color cr(ArgbEncode(0xff, 0xff, 0, 0));
  pParams->m_pGraphics->SetFillColor(&cr);
  pParams->m_pGraphics->FillPath(&path, FXFILL_WINDING, &pParams->m_matrix);
}

void CFWL_ComboBoxTP::DrawDropDownButton(CFWL_ThemeBackground* pParams,
                                         uint32_t dwStates,
                                         CFX_Matrix* pMatrix) {
  FWLTHEME_STATE eState = FWLTHEME_STATE_Normal;
  switch (dwStates) {
    case CFWL_PartState_Normal: {
      eState = FWLTHEME_STATE_Normal;
      break;
    }
    case CFWL_PartState_Hovered: {
      eState = FWLTHEME_STATE_Hover;
      break;
    }
    case CFWL_PartState_Pressed: {
      eState = FWLTHEME_STATE_Pressed;
      break;
    }
    case CFWL_PartState_Disabled: {
      eState = FWLTHEME_STATE_Disable;
      break;
    }
    default:
      break;
  }
  DrawArrowBtn(pParams->m_pGraphics, &pParams->m_rtPart,
               FWLTHEME_DIRECTION_Down, eState, &pParams->m_matrix);
}
