// 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 "../../public/fpdf_dataavail.h"
#include "../../public/fpdf_formfill.h"
#include "../include/fsdk_define.h"
#include "../include/fpdfxfa/fpdfxfa_doc.h"
#include "../include/fpdfxfa/fpdfxfa_app.h"

extern void ProcessParseError(FX_DWORD err_code);
class CFPDF_FileAvailWrap : public IFX_FileAvail
{
public:
	CFPDF_FileAvailWrap()
	{
		m_pfileAvail = NULL;
	}

	void Set(FX_FILEAVAIL* pfileAvail)
	{
		m_pfileAvail = pfileAvail;
	}

	virtual FX_BOOL			IsDataAvail( FX_FILESIZE offset, FX_DWORD size)
	{
		return m_pfileAvail->IsDataAvail(m_pfileAvail, offset, size);
	}

private:
	FX_FILEAVAIL* m_pfileAvail;
};

class CFPDF_FileAccessWrap : public IFX_FileRead
{
public:
	CFPDF_FileAccessWrap()
	{
		m_pFileAccess = NULL;
	}

	void Set(FPDF_FILEACCESS* pFile)
	{
		m_pFileAccess = pFile;
	}

	virtual FX_FILESIZE		GetSize()
	{
		return m_pFileAccess->m_FileLen;
	}

	virtual FX_BOOL			ReadBlock(void* buffer, FX_FILESIZE offset, size_t size)
	{
		return m_pFileAccess->m_GetBlock(m_pFileAccess->m_Param, offset, (uint8_t*)buffer, size);
	}

	virtual void			Release()
	{
	}

private:
	FPDF_FILEACCESS*		m_pFileAccess;
};

class CFPDF_DownloadHintsWrap : public IFX_DownloadHints
{
public:
	CFPDF_DownloadHintsWrap(FX_DOWNLOADHINTS* pDownloadHints)
	{
		m_pDownloadHints = pDownloadHints;
	}
public:
	virtual void			AddSegment(FX_FILESIZE offset, FX_DWORD size)
	{
		m_pDownloadHints->AddSegment(m_pDownloadHints, offset, size);
	}
private:
	FX_DOWNLOADHINTS* m_pDownloadHints;
};

class CFPDF_DataAvail
{
public:
	CFPDF_DataAvail()
	{
		m_pDataAvail = NULL;
	}

	~CFPDF_DataAvail()
	{
            delete m_pDataAvail;
	}

	IPDF_DataAvail*			m_pDataAvail;
	CFPDF_FileAvailWrap		m_FileAvail;
	CFPDF_FileAccessWrap	m_FileRead;
};

DLLEXPORT FPDF_AVAIL STDCALL FPDFAvail_Create(FX_FILEAVAIL* file_avail, FPDF_FILEACCESS* file)
{
	CFPDF_DataAvail* pAvail = FX_NEW CFPDF_DataAvail;
	pAvail->m_FileAvail.Set(file_avail);
	pAvail->m_FileRead.Set(file);
	pAvail->m_pDataAvail = IPDF_DataAvail::Create(&pAvail->m_FileAvail, &pAvail->m_FileRead);
	return pAvail;
}

DLLEXPORT void STDCALL FPDFAvail_Destroy(FPDF_AVAIL avail)
{
    delete (CFPDF_DataAvail*)avail;
}

DLLEXPORT int STDCALL FPDFAvail_IsDocAvail(FPDF_AVAIL avail, FX_DOWNLOADHINTS* hints)
{
	if (avail == NULL || hints == NULL) return 0;
	CFPDF_DownloadHintsWrap hints_wrap(hints);
	return ((CFPDF_DataAvail*)avail)->m_pDataAvail->IsDocAvail(&hints_wrap);
}

extern void CheckUnSupportError(CPDF_Document * pDoc, FX_DWORD err_code);

DLLEXPORT FPDF_DOCUMENT STDCALL FPDFAvail_GetDocument(FPDF_AVAIL avail,	FPDF_BYTESTRING password)
{
	if (avail == NULL) return NULL;
	CPDF_Parser* pParser = FX_NEW CPDF_Parser;
	pParser->SetPassword(password);

	FX_DWORD err_code = pParser->StartAsynParse(((CFPDF_DataAvail*)avail)->m_pDataAvail->GetFileRead());
	if (err_code) {
		delete pParser;
		ProcessParseError(err_code);
		return NULL;
	}
	((CFPDF_DataAvail*)avail)->m_pDataAvail->SetDocument(pParser->GetDocument());
	CheckUnSupportError(pParser->GetDocument(), FPDF_ERR_SUCCESS);
	CPDF_Document* pPDFDoc = pParser->GetDocument();
	CPDFXFA_App* pApp = CPDFXFA_App::GetInstance();
	CPDFXFA_Document* pDocument = FX_NEW CPDFXFA_Document(pPDFDoc, pApp);
	return pDocument;
}

DLLEXPORT int STDCALL FPDFAvail_GetFirstPageNum(FPDF_DOCUMENT doc)
{
	if (doc == NULL) return 0;
	CPDF_Document* pDoc = ((CPDFXFA_Document*)doc)->GetPDFDoc();
	return ((CPDF_Parser*)pDoc->GetParser())->GetFirstPageNo();
}

DLLEXPORT int STDCALL FPDFAvail_IsPageAvail(FPDF_AVAIL avail, int page_index, FX_DOWNLOADHINTS* hints)
{
	if (avail == NULL || hints == NULL) return 0;
	CFPDF_DownloadHintsWrap hints_wrap(hints);
	return ((CFPDF_DataAvail*)avail)->m_pDataAvail->IsPageAvail(page_index, &hints_wrap);
}

DLLEXPORT int STDCALL FPDFAvail_IsFormAvail(FPDF_AVAIL avail, FX_DOWNLOADHINTS* hints)
{
	if (avail == NULL || hints == NULL) return -1;
	CFPDF_DownloadHintsWrap hints_wrap(hints);
	return ((CFPDF_DataAvail*)avail)->m_pDataAvail->IsFormAvail(&hints_wrap);
}

DLLEXPORT FPDF_BOOL STDCALL FPDFAvail_IsLinearized(FPDF_AVAIL avail)
{
		if (avail == NULL) return -1;
	return ((CFPDF_DataAvail*)avail)->m_pDataAvail->IsLinearizedPDF();

}
