/* This file is part of the KDE project
   Copyright (C) 2005 Peter Simonsson <psn@linux.se>

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

   This library is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   Library General Public License for more details.

   You should have received a copy of the GNU Library General Public License
   along with this library; see the file COPYING.LIB.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301, USA.
*/

#include "KoOpenPane.h"

#include <tqvbox.h>
#include <tqlayout.h>
#include <tqheader.h>
#include <tqwidgetstack.h>
#include <tqlabel.h>
#include <tqvaluelist.h>
#include <tqimage.h>
#include <tqpainter.h>
#include <tqpen.h>

#include <tdelocale.h>
#include <tdefiledialog.h>
#include <kinstance.h>
#include <kpushbutton.h>
#include <kiconloader.h>
#include <kdebug.h>
#include <tdelistview.h>

#include "KoFilterManager.h"
#include "KoTemplates.h"
#include "KoDocument.h"
#include "KoDetailsPane.h"
#include "koDetailsPaneBase.h"

#include <limits.h>

class KoSectionListItem : public TQListViewItem
{
  public:
    KoSectionListItem(TDEListView* listView, const TQString& name, int sortWeight, int widgetIndex = -1)
      : TQListViewItem(listView, name), m_sortWeight(sortWeight), m_widgetIndex(widgetIndex)
    {
    }

    virtual int compare(TQListViewItem* i, int, bool) const
    {
      KoSectionListItem* item = dynamic_cast<KoSectionListItem*>(i);

      if(!item)
        return 0;

      return sortWeight() - item->sortWeight();
    }

    virtual void paintCell(TQPainter* p, const TQColorGroup& cg, int column, int width, int align)
    {
      if(widgetIndex() >= 0) {
        TQListViewItem::paintCell(p, cg, column, width, align);
      } else {
        int ypos = (height() - 2) / 2;
        TQPen pen(cg.foreground(), 2);
        p->setPen(pen);
        p->drawLine(0, ypos, width, ypos);
      }
    }

    int sortWeight() const { return m_sortWeight; }
    int widgetIndex() const { return m_widgetIndex; }

  private:
    int m_sortWeight;
    int m_widgetIndex;
};

class KoOpenPanePrivate
{
  public:
    KoOpenPanePrivate() :
      m_instance(0)
    {
    }

    TDEInstance* m_instance;
};

KoOpenPane::KoOpenPane(TQWidget *parent, TDEInstance* instance, const TQString& templateType)
  : KoOpenPaneBase(parent, "OpenPane")
{
  d = new KoOpenPanePrivate;
  d->m_instance = instance;

  m_sectionList->header()->hide();
  m_sectionList->setSorting(0);
#if KDE_IS_VERSION(3,4,0)
  m_sectionList->setShadeSortColumn(false);
#endif
  connect(m_sectionList, TQT_SIGNAL(selectionChanged(TQListViewItem*)),
          this, TQT_SLOT(selectionChanged(TQListViewItem*)));
  connect(m_sectionList, TQT_SIGNAL(pressed(TQListViewItem*)),
          this, TQT_SLOT(itemClicked(TQListViewItem*)));
  connect(m_sectionList, TQT_SIGNAL(spacePressed(TQListViewItem*)),
          this, TQT_SLOT(itemClicked(TQListViewItem*)));
  connect(m_sectionList, TQT_SIGNAL(returnPressed(TQListViewItem*)),
          this, TQT_SLOT(itemClicked(TQListViewItem*)));

  KGuiItem openExistingGItem(i18n("Open Existing Document..."), "fileopen");
  m_openExistingButton->setGuiItem(openExistingGItem);
  connect(m_openExistingButton, TQT_SIGNAL(clicked()), this, TQT_SLOT(showOpenFileDialog()));

  initRecentDocs();
  initTemplates(templateType);

  KoSectionListItem* selectedItem = static_cast<KoSectionListItem*>(m_sectionList->selectedItem());

  if(selectedItem) {
    m_widgetStack->widget(selectedItem->widgetIndex())->setFocus();
  }

  TQValueList<int> sizes;
  sizes << 20 << width() - 20;
  m_splitter->setSizes(sizes);

  // Set the sizes of the details pane splitters
  TDEConfigGroup cfgGrp(d->m_instance->config(), "TemplateChooserDialog");
  sizes = cfgGrp.readIntListEntry("DetailsPaneSplitterSizes");
  emit splitterResized(0, sizes);

  connect(this, TQT_SIGNAL(splitterResized(KoDetailsPaneBase*, const TQValueList<int>&)),
          this, TQT_SLOT(saveSplitterSizes(KoDetailsPaneBase*, const TQValueList<int>&)));
}

KoOpenPane::~KoOpenPane()
{
  KoSectionListItem* item = dynamic_cast<KoSectionListItem*>(m_sectionList->selectedItem());

  if(item) {
    if(!dynamic_cast<KoDetailsPaneBase*>(m_widgetStack->widget(item->widgetIndex()))) {
      TDEConfigGroup cfgGrp(d->m_instance->config(), "TemplateChooserDialog");
      cfgGrp.writeEntry("LastReturnType", "Custom");
    }
  }

  delete d;
}

void KoOpenPane::showOpenFileDialog()
{
  const TQStringList mimeFilter = KoFilterManager::mimeFilter(KoDocument::readNativeFormatMimeType(),
      KoFilterManager::Import, KoDocument::readExtraNativeMimeTypes());

  KURL url = KFileDialog::getOpenURL(":OpenDialog", mimeFilter.join(" "), this);

  if(!url.isEmpty()) {
    TDEConfigGroup cfgGrp(d->m_instance->config(), "TemplateChooserDialog");
    cfgGrp.writeEntry("LastReturnType", "File");
    emit openExistingFile(url.url());
  }
}

void KoOpenPane::initRecentDocs()
{
  KoRecentDocumentsPane* recentDocPane = new KoRecentDocumentsPane(this, d->m_instance);
  connect(recentDocPane, TQT_SIGNAL(openFile(const TQString&)), this, TQT_SIGNAL(openExistingFile(const TQString&)));
  TQListViewItem* item = addPane(i18n("Recent Documents"), "fileopen", recentDocPane, 0);
  connect(recentDocPane, TQT_SIGNAL(splitterResized(KoDetailsPaneBase*, const TQValueList<int>&)),
          this, TQT_SIGNAL(splitterResized(KoDetailsPaneBase*, const TQValueList<int>&)));
  connect(this, TQT_SIGNAL(splitterResized(KoDetailsPaneBase*, const TQValueList<int>&)),
          recentDocPane, TQT_SLOT(resizeSplitter(KoDetailsPaneBase*, const TQValueList<int>&)));

  KoSectionListItem* separator = new KoSectionListItem(m_sectionList, "", 1);
  separator->setEnabled(false);

  if(d->m_instance->config()->hasGroup("RecentFiles")) {
    m_sectionList->setSelected(item, true);
  }
}

void KoOpenPane::initTemplates(const TQString& templateType)
{
  TQListViewItem* selectItem = 0;
  TQListViewItem* firstItem = 0;
  const int templateOffset = 1000;

  if(!templateType.isEmpty())
  {
    KoTemplateTree templateTree(templateType.local8Bit(), d->m_instance, true);

    for (KoTemplateGroup *group = templateTree.first(); group != 0L; group = templateTree.next()) {
      if (group->isHidden()) {
        continue;
      }

      KoTemplatesPane* pane = new KoTemplatesPane(this, d->m_instance,
          group, templateTree.defaultTemplate());
      connect(pane, TQT_SIGNAL(openTemplate(const TQString&)), this, TQT_SIGNAL(openTemplate(const TQString&)));
      connect(pane, TQT_SIGNAL(alwaysUseChanged(KoTemplatesPane*, const TQString&)),
              this, TQT_SIGNAL(alwaysUseChanged(KoTemplatesPane*, const TQString&)));
      connect(this, TQT_SIGNAL(alwaysUseChanged(KoTemplatesPane*, const TQString&)),
              pane, TQT_SLOT(changeAlwaysUseTemplate(KoTemplatesPane*, const TQString&)));
      connect(pane, TQT_SIGNAL(splitterResized(KoDetailsPaneBase*, const TQValueList<int>&)),
              this, TQT_SIGNAL(splitterResized(KoDetailsPaneBase*, const TQValueList<int>&)));
      connect(this, TQT_SIGNAL(splitterResized(KoDetailsPaneBase*, const TQValueList<int>&)),
              pane, TQT_SLOT(resizeSplitter(KoDetailsPaneBase*, const TQValueList<int>&)));
      TQListViewItem* item = addPane(group->name(), group->first()->loadPicture(d->m_instance),
                                    pane, group->sortingWeight() + templateOffset);

      if(!firstItem) {
        firstItem = item;
      }

      if(group == templateTree.defaultGroup()) {
        firstItem = item;
      }

      if(pane->isSelected()) {
        selectItem = item;
      }
    }
  } else {
    firstItem = m_sectionList->firstChild();
  }

  TDEConfigGroup cfgGrp(d->m_instance->config(), "TemplateChooserDialog");

  if(selectItem && (cfgGrp.readEntry("LastReturnType") == "Template")) {
    m_sectionList->setSelected(selectItem, true);
  } else if(!m_sectionList->selectedItem() && firstItem) {
    m_sectionList->setSelected(firstItem, true);
  }
}

void KoOpenPane::setCustomDocumentWidget(TQWidget *widget) {
  Q_ASSERT(widget);
  KoSectionListItem* separator = new KoSectionListItem(m_sectionList, "", INT_MAX-1);
  separator->setEnabled(false);

  TQListViewItem* item = addPane(i18n("Custom Document"), TQString(), widget, INT_MAX);

  TDEConfigGroup cfgGrp(d->m_instance->config(), "TemplateChooserDialog");

  if(cfgGrp.readEntry("LastReturnType") == "Custom") {
    m_sectionList->setSelected(item, true);
    KoSectionListItem* selectedItem = static_cast<KoSectionListItem*>(item);
    m_widgetStack->widget(selectedItem->widgetIndex())->setFocus();
  }
}

TQListViewItem* KoOpenPane::addPane(const TQString& title, const TQString& icon, TQWidget* widget, int sortWeight)
{
  return addPane(title, SmallIcon(icon, TDEIcon::SizeLarge, TDEIcon::DefaultState, d->m_instance),
                 widget, sortWeight);
}

TQListViewItem* KoOpenPane::addPane(const TQString& title, const TQPixmap& icon, TQWidget* widget, int sortWeight)
{
  if(!widget) {
    return 0;
  }

  int id = m_widgetStack->addWidget(widget);
  KoSectionListItem* listItem = new KoSectionListItem(m_sectionList, title, sortWeight, id);

  if(!icon.isNull()) {
    TQImage image = icon.convertToImage();

    if((image.width() > 48) || (image.height() > 48)) {
      image = image.smoothScale(48, 48, TQ_ScaleMin);
    }

    image.setAlphaBuffer(true);
    image = image.copy((image.width() - 48) / 2, (image.height() - 48) / 2, 48, 48);
    listItem->setPixmap(0, TQPixmap(image));
  }

  return listItem;
}

void KoOpenPane::selectionChanged(TQListViewItem* item)
{
  KoSectionListItem* section = dynamic_cast<KoSectionListItem*>(item);

  if(!item)
    return;

  m_headerLabel->setText(section->text(0));
  m_widgetStack->raiseWidget(section->widgetIndex());
}

void KoOpenPane::saveSplitterSizes(KoDetailsPaneBase* /*sender*/, const TQValueList<int>& sizes)
{
  TDEConfigGroup cfgGrp(d->m_instance->config(), "TemplateChooserDialog");
  cfgGrp.writeEntry("DetailsPaneSplitterSizes", sizes);
}

void KoOpenPane::itemClicked(TQListViewItem* item)
{
  KoSectionListItem* selectedItem = static_cast<KoSectionListItem*>(item);

  if(selectedItem) {
    m_widgetStack->widget(selectedItem->widgetIndex())->setFocus();
  }
}

#include "KoOpenPane.moc"
