// 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 "../../include/pdfwindow/PDFWindow.h"
#include "../../include/pdfwindow/PWL_Wnd.h"
#include "../../include/pdfwindow/PWL_Icon.h"
#include "../../include/pdfwindow/PWL_Utils.h"

/* ------------------------------- CPWL_Image ---------------------------------- */

CPWL_Image::CPWL_Image() : m_pPDFStream(NULL)
{
}

CPWL_Image::~CPWL_Image()
{
}

CFX_ByteString CPWL_Image::GetImageAppStream()
{
	CFX_ByteTextBuf sAppStream;

	CFX_ByteString sAlias = GetImageAlias();
	CPDF_Rect rcPlate = GetClientRect();
	CPDF_Matrix mt;
	mt.SetReverse(GetImageMatrix());

	FX_FLOAT fHScale = 1.0f;
	FX_FLOAT fVScale = 1.0f;
	GetScale(fHScale,fVScale);

	FX_FLOAT fx = 0.0f;
	FX_FLOAT fy = 0.0f;
	GetImageOffset(fx,fy);

	if (m_pPDFStream && sAlias.GetLength()>0)
	{
		sAppStream << "q\n";
		sAppStream << rcPlate.left << " " << rcPlate.bottom << " "
			<< rcPlate.right - rcPlate.left << " " << rcPlate.top - rcPlate.bottom << " re W n\n";

		sAppStream << fHScale << " 0 0 " << fVScale << " " << rcPlate.left + fx << " " << rcPlate.bottom + fy << " cm\n";
		sAppStream << mt.GetA() << " " << mt.GetB() << " " << mt.GetC() << " " << mt.GetD() << " " << mt.GetE() << " " << mt.GetF() << " cm\n";

		sAppStream << "0 g 0 G 1 w /" << sAlias << " Do\n" << "Q\n";
	}

	return sAppStream.GetByteString();
}

void CPWL_Image::SetPDFStream(CPDF_Stream * pStream)
{
	m_pPDFStream = pStream;
}

CPDF_Stream * CPWL_Image::GetPDFStream()
{
	return m_pPDFStream;
}

void CPWL_Image::GetImageSize(FX_FLOAT & fWidth,FX_FLOAT & fHeight)
{
	fWidth = 0.0f;
	fHeight = 0.0f;

	if (m_pPDFStream)
	{
		if (CPDF_Dictionary * pDict = m_pPDFStream->GetDict())
		{
			CPDF_Rect rect = pDict->GetRect("BBox");

			fWidth = rect.right - rect.left;
			fHeight = rect.top - rect.bottom;
		}
	}
}

CPDF_Matrix	CPWL_Image::GetImageMatrix()
{
	if (m_pPDFStream)
	{
		if (CPDF_Dictionary * pDict = m_pPDFStream->GetDict())
		{
			return pDict->GetMatrix("Matrix");
		}
	}

	return CPDF_Matrix();
}

CFX_ByteString CPWL_Image::GetImageAlias()
{
	if (m_sImageAlias.IsEmpty())
	{
		if (m_pPDFStream)
		{
			if (CPDF_Dictionary * pDict = m_pPDFStream->GetDict())
			{
				return pDict->GetString("Name");
			}
		}
	}
	else
		return m_sImageAlias;

	return CFX_ByteString();
}

void CPWL_Image::SetImageAlias(const FX_CHAR* sImageAlias)
{
	m_sImageAlias = sImageAlias;
}

void CPWL_Image::GetScale(FX_FLOAT & fHScale,FX_FLOAT & fVScale)
{
	fHScale = 1.0f;
	fVScale = 1.0f;
}


void CPWL_Image::GetImageOffset(FX_FLOAT & x,FX_FLOAT & y)
{
	x = 0.0f;
	y = 0.0f;
}

/* ------------------------------- CPWL_Icon ---------------------------------- */

CPWL_Icon::CPWL_Icon() : m_pIconFit(NULL)
{
}

CPWL_Icon::~CPWL_Icon()
{
}

int32_t CPWL_Icon::GetScaleMethod()
{
	if (m_pIconFit)
		return m_pIconFit->GetScaleMethod();

	return 0;
}

bool	CPWL_Icon::IsProportionalScale()
{
	if (m_pIconFit)
		return m_pIconFit->IsProportionalScale();

	return false;
}

void CPWL_Icon::GetIconPosition(FX_FLOAT & fLeft, FX_FLOAT & fBottom)
{
	if (m_pIconFit)
	{
		//m_pIconFit->GetIconPosition(fLeft,fBottom);
		fLeft = 0.0f;
		fBottom = 0.0f;
		CPDF_Array* pA = m_pIconFit->m_pDict ? m_pIconFit->m_pDict->GetArray("A") : NULL;
		if (pA != NULL)
		{
			FX_DWORD dwCount = pA->GetCount();
			if (dwCount > 0) fLeft = pA->GetNumber(0);
			if (dwCount > 1) fBottom = pA->GetNumber(1);
		}
	}
	else
	{
		fLeft = 0.0f;
		fBottom = 0.0f;
	}
}

bool CPWL_Icon::GetFittingBounds()
{
	if (m_pIconFit)
		return m_pIconFit->GetFittingBounds();

	return false;
}

void CPWL_Icon::GetScale(FX_FLOAT & fHScale,FX_FLOAT & fVScale)
{
	fHScale = 1.0f;
	fVScale = 1.0f;

	if (m_pPDFStream)
	{
		FX_FLOAT fImageWidth,fImageHeight;
		FX_FLOAT fPlateWidth,fPlateHeight;

		CPDF_Rect rcPlate = GetClientRect();
		fPlateWidth = rcPlate.right - rcPlate.left;
		fPlateHeight = rcPlate.top - rcPlate.bottom;

		GetImageSize(fImageWidth,fImageHeight);

		int32_t nScaleMethod = GetScaleMethod();

		switch (nScaleMethod)
		{
		default:
		case 0:
			fHScale = fPlateWidth / PWL_MAX(fImageWidth,1.0f);
			fVScale = fPlateHeight / PWL_MAX(fImageHeight,1.0f);
			break;
		case 1:
			if (fPlateWidth < fImageWidth)
				fHScale = fPlateWidth / PWL_MAX(fImageWidth,1.0f);
			if (fPlateHeight < fImageHeight)
				fVScale = fPlateHeight / PWL_MAX(fImageHeight,1.0f);
			break;
		case 2:
			if (fPlateWidth > fImageWidth)
				fHScale = fPlateWidth / PWL_MAX(fImageWidth,1.0f);
			if (fPlateHeight > fImageHeight)
				fVScale = fPlateHeight / PWL_MAX(fImageHeight,1.0f);
			break;
		case 3:
			break;
		}

		FX_FLOAT fMinScale;
		if (IsProportionalScale())
		{
			fMinScale = PWL_MIN(fHScale,fVScale);
			fHScale = fMinScale;
			fVScale = fMinScale;
		}
	}
}

void CPWL_Icon::GetImageOffset(FX_FLOAT & x,FX_FLOAT & y)
{
	FX_FLOAT fLeft,fBottom;

	GetIconPosition(fLeft, fBottom);
	x = 0.0f;
	y = 0.0f;

	FX_FLOAT fImageWidth,fImageHeight;
	GetImageSize(fImageWidth,fImageHeight);

	FX_FLOAT fHScale,fVScale;
	GetScale(fHScale,fVScale);

	FX_FLOAT fImageFactWidth = fImageWidth * fHScale;
	FX_FLOAT fImageFactHeight = fImageHeight * fVScale;

	FX_FLOAT fPlateWidth,fPlateHeight;
	CPDF_Rect rcPlate = GetClientRect();
	fPlateWidth = rcPlate.right - rcPlate.left;
	fPlateHeight = rcPlate.top - rcPlate.bottom;

	x = (fPlateWidth - fImageFactWidth) * fLeft;
	y = (fPlateHeight - fImageFactHeight)  * fBottom;
}

