////////////////////////////////////////////////////////
// File Name: OpenArchive.h
//
//  Abstract: Manages the opening process for archives.  Determines the correct format of an archive.
//
////////////////////////////////////////////////////////

#ifndef __OPEN_ARCHIVE_H
#define __OPEN_ARCHIVE_H

#include "../7Zip/CPP/Common/MyString.h"

#include "../7Zip/CPP/Windows/FileFind.h"
#include "LoadCodecs.h"

HRESULT GetArchiveItemBoolProp(IInArchive *archive, UInt32 index, PROPID propID, bool &result);
HRESULT IsArchiveItemFolder(IInArchive *archive, UInt32 index, bool &result);

namespace SevenZipExtractor
{
	class ArchiveOpenCallback;
}

struct CArc
{
  CMyComPtr<IInArchive> Archive;
  UString Path;
  UString DefaultName;
  int FormatIndex;
  int SubfileIndex;
  FILETIME MTime;
  bool MTimeDefined;
  UString ErrorMessage;

  CArc(): MTimeDefined(false) {}

  HRESULT GetItemPath(UInt32 index, UString &result) const;
  HRESULT GetItemMTime(UInt32 index, FILETIME &ft, bool &defined) const;
  HRESULT IsItemAnti(UInt32 index, bool &result) const
    { return GetArchiveItemBoolProp(Archive, index, kpidIsAnti, result); }
  HRESULT GetUnpackedSize(UInt32 index, UInt64 &value) const;

  HRESULT OpenStream(
    CCodecs *codecs,
    int formatIndex,
    IInStream *stream,
    ISequentialInStream *seqStream,
    IArchiveOpenCallback *callback);

  HRESULT OpenStreamOrFile(
    CCodecs *codecs,
    int formatIndex,
    bool stdInMode,
    IInStream *stream,
    IArchiveOpenCallback *callback);
};

struct CArchiveLink
{
  CObjectVector<CArc> Arcs;
  UStringVector VolumePaths;
  UInt64 VolumesSize;
  bool IsOpen;

  CArchiveLink(): VolumesSize(0), IsOpen(false) {}
  HRESULT Close();
  void Release();
  ~CArchiveLink() { Release(); }

  IInArchive *GetArchive() const { return Arcs.Back().Archive; }

  HRESULT Open(
    CCodecs *codecs,
    const CIntVector &formatIndices,
    bool stdInMode,
    IInStream *stream,
    const UString &filePath,
    IArchiveOpenCallback *callback);

  HRESULT Open2(
    CCodecs *codecs,
    const CIntVector &formatIndices,
    bool stdInMode,
    IInStream *stream,
    const UString &filePath,
    SevenZipExtractor::ArchiveOpenCallback *callbackUI);
};

#endif
