// 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_Node* pNode) : CXFA_FFDraw(pNode) {}

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_pNode->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_pNode->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();
}
