// 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/compiler_specific.h"
#include "third_party/base/stl_util.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(CPDF_Dictionary* pGS,
                                  CPDF_StreamContentParser* pParser) {
  CPDF_DictionaryLocker locker(pGS);
  for (const auto& it : locker) {
    const ByteString& key_str = it.first;
    CPDF_Object* pElement = it.second.Get();
    CPDF_Object* pObject = pElement ? pElement->GetDirect() : nullptr;
    if (!pObject)
      continue;

    uint32_t key = key_str.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): {
        CPDF_Array* pDash = pObject->AsArray();
        if (!pDash)
          break;

        CPDF_Array* pArray = pDash->GetArrayAt(0);
        if (!pArray)
          break;

        SetLineDash(pArray, pDash->GetNumberAt(1), 1.0f);
        break;
      }
      case FXBSTR_ID('R', 'I', 0, 0):
        m_GeneralState.SetRenderIntent(pObject->GetString());
        break;
      case FXBSTR_ID('F', 'o', 'n', 't'): {
        CPDF_Array* pFont = pObject->AsArray();
        if (!pFont)
          break;

        m_TextState.SetFontSize(pFont->GetNumberAt(1));
        m_TextState.SetFont(pParser->FindFont(pFont->GetStringAt(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 && !pObject->IsName() ? pObject : nullptr);
        break;
      case FXBSTR_ID('B', 'M', 0, 0): {
        CPDF_Array* pArray = pObject->AsArray();
        m_GeneralState.SetBlendMode(pArray ? pArray->GetStringAt(0)
                                           : pObject->GetString());
        if (m_GeneralState.GetBlendType() > BlendMode::kMultiply)
          pParser->GetPageObjectHolder()->SetBackgroundAlphaNeeded(true);
        break;
      }
      case FXBSTR_ID('S', 'M', 'a', 's'):
        if (ToDictionary(pObject)) {
          m_GeneralState.SetSoftMask(pObject);
          m_GeneralState.SetSMaskMatrix(pParser->GetCurStates()->m_CTM);
        } else {
          m_GeneralState.SetSoftMask(nullptr);
        }
        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);
        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);
        break;
      case FXBSTR_ID('H', 'T', 0, 0):
        m_GeneralState.SetHT(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);
}
