/*
 * Copyright (C) 2004 Stephan M�res <Erdling@gmx.net>
 */

#include "plugin_katesnippets.h"

#include <tdeaction.h>
#include <tdelocale.h>
#include <kstandarddirs.h>
#include <kgenericfactory.h>


// let the world know ...
K_EXPORT_COMPONENT_FACTORY(katesnippetsplugin, KGenericFactory<KatePluginSnippets>( "katesnippets" ) )


// < IMPLEMENTAIONS for KatePluginSnippetsView >
//
//

/**
 * ctor KatePluginSnippetsView
 * @param w
 * @return
 */
KatePluginSnippetsView::KatePluginSnippetsView(Kate::MainWindow *w, TQWidget *dock) : CWidgetSnippets(dock,"snippetswidget")
  , dock (dock)
{
  setInstance (new TDEInstance("kate"));
  setXMLFile("plugins/katesnippets/plugin_katesnippets.rc");

  w->guiFactory()->addClient (this);
  win = w;


  //<make connections>
  connect (
    lvSnippets, TQ_SIGNAL( selectionChanged(TQListViewItem *) ),
    this, TQ_SLOT( slot_lvSnippetsSelectionChanged(TQListViewItem *) )
  );
  connect (
    lvSnippets, TQ_SIGNAL( doubleClicked (TQListViewItem *) ),
    this, TQ_SLOT( slot_lvSnippetsClicked(TQListViewItem  *) )
  );
  connect (
    lvSnippets, TQ_SIGNAL( itemRenamed(TQListViewItem *, int, const TQString &) ),
    this, TQ_SLOT( slot_lvSnippetsItemRenamed(TQListViewItem *, int, const TQString &) )
  );

  connect (
    btnNew, TQ_SIGNAL( clicked () ),
    this, TQ_SLOT( slot_btnNewClicked() )
  );
  connect (
    btnSave, TQ_SIGNAL( clicked () ),
    this, TQ_SLOT( slot_btnSaveClicked() )
  );
  connect (
    btnDelete, TQ_SIGNAL( clicked () ),
    this, TQ_SLOT( slot_btnDeleteClicked() )
  );
  //</make connections>

  lSnippets.setAutoDelete( true ); // the list owns the objects

  config = new TDEConfig("katesnippetspluginrc");
  readConfig();

  // set text of selected item at startup
  slot_lvSnippetsSelectionChanged(lvSnippets->selectedItem() );
}


/**
 * dtor KatePluginSnippetsView
 * @return
 */
KatePluginSnippetsView::~ KatePluginSnippetsView() {
  writeConfig();

  win->guiFactory()->removeClient(this);
}


//
//
// < IMPLEMENTAIONS for KatePluginSnippetsView >




// < IMPLEMENTAIONS for KatePluginSnippets >
//
//

/**
 * ctor KatePluginSnippets
 * @param parent
 * @param name
 * @return
 */
KatePluginSnippets::KatePluginSnippets( TQObject* parent, const char* name, const TQStringList& )
    : Kate::Plugin ( (Kate::Application*)parent, name ) {}

/**
 * dtor KatePluginSnippets
 * @return
 */
KatePluginSnippets::~KatePluginSnippets() {}

/**
 *
 * @param win
 */
void KatePluginSnippets::addView(Kate::MainWindow *win)
{
  TQWidget *dock = win->toolViewManager()->createToolView(
              "kate_plugin_snippets",
              Kate::ToolViewManager::Left,
              SmallIcon("contents"),
              i18n("Snippets"));

  KatePluginSnippetsView *view = new KatePluginSnippetsView (win,dock);
  m_views.append(view);
}


/**
 *
 * @param win
 */
void KatePluginSnippets::removeView(Kate::MainWindow *win) {
  for (uint z=0; z < m_views.count(); z++)
    if (m_views.at(z)->win == win) {
      KatePluginSnippetsView *view = m_views.at(z);
      m_views.remove (view);
      delete view->dock;
    }
}

/**
 *
 * @param item
 */
void KatePluginSnippetsView::slot_lvSnippetsSelectionChanged(TQListViewItem  * item) {
  CSnippet *snippet;
  if ( (snippet = findSnippetByListViewItem(item))!= NULL ) {
    teSnippetText->setText(snippet->getValue());
  }

}


/**
 * Special meaning of <mark/> and <cursor/> ...
 * @param item
 */
void KatePluginSnippetsView::slot_lvSnippetsClicked (TQListViewItem  * item) {
  Kate::View *kv = win->viewManager()->activeView();
  CSnippet *snippet;

  if (kv) {
    if ( (snippet = findSnippetByListViewItem(item))!= NULL ) {
      TQString sText = snippet->getValue();
      TQString sSelection = "";

      if ( kv->getDoc()->hasSelection() ) {
        sSelection = kv->getDoc()->selection();
        // clear selection
        kv->keyDelete();
      }

      sText.replace( TQRegExp("<mark/>"), sSelection );
      sText.replace( TQRegExp("<date/>"), TQDate::currentDate().toString(TQt::LocalDate) );
      sText.replace( TQRegExp("<time/>"), TQTime::currentTime().toString(TQt::LocalDate) );
      kv->insertText ( sText );
    }
    kv->setFocus();
  }
}


/**
 *
 * @param lvi
 * @param
 * @param text
 */
void KatePluginSnippetsView::slot_lvSnippetsItemRenamed(TQListViewItem *lvi,int /*col*/, const TQString& text) {
  CSnippet *snippet;
  if ( (snippet = findSnippetByListViewItem(lvi)) != NULL ) {
    snippet->setKey( text );
    writeConfig();
  }
}


/**
 *
 */
void KatePluginSnippetsView::slot_btnNewClicked() {
  TQString sKey = "New Snippet";
  TQString sValue = "";

  TQListViewItem *lvi = insertItem(sKey, true);
  lSnippets.append( new CSnippet(sKey, sValue, lvi) );
}


/**
 *
 */
void KatePluginSnippetsView::slot_btnSaveClicked() {
  CSnippet *snippet;
  TQListViewItem *lvi = lvSnippets->selectedItem();
  if ( (snippet = findSnippetByListViewItem(lvi)) != NULL ) {
    snippet->setValue(teSnippetText->text() );
    writeConfig();
  }
}


/**
 *
 */
void KatePluginSnippetsView::slot_btnDeleteClicked() {
  CSnippet *snippet;
  TQListViewItem *lvi = lvSnippets->selectedItem();


  if ( (snippet = findSnippetByListViewItem(lvi)) != NULL ) {
    lvSnippets->takeItem(lvi);
    lSnippets.remove(snippet);
  }
}


/**
 *
 */
void KatePluginSnippetsView::readConfig() {
  TQString sKey, sValue;
  TQListViewItem *lvi;

  config->setGroup("Snippets");

  int iNrOfSnippets = config->readEntry("NumberOfSnippets", "0").toInt() ;
  for (int i=0; i < iNrOfSnippets; i++) {
    TQStringList slFields;
    slFields = config->readListEntry ( TQString::number(i) );

    sKey   = slFields[0];
    sValue = slFields[1];

    lvi = insertItem(sKey, false);

    lSnippets.append( new CSnippet(sKey, sValue, lvi, this) );
  }

  // <defaults>
  if ( iNrOfSnippets == 0 ) {
    sKey	= "DEBUG variable";
    sValue = "## < DEBUG >\nout \"<pre>\\$<mark/> : \\\"$<mark/>\\\"\\n</pre>\"\n## </DEBUG >\n";
    lvi = insertItem(sKey, false);
    lSnippets.append( new CSnippet(sKey, sValue, lvi, this) );

    sKey	= "proc-header";
    sValue	= "## [created : <date/>, <time/>]\n## Description:\n## ============\n## The function \"<mark/>\" ...\n##\n##\n##\n##\n## Input:\n## ======\n##\n##\n##\nproc <mark/> {args} {\n\n	## add your code here\n\n	return \"\"\n}\n";
    lvi = insertItem(sKey, false);
    lSnippets.append( new CSnippet(sKey, sValue, lvi, this) );
  }
  // </defaults>

}


/**
 *
 */
void KatePluginSnippetsView::writeConfig() {
  config->setGroup("Snippets");

  int iNrOfSnippets = lSnippets.count();

  config->writeEntry("NumberOfSnippets", iNrOfSnippets );

  int i=0;

  CSnippet *snippet;
  for ( snippet = lSnippets.first(); snippet; snippet = lSnippets.next() ) {
    TQStringList slFields;
    slFields.append( snippet->getKey() );
    slFields.append( snippet->getValue() );

    config->writeEntry ( TQString::number(i), slFields, ',' );
    i++;
  }
  // sync to disc ...
  config->sync();
}


/**
 *
 * @param item
 * @return
 */
CSnippet* KatePluginSnippetsView::findSnippetByListViewItem(TQListViewItem *item) {
  CSnippet *snippet = NULL;
  for ( snippet = lSnippets.first(); snippet; snippet = lSnippets.next() ) {
    if ( snippet->getListViewItem() == item)
      break;
  }
  return snippet;
}

//
//
// < IMPLEMENTAIONS for KatePluginSnippets >

#include "plugin_katesnippets.moc"
