// 7zHandlerOut.cpp

#include "StdAfx.h"

#include "../../../Common/ComTry.h"
#include "../../../Common/StringToInt.h"
#include "../../../Common/Wildcard.h"

#include "../Common/ItemNameUtils.h"
#include "../Common/ParseProperties.h"

#include "7zHandler.h"
#include "7zOut.h"
#include "7zUpdate.h"

using namespace NWindows;

namespace NArchive {
namespace N7z {

static const wchar_t *k_LZMA_Name = L"LZMA";
static const wchar_t *kDefaultMethodName = L"LZMA2";
static const wchar_t *k_Copy_Name = L"Copy";

static const wchar_t *k_MatchFinder_ForHeaders = L"BT2";
static const UInt32 k_NumFastBytes_ForHeaders = 273;
static const UInt32 k_Level_ForHeaders = 5;
static const UInt32 k_Dictionary_ForHeaders =
  #ifdef UNDER_CE
  1 << 18;
  #else
  1 << 20;
  #endif

STDMETHODIMP CHandler::GetFileTimeType(UInt32 *type)
{
  *type = NFileTimeType::kWindows;
  return S_OK;
}

HRESULT CHandler::PropsMethod_To_FullMethod(CMethodFull &dest, const COneMethodInfo &m)
{
  if (!FindMethod(
      EXTERNAL_CODECS_VARS
      m.MethodName, dest.Id, dest.NumInStreams, dest.NumOutStreams))
    return E_INVALIDARG;
  (CProps &)dest = (CProps &)m;
  return S_OK;
}

HRESULT CHandler::SetHeaderMethod(CCompressionMethodMode &headerMethod)
{
  if (!_compressHeaders)
    return S_OK;
  COneMethodInfo m;
  m.MethodName = k_LZMA_Name;
  m.AddPropString(NCoderPropID::kMatchFinder, k_MatchFinder_ForHeaders);
  m.AddProp32(NCoderPropID::kLevel, k_Level_ForHeaders);
  m.AddProp32(NCoderPropID::kNumFastBytes, k_NumFastBytes_ForHeaders);
  m.AddProp32(NCoderPropID::kDictionarySize, k_Dictionary_ForHeaders);
  m.AddNumThreadsProp(1);

  CMethodFull methodFull;
  RINOK(PropsMethod_To_FullMethod(methodFull, m));
  headerMethod.Methods.Add(methodFull);
  return S_OK;
}

void CHandler::AddDefaultMethod()
{
  FOR_VECTOR (i, _methods)
  {
    UString &methodName = _methods[i].MethodName;
    if (methodName.IsEmpty())
      methodName = kDefaultMethodName;
  }
  if (_methods.IsEmpty())
  {
    COneMethodInfo m;
    m.MethodName = (GetLevel() == 0 ? k_Copy_Name : kDefaultMethodName);
    _methods.Add(m);
  }
}

HRESULT CHandler::SetMainMethod(
    CCompressionMethodMode &methodMode,
    CObjectVector<COneMethodInfo> &methods
    #ifndef _7ZIP_ST
    , UInt32 numThreads
    #endif
    )
{
  AddDefaultMethod();

  const UInt64 kSolidBytes_Min = (1 << 24);
  const UInt64 kSolidBytes_Max = ((UInt64)1 << 32) - 1;

  bool needSolid = false;
  FOR_VECTOR (i, methods)
  {
    COneMethodInfo &oneMethodInfo = methods[i];
    SetGlobalLevelAndThreads(oneMethodInfo
      #ifndef _7ZIP_ST
      , numThreads
      #endif
      );

    CMethodFull methodFull;
    RINOK(PropsMethod_To_FullMethod(methodFull, oneMethodInfo));
    methodMode.Methods.Add(methodFull);

    if (methodFull.Id != k_Copy)
      needSolid = true;

    if (_numSolidBytesDefined)
      continue;

    UInt32 dicSize;
    switch (methodFull.Id)
    {
      case k_LZMA:
      case k_LZMA2: dicSize = oneMethodInfo.Get_Lzma_DicSize(); break;
      case k_PPMD: dicSize = oneMethodInfo.Get_Ppmd_MemSize(); break;
      case k_Deflate: dicSize = (UInt32)1 << 15; break;
      case k_BZip2: dicSize = oneMethodInfo.Get_BZip2_BlockSize(); break;
      default: continue;
    }
    _numSolidBytes = (UInt64)dicSize << 7;
    if (_numSolidBytes < kSolidBytes_Min) _numSolidBytes = kSolidBytes_Min;
    if (_numSolidBytes > kSolidBytes_Max) _numSolidBytes = kSolidBytes_Max;
    _numSolidBytesDefined = true;
  }

  if (!_numSolidBytesDefined)
    if (needSolid)
      _numSolidBytes = kSolidBytes_Max;
    else
      _numSolidBytes = 0;
  _numSolidBytesDefined = true;
  return S_OK;
}

static HRESULT GetTime(IArchiveUpdateCallback *updateCallback, int index, PROPID propID, UInt64 &ft, bool &ftDefined)
{
  // ft = 0;
  // ftDefined = false;
  NCOM::CPropVariant prop;
  RINOK(updateCallback->GetProperty(index, propID, &prop));
  if (prop.vt == VT_FILETIME)
  {
    ft = prop.filetime.dwLowDateTime | ((UInt64)prop.filetime.dwHighDateTime << 32);
    ftDefined = true;
  }
  else if (prop.vt != VT_EMPTY)
    return E_INVALIDARG;
  else
  {
    ft = 0;
    ftDefined = false;
  }
  return S_OK;
}

/*

#ifdef _WIN32
static const wchar_t kDirDelimiter1 = L'\\';
#endif
static const wchar_t kDirDelimiter2 = L'/';

static inline bool IsCharDirLimiter(wchar_t c)
{
  return (
    #ifdef _WIN32
    c == kDirDelimiter1 ||
    #endif
    c == kDirDelimiter2);
}

static int FillSortIndex(CObjectVector<CTreeFolder> &treeFolders, int cur, int curSortIndex)
{
  CTreeFolder &tf = treeFolders[cur];
  tf.SortIndex = curSortIndex++;
  for (int i = 0; i < tf.SubFolders.Size(); i++)
    curSortIndex = FillSortIndex(treeFolders, tf.SubFolders[i], curSortIndex);
  tf.SortIndexEnd = curSortIndex;
  return curSortIndex;
}

static int FindSubFolder(const CObjectVector<CTreeFolder> &treeFolders, int cur, const UString &name, int &insertPos)
{
  const CIntVector &subFolders = treeFolders[cur].SubFolders;
  int left = 0, right = subFolders.Size();
  insertPos = -1;
  for (;;)
  {
    if (left == right)
    {
      insertPos = left;
      return -1;
    }
    int mid = (left + right) / 2;
    int midFolder = subFolders[mid];
    int compare = CompareFileNames(name, treeFolders[midFolder].Name);
    if (compare == 0)
      return midFolder;
    if (compare < 0)
      right = mid;
    else
      left = mid + 1;
  }
}

static int AddFolder(CObjectVector<CTreeFolder> &treeFolders, int cur, const UString &name)
{
  int insertPos;
  int folderIndex = FindSubFolder(treeFolders, cur, name, insertPos);
  if (folderIndex < 0)
  {
    folderIndex = treeFolders.Size();
    CTreeFolder &newFolder = treeFolders.AddNew();
    newFolder.Parent = cur;
    newFolder.Name = name;
    treeFolders[cur].SubFolders.Insert(insertPos, folderIndex);
  }
  // else if (treeFolders[folderIndex].IsAltStreamFolder != isAltStreamFolder) throw 1123234234;
  return folderIndex;
}
*/

STDMETHODIMP CHandler::UpdateItems(ISequentialOutStream *outStream, UInt32 numItems,
    IArchiveUpdateCallback *updateCallback)
{
  COM_TRY_BEGIN

  const CDbEx *db = 0;
  #ifdef _7Z_VOL
  if (_volumes.Size() > 1)
    return E_FAIL;
  const CVolume *volume = 0;
  if (_volumes.Size() == 1)
  {
    volume = &_volumes.Front();
    db = &volume->Database;
  }
  #else
  if (_inStream != 0)
    db = &_db;
  #endif

  /*
  CMyComPtr<IArchiveGetRawProps> getRawProps;
  updateCallback->QueryInterface(IID_IArchiveGetRawProps, (void **)&getRawProps);

  CUniqBlocks secureBlocks;
  secureBlocks.AddUniq(NULL, 0);

  CObjectVector<CTreeFolder> treeFolders;
  {
    CTreeFolder folder;
    folder.Parent = -1;
    treeFolders.Add(folder);
  }
  */

  CObjectVector<CUpdateItem> updateItems;

  bool need_CTime = (Write_CTime.Def && Write_CTime.Val);
  bool need_ATime = (Write_ATime.Def && Write_ATime.Val);
  bool need_MTime = (Write_MTime.Def && Write_MTime.Val || !Write_MTime.Def);
  if (db)
  {
    if (!Write_CTime.Def) need_CTime = !db->CTime.Defs.IsEmpty();
    if (!Write_ATime.Def) need_ATime = !db->ATime.Defs.IsEmpty();
    if (!Write_MTime.Def) need_MTime = !db->MTime.Defs.IsEmpty();
  }

  UString s;

  for (UInt32 i = 0; i < numItems; i++)
  {
    Int32 newData, newProps;
    UInt32 indexInArchive;
    if (!updateCallback)
      return E_FAIL;
    RINOK(updateCallback->GetUpdateItemInfo(i, &newData, &newProps, &indexInArchive));
    CUpdateItem ui;
    ui.NewProps = IntToBool(newProps);
    ui.NewData = IntToBool(newData);
    ui.IndexInArchive = indexInArchive;
    ui.IndexInClient = i;
    ui.IsAnti = false;
    ui.Size = 0;

    UString name;
    // bool isAltStream = false;
    if (ui.IndexInArchive != -1)
    {
      if (db == 0 || (unsigned)ui.IndexInArchive >= db->Files.Size())
        return E_INVALIDARG;
      const CFileItem &fi = db->Files[ui.IndexInArchive];
      if (!ui.NewProps)
      {
        _db.GetPath(ui.IndexInArchive, name);
      }
      ui.IsDir = fi.IsDir;
      ui.Size = fi.Size;
      // isAltStream = fi.IsAltStream;
      ui.IsAnti = db->IsItemAnti(ui.IndexInArchive);
      
      if (!ui.NewProps)
      {
        ui.CTimeDefined = db->CTime.GetItem(ui.IndexInArchive, ui.CTime);
        ui.ATimeDefined = db->ATime.GetItem(ui.IndexInArchive, ui.ATime);
        ui.MTimeDefined = db->MTime.GetItem(ui.IndexInArchive, ui.MTime);
      }
    }

    if (ui.NewProps)
    {
      bool folderStatusIsDefined;
      {
        NCOM::CPropVariant prop;
        RINOK(updateCallback->GetProperty(i, kpidAttrib, &prop));
        if (prop.vt == VT_EMPTY)
          ui.AttribDefined = false;
        else if (prop.vt != VT_UI4)
          return E_INVALIDARG;
        else
        {
          ui.Attrib = prop.ulVal;
          ui.AttribDefined = true;
        }
      }
      
      // we need MTime to sort files.
      if (need_CTime) RINOK(GetTime(updateCallback, i, kpidCTime, ui.CTime, ui.CTimeDefined));
      if (need_ATime) RINOK(GetTime(updateCallback, i, kpidATime, ui.ATime, ui.ATimeDefined));
      if (need_MTime) RINOK(GetTime(updateCallback, i, kpidMTime, ui.MTime, ui.MTimeDefined));

      /*
      if (getRawProps)
      {
        const void *data;
        UInt32 dataSize;
        UInt32 propType;

        getRawProps->GetRawProp(i, kpidNtSecure, &data, &dataSize, &propType);
        if (dataSize != 0 && propType != NPropDataType::kRaw)
          return E_FAIL;
        ui.SecureIndex = secureBlocks.AddUniq((const Byte *)data, dataSize);
      }
      */

      {
        NCOM::CPropVariant prop;
        RINOK(updateCallback->GetProperty(i, kpidPath, &prop));
        if (prop.vt == VT_EMPTY)
        {
        }
        else if (prop.vt != VT_BSTR)
          return E_INVALIDARG;
        else
        {
          name = NItemName::MakeLegalName(prop.bstrVal);
        }
      }
      {
        NCOM::CPropVariant prop;
        RINOK(updateCallback->GetProperty(i, kpidIsDir, &prop));
        if (prop.vt == VT_EMPTY)
          folderStatusIsDefined = false;
        else if (prop.vt != VT_BOOL)
          return E_INVALIDARG;
        else
        {
          ui.IsDir = (prop.boolVal != VARIANT_FALSE);
          folderStatusIsDefined = true;
        }
      }

      {
        NCOM::CPropVariant prop;
        RINOK(updateCallback->GetProperty(i, kpidIsAnti, &prop));
        if (prop.vt == VT_EMPTY)
          ui.IsAnti = false;
        else if (prop.vt != VT_BOOL)
          return E_INVALIDARG;
        else
          ui.IsAnti = (prop.boolVal != VARIANT_FALSE);
      }

      /*
      {
        NCOM::CPropVariant prop;
        RINOK(updateCallback->GetProperty(i, kpidIsAltStream, &prop));
        if (prop.vt == VT_EMPTY)
          isAltStream = false;
        else if (prop.vt != VT_BOOL)
          return E_INVALIDARG;
        else
          isAltStream = (prop.boolVal != VARIANT_FALSE);
      }
      */

      if (ui.IsAnti)
      {
        ui.AttribDefined = false;

        ui.CTimeDefined = false;
        ui.ATimeDefined = false;
        ui.MTimeDefined = false;
        
        ui.Size = 0;
      }

      if (!folderStatusIsDefined && ui.AttribDefined)
        ui.SetDirStatusFromAttrib();
    }
    else
    {
      /*
      if (_db.SecureIDs.IsEmpty())
        ui.SecureIndex = secureBlocks.AddUniq(NULL, 0);
      else
      {
        int id = _db.SecureIDs[ui.IndexInArchive];
        size_t offs = _db.SecureOffsets[id];
        size_t size = _db.SecureOffsets[id + 1] - offs;
        ui.SecureIndex = secureBlocks.AddUniq(_db.SecureBuf + offs, size);
      }
      */
    }

    /*
    {
      int folderIndex = 0;
      if (_useParents)
      {
        int j;
        s.Empty();
        for (j = 0; j < name.Len(); j++)
        {
          wchar_t c = name[j];
          if (IsCharDirLimiter(c))
          {
            folderIndex = AddFolder(treeFolders, folderIndex, s);
            s.Empty();
            continue;
          }
          s += c;
        }
        if (isAltStream)
        {
          int colonPos = s.Find(':');
          if (colonPos < 0)
          {
            // isAltStream = false;
            return E_INVALIDARG;
          }
          UString mainName = s.Left(colonPos);
          int newFolderIndex = AddFolder(treeFolders, folderIndex, mainName);
          if (treeFolders[newFolderIndex].UpdateItemIndex < 0)
          {
            for (int j = updateItems.Size() - 1; j >= 0; j--)
            {
              CUpdateItem &ui2 = updateItems[j];
              if (ui2.ParentFolderIndex == folderIndex
                  && ui2.Name == mainName)
              {
                ui2.TreeFolderIndex = newFolderIndex;
                treeFolders[newFolderIndex].UpdateItemIndex = j;
              }
            }
          }
          folderIndex = newFolderIndex;
          s.Delete(0, colonPos + 1);
        }
        ui.Name = s;
      }
      else
        ui.Name = name;
      ui.IsAltStream = isAltStream;
      ui.ParentFolderIndex = folderIndex;
      ui.TreeFolderIndex = -1;
      if (ui.IsDir && !s.IsEmpty())
      {
        ui.TreeFolderIndex = AddFolder(treeFolders, folderIndex, s);
        treeFolders[ui.TreeFolderIndex].UpdateItemIndex = updateItems.Size();
      }
    }
    */
    ui.Name = name;

    if (ui.NewData)
    {
      NCOM::CPropVariant prop;
      RINOK(updateCallback->GetProperty(i, kpidSize, &prop));
      if (prop.vt != VT_UI8)
        return E_INVALIDARG;
      ui.Size = (UInt64)prop.uhVal.QuadPart;
      if (ui.Size != 0 && ui.IsAnti)
        return E_INVALIDARG;
    }
    updateItems.Add(ui);
  }

  /*
  FillSortIndex(treeFolders, 0, 0);
  for (i = 0; i < (UInt32)updateItems.Size(); i++)
  {
    CUpdateItem &ui = updateItems[i];
    ui.ParentSortIndex = treeFolders[ui.ParentFolderIndex].SortIndex;
    ui.ParentSortIndexEnd = treeFolders[ui.ParentFolderIndex].SortIndexEnd;
  }
  */

  CCompressionMethodMode methodMode, headerMethod;

  HRESULT res = SetMainMethod(methodMode, _methods
    #ifndef _7ZIP_ST
    , _numThreads
    #endif
    );
  RINOK(res);
  methodMode.Binds = _binds;

  RINOK(SetHeaderMethod(headerMethod));
  #ifndef _7ZIP_ST
  methodMode.NumThreads = _numThreads;
  headerMethod.NumThreads = 1;
  #endif

  CMyComPtr<ICryptoGetTextPassword2> getPassword2;
  updateCallback->QueryInterface(IID_ICryptoGetTextPassword2, (void **)&getPassword2);

  methodMode.PasswordIsDefined = false;
  methodMode.Password.Empty();
  if (getPassword2)
  {
    CMyComBSTR password;
    Int32 passwordIsDefined;
    RINOK(getPassword2->CryptoGetTextPassword2(&passwordIsDefined, &password));
    methodMode.PasswordIsDefined = IntToBool(passwordIsDefined);
    if (methodMode.PasswordIsDefined && (BSTR)password)
      methodMode.Password = password;
  }

  bool compressMainHeader = _compressHeaders;  // check it

  bool encryptHeaders = false;

  if (methodMode.PasswordIsDefined)
  {
    if (_encryptHeadersSpecified)
      encryptHeaders = _encryptHeaders;
    #ifndef _NO_CRYPTO
    else
      encryptHeaders = _passwordIsDefined;
    #endif
    compressMainHeader = true;
    if (encryptHeaders)
    {
      headerMethod.PasswordIsDefined = methodMode.PasswordIsDefined;
      headerMethod.Password = methodMode.Password;
    }
  }

  if (numItems < 2)
    compressMainHeader = false;

  CUpdateOptions options;
  options.Method = &methodMode;
  options.HeaderMethod = (_compressHeaders || encryptHeaders) ? &headerMethod : 0;
  int level = GetLevel();
  options.UseFilters = level != 0 && _autoFilter;
  options.MaxFilter = level >= 8;

  options.HeaderOptions.CompressMainHeader = compressMainHeader;
  /*
  options.HeaderOptions.WriteCTime = Write_CTime;
  options.HeaderOptions.WriteATime = Write_ATime;
  options.HeaderOptions.WriteMTime = Write_MTime;
  */
  
  options.NumSolidFiles = _numSolidFiles;
  options.NumSolidBytes = _numSolidBytes;
  options.SolidExtension = _solidExtension;
  options.RemoveSfxBlock = _removeSfxBlock;
  options.VolumeMode = _volumeMode;

  COutArchive archive;
  CArchiveDatabaseOut newDatabase;

  CMyComPtr<ICryptoGetTextPassword> getPassword;
  updateCallback->QueryInterface(IID_ICryptoGetTextPassword, (void **)&getPassword);
  
  /*
  if (secureBlocks.Sorted.Size() > 1)
  {
    secureBlocks.GetReverseMap();
    for (int i = 0; i < updateItems.Size(); i++)
    {
      int &secureIndex = updateItems[i].SecureIndex;
      secureIndex = secureBlocks.BufIndexToSortedIndex[secureIndex];
    }
  }
  */

  res = Update(
      EXTERNAL_CODECS_VARS
      #ifdef _7Z_VOL
      volume ? volume->Stream: 0,
      volume ? db : 0,
      #else
      _inStream,
      db,
      #endif
      updateItems,
      // treeFolders,
      // secureBlocks,
      archive, newDatabase, outStream, updateCallback, options
      #ifndef _NO_CRYPTO
      , getPassword
      #endif
      );

  RINOK(res);

  updateItems.ClearAndFree();

  return archive.WriteDatabase(EXTERNAL_CODECS_VARS
      newDatabase, options.HeaderMethod, options.HeaderOptions);

  COM_TRY_END
}

static HRESULT GetBindInfoPart(UString &srcString, UInt32 &coder, UInt32 &stream)
{
  stream = 0;
  int index = ParseStringToUInt32(srcString, coder);
  if (index == 0)
    return E_INVALIDARG;
  srcString.Delete(0, index);
  if (srcString[0] == 's')
  {
    srcString.Delete(0);
    int index = ParseStringToUInt32(srcString, stream);
    if (index == 0)
      return E_INVALIDARG;
    srcString.Delete(0, index);
  }
  return S_OK;
}

void COutHandler::InitProps()
{
  CMultiMethodProps::Init();

  _removeSfxBlock = false;
  _compressHeaders = true;
  _encryptHeadersSpecified = false;
  _encryptHeaders = false;
  // _useParents = false;
  
  Write_CTime.Init();
  Write_ATime.Init();
  Write_MTime.Init();

  _volumeMode = false;
  InitSolid();
}

HRESULT COutHandler::SetSolidFromString(const UString &s)
{
  UString s2 = s;
  s2.MakeLower_Ascii();
  for (unsigned i = 0; i < s2.Len();)
  {
    const wchar_t *start = ((const wchar_t *)s2) + i;
    const wchar_t *end;
    UInt64 v = ConvertStringToUInt64(start, &end);
    if (start == end)
    {
      if (s2[i++] != 'e')
        return E_INVALIDARG;
      _solidExtension = true;
      continue;
    }
    i += (int)(end - start);
    if (i == s2.Len())
      return E_INVALIDARG;
    wchar_t c = s2[i++];
    if (c == 'f')
    {
      if (v < 1)
        v = 1;
      _numSolidFiles = v;
    }
    else
    {
      unsigned numBits;
      switch (c)
      {
        case 'b': numBits =  0; break;
        case 'k': numBits = 10; break;
        case 'm': numBits = 20; break;
        case 'g': numBits = 30; break;
        case 't': numBits = 40; break;
        default: return E_INVALIDARG;
      }
      _numSolidBytes = (v << numBits);
      _numSolidBytesDefined = true;
    }
  }
  return S_OK;
}

HRESULT COutHandler::SetSolidFromPROPVARIANT(const PROPVARIANT &value)
{
  bool isSolid;
  switch (value.vt)
  {
    case VT_EMPTY: isSolid = true; break;
    case VT_BOOL: isSolid = (value.boolVal != VARIANT_FALSE); break;
    case VT_BSTR:
      if (StringToBool(value.bstrVal, isSolid))
        break;
      return SetSolidFromString(value.bstrVal);
    default: return E_INVALIDARG;
  }
  if (isSolid)
    InitSolid();
  else
    _numSolidFiles = 1;
  return S_OK;
}

static HRESULT PROPVARIANT_to_BoolPair(const PROPVARIANT &prop, CBoolPair &dest)
{
  RINOK(PROPVARIANT_to_bool(prop, dest.Val));
  dest.Def = true;
  return S_OK;
}

HRESULT COutHandler::SetProperty(const wchar_t *nameSpec, const PROPVARIANT &value)
{
  UString name = nameSpec;
  name.MakeLower_Ascii();
  if (name.IsEmpty())
    return E_INVALIDARG;
  
  if (name[0] == L's')
  {
    name.Delete(0);
    if (name.IsEmpty())
      return SetSolidFromPROPVARIANT(value);
    if (value.vt != VT_EMPTY)
      return E_INVALIDARG;
    return SetSolidFromString(name);
  }
  
  UInt32 number;
  int index = ParseStringToUInt32(name, number);
  UString realName = name.Ptr(index);
  if (index == 0)
  {
    if (name.IsEqualTo("rsfx")) return PROPVARIANT_to_bool(value, _removeSfxBlock);
    if (name.IsEqualTo("hc")) return PROPVARIANT_to_bool(value, _compressHeaders);
    // if (name.IsEqualToNoCase(L"HS")) return PROPVARIANT_to_bool(value, _useParents);
    
    if (name.IsEqualTo("hcf"))
    {
      bool compressHeadersFull = true;
      RINOK(PROPVARIANT_to_bool(value, compressHeadersFull));
      return compressHeadersFull ? S_OK: E_INVALIDARG;
    }
    
    if (name.IsEqualTo("he"))
    {
      RINOK(PROPVARIANT_to_bool(value, _encryptHeaders));
      _encryptHeadersSpecified = true;
      return S_OK;
    }
    
    if (name.IsEqualTo("tc")) return PROPVARIANT_to_BoolPair(value, Write_CTime);
    if (name.IsEqualTo("ta")) return PROPVARIANT_to_BoolPair(value, Write_ATime);
    if (name.IsEqualTo("tm")) return PROPVARIANT_to_BoolPair(value, Write_MTime);
    
    if (name.IsEqualTo("v"))  return PROPVARIANT_to_bool(value, _volumeMode);
  }
  return CMultiMethodProps::SetProperty(name, value);
}

STDMETHODIMP CHandler::SetProperties(const wchar_t **names, const PROPVARIANT *values, UInt32 numProps)
{
  COM_TRY_BEGIN
  _binds.Clear();
  InitProps();

  for (UInt32 i = 0; i < numProps; i++)
  {
    UString name = names[i];
    name.MakeLower_Ascii();
    if (name.IsEmpty())
      return E_INVALIDARG;

    const PROPVARIANT &value = values[i];

    if (name[0] == 'b')
    {
      if (value.vt != VT_EMPTY)
        return E_INVALIDARG;
      name.Delete(0);
      CBind bind;
      RINOK(GetBindInfoPart(name, bind.OutCoder, bind.OutStream));
      if (name[0] != ':')
        return E_INVALIDARG;
      name.Delete(0);
      RINOK(GetBindInfoPart(name, bind.InCoder, bind.InStream));
      if (!name.IsEmpty())
        return E_INVALIDARG;
      _binds.Add(bind);
      continue;
    }

    RINOK(SetProperty(name, value));
  }

  unsigned numEmptyMethods = GetNumEmptyMethods();
  if (numEmptyMethods > 0)
  {
    unsigned k;
    for (k = 0; k < _binds.Size(); k++)
    {
      const CBind &bind = _binds[k];
      if (bind.InCoder < (UInt32)numEmptyMethods ||
          bind.OutCoder < (UInt32)numEmptyMethods)
        return E_INVALIDARG;
    }
    for (k = 0; k < _binds.Size(); k++)
    {
      CBind &bind = _binds[k];
      bind.InCoder -= (UInt32)numEmptyMethods;
      bind.OutCoder -= (UInt32)numEmptyMethods;
    }
    _methods.DeleteFrontal(numEmptyMethods);
  }
  
  AddDefaultMethod();

  if (!_filterMethod.MethodName.IsEmpty())
  {
    FOR_VECTOR (k, _binds)
    {
      CBind &bind = _binds[k];
      bind.InCoder++;
      bind.OutCoder++;
    }
    _methods.Insert(0, _filterMethod);
  }

  FOR_VECTOR (k, _binds)
  {
    const CBind &bind = _binds[k];
    if (bind.InCoder >= (UInt32)_methods.Size() ||
        bind.OutCoder >= (UInt32)_methods.Size())
      return E_INVALIDARG;
  }

  return S_OK;
  COM_TRY_END
}

}}
