// Copyright 2014 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/fwl/core/cfwl_picturebox.h"

#include <memory>

IFWL_PictureBox* CFWL_PictureBox::GetWidget() {
  return static_cast<IFWL_PictureBox*>(m_pIface.get());
}

const IFWL_PictureBox* CFWL_PictureBox::GetWidget() const {
  return static_cast<IFWL_PictureBox*>(m_pIface.get());
}

FWL_Error CFWL_PictureBox::Initialize(
    const CFWL_WidgetProperties* pProperties) {
  if (m_pIface)
    return FWL_Error::Indefinite;
  if (pProperties) {
    *m_pProperties = *pProperties;
  }
  std::unique_ptr<IFWL_PictureBox> pPictureBox(new IFWL_PictureBox(
      m_pProperties->MakeWidgetImpProperties(&m_PictureBoxDP)));
  FWL_Error ret = pPictureBox->Initialize();
  if (ret != FWL_Error::Succeeded) {
    return ret;
  }
  m_pIface = std::move(pPictureBox);
  CFWL_Widget::Initialize();
  return FWL_Error::Succeeded;
}

CFX_DIBitmap* CFWL_PictureBox::GetPicture() {
  return m_PictureBoxDP.m_pBitmap;
}

FWL_Error CFWL_PictureBox::SetPicture(CFX_DIBitmap* pBitmap) {
  m_PictureBoxDP.m_pBitmap = pBitmap;
  return FWL_Error::Succeeded;
}

FX_FLOAT CFWL_PictureBox::GetRotation() {
  return m_PictureBoxDP.m_fRotation;
}

FWL_Error CFWL_PictureBox::SetRotation(FX_FLOAT fRotation) {
  m_PictureBoxDP.m_fRotation = fRotation;
  return FWL_Error::Succeeded;
}

int32_t CFWL_PictureBox::GetFlipMode() {
  return m_PictureBoxDP.GetFlipMode(m_pIface.get());
}

FWL_Error CFWL_PictureBox::SetFlipMode(int32_t iFlipMode) {
  m_PictureBoxDP.m_iFlipMode = iFlipMode;
  return FWL_Error::Succeeded;
}

int32_t CFWL_PictureBox::GetOpacity() {
  return m_PictureBoxDP.GetOpacity(m_pIface.get());
}

FWL_Error CFWL_PictureBox::SetOpacity(int32_t iOpacity) {
  m_PictureBoxDP.m_iOpacity = iOpacity;
  return FWL_Error::Succeeded;
}

FWL_Error CFWL_PictureBox::GetScale(FX_FLOAT& fScaleX, FX_FLOAT& fScaleY) {
  CFX_Matrix matrix;
  m_PictureBoxDP.GetMatrix(m_pIface.get(), matrix);
  matrix.Scale(fScaleX, fScaleY);
  return FWL_Error::Succeeded;
}

FWL_Error CFWL_PictureBox::SetScale(FX_FLOAT fScaleX, FX_FLOAT fScaleY) {
  m_PictureBoxDP.m_fScaleX = fScaleX;
  m_PictureBoxDP.m_fScaleY = fScaleY;
  return FWL_Error::Succeeded;
}

FWL_Error CFWL_PictureBox::GetOffset(FX_FLOAT& fx, FX_FLOAT& fy) {
  CFX_Matrix matrix;
  m_PictureBoxDP.GetMatrix(m_pIface.get(), matrix);
  fx = matrix.e;
  fy = matrix.f;
  return FWL_Error::Succeeded;
}

FWL_Error CFWL_PictureBox::SetOffset(FX_FLOAT fx, FX_FLOAT fy) {
  m_PictureBoxDP.m_fOffSetX = fx;
  m_PictureBoxDP.m_fOffSetY = fy;
  return FWL_Error::Succeeded;
}

CFWL_PictureBox::CFWL_PictureBox() {}

CFWL_PictureBox::~CFWL_PictureBox() {}

CFWL_PictureBox::CFWL_PictureBoxDP::CFWL_PictureBoxDP()
    : m_pBitmap(nullptr),
      m_iOpacity(0),
      m_iFlipMode(0),
      m_fRotation(0.0f),
      m_fScaleX(1.0f),
      m_fScaleY(1.0f),
      m_fOffSetX(0.0f),
      m_fOffSetY(0.0f) {}

FWL_Error CFWL_PictureBox::CFWL_PictureBoxDP::GetCaption(
    IFWL_Widget* pWidget,
    CFX_WideString& wsCaption) {
  return FWL_Error::Succeeded;
}

CFX_DIBitmap* CFWL_PictureBox::CFWL_PictureBoxDP::GetPicture(
    IFWL_Widget* pWidget) {
  return m_pBitmap;
}

CFX_DIBitmap* CFWL_PictureBox::CFWL_PictureBoxDP::GetErrorPicture(
    IFWL_Widget* pWidget) {
  return m_pBitmap;
}

CFX_DIBitmap* CFWL_PictureBox::CFWL_PictureBoxDP::GetInitialPicture(
    IFWL_Widget* pWidget) {
  return m_pBitmap;
}

int32_t CFWL_PictureBox::CFWL_PictureBoxDP::GetOpacity(IFWL_Widget* pWidget) {
  return m_iOpacity;
}

FWL_Error CFWL_PictureBox::CFWL_PictureBoxDP::GetMatrix(IFWL_Widget* pWidget,
                                                        CFX_Matrix& matrix) {
  CFX_RectF rect;
  pWidget->GetClientRect(rect);
  FX_FLOAT fLen = rect.width / 2;
  FX_FLOAT fWid = rect.height / 2;
  matrix.SetIdentity();
  matrix.Translate(-fLen, -fWid);
  matrix.Rotate(m_fRotation);
  matrix.Translate(fLen, fWid);
  matrix.Scale(m_fScaleX, m_fScaleY);
  matrix.Translate(m_fOffSetX, m_fOffSetY);
  return FWL_Error::Succeeded;
}

int32_t CFWL_PictureBox::CFWL_PictureBoxDP::GetFlipMode(IFWL_Widget* pWidget) {
  return m_iFlipMode;
}
