#include "cmodule.h"
#include "lyrics.h"
#include <tqlayout.h>
#include <tqstringlist.h>
#include <tqlabel.h>
#include <kmessagebox.h>
#include <tqvgroupbox.h>
#include <tqgrid.h>
#include <klistbox.h>
#include <klineedit.h>
#include <kbuttonbox.h>
#include <klocale.h>
#include <kconfig.h>
#include <kdebug.h>

extern Lyrics *lyrics;

const char *const DEFAULT_NAME =
  "Google,"
  "Pure Lyrics,"
  "Sing365,"
  "Lyrics Planet,"
  "Lyrics World,"
  "Get Lyrics,"
  "AZLyrics,"
  "Astraweb,"
  "SongMeanings,"
  "Google (Feeling Lucky),"
  "Everything2,"
  "Everything2 (author info)";

const char *const DEFAULT_TQUERY =
  "http://www.google.com/search?q=lyrics+$(title)+$(author)+$(album),"
  "http://www.purelyrics.com/index.php?search_artist=$(author)&search_album=$(album)&search_title=$(title)&search_lyrics=&search_advsubmit2=Search,"
  "http://search.sing365.com/search.php?searchstr=$(title)&submit=search&category=song,"
  "http://www.lyricsplanet.com/index.php3?style=searchtitle&fix=1&searchstring=$(title),"
  "http://www.lyricsworld.com/cgi-bin/search.cgi?q=$(title)+$(author),"
  "http://www.getlyrics.com/search.php?Song=$(title),"
  "http://www.azlyrics.com/cgi-bin/s.cgi?q=$(title)+$(author),"
  "http://search.lyrics.astraweb.com?word=$(title)+$(author)+$(album),"
  "http://www.songmeanings.net/search.php?type=titles&query=$(title),"
  "http://www.google.com/search?q=lyrics+%22$(title)%22+%22$(author)%22+%22$(album)%22&btnI=I%27m+Feeling+Lucky,"
  "http://everything2.com/index.pl?node=$(title),"
  "http://everything2.com/index.pl?node=$(author),"
  "http://www.letssingit.com/cgi-exe/am.cgi?a=search&p=1&s=$(title)&l=song";

LyricsCModule::LyricsCModule(TQObject *_parent) : CModule(i18n("Lyrics"), i18n("Configure Lyrics Plugin"), "document", _parent) {
  /* Thanks to the kde-usability guys for the help designing this dialog!
   * help to simon edwards of KGuardGod, for a big help designing it */
  TQVBoxLayout *vtqlayout = new TQVBoxLayout(this, KDialog::marginHint(), KDialog::spacingHint());
  TQHBoxLayout *htqlayout = new TQHBoxLayout(vtqlayout, KDialog::spacingHint());
  vtqlayout->setStretchFactor( htqlayout, 1 );

  // Search box
  TQVBoxLayout *boxtqlayout = new TQVBoxLayout( htqlayout, KDialog::spacingHint() );
  boxtqlayout->addWidget( new TQLabel( i18n("Search providers:" ), this ) );
  providersBox = new KListBox( this, "providersBox" );
  boxtqlayout->addWidget(providersBox);

  boxButtons = new KButtonBox( this,Qt::Vertical );
  boxButtons->addButton( i18n( "New Search Provider" ), TQT_TQOBJECT(this), TQT_SLOT( newSearch() ) );
  boxButtons->addButton( i18n( "Delete Search Provider" ), TQT_TQOBJECT(this), TQT_SLOT( delSearch() ) );
  boxButtons->addButton( i18n( "Move Up" ), TQT_TQOBJECT(this), TQT_SLOT( moveUpSearch() ) );
  boxButtons->addButton( i18n( "Move Down" ), TQT_TQOBJECT(this), TQT_SLOT( moveDownSearch() ) );
  boxButtons->tqlayout();
  boxtqlayout->addWidget( boxButtons );

  // Edit box
  TQGroupBox *propBox = new TQVGroupBox( i18n("Search Provider Properties" ), this );
  TQGrid *editGrid = new TQGrid(2, propBox );
  editGrid->setSpacing(  propBox->insideSpacing() );
  new TQLabel( i18n( "Name:" ), editGrid );
  nameEdit = new KLineEdit( editGrid );
  new TQLabel( i18n( "Query:" ), editGrid );
  queryEdit = new KLineEdit( editGrid );
  /* ATTENTION to translators:
   * The property names can't be translated. This means that $(author) must be kept as $(author), $(title) as $(title), etc, or it won't work.*/
  TQLabel *textLabel = new TQLabel(i18n("For your query, you can use any property of your multimedia item, just enclosing it with a $(property).\n\nSome common properties used are $(title), $(author) and $(album). For example, to search in Google for the author, title and track, just use:\nhttp://www.google.com/search?q=$(author)+$(title)+$(track)"), propBox, "textLabel");
  textLabel->tqsetAlignment(TQt::WordBreak);
  htqlayout->addWidget( propBox, 1 );

  /* Signal/slots */
  nameEdit->setEnabled( false );
  queryEdit->setEnabled( false );
  connect( providersBox, TQT_SIGNAL( highlighted( TQListBoxItem * ) ), this, TQT_SLOT( selected( TQListBoxItem * ) ) );
  connect( nameEdit, TQT_SIGNAL( textChanged( const TQString &) ), this, TQT_SLOT( nameChanged( const TQString & ) ) );
  connect( queryEdit, TQT_SIGNAL( textChanged( const TQString & ) ), this, TQT_SLOT( queryChanged( const TQString & ) ) );



  vtqlayout->addStretch();
  reopen();
  save();
}

void LyricsCModule::newSearch(TQString name, TQString query) {
  kdDebug(90020) << "New search" << endl;
  SearchProvider s = { name, query };
  mProviders.push_back( s );
  providersBox->insertItem( name );
  providersBox->setCurrentItem( providersBox->count()-1 );
  nameEdit->setEnabled( true );
  queryEdit->setEnabled( true );
//X   if ( providersBox->count() == 1 )
//X     providersBox->setCurrentItem( 0 );
}

void LyricsCModule::selected( TQListBoxItem *i ) {
  kdDebug(90020) << "selected" << endl;
  int index = providersBox->index( i );
  if ( index < 0 )
    return;
  if ( nameEdit->text() != mProviders[ index ].name )
    nameEdit->setText( mProviders[ index ].name );
  if ( queryEdit->text() != mProviders[ index ].url )
    queryEdit->setText( mProviders[ index ].url );
}


void LyricsCModule::delSearch() {
  if ( mProviders.size() == 1 ) {
    KMessageBox::sorry( this, i18n( "You must have at least one search provider. The current one will not be removed." ) );
    return;
  }
  int index = providersBox->currentItem();
  TQValueVector<SearchProvider>::iterator it;
  for ( it = mProviders.begin(); ( *it ).name != mProviders[ index ].name || ( *it ).url != mProviders[ index ].url; ++it );
  mProviders.erase( it );
  providersBox->removeItem( index );
  providersBox->setSelected( providersBox->currentItem(), true );
}

void LyricsCModule::moveUpSearch() {
  if ( providersBox->currentItem() <= 0 )
    return;
  int index = providersBox->currentItem();
  TQString name = mProviders[ index ].name;
  TQString url = mProviders[ index ].url;
  mProviders[ index ].name = mProviders[ index-1 ].name;
  mProviders[ index ].url = mProviders[ index-1 ].url;
  mProviders[ index-1 ].name = name;
  mProviders[ index-1 ].url = url;
  providersBox->changeItem( mProviders[ index-1 ].name, index-1 );
  providersBox->changeItem( mProviders[ index ].name, index );
  providersBox->setSelected( index-1, true );
}

void LyricsCModule::moveDownSearch() {
  if ( static_cast<unsigned int>( providersBox->currentItem() ) >= providersBox->count()-1 )
    return;
  int index = providersBox->currentItem();
  TQString name = mProviders[ index ].name;
  TQString url = mProviders[ index ].url;
  mProviders[ index ].name = mProviders[ index+1 ].name;
  mProviders[ index ].url = mProviders[ index+1 ].url;
  mProviders[ index+1 ].name = name;
  mProviders[ index+1 ].url = url;
  providersBox->changeItem( mProviders[ index+1 ].name, index+1 );
  providersBox->changeItem( mProviders[ index ].name, index );
  providersBox->setSelected( index+1, true );
}

void LyricsCModule::nameChanged( const TQString &name ) {
  kdDebug(90020) << "name changed" << endl;
  if ( providersBox->currentItem() < 0 )
    return;
  mProviders[ providersBox->currentItem() ].name = name;
  if ( name != providersBox->text( providersBox->currentItem() ) )
    providersBox->changeItem( name, providersBox->currentItem() );
}

void LyricsCModule::queryChanged( const TQString &query ) {
  kdDebug(90020) << "query changed" << endl;
  if ( providersBox->currentItem() < 0 )
    return;
  mProviders[ providersBox->currentItem() ].url = query;
}


void LyricsCModule::save() {
  KConfig *conf = KGlobal::config();
  conf->setGroup( "Lyrics" );
  TQStringList queryList, nameList;
  TQValueVector<SearchProvider>::iterator it;
  for ( it = mProviders.begin(); it != mProviders.end(); ++it ) {
    kdDebug(90020) << "query:" << ( *it ).url << endl;
    queryList += ( *it ).url;
    nameList += ( *it ).name;
  }
  conf->writeEntry( "queryList", queryList );
  conf->writeEntry( "nameList", nameList );
  /* TODO */
  // APPLY settings
  if ( lyrics )
    lyrics->setProviders( mProviders );
}

void LyricsCModule::reopen() {
  TQStringList queryList, nameList;
  KConfig *conf = KGlobal::config();
  mProviders.clear();
  providersBox->clear();
  kdDebug(90020) << "config read" << endl;
  conf->setGroup( "Lyrics" );
  queryList = conf->readListEntry( "queryList" );
  nameList = conf->readListEntry( "nameList" );
  if ( queryList.count() == 0 && nameList.count() == 0 ) {
    queryList = TQStringList::split( ",", DEFAULT_TQUERY );
    nameList = TQStringList::split( ",", DEFAULT_NAME );
  }
  TQStringList::Iterator queryIt, nameIt;
  for ( queryIt = queryList.begin(), nameIt = nameList.begin(); queryIt != queryList.end() && nameIt != nameList.end(); ++queryIt, ++nameIt ) {
    kdDebug(90020) << "Read:" << *queryIt << " and " << *nameIt << endl;
    newSearch( *nameIt, *queryIt );
  }
}

#include "cmodule.moc"
