// Copyright 2016 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/parser/cxfa_box.h"

#include "xfa/fxfa/parser/cxfa_corner.h"
#include "xfa/fxfa/parser/xfa_object.h"

namespace {

void GetStrokesInternal(CXFA_Node* pNode,
                        CXFA_StrokeArray& strokes,
                        FX_BOOL bNULL) {
  strokes.RemoveAll();
  if (!pNode)
    return;

  strokes.SetSize(8);
  int32_t i, j;
  for (i = 0, j = 0; i < 4; i++) {
    CXFA_Corner corner =
        CXFA_Corner(pNode->GetProperty(i, XFA_ELEMENT_Corner, i == 0));
    if (corner || i == 0)
      strokes.SetAt(j, corner);
    else if (bNULL)
      strokes.SetAt(j, CXFA_Stroke(nullptr));
    else if (i == 1)
      strokes.SetAt(j, strokes[0]);
    else if (i == 2)
      strokes.SetAt(j, strokes[0]);
    else
      strokes.SetAt(j, strokes[2]);

    j++;
    CXFA_Edge edge = CXFA_Edge(pNode->GetProperty(i, XFA_ELEMENT_Edge, i == 0));
    if (edge || i == 0)
      strokes.SetAt(j, edge);
    else if (bNULL)
      strokes.SetAt(j, CXFA_Stroke(nullptr));
    else if (i == 1)
      strokes.SetAt(j, strokes[1]);
    else if (i == 2)
      strokes.SetAt(j, strokes[1]);
    else
      strokes.SetAt(j, strokes[3]);

    j++;
  }
}

static int32_t Style3D(const CXFA_StrokeArray& strokes, CXFA_Stroke& stroke) {
  int32_t iCount = strokes.GetSize();
  if (iCount < 1)
    return 0;

  stroke = strokes[0];
  for (int32_t i = 1; i < iCount; i++) {
    CXFA_Stroke find = strokes[i];
    if (!find)
      continue;

    if (!stroke)
      stroke = find;
    else if (stroke.GetStrokeType() != find.GetStrokeType())
      stroke = find;
    break;
  }
  int32_t iType = stroke.GetStrokeType();
  if (iType == XFA_ATTRIBUTEENUM_Lowered || iType == XFA_ATTRIBUTEENUM_Raised ||
      iType == XFA_ATTRIBUTEENUM_Etched ||
      iType == XFA_ATTRIBUTEENUM_Embossed) {
    return iType;
  }
  return 0;
}

}  // namespace

int32_t CXFA_Box::GetHand() const {
  if (!m_pNode)
    return XFA_ATTRIBUTEENUM_Even;
  return m_pNode->GetEnum(XFA_ATTRIBUTE_Hand);
}

int32_t CXFA_Box::GetPresence() const {
  if (!m_pNode)
    return XFA_ATTRIBUTEENUM_Hidden;
  return m_pNode->GetEnum(XFA_ATTRIBUTE_Presence);
}

int32_t CXFA_Box::CountEdges() const {
  if (!m_pNode)
    return 0;
  return m_pNode->CountChildren(XFA_ELEMENT_Edge);
}

CXFA_Edge CXFA_Box::GetEdge(int32_t nIndex) const {
  return CXFA_Edge(
      m_pNode ? m_pNode->GetProperty(nIndex, XFA_ELEMENT_Edge, nIndex == 0)
              : nullptr);
}

void CXFA_Box::GetStrokes(CXFA_StrokeArray& strokes) const {
  GetStrokesInternal(m_pNode, strokes, FALSE);
}

FX_BOOL CXFA_Box::IsCircular() const {
  if (!m_pNode)
    return FALSE;
  return m_pNode->GetBoolean(XFA_ATTRIBUTE_Circular);
}

FX_BOOL CXFA_Box::GetStartAngle(FX_FLOAT& fStartAngle) const {
  fStartAngle = 0;
  if (!m_pNode)
    return FALSE;

  CXFA_Measurement ms;
  FX_BOOL bRet = m_pNode->TryMeasure(XFA_ATTRIBUTE_StartAngle, ms, FALSE);
  if (bRet)
    fStartAngle = ms.GetValue();

  return bRet;
}

FX_BOOL CXFA_Box::GetSweepAngle(FX_FLOAT& fSweepAngle) const {
  fSweepAngle = 360;
  if (!m_pNode)
    return FALSE;

  CXFA_Measurement ms;
  FX_BOOL bRet = m_pNode->TryMeasure(XFA_ATTRIBUTE_SweepAngle, ms, FALSE);
  if (bRet)
    fSweepAngle = ms.GetValue();

  return bRet;
}

CXFA_Fill CXFA_Box::GetFill(FX_BOOL bModified) const {
  if (!m_pNode)
    return CXFA_Fill(nullptr);

  CXFA_Node* pFillNode = m_pNode->GetProperty(0, XFA_ELEMENT_Fill, bModified);
  return CXFA_Fill(pFillNode);
}

CXFA_Margin CXFA_Box::GetMargin() const {
  return CXFA_Margin(m_pNode ? m_pNode->GetChild(0, XFA_ELEMENT_Margin)
                             : nullptr);
}

int32_t CXFA_Box::Get3DStyle(FX_BOOL& bVisible, FX_FLOAT& fThickness) const {
  if (IsArc())
    return 0;

  CXFA_StrokeArray strokes;
  GetStrokesInternal(m_pNode, strokes, TRUE);
  CXFA_Stroke stroke(NULL);
  int32_t iType = Style3D(strokes, stroke);
  if (iType) {
    bVisible = stroke.IsVisible();
    fThickness = stroke.GetThickness();
  }
  return iType;
}
