// 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 "core/fpdfapi/page/cpdf_allstates.h"

#include <algorithm>
#include <utility>
#include <vector>

#include "core/fpdfapi/font/cpdf_font.h"
#include "core/fpdfapi/page/cpdf_pageobjectholder.h"
#include "core/fpdfapi/page/cpdf_streamcontentparser.h"
#include "core/fpdfapi/parser/cpdf_array.h"
#include "core/fpdfapi/parser/cpdf_dictionary.h"
#include "core/fpdfapi/parser/fpdf_parser_utility.h"
#include "core/fxge/cfx_graphstatedata.h"
#include "third_party/base/cxx17_backports.h"

CPDF_AllStates::CPDF_AllStates() = default;

CPDF_AllStates::~CPDF_AllStates() = default;

void CPDF_AllStates::Copy(const CPDF_AllStates& src) {
  CopyStates(src);
  m_TextMatrix = src.m_TextMatrix;
  m_ParentMatrix = src.m_ParentMatrix;
  m_CTM = src.m_CTM;
  m_TextPos = src.m_TextPos;
  m_TextLinePos = src.m_TextLinePos;
  m_TextLeading = src.m_TextLeading;
  m_TextRise = src.m_TextRise;
  m_TextHorzScale = src.m_TextHorzScale;
}

void CPDF_AllStates::SetLineDash(const CPDF_Array* pArray,
                                 float phase,
                                 float scale) {
  std::vector<float> dashes = ReadArrayElementsToVector(pArray, pArray->size());
  m_GraphState.SetLineDash(std::move(dashes), phase, scale);
}

void CPDF_AllStates::ProcessExtGS(const CPDF_Dictionary* pGS,
                                  CPDF_StreamContentParser* pParser) {
  CPDF_DictionaryLocker locker(pGS);
  for (const auto& it : locker) {
    RetainPtr<CPDF_Object> pObject = it.second->GetMutableDirect();
    if (!pObject)
      continue;

    uint32_t key = it.first.GetID();
    switch (key) {
      case FXBSTR_ID('L', 'W', 0, 0):
        m_GraphState.SetLineWidth(pObject->GetNumber());
        break;
      case FXBSTR_ID('L', 'C', 0, 0):
        m_GraphState.SetLineCap(
            static_cast<CFX_GraphStateData::LineCap>(pObject->GetInteger()));
        break;
      case FXBSTR_ID('L', 'J', 0, 0):
        m_GraphState.SetLineJoin(
            static_cast<CFX_GraphStateData::LineJoin>(pObject->GetInteger()));
        break;
      case FXBSTR_ID('M', 'L', 0, 0):
        m_GraphState.SetMiterLimit(pObject->GetNumber());
        break;
      case FXBSTR_ID('D', 0, 0, 0): {
        const CPDF_Array* pDash = pObject->AsArray();
        if (!pDash)
          break;

        RetainPtr<const CPDF_Array> pArray = pDash->GetArrayAt(0);
        if (!pArray)
          break;

        // TODO(tsepez): pass moved retained object.
        SetLineDash(pArray.Get(), pDash->GetFloatAt(1), 1.0f);
        break;
      }
      case FXBSTR_ID('R', 'I', 0, 0):
        m_GeneralState.SetRenderIntent(pObject->GetString());
        break;
      case FXBSTR_ID('F', 'o', 'n', 't'): {
        const CPDF_Array* pFont = pObject->AsArray();
        if (!pFont)
          break;

        m_TextState.SetFontSize(pFont->GetFloatAt(1));
        m_TextState.SetFont(pParser->FindFont(pFont->GetByteStringAt(0)));
        break;
      }
      case FXBSTR_ID('T', 'R', 0, 0):
        if (pGS->KeyExist("TR2")) {
          continue;
        }
        [[fallthrough]];
      case FXBSTR_ID('T', 'R', '2', 0):
        m_GeneralState.SetTR(!pObject->IsName() ? std::move(pObject) : nullptr);
        break;
      case FXBSTR_ID('B', 'M', 0, 0): {
        const CPDF_Array* pArray = pObject->AsArray();
        m_GeneralState.SetBlendMode(pArray ? pArray->GetByteStringAt(0)
                                           : pObject->GetString());
        if (m_GeneralState.GetBlendType() > BlendMode::kMultiply)
          pParser->GetPageObjectHolder()->SetBackgroundAlphaNeeded(true);
        break;
      }
      case FXBSTR_ID('S', 'M', 'a', 's'): {
        RetainPtr<CPDF_Dictionary> pMaskDict = ToDictionary(pObject);
        m_GeneralState.SetSoftMask(pMaskDict);
        if (pMaskDict)
          m_GeneralState.SetSMaskMatrix(pParser->GetCurStates()->m_CTM);
        break;
      }
      case FXBSTR_ID('C', 'A', 0, 0):
        m_GeneralState.SetStrokeAlpha(
            pdfium::clamp(pObject->GetNumber(), 0.0f, 1.0f));
        break;
      case FXBSTR_ID('c', 'a', 0, 0):
        m_GeneralState.SetFillAlpha(
            pdfium::clamp(pObject->GetNumber(), 0.0f, 1.0f));
        break;
      case FXBSTR_ID('O', 'P', 0, 0):
        m_GeneralState.SetStrokeOP(!!pObject->GetInteger());
        if (!pGS->KeyExist("op"))
          m_GeneralState.SetFillOP(!!pObject->GetInteger());
        break;
      case FXBSTR_ID('o', 'p', 0, 0):
        m_GeneralState.SetFillOP(!!pObject->GetInteger());
        break;
      case FXBSTR_ID('O', 'P', 'M', 0):
        m_GeneralState.SetOPMode(pObject->GetInteger());
        break;
      case FXBSTR_ID('B', 'G', 0, 0):
        if (pGS->KeyExist("BG2")) {
          continue;
        }
        [[fallthrough]];
      case FXBSTR_ID('B', 'G', '2', 0):
        m_GeneralState.SetBG(pObject.Get());
        break;
      case FXBSTR_ID('U', 'C', 'R', 0):
        if (pGS->KeyExist("UCR2")) {
          continue;
        }
        [[fallthrough]];
      case FXBSTR_ID('U', 'C', 'R', '2'):
        m_GeneralState.SetUCR(pObject.Get());
        break;
      case FXBSTR_ID('H', 'T', 0, 0):
        m_GeneralState.SetHT(pObject.Get());
        break;
      case FXBSTR_ID('F', 'L', 0, 0):
        m_GeneralState.SetFlatness(pObject->GetNumber());
        break;
      case FXBSTR_ID('S', 'M', 0, 0):
        m_GeneralState.SetSmoothness(pObject->GetNumber());
        break;
      case FXBSTR_ID('S', 'A', 0, 0):
        m_GeneralState.SetStrokeAdjust(!!pObject->GetInteger());
        break;
      case FXBSTR_ID('A', 'I', 'S', 0):
        m_GeneralState.SetAlphaSource(!!pObject->GetInteger());
        break;
      case FXBSTR_ID('T', 'K', 0, 0):
        m_GeneralState.SetTextKnockout(!!pObject->GetInteger());
        break;
    }
  }
  m_GeneralState.SetMatrix(m_CTM);
}
