/**
 * \file BGDNetPath.cpp
 * \brief Реализация класса Path
 */

#include "BGDNetPch.h"

#include <algorithm>

#include "BGDNetPath.h"

namespace BGDNet
{

Path::Path( void ) : m_nameSpc(NW_NS_DOS)
{
}

Path::Path( const String& fullPath, nuint8 nameSpc ) :
  String(fullPath),
  m_nameSpc(nameSpc)
{
}

Path::Path( const Path& p ) : String(p), m_nameSpc(p.ns())
{
}

Path& Path::operator =( const Path& p )
{
  if (this != &p) // не допускаем присваивания самому себе!
  {
    m_nameSpc = p.ns();
    String::operator =(p);
  }
  return *this;
}

nuint8 Path::ns( void ) const
{
  return m_nameSpc;
}

String Path::srv( void ) const
{
  const char* const begin = ptr();
  const char* const end = ptr() + length();
  
  // Ищем двоеточие:
  const char* const colon = std::find(begin, end, ':');
  
  // Ищем слэш перед двоеточием:
  const char slashes[2] = {'\\', '/'};
  const char* const slash = std::find_first_of(
    begin, colon,
    slashes, slashes + 2);
  
  // Анализируем результаты:
  if (end != colon)
  {
    // Есть двоеточие. Значит, имя сервера расположено
    // от начала строки до слэша:
    return String(begin, slash - begin);
  }
  else
  {
    // Двоеточия нет.
    if (end == slash)
    {
      // Слэша тоже нет. Значит, вся строка - это имя сервера.
      return String(*this);
    }
    else
    {
      // Двоеточия нет, а слэш есть. Значит, это просто путь
      // без указания сервера и тома.
      return String();
    }
  }
}

String Path::vol( void ) const
{
  const char* const begin = ptr();
  const char* const end = ptr() + length();
  
  // Ищем двоеточие:
  const char* const colon = std::find(begin, end, ':');
  
  // Ищем слэш перед двоеточием:
  const char* const slashes = "\\/";
  const char* const slash = std::find_first_of(
    begin, colon,
    slashes, slashes + 2);
  
  // Анализируем результаты:
  if (end != colon)
  {
    // Есть двоеточие. Значит, имя тома расположено
    // между слэшем и двоеточием:
    return String(slash + 1, colon - (slash + 1));
  }
  else
  {
    // Двоеточия нет. Значит нет и тома:(
    return String();
  }
}

String Path::path( void ) const
{
  const char* const begin = ptr();
  const char* const end = ptr() + length();
  
  // Ищем двоеточие:
  const char* const colon = std::find(begin, end, ':');
  
  // Анализируем результат:
  if (end != colon)
  {
    // Есть двоеточие. Значит, путь расположен
    // от двоеточия до конца:
    return String(colon + 1, end - (colon + 1));
  }
  else
  {
    // Двоеточия нет. Ищем слэш:
    const char* const slashes = "\\/";
    const char* const slash = std::find_first_of(
      begin, end,
      slashes, slashes + 2);
    if (end == slash)
    {
      // Слэша тоже нет. Значит, вся строка - это имя сервера.
      return String();
    }
    else
    {
      // Двоеточия нет, а слэш есть. Значит, это просто путь
      // без указания сервера и тома.
      return String(*this);
    }
  }
}

String Path::name( void ) const
  throw(Exception)
{
  const char* const begin = ptr();
  const char* const end = ptr() + length();

  // Ищем слэш начиная с конца:
  const char* const slashes = "\\/";
  const char* p = end;
  while (p != begin && !strchr(slashes, p[-1]))
    --p;
  
  return String(p, end - p);
}

String Path::dir( void ) const
  throw(Exception)
{
  const char* const begin = ptr();
  const char* const end = ptr() + length();

  // Ищем слэш начиная с конца:
  const char* const slashes = "\\/";
  const char* p = end;
  while (p != begin && !strchr(slashes, p[-1]))
    --p;
  
  if (begin == p)
    return String();
  else
    return String(begin, (p - 1) - begin);
}

} // namespace BGDNet
