/***************************************************************************
                          kaccounttemplateselector.cpp  -  description
                             -------------------
    begin                : Tue Feb 5 2008
    copyright            : (C) 2008 by Thomas Baumgart
    email                : Thomas Baumgart <ipwizard@users.sourceforge.net>
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

// ----------------------------------------------------------------------------
// QT Includes

#include <tqdir.h>
#include <tqheader.h>
#include <tqtimer.h>

// ----------------------------------------------------------------------------
// KDE Includes

#include <tdeglobal.h>
#include <tdelocale.h>
#include <kstandarddirs.h>
#include <tdelistview.h>
#include <ktextedit.h>

// ----------------------------------------------------------------------------
// Project Includes

#include <kmymoney/mymoneytemplate.h>

#include "kaccounttemplateselector.h"

class KTemplateListItem : public TDEListViewItem
{
  public:
    KTemplateListItem(TQListViewItem* parent, const TQString& text);
    void setAvailable(void);
  public:
    bool m_isAvailable;
};

KTemplateListItem::KTemplateListItem(TQListViewItem* parent, const TQString& text) :
  TDEListViewItem(parent, text),
  m_isAvailable(false)
{
}

void KTemplateListItem::setAvailable(void)
{
  m_isAvailable = true;
}

class KAccountTemplateSelector::Private
{
  public:
    Private(KAccountTemplateSelector* p) { m_parent = p; }
#ifndef KMM_DESIGNER
    TQValueList<MyMoneyTemplate> selectedTemplates(void) const;
    TQListViewItem* hierarchyItem(const TQString& parent, const TQString& name);
    void loadHierarchy(void);
#endif

  public:
    KAccountTemplateSelector*         m_parent;
    TQMap<TQString, TQListViewItem*>     m_templateHierarchy;
#ifndef KMM_DESIGNER
    TQMap<TQString, MyMoneyTemplate>    m_templates;
    TQMap<TQString, TQString> countries;
    TQMap<TQString, TQString>::iterator it_m;
    TQStringList                      dirlist;
    int                              id;
#endif
};


#ifndef KMM_DESIGNER
TQListViewItem* KAccountTemplateSelector::Private::hierarchyItem(const TQString& parent, const TQString& name)
{
  if(!m_templateHierarchy.contains(parent)
  || m_templateHierarchy[parent] == 0) {
    TQRegExp exp("(.*):(.*)");
    if(exp.search(parent) != -1)
      m_templateHierarchy[parent] = hierarchyItem(exp.cap(1), exp.cap(2));
  }
  return new KTemplateListItem(m_templateHierarchy[parent], name);
}

void KAccountTemplateSelector::Private::loadHierarchy(void)
{
  m_templateHierarchy.clear();
  TQListViewItemIterator it(m_parent->m_groupList, TQListViewItemIterator::Selected);
  TQListViewItem* it_v;
  while((it_v = it.current()) != 0) {
    m_templates[it_v->text(2)].hierarchy(m_templateHierarchy);
    ++it;
  }

  // I need to think about this some more. The code works and shows
  // the current account hierarchy. It might be usefull, to show
  // existing accounts dimmed and the new ones in bold or so.
#if 0

  // add the hierarchy from the MyMoneyFile object
  TQValueList<MyMoneyAccount> aList;
  TQValueList<MyMoneyAccount>::const_iterator it_a;
  MyMoneyFile* file = MyMoneyFile::instance();
  file->accountList(aList);
  if(aList.count() > 0) {
    m_templateHierarchy[file->accountToCategory(file->asset().id(), true)] = 0;
    m_templateHierarchy[file->accountToCategory(file->liability().id(), true)] = 0;
    m_templateHierarchy[file->accountToCategory(file->income().id(), true)] = 0;
    m_templateHierarchy[file->accountToCategory(file->expense().id(), true)] = 0;
    m_templateHierarchy[file->accountToCategory(file->equity().id(), true)] = 0;
  }

  for(it_a = aList.begin(); it_a != aList.end(); ++it_a) {
    m_templateHierarchy[file->accountToCategory((*it_a).id(), true)] = 0;
  }
#endif

  m_parent->m_accountList->clear();
  TQMap<TQString, TQListViewItem*>::iterator it_m;

  TQRegExp exp("(.*):(.*)");
  for(it_m = m_templateHierarchy.begin(); it_m != m_templateHierarchy.end(); ++it_m) {
    if(exp.search(it_m.key()) == -1) {
      (*it_m) = new TDEListViewItem(m_parent->m_accountList, it_m.key());
    } else {
      (*it_m) = hierarchyItem(exp.cap(1), exp.cap(2));
    }
    (*it_m)->setOpen(true);
  }

  m_parent->m_description->clear();
  if(m_parent->m_groupList->currentItem()) {
    m_parent->m_description->setText(m_templates[m_parent->m_groupList->currentItem()->text(2)].longDescription());
  }
}

TQValueList<MyMoneyTemplate> KAccountTemplateSelector::Private::selectedTemplates(void) const
{
  TQValueList<MyMoneyTemplate> list;
  TQListViewItemIterator it(m_parent->m_groupList, TQListViewItemIterator::Selected);
  TQListViewItem* it_v;
  while((it_v = it.current()) != 0) {
    list << m_templates[it_v->text(2)];
    ++it;
  }
  return list;
}
#endif


KAccountTemplateSelector::KAccountTemplateSelector(TQWidget* parent, const char* name) :
  KAccountTemplateSelectorDecl(parent, name),
  d(new Private(this))
{
  m_accountList->header()->hide();
  connect(m_groupList, TQT_SIGNAL(selectionChanged()), this, TQT_SLOT(slotLoadHierarchy()));

  // kick off loading of account template data
  TQTimer::singleShot(0, this, TQT_SLOT(slotLoadTemplateList()));
}

KAccountTemplateSelector::~KAccountTemplateSelector()
{
  delete d;
}

void KAccountTemplateSelector::slotLoadTemplateList(void)
{
#ifndef KMM_DESIGNER
  TQStringList dirs;
  // get list of template subdirs and scan them for the list of subdirs
  d->dirlist = TDEGlobal::dirs()->findDirs("appdata", "templates");
  TQStringList::iterator it;
  for(it = d->dirlist.begin(); it != d->dirlist.end(); ++it) {
    TQDir dir(*it);
    // tqDebug("Reading dir '%s' with %d entries", (*it).data(), dir.count());
    dirs = dir.entryList("*", TQDir::Dirs);
    TQStringList::iterator it_d;
    for(it_d= dirs.begin(); it_d != dirs.end(); ++it_d) {
      // we don't care about . and ..
      if((*it_d) == ".." || (*it_d) == "." || (*it_d) == "C")
        continue;
      TQRegExp exp("(..)_(..)");
      if(exp.search(*it_d) != -1) {
        TQString country = TDEGlobal::locale()->twoAlphaToCountryName(exp.cap(2));
        if(country.isEmpty())
          country = exp.cap(2);
        TQString lang = TDEGlobal::locale()->twoAlphaToLanguageName(exp.cap(1));
        if(d->countries.contains(country)) {
          if(d->countries[country] != *it_d) {
            TQString oName = d->countries[country];
            exp.search(oName);
            TQString oCountry = TDEGlobal::locale()->twoAlphaToCountryName(exp.cap(2));
            TQString oLang = TDEGlobal::locale()->twoAlphaToLanguageName(exp.cap(1));
            d->countries.remove(country);
            d->countries[TQString("%1 (%2)").arg(oCountry).arg(oLang)] = oName;
            d->countries[TQString("%1 (%2)").arg(country).arg(lang)] = *it_d;
          }
        } else {
          d->countries[country] = *it_d;
        }
      } else if((*it_d).length() == 2) {
        TQString country = TDEGlobal::locale()->twoAlphaToCountryName((*it_d).upper());
        d->countries[country] = *it_d;
      } else {
        tqDebug("'%s/%s' not scanned", (*it).data(), (*it_d).data());
      }
    }
  }

  // now that we know, what we can get at max, we scan everything
  // and parse the templates into memory
  m_groupList->clear();
  d->m_templates.clear();
  d->it_m = d->countries.begin();
  d->id = 1;
  TQTimer::singleShot(0, this, TQT_SLOT(slotLoadCountry()));
#endif
}

void KAccountTemplateSelector::slotLoadCountry(void)
{
#ifndef KMM_DESIGNER

  TDEListViewItem* parent = new TDEListViewItem(m_groupList, d->it_m.key());
  parent->setSelectable(false);
  TQStringList::iterator it;
  for(it = d->dirlist.begin(); it != d->dirlist.end(); ++it) {
    TQStringList::iterator it_f;
    TQDir dir(TQString("%1%2").arg(*it).arg(*(d->it_m)));
    if(dir.exists()) {
      TQStringList files = dir.entryList("*", TQDir::Files);
      for(it_f = files.begin(); it_f != files.end(); ++it_f) {
        MyMoneyTemplate templ(TQString("%1/%2").arg(dir.canonicalPath()).arg(*it_f));
        d->m_templates[TQString("%1").arg(d->id)] = templ;
        new TDEListViewItem(parent, templ.title(), templ.shortDescription(), TQString("%1").arg(d->id));
        ++d->id;
      }
    }
  }

  ++d->it_m;
  if(d->it_m != d->countries.end())
    TQTimer::singleShot(0, this, TQT_SLOT(slotLoadCountry()));
  else {
    d->loadHierarchy();
  }
#endif

}

void KAccountTemplateSelector::slotLoadHierarchy(void)
{
#ifndef KMM_DESIGNER
  d->loadHierarchy();
#endif
}

TQValueList<MyMoneyTemplate> KAccountTemplateSelector::selectedTemplates(void) const
{
#ifndef KMM_DESIGNER
  return d->selectedTemplates();
#else
  return TQValueList<MyMoneyTemplate>();
#endif
}

#include "kaccounttemplateselector.moc"
