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

#include "xfa/fxfa/parser/cxfa_cornerdata.h"
#include "xfa/fxfa/parser/cxfa_measurement.h"
#include "xfa/fxfa/parser/cxfa_node.h"

namespace {

std::vector<CXFA_StrokeData> GetStrokesInternal(CXFA_Node* pNode, bool bNull) {
  if (!pNode)
    return {};

  std::vector<CXFA_StrokeData> strokes;
  strokes.resize(8);
  int32_t i, j;
  for (i = 0, j = 0; i < 4; i++) {
    CXFA_CornerData cornerData = CXFA_CornerData(
        pNode->JSNode()->GetProperty(i, XFA_Element::Corner, i == 0));
    if (cornerData || i == 0) {
      strokes[j] = cornerData;
    } else if (!bNull) {
      if (i == 1 || i == 2)
        strokes[j] = strokes[0];
      else
        strokes[j] = strokes[2];
    }
    j++;
    CXFA_EdgeData edgeData = CXFA_EdgeData(
        pNode->JSNode()->GetProperty(i, XFA_Element::Edge, i == 0));
    if (edgeData || i == 0) {
      strokes[j] = edgeData;
    } else if (!bNull) {
      if (i == 1 || i == 2)
        strokes[j] = strokes[1];
      else
        strokes[j] = strokes[3];
    }
    j++;
  }
  return strokes;
}

static int32_t Style3D(const std::vector<CXFA_StrokeData>& strokes,
                       CXFA_StrokeData& strokeData) {
  if (strokes.empty())
    return 0;

  strokeData = strokes[0];
  for (size_t i = 1; i < strokes.size(); i++) {
    CXFA_StrokeData find = strokes[i];
    if (!find)
      continue;

    if (!strokeData)
      strokeData = find;
    else if (strokeData.GetStrokeType() != find.GetStrokeType())
      strokeData = find;
    break;
  }
  int32_t iType = strokeData.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_BoxData::GetHand() const {
  if (!m_pNode)
    return XFA_ATTRIBUTEENUM_Even;
  return m_pNode->JSNode()->GetEnum(XFA_ATTRIBUTE_Hand);
}

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

int32_t CXFA_BoxData::CountEdges() const {
  if (!m_pNode)
    return 0;
  return m_pNode->CountChildren(XFA_Element::Edge, false);
}

CXFA_EdgeData CXFA_BoxData::GetEdgeData(int32_t nIndex) const {
  return CXFA_EdgeData(m_pNode ? m_pNode->JSNode()->GetProperty(
                                     nIndex, XFA_Element::Edge, nIndex == 0)
                               : nullptr);
}

std::vector<CXFA_StrokeData> CXFA_BoxData::GetStrokes() const {
  return GetStrokesInternal(m_pNode, false);
}

bool CXFA_BoxData::IsCircular() const {
  if (!m_pNode)
    return false;
  return m_pNode->JSNode()->GetBoolean(XFA_ATTRIBUTE_Circular);
}

bool CXFA_BoxData::GetStartAngle(float& fStartAngle) const {
  fStartAngle = 0;
  if (!m_pNode)
    return false;

  CXFA_Measurement ms;
  bool bRet =
      m_pNode->JSNode()->TryMeasure(XFA_ATTRIBUTE_StartAngle, ms, false);
  if (bRet)
    fStartAngle = ms.GetValue();

  return bRet;
}

bool CXFA_BoxData::GetSweepAngle(float& fSweepAngle) const {
  fSweepAngle = 360;
  if (!m_pNode)
    return false;

  CXFA_Measurement ms;
  bool bRet =
      m_pNode->JSNode()->TryMeasure(XFA_ATTRIBUTE_SweepAngle, ms, false);
  if (bRet)
    fSweepAngle = ms.GetValue();

  return bRet;
}

CXFA_FillData CXFA_BoxData::GetFillData(bool bModified) const {
  if (!m_pNode)
    return CXFA_FillData(nullptr);

  CXFA_Node* pFillNode =
      m_pNode->JSNode()->GetProperty(0, XFA_Element::Fill, bModified);
  return CXFA_FillData(pFillNode);
}

CXFA_MarginData CXFA_BoxData::GetMarginData() const {
  return CXFA_MarginData(
      m_pNode ? m_pNode->GetChild(0, XFA_Element::Margin, false) : nullptr);
}

int32_t CXFA_BoxData::Get3DStyle(bool& bVisible, float& fThickness) const {
  if (IsArc())
    return 0;

  std::vector<CXFA_StrokeData> strokes = GetStrokesInternal(m_pNode, true);
  CXFA_StrokeData strokeData(nullptr);
  int32_t iType = Style3D(strokes, strokeData);
  if (iType) {
    bVisible = strokeData.IsVisible();
    fThickness = strokeData.GetThickness();
  }
  return iType;
}
