/* ====================================================================
 * Copyright (c) 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 "ProjectReader.h"
#include "SingleProjectReader.h"
#include "Project.h"
#include "sublib/config/ConfigData.h"
#include "sublib/config/ConfigValue.h"

// qt
#include <QtCore/QString>


const long MaxProjects = 128;

///////////////////////////////////////////////////////////////////////

sc::String createKey( const char* format, long num )
{
  return sc::String(QString(format).arg(num));
}

///////////////////////////////////////////////////////////////////////

ProjectReader::ProjectReader( ConfigData* cfg, bool cleanup )
: _cfg(cfg), _clr(cleanup)
{
}

ProjectReader::~ProjectReader()
{
  if(!_clr)
    return;

  for( Projects::iterator it = _prjs.begin(); it != _prjs.end(); it++ )
    delete *it;
}


void ProjectReader::readProjects()
{
  for( int cnt = 0; cnt < MaxProjects; cnt++ )
  {
    bool noproject = readProject(cnt);
    if(!noproject)
      return;
  }
}

bool ProjectReader::readProject( long num )
{
  ConfigValues values;
  _cfg->getValues( createKey("project.%1.",num), values );

  if( values.size() == 0 )
    return false;

  SingleProjectReader reader( num, values );
  reader.read();
  Project* prj = reader.getProject();

  _prjs.push_back(prj);
  return true;
}

void ProjectReader::getProjects( Projects &projects )
{
  projects = _prjs;
}

#if 0
void ConfigManager::getProjects( Projects& projects )
{
  const int maxProject = 64;
  const int maxItems   = 64;

  for( int cnt = 0; cnt < maxProject; cnt++ )
  {
    QString key = QString("project.%1.").arg(cnt);

    ConfigValues values;
    _cfg->getValues( sc::String(key), values );

    if( values.size() == 0 )
    {
      return;
    }

    // collect the project values
    sc::String prjName;
    Uuid       prjId    = Uuid::createEmpty();
    long       prjIndex = cnt;
    long       prjSort  = 0;
    long       wcCurId = 0;

    // read project information
    for( ConfigValues::iterator it = values.begin(); it != values.end(); it++ )
    {
      ConfigValue& cval = *it;
      QString      key  = QString::fromUtf8(cval.getKey());
      sc::String   val  = cval.getStringValue();

      if( reGuid.exactMatch(key) )
      {
        prjId = Uuid(val);
      }
      else if( reName.exactMatch(key) )
      {
        prjName = val;
      }
      else if( reSort.exactMatch(key) )
      {
        prjSort = cval.getNumericValue();
      }
      else if( reWcCurrent.exactMatch(key) )
      {
        wcCurId = cval.getNumericValue();
      }
    }

    Project* project = new Project( prjId, prjName );
    project->setIndex(prjIndex);
    project->setSortPos(prjSort);
    projects.push_back(project);



    Project::Item trunk;
    Project::Item branches;
    Project::Item tags;

    // read trunk/branches/tags bookmarks
    for( ConfigValues::iterator it = values.begin(); it != values.end(); it++ )
    {
      ConfigValue& cval = *it;
      getProjectRpItem( QString("trunk"),    cval, trunk );
      getProjectRpItem( QString("branches"), cval, branches );
      getProjectRpItem( QString("tags"),     cval, tags );
    }

    project->setTrunk(trunk);
    project->setBranches(branches);
    project->setTags(tags);



    // get working copies
    // note: the wc numbers are not used as the ProjectItem ids.
    for( int cntwc = 0; cntwc < maxItems; cntwc++ )
    {
      QString keywc = QString("project.%1.wc.%2.").arg(cnt).arg(cntwc);

      ConfigValues valueswc;
      _cfg->getValues( sc::String(keywc), values, valueswc, true );

      if( valueswc.size() == 0 )
      {
        break;
      }

      Project::Item item = project->createWorkingCopyItem();

      // map config current id to real current id as returned
      // from createWorkingCopyItem() above.
      if( cntwc == wcCurId )
      {
        wcCurId = item.getId();
      }

      for( ConfigValues::iterator it = valueswc.begin(); it != valueswc.end(); it++ )
      {
        ConfigValue& cval = *it;
        getProjectWcItem( cval, item );
      }
//
      for( int cntsub = 0; cntsub < 64; cntsub++ )
      {
        QString keysubitem = QString("project.%1.wc.%2.subitem.%3")
          .arg(cnt).arg(cntwc).arg(cntsub);

        ConfigValues valuessub;
        _cfg->getValues( sc::String(keysubitem), values, valuessub,
          true );

        if( valuessub.size() == 0 )
        {
          Project::SubItem subitem = item.createSubItem();
          subitem.setPath(item.getSource());
          break;
        }

        Project::SubItem subitem = item.createSubItem();

        for( ConfigValues::iterator it = valuessub.begin(); it != valuessub.end(); it++ )
        {
          ConfigValue& cval = *it;
          getProjectWcSubItem( cval, subitem );
          item.setSubItem(subitem);
        }
      }
//
      project->setItem(item);
    }

    project->setCurWorkingCopy( wcCurId );

    // get repositories
    // note: the rp numbers are not used as the ProjectItem ids.
    for( int cntrp = 0; cntrp < maxItems; cntrp++ )
    {
      QString keyrp = QString("project.%1.rp.%2.").arg(cnt).arg(cntrp);

      ConfigValues valuesrp;
      _cfg->getValues( sc::String(keyrp), values, valuesrp, true );

      if( valuesrp.size() == 0 )
      {
        break;
      }

      Project::Item item = project->createRepositoryItem();

      for( ConfigValues::iterator it = valuesrp.begin(); it != valuesrp.end(); it++ )
      {
        ConfigValue& cval = *it;
        getProjectRpItem( QString::null, cval, item );
      }

      project->setItem(item);
    }
  }
}

#endif