// Copyright 2016 The PDFium Authors
// 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/fxcrt/bytestring.h"
#include "core/fxge/cfx_graphstatedata.h"

CPDF_AllStates::CPDF_AllStates() = default;

CPDF_AllStates::~CPDF_AllStates() = default;

void CPDF_AllStates::Copy(const CPDF_AllStates& src) {
  CopyStates(src);
  m_GraphicsResourceNames = src.m_GraphicsResourceNames;
  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;

        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(
            std::clamp(pObject->GetNumber(), 0.0f, 1.0f));
        break;
      case FXBSTR_ID('c', 'a', 0, 0):
        m_GeneralState.SetFillAlpha(
            std::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(std::move(pObject));
        break;
      case FXBSTR_ID('U', 'C', 'R', 0):
        if (pGS->KeyExist("UCR2")) {
          continue;
        }
        [[fallthrough]];
      case FXBSTR_ID('U', 'C', 'R', '2'):
        m_GeneralState.SetUCR(std::move(pObject));
        break;
      case FXBSTR_ID('H', 'T', 0, 0):
        m_GeneralState.SetHT(std::move(pObject));
        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);
}
