// 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->GetFormValueIfExists();
  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->GetMarginIfExists();
  if (margin)
    XFA_RectWithoutMargin(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();
}
