/* ====================================================================
 * Copyright (c) 2007-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 "WcViewTreeProxyModel.h"
#include "svn/Path.h"
#include "util/Compare.h"


WcViewTreeProxyModel::WcViewTreeProxyModel()
: _flat(false), _all(false), _outofdate(false), _modifiedFolder(false)
{
  //setSortRole(SortRole);
  setDynamicSortFilter(true);
}

WcViewTreeProxyModel::~WcViewTreeProxyModel()
{
}

QModelIndex WcViewTreeProxyModel::index( int row, int column, const QModelIndex& parent ) const
{
  return QSortFilterProxyModel::index(row,column,parent);
}

QVariant WcViewTreeProxyModel::data( const QModelIndex& index, int role ) const
{
  QVariant value = sourceModel()->data( mapToSource(index), role );

  if( index.column() == 0 && role == Qt::DisplayRole || role == Qt::EditRole )
  {
    QString temp = value.toString();

    if( temp == (const char*)_current )
    {
      temp = ".";
    }
    else
    {
      if(_flat)
        temp.remove( 0, _current.getCharCnt()+1 );
      else
        temp = temp.section('/', -1);
    }

    value = temp;
  }

  return value;
}

Qt::ItemFlags WcViewTreeProxyModel::flags( const QModelIndex &index ) const
{
  Qt::ItemFlags flags = sourceModel()->flags( mapToSource(index) );
  sc::String target = index.data(NameRole).value<sc::String>();

  if( target == _current )
    flags &= ~(Qt::ItemIsDragEnabled | Qt::ItemIsEditable);

  return flags;
}

bool WcViewTreeProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const
{
  QModelIndex index = sourceModel()->index( sourceRow, 0, sourceParent );
  sc::String  name  = index.data(NameRole).value<sc::String>();

  if( isSelf(name) )
    return true;

  if( isSibling(name) )
    return false;

  bool outofdate = index.data(OutOfDateRole).asBool();
  if( isVisible(outofdate) )
    return true;


  bool dir     = index.data(DirRole).asBool();
  bool changed = index.data(ChangedRole).asBool();

  if( !dir && changed )
    return _status.test(index.data(TextStatusRole).value<StatusId>());

  //bool dir = index.data(DirRole).asBool();
  if( dir )
  {
    bool switched = index.data(SwitchedRole).asBool();
    if( switched )
      return true;
    
    bool deep = index.data(DeepRole).toBool();

    if( _flat )
      return deep;

    else if( _modifiedFolder )
      return deep;

    else
      return true;
  }
  return false;
}

bool WcViewTreeProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
{
  if( left.column() == 0 && left.isValid() && right.isValid() )
  {
    sc::String lname = left.data(NameRole).value<sc::String>();
    sc::String rname = right.data(NameRole).value<sc::String>();
    bool ldir = left.data(DirRole).asBool();
    bool rdir = right.data(DirRole).asBool();

    int result = compare3( lname, ldir, rname, rdir );
    return result < 0;
  }
  else
  {
    return super::lessThan(left,right);
  }

  return false;
}

void WcViewTreeProxyModel::setCurrentPath( const sc::String& current )
{
  _current = current;
}

void WcViewTreeProxyModel::setFilterFlat( bool on )
{
  _flat = on;
}

void WcViewTreeProxyModel::setFilterAll( bool on )
{
  _all = on;
}

void WcViewTreeProxyModel::setFilterOutOfDate( bool on )
{
  _outofdate = on;
}

void WcViewTreeProxyModel::setFilterTextStatus( const TextStatusFilter&
  filter )
{
  _status = filter;
}

void WcViewTreeProxyModel::setFilterModifiedFolder( bool on )
{
  _modifiedFolder = on;
}

QModelIndex WcViewTreeProxyModel::index( const sc::String& name ) const
{
  return mapFromSource( sourceModel2()->index(name) );
}

void WcViewTreeProxyModel::insert( const sc::String& path, const WcViewItems& items )
{
  sourceModel2()->insert(path,items);
}

void WcViewTreeProxyModel::remove( const sc::String& path )
{
  sourceModel2()->remove(path);
}

WcViewItemModel* WcViewTreeProxyModel::sourceModel2() const
{
  return dynamic_cast<WcViewItemModel*>(sourceModel());
}

bool WcViewTreeProxyModel::isSelf( const sc::String& path ) const
{
  return _current == path;
}

bool WcViewTreeProxyModel::isSibling( const sc::String& path ) const
{
  sc::String item = svn::Path::getDirName(path);
  sc::String root = svn::Path::getDirName(_current);

  if( item != root )
    return false;

  return true;
}

bool WcViewTreeProxyModel::isVisible( bool outofdate ) const
{
  if( _all && ! outofdate )
    return true;

  if( _outofdate && outofdate )
    return true;

  return false;
}
