// Copyright 2017 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/fxfa/cxfa_ffline.h"

#include "xfa/fxfa/parser/cxfa_edge.h"
#include "xfa/fxfa/parser/cxfa_line.h"
#include "xfa/fxfa/parser/cxfa_value.h"
#include "xfa/fxgraphics/cxfa_gecolor.h"
#include "xfa/fxgraphics/cxfa_gepath.h"
#include "xfa/fxgraphics/cxfa_graphics.h"

namespace {

CFX_GraphStateData::LineCap LineCapToFXGE(XFA_AttributeEnum iLineCap) {
  switch (iLineCap) {
    case XFA_AttributeEnum::Round:
      return CFX_GraphStateData::LineCapRound;
    case XFA_AttributeEnum::Butt:
      return CFX_GraphStateData::LineCapButt;
    default:
      break;
  }
  return CFX_GraphStateData::LineCapSquare;
}

}  // namespace

CXFA_FFLine::CXFA_FFLine(CXFA_WidgetAcc* pDataAcc) : CXFA_FFDraw(pDataAcc) {}

CXFA_FFLine::~CXFA_FFLine() {}

void CXFA_FFLine::GetRectFromHand(CFX_RectF& rect,
                                  XFA_AttributeEnum iHand,
                                  float fLineWidth) {
  float fHalfWidth = fLineWidth / 2.0f;
  if (rect.height < 1.0f) {
    switch (iHand) {
      case XFA_AttributeEnum::Left:
        rect.top -= fHalfWidth;
        break;
      case XFA_AttributeEnum::Right:
        rect.top += fHalfWidth;
      case XFA_AttributeEnum::Even:
        break;
      default:
        NOTREACHED();
        break;
    }
  } else if (rect.width < 1.0f) {
    switch (iHand) {
      case XFA_AttributeEnum::Left:
        rect.left += fHalfWidth;
        break;
      case XFA_AttributeEnum::Right:
        rect.left += fHalfWidth;
        break;
      case XFA_AttributeEnum::Even:
        break;
      default:
        NOTREACHED();
        break;
    }
  } else {
    switch (iHand) {
      case XFA_AttributeEnum::Left:
        rect.Inflate(fHalfWidth, fHalfWidth);
        break;
      case XFA_AttributeEnum::Right:
        rect.Deflate(fHalfWidth, fHalfWidth);
        break;
      case XFA_AttributeEnum::Even:
        break;
      default:
        NOTREACHED();
        break;
    }
  }
}

void CXFA_FFLine::RenderWidget(CXFA_Graphics* pGS,
                               const CFX_Matrix& matrix,
                               uint32_t dwStatus) {
  if (!IsMatchVisibleStatus(dwStatus))
    return;

  CXFA_Value* value = m_pDataAcc->GetFormValue();
  if (!value)
    return;

  CXFA_Line* line = value->GetLine();
  FX_ARGB lineColor = 0xFF000000;
  float fLineWidth = 1.0f;
  XFA_AttributeEnum iStrokeType = XFA_AttributeEnum::Unknown;
  XFA_AttributeEnum iCap = XFA_AttributeEnum::Unknown;
  CXFA_Edge* edge = line->GetEdge();
  if (edge) {
    if (!edge->IsVisible())
      return;

    lineColor = edge->GetColor();
    iStrokeType = edge->GetStrokeType();
    fLineWidth = edge->GetThickness();
    iCap = edge->GetCapType();
  }

  CFX_Matrix mtRotate = GetRotateMatrix();
  mtRotate.Concat(matrix);

  CFX_RectF rtLine = GetRectWithoutRotate();
  CXFA_Margin* margin = m_pDataAcc->GetMargin();
  if (margin)
    XFA_RectWidthoutMargin(rtLine, margin);

  GetRectFromHand(rtLine, line->GetHand(), fLineWidth);
  CXFA_GEPath linePath;
  if (line->GetSlope() && rtLine.right() > 0.0f && rtLine.bottom() > 0.0f)
    linePath.AddLine(rtLine.TopRight(), rtLine.BottomLeft());
  else
    linePath.AddLine(rtLine.TopLeft(), rtLine.BottomRight());

  pGS->SaveGraphState();
  pGS->SetLineWidth(fLineWidth);
  pGS->EnableActOnDash();
  XFA_StrokeTypeSetLineDash(pGS, iStrokeType, iCap);

  pGS->SetStrokeColor(CXFA_GEColor(lineColor));
  pGS->SetLineCap(LineCapToFXGE(iCap));
  pGS->StrokePath(&linePath, &mtRotate);
  pGS->RestoreGraphState();
}
