/* ====================================================================
 * Copyright (c) 2008-2009  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 "config.h"
#include "WcViewStatus.h"
#include "StatusId.h"
#include "svn/WcStatus.h"
#include "svn/WcEntry.h"


WcViewStatus::WcViewStatus( svn::WcStatusPtr status )
: _status(status)
{
}

svn::WcStatusPtr WcViewStatus::status() const
{
  return _status;
}

const sc::String& WcViewStatus::path() const
{
  return _status->getName();
}

bool WcViewStatus::isDir() const
{
  return _status->isDir();
}

bool WcViewStatus::isChanged() const
{
  return _status->isChangedOrFlaged();
}

bool WcViewStatus::isIgnored() const
{ 
  return _status->isIgnored();
}

bool WcViewStatus::isSwitched() const
{
  return _status->isSwitched();
}

bool WcViewStatus::isOutOfDate() const
{
  return _status->isReposChanged();
}

StatusId WcViewStatus::getTextStatus() const
{
  switch( _status->getTextStatus() )
  {
  case svn::WcStatus_None:
    return StatusNone;
  case svn::WcStatus_Unversioned:
    return StatusUnversioned;
  case svn::WcStatus_Normal:
    return StatusNormal;
  case svn::WcStatus_Added:
    return StatusAdded;
  case svn::WcStatus_Missing:
    return StatusMissing;
  case svn::WcStatus_Deleted:
    return StatusDeleted;
  case svn::WcStatus_Replaced:
    return StatusReplaced;
  case svn::WcStatus_Modified:
    return StatusModified;
  case svn::WcStatus_Merged:
    return StatusMerged;
  case svn::WcStatus_Conflicted:
    return StatusConflicted;
  case svn::WcStatus_Ignored:
    return StatusIgnored;
  case svn::WcStatus_Obstructed:
    return StatusObstructed;
  case svn::WcStatus_External:
    return StatusExternal;
  case svn::WcStatus_Incomplete:
    return StatusIncomplete;
  default:
    return StatusFallback;
  }
}



enum WcViewStatusColumns
{
  ColName,
  ColTextStatus,
  ColPropStatus,
  ColRpLock,
  //ColWcLock,
  ColCopied,          ///< add with history
  ColSwitched,
  ColUpdate,
  ColWcRevision,
  ColCommitRevision,
  ColCommitAuthor,
  ColDeepStatus,
  ColEmpty,
  ColMax
};


WcViewStatusData::WcViewStatusData()
{
}

int WcViewStatusData::columns() const
{
  return ColMax;
}

QString WcViewStatusData::data( int column, const WcViewItem* item ) const
{
  svn::WcStatusPtr status = static_cast<const WcViewStatus*>(item)->status();

  switch(column)
  {
  case ColName:
    {
      return QString::fromUtf8( status->getName().getStr() );
    }
  case ColTextStatus:
    {
      return getStatusCode( status->getTextStatus() );
    }
  case ColPropStatus:
    {
      return getStatusCode( status->getPropStatus() );
    }
  case ColRpLock:
    {
      return getLockStatusCode( status->getLockStatus() );
    }
#if 0
  case ColWcLock:
    {
      return status->isLocked() ?
        getStatusCode(StatusWcLockLocked) : getStatusCode(StatusWcLockNone);
    }
#endif
  case ColCopied:
    {
      return status->isCopied() ?
        getStatusCode(StatusHistory) : getStatusCode(StatusHistoryNone);
    }
  case ColSwitched:
    {
      return status->isSwitched() ?
        getStatusCode(StatusSwitched) : getStatusCode(StatusSwitchedNo);
    }
  case ColUpdate:
    {
      bool t = status->getReposTextStatus() != svn::WcStatus_None;
      bool p = status->getReposTextStatus() != svn::WcStatus_None;

      return ( t || p ) ?
        getStatusCode(StatusUpToDateNo) : getStatusCode(StatusUpToDate);
    }
  case ColWcRevision:
    {
      const svn::WcEntry* e = status->getWcEntry();
      if( ! e )
      {
        return "";
      }
      else if( e->getRevnumber() < 0 )
      {
        return "?";
      }
      else if( status->isCopied() )
      {
        return "-";
      }
      else
      {
        return QString().sprintf( "%ld", (unsigned long)e->getRevnumber() );
      }
    }
  case ColCommitRevision:
    {
      const svn::WcEntry* e = status->getWcEntry();
      if( ! e )
      {
        return "";
      }
      else if( e->getCmtRevnumber() < 0 )
      {
        return "?";
      }
      else
      {
        return QString().sprintf( "%ld", (unsigned long)e->getCmtRevnumber() );
      }
    }
  case ColCommitAuthor:
    {
      const svn::WcEntry* e = status->getWcEntry();
      if( ! e )
      {
        return "";
      }
      else if( ! e->getCmtAuthor().getStr() )
      {
        return "?";
      }
      else
      {
        return QString::fromUtf8( e->getCmtAuthor().getStr() );
      }
    }
  case ColDeepStatus:
  case ColEmpty:
    {
      return "";
    }
  default:
    return "?";
  }
}

QColor WcViewStatusData::color( int column, const WcViewItem* item ) const
{
  svn::WcStatusPtr status = static_cast<const WcViewStatus*>(item)->status();

  return getStatusColor(status->getTextStatus());
}

QVariant WcViewStatusData::dataSort( int column, const WcViewItem* item
  ) const
{
  svn::WcStatusPtr status = static_cast<const WcViewStatus*>(item)->status();

  switch(column)
  {
  case ColCommitRevision:
    {
      const svn::WcEntry* e = status->getWcEntry();
      if(!e)
        return 0;

      return QVariant((int)e->getCmtRevnumber());
    }
  case ColWcRevision:
    {
      const svn::WcEntry* e = status->getWcEntry();
      if(!e)
        return 0;

      return QVariant((int)e->getRevnumber());
    }
  }
  return data( column, item );
}

QString WcViewStatusData::header( int column ) const
{
  switch(column)
  {
  case ColName: 
    return _q("path/name");
  case ColTextStatus:
    return _q("ts");
  case ColPropStatus:
    return _q("ps");
  case ColRpLock:
    return _q("rl");
#if 0
  case ColWcLock:
    return _q("wl");
#endif
  case ColCopied:
    return _q("ah");
  case ColSwitched:
    return _q("sw");
  case ColUpdate:
    return _q("upd");
  case ColWcRevision:
    return _q("wc rev");
  case ColCommitRevision:
    return _q("cmt rev");
  case ColCommitAuthor:
    return _q("cmt author");
  case ColDeepStatus:
    return _q("ds");
  case ColEmpty:
    return "";
  default:
    return "?";
  }
}

Qt::Alignment WcViewStatusData::alignment( int column ) const
{
  switch(column)
  {
  case ColName:
    return Qt::AlignLeft | Qt::AlignVCenter;
  default:
    return Qt::AlignCenter | Qt::AlignVCenter;
  }
}

bool WcViewStatusData::deep( int column ) const
{
  return column == ColDeepStatus;
}
