////////////////////////////////////////////////////////
// File Name: ArchiveExtractCallback.cpp
//
//  Abstract: Callback for when 7 zip extracts a compressed file.
//
////////////////////////////////////////////////////////

#include "stdafx.h"
#include "ArchiveExtractCallback.h"
#include "OpenArchive.h"
#include <../7Zip/CPP/7zip/Common/FileStreams.h>

namespace SevenZipExtractor
{
using namespace std;
using namespace NArchive::NExtract;

CArchiveExtractCallback::CArchiveExtractCallback(const CArc *arc, const CATLString& OutputFilePath)
    : m_arc(arc)
    , m_totalBytes(0),
	m_OutputFilePath(OutputFilePath)
{
}

STDMETHODIMP CArchiveExtractCallback::SetTotal(UInt64 size)
{
    m_totalBytes = size;
    return S_OK;
}

STDMETHODIMP CArchiveExtractCallback::SetCompleted(const UInt64 *pCompleteValue)
{
    return S_OK;
}

STDMETHODIMP CArchiveExtractCallback::GetStream(UInt32 index, ISequentialOutStream **ppOutStream, Int32 askExtractMode)
{
	HRESULT RetVal = S_OK;
	CComPtr<IInArchive> spArchive;
	bool IsFolder = false;

    if (!ppOutStream) return E_POINTER;
    *ppOutStream = NULL;

	if(ppOutStream)
	{
		if (askExtractMode == NAskMode::kExtract)
		{
			spArchive = m_arc->Archive;

			RINOK(IsArchiveItemFolder(spArchive, index, IsFolder));

			if(!IsFolder)
			{
				::DeleteFile(m_OutputFilePath);

				CComPtr<COutFileStream> spFile(new COutFileStream());
				if (spFile->Open(m_OutputFilePath, CREATE_ALWAYS))
				{
					*ppOutStream = spFile.Detach();					
				}
				else
				{
					return E_ABORT;
				}				
			}
		}
	}
	else
	{
		RetVal = E_POINTER;
	}

    return RetVal;
}

STDMETHODIMP CArchiveExtractCallback::PrepareOperation(Int32 askExtractMode)
{
    return S_OK;
}

STDMETHODIMP CArchiveExtractCallback::SetOperationResult(Int32 result)
{
    return S_OK;
}

}
