// ArchiveOpenCallback.cpp

#include "StdAfx.h"

#include "../../../Common/ComTry.h"

#include "../../../Windows/FileName.h"
#include "../../../Windows/PropVariant.h"

#include "../../Common/FileStreams.h"

#include "ArchiveOpenCallback.h"

using namespace NWindows;

STDMETHODIMP COpenCallbackImp::SetTotal(const UInt64 *files, const UInt64 *bytes)
{
  COM_TRY_BEGIN
  if (ReOpenCallback)
    return ReOpenCallback->SetTotal(files, bytes);
  if (!Callback)
    return S_OK;
  return Callback->Open_SetTotal(files, bytes);
  COM_TRY_END
}

STDMETHODIMP COpenCallbackImp::SetCompleted(const UInt64 *files, const UInt64 *bytes)
{
  COM_TRY_BEGIN
  if (ReOpenCallback)
    return ReOpenCallback->SetCompleted(files, bytes);
  if (!Callback)
    return S_OK;
  return Callback->Open_SetCompleted(files, bytes);
  COM_TRY_END
}
  
STDMETHODIMP COpenCallbackImp::GetProperty(PROPID propID, PROPVARIANT *value)
{
  COM_TRY_BEGIN
  NCOM::CPropVariant prop;
  if (_subArchiveMode)
    switch(propID)
    {
      case kpidName: prop = _subArchiveName; break;
    }
  else
    switch(propID)
    {
      case kpidName:  prop = _fileInfo.Name; break;
      case kpidIsDir:  prop = _fileInfo.IsDir(); break;
      case kpidSize:  prop = _fileInfo.Size; break;
      case kpidAttrib:  prop = (UInt32)_fileInfo.Attrib; break;
      case kpidCTime:  prop = _fileInfo.CTime; break;
      case kpidATime:  prop = _fileInfo.ATime; break;
      case kpidMTime:  prop = _fileInfo.MTime; break;
    }
  prop.Detach(value);
  return S_OK;
  COM_TRY_END
}

struct CInFileStreamVol: public CInFileStream
{
  int FileNameIndex;
  COpenCallbackImp *OpenCallbackImp;
  CMyComPtr<IArchiveOpenCallback> OpenCallbackRef;
 
  ~CInFileStreamVol()
  {
    if (OpenCallbackRef)
      OpenCallbackImp->FileNames_WasUsed[FileNameIndex] = false;
  }
};

STDMETHODIMP COpenCallbackImp::GetStream(const wchar_t *name, IInStream **inStream)
{
  COM_TRY_BEGIN
  *inStream = NULL;
  if (_subArchiveMode)
    return S_FALSE;
  if (Callback)
  {
    RINOK(Callback->Open_CheckBreak());
  }
  FString fullPath;
  if (!NFile::NName::GetFullPath(_folderPrefix, us2fs(name), fullPath))
    return S_FALSE;
  if (!_fileInfo.Find(fullPath))
    return S_FALSE;
  if (_fileInfo.IsDir())
    return S_FALSE;
  CInFileStreamVol *inFile = new CInFileStreamVol;
  CMyComPtr<IInStream> inStreamTemp = inFile;
  if (!inFile->Open(fullPath))
    return ::GetLastError();

  FileSizes.Add(_fileInfo.Size);
  FileNames.Add(name);
  inFile->FileNameIndex = FileNames_WasUsed.Add(true);
  inFile->OpenCallbackImp = this;
  inFile->OpenCallbackRef = this;
  // TotalSize += _fileInfo.Size;
  *inStream = inStreamTemp.Detach();
  return S_OK;
  COM_TRY_END
}

#ifndef _NO_CRYPTO
STDMETHODIMP COpenCallbackImp::CryptoGetTextPassword(BSTR *password)
{
  COM_TRY_BEGIN
  if (ReOpenCallback)
  {
    CMyComPtr<ICryptoGetTextPassword> getTextPassword;
    ReOpenCallback.QueryInterface(IID_ICryptoGetTextPassword, &getTextPassword);
    if (getTextPassword)
      return getTextPassword->CryptoGetTextPassword(password);
  }
  if (!Callback)
    return E_NOTIMPL;
  return Callback->Open_CryptoGetTextPassword(password);
  COM_TRY_END
}
#endif
