// 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/cxfa_measurement.h"
#include "xfa/fxfa/parser/cxfa_node.h"

namespace {

void GetStrokesInternal(CXFA_Node* pNode,
                        std::vector<CXFA_Stroke>* strokes,
                        bool bNull) {
  strokes->clear();
  if (!pNode)
    return;

  strokes->resize(8);
  int32_t i, j;
  for (i = 0, j = 0; i < 4; i++) {
    CXFA_Corner corner = CXFA_Corner(
        pNode->JSNode()->GetProperty(i, XFA_Element::Corner, i == 0));
    if (corner || i == 0) {
      (*strokes)[j] = corner;
    } else if (!bNull) {
      if (i == 1 || i == 2)
        (*strokes)[j] = (*strokes)[0];
      else
        (*strokes)[j] = (*strokes)[2];
    }
    j++;
    CXFA_Edge edge =
        CXFA_Edge(pNode->JSNode()->GetProperty(i, XFA_Element::Edge, i == 0));
    if (edge || i == 0) {
      (*strokes)[j] = edge;
    } else if (!bNull) {
      if (i == 1 || i == 2)
        (*strokes)[j] = (*strokes)[1];
      else
        (*strokes)[j] = (*strokes)[3];
    }
    j++;
  }
}

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

  stroke = strokes[0];
  for (size_t i = 1; i < strokes.size(); 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->JSNode()->GetEnum(XFA_ATTRIBUTE_Hand);
}

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

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

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

void CXFA_Box::GetStrokes(std::vector<CXFA_Stroke>* strokes) const {
  GetStrokesInternal(m_pNode, strokes, false);
}

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

bool CXFA_Box::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_Box::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_Fill CXFA_Box::GetFill(bool bModified) const {
  if (!m_pNode)
    return CXFA_Fill(nullptr);

  CXFA_Node* pFillNode =
      m_pNode->JSNode()->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, false)
                             : nullptr);
}

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

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