/**
 * \file BGDNetVolume.cpp
 * \brief Реализция классов Volume и Volumes
 */

#include "BGDNetPch.h"

#include "BGDNetVolume.h"

#include <nwmisc.h>
#include "BGDNetServer.h"
#include "BGDNetConnection.h"
#include "BGDNetDirectory.h"
#include "BGDNetFile.h"

#ifdef BGDNET_USE_MFC
# ifdef _DEBUG
#   define new DEBUG_NEW
#   undef THIS_FILE
    static char THIS_FILE[] = __FILE__;
# endif
#endif

namespace BGDNet
{

Volume::Volume( const Server* pSrv, const String& volName )
  throw(Exception) :
  m_pSrv(pSrv),
  m_pRoot(0),
  m_supportsLongNames(false)
{
  // Чтобы проверить корректность имени тома, попытаемся получить
  // его номер на сервере:
  nuint16 n;
  NWCCODE err = NWGetVolumeNumber(
    Connection(pSrv->connRef()),
    volName,
    &n);
  if (SUCCESS != err)
    throw Exception(err);
  
  m_volName = volName;

  // Проверяем, поддерживает ли том длинные имена:
  NWCCODE code = NWIsLNSSupportedOnVolume(
    Connection(srv()->connRef()),
    DirHandle(this, Path("", NW_NS_DOS), NW_NS_DOS),
    "");
  m_supportsLongNames = (0 != code);
}

Volume::Volume( const Volume& v ) :
  m_pSrv(v.srv()),
  m_volName(v.name()),
  m_pRoot(0),
  m_supportsLongNames(v.supportsLongNames())
{
}

Volume::~Volume( void )
{
  if (m_pRoot)
    delete m_pRoot;
}

Volume& Volume::operator =( const Volume& v )
{
  if (this != &v) // не допускаем присваивания самому себе!
  {
    m_pSrv = v.srv();
    m_volName = v.name();
    m_supportsLongNames = v.supportsLongNames();
    if (m_pRoot)
    {
      delete m_pRoot;
      m_pRoot = 0;
    }
  }
  return *this;
}

const Server* Volume::srv( void ) const
{
  return m_pSrv;
}

const String& Volume::name( void ) const
{
  return m_volName;
}

Directory* Volume::root( void )
{
  // Если корневой каталог еще не получен, получаем его:
  if (!m_pRoot)
    getRoot();
  return m_pRoot;
}

const Directory* Volume::root( void ) const
{
  // Если корневой каталог еще не получен, получаем его:
  if (!m_pRoot)
    const_cast<Volume*>(this)->getRoot();
  return m_pRoot;
}

bool Volume::supportsLongNames( void ) const
{
  return m_supportsLongNames;
}

void Volume::getRoot( void )
{
  if (m_pRoot)
  {
    // Удаляем старый каталог:
    delete m_pRoot;
    m_pRoot = 0;
  }

  const nuint8 nameSpc = supportsLongNames() ? NW_NS_LONG : NW_NS_DOS;
  m_pRoot = new Directory(this, Path("", nameSpc));
}

} // namespace BGDNet
