/* ====================================================================
 * Copyright (c) 2006-2007, Martin Hauner
 *                          http://subcommander.tigris.org
 *
 * Subcommander is licensed as described in the file doc/COPYING, which
 * you should have received as part of this distribution.
 * ====================================================================
 */


// sc
#include "WcSelection.h"
#include "svn/WcStatus.h"
#include "svn/WcEntry.h"

WcSelection::WcSelection()
{
}

WcSelection::WcSelection( const WcSelection& sel )
: _statuss(sel._statuss)
{
}

WcSelection::WcSelection( const svn::WcStatuss& statuss )
: _statuss(statuss)
{
}

const svn::WcStatuss& WcSelection::get() const
{
  return _statuss;
}

svn::WcStatusPtr WcSelection::getSingle() const
{
  return *(_statuss.begin());
}

void WcSelection::getNames( svn::Paths& paths )
{
  for( svn::WcStatuss::iterator it = _statuss.begin(); it != _statuss.end(); it++ )
  {
    paths.push_back( (*it)->getName() );
  }
}

void WcSelection::getVersionedNames( svn::Paths& paths )
{
  for( svn::WcStatuss::iterator it = _statuss.begin(); it != _statuss.end(); it++ )
  {
    if( (*it)->isVersioned() )
    {
      paths.push_back( (*it)->getName() );
    }
  }
}

void WcSelection::getUnversionNames( svn::Paths& paths )
{
  for( svn::WcStatuss::iterator it = _statuss.begin(); it != _statuss.end(); it++ )
  {
    if( ! (*it)->isVersioned() )
    {
      paths.push_back( (*it)->getName() );
    }
  }
}

bool WcSelection::isEmpty() const
{
  return _statuss.size() == 0;
}

bool WcSelection::isSingle() const
{
  return _statuss.size() == 1;
}

bool WcSelection::isMulti() const
{
  return _statuss.size() > 1;
}

bool WcSelection::isDiffable() const
{
  if( ! isSingle() )
    return false;

  svn::WcStatusPtr status = *(_statuss.begin());

  return !status->isAddable()
    &&   status->isChanged()
    ||   status->isDir();
}

bool WcSelection::isVersioned() const
{
  if( ! isSingle() )
    return false;

  svn::WcStatusPtr status = *(_statuss.begin());

  return status->isVersioned();
}

bool WcSelection::isVersionedDir() const
{
  if( ! isSingle() )
    return false;

  svn::WcStatusPtr status = *(_statuss.begin());

  return status->isVersioned()
    &&   status->isDir();
}

bool WcSelection::isVersionedFile() const
{
  if( ! isSingle() )
    return false;

  svn::WcStatusPtr status = *(_statuss.begin());

  return status->isVersioned()
    && ! status->isDir();
}

bool WcSelection::isVersionedAll() const
{
  if( isEmpty() )
    return false;

  bool allow = true;

  for( svn::WcStatuss::const_iterator it = _statuss.begin(); it != _statuss.end(); it++ )
  {
    allow &= (*it)->isVersioned();
  }

  return allow;
}

bool WcSelection::isUnversionedAll() const
{
  if( isEmpty() )
    return false;

  bool allow = true;

  for( svn::WcStatuss::const_iterator it = _statuss.begin(); it != _statuss.end(); it++ )
  {
    allow &= !(*it)->isVersioned();
  }

  return allow;
}

bool WcSelection::isMoveable() const
{
  return isVersioned();
}

bool WcSelection::isAddable() const
{
  if( isEmpty() )
  {
    return false;
  }

  bool allow = true;

  for( svn::WcStatuss::const_iterator it = _statuss.begin(); it != _statuss.end(); it++ )
  {
    allow &= (*it)->isAddable();
  }

  return allow;
}

bool WcSelection::isConflicted() const
{
  if( ! isSingle() )
    return false;

  svn::WcStatusPtr status = *(_statuss.begin());

  return status->isConflicted();
}

bool WcSelection::isPropConflicted() const
{
  if( ! isSingle() )
    return false;

  svn::WcStatusPtr status = *(_statuss.begin());

  return status->isPropConflicted();
}

bool WcSelection::isRemoveable() const
{
  if( isEmpty() )
    return false;

  bool allow = true;

  for( svn::WcStatuss::const_iterator it = _statuss.begin(); it != _statuss.end(); it++ )
  {
    allow &= (*it)->isRemoveable();
  }

  return allow;
}

bool WcSelection::isRevertable() const
{
  if( isEmpty() )
    return false;

  bool allow = true;

  for( svn::WcStatuss::const_iterator it = _statuss.begin(); it != _statuss.end(); it++ )
  {
    allow &= (*it)->isRevertable() || ((*it)->isDir() && (*it)->isVersioned());
  }

  return allow;
}

bool WcSelection::isCommitable() const
{
  if( isEmpty() )
    return false;

  bool allow = true;

  for( svn::WcStatuss::const_iterator it = _statuss.begin(); it != _statuss.end(); it++ )
  {
    svn::WcStatusPtr    status = (*it);
    const svn::WcEntry* entry  = status->getWcEntry();

    if( entry && entry->isDir() )
    {
      allow &= status->isVersioned();
    }
    else
    {
      allow &= status->isChanged() && (! status->isAddable());
    }
  }

  return allow;
}

bool WcSelection::isSelected( const sc::String& path ) const
{
  for( svn::WcStatuss::const_iterator it = _statuss.begin(); it != _statuss.end(); it++ )
  {
    if( (*it)->getName() == path )
      return true;
  }
  return false;
}
