/***************************************************************************
                          kern.cpp  -  description
                             -------------------
    begin                : Sun Jul 13 03:14:52 EDT 2003
    copyright            : (C) 2003 by Armando Navarro-Vazquez
    email                : qoajnv@usc.es
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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.                                   *
 *                                                                         *
 ***************************************************************************/

//#include <kparts/genericfactory.h>
#include <iostream>

#include <ktoggleaction.h>
#include <kdebug.h>
#include <kaction.h>
#include <kactioncollection.h>
#include <kcomponentdata.h>
#include <kiconloader.h>
#include <qmessagebox.h>
//Added by qt3to4:
#include <QPixmap>
#include <klocale.h>
#include <kryonmrsettingsdialog.h>
#include <kaboutapplicationdialog.h>
#include <kfiledialog.h>
#include <kmessagebox.h>
#include <ktempdir.h>
#include <kio/netaccess.h>





#include <q3whatsthis.h>
#include <q3process.h>
#include <qimage.h>

#include "icons_nmr.h"
#include "kryonmr.h"
#include "spectralwidget.h"
#include "tokenizer.h"
#include "nmrfile.h"
#include "parsers.h"


// Factory code for KDE 3
//typedef KParts::GenericFactory<KryoNMR> KryoNMRFactory;
K_EXPORT_COMPONENT_FACTORY( libkryonmr /*library name*/, KryoNMRFactory );

KryoNMR::KryoNMR( QWidget *parentWidget, 
                  QObject *parent, const QStringList &) : KParts::ReadOnlyPart(parent)
{

  //setFocusPolicy(QWidget::ClickFocus);
  //setInstance( KryoNMRFactory::instance() );

  // Create the tree widget, and set it as the part's widget
  m_spectrumwidget = new SpectralWidget( parentWidget );
  m_spectrumwidget->setFocusPolicy(Qt::ClickFocus);
  setWidget( m_spectrumwidget );
  connect(m_spectrumwidget,SIGNAL(ft(bool)),this,SLOT(enableSpectrumActions(bool)));
  connect(m_spectrumwidget,SIGNAL(info(const QString&)),this, SIGNAL(setStatusBarText(const QString&)));
  // Ask for one column in the tree and hide the horizontal header at the top

  // By default the root items don't display a '+' sign in QListView);

  // Action creation code will go here

  InitActions();
  setXMLFile( "kryonmrpart.rc" );
  m_extension = new KryoNMRExtension(this);

 // m_settingsdialog= new KryoNMRSettingsDialog();
 // connect(m_settingsdialog,SIGNAL(settingsmodified()),m_spectrumwidget,SLOT(OnModifySettings()));


}

/** No descriptions */
bool KryoNMR::openFile()
{
  kDebug() << "opening file " << localFilePath();
  ResetActions();
  enableSpectrumActions(false);
  QFileInfo parentdir(localFilePath());
  m_spectrumwidget->OpenFile(localFilePath());
  return true;

}

bool KryoNMR::openUrl(const KUrl& url)
{
  
   if(url.isLocalFile())
  {
    return KParts::ReadOnlyPart::openUrl(url);
  }
  
    if ( url.fileName() == "fid" )
    {
    KUrl srcurl(url);
    QString dir=url.directory().section('/',-1);
    srcurl.setDirectory(url.directory());
    KTempDir tempdir;
    KUrl targeturl= KUrl::fromPathOrUrl(tempdir.name());
    KIO::NetAccess::dircopy(srcurl,targeturl,0);
    setLocalFilePath(tempdir.name()+dir+"/fid");
    openFile();
    return true;
    }
    else if ( url.fileName() == "1i" || url.fileName() == "1r" )
    {
    KUrl srcurl(url);
    QString dir=url.directory().section('/',-3,-1);
    int pos=url.directory().findRev("pdata");
    srcurl.setDirectory(url.directory().left(pos));
    KTempDir tempdir;
    KUrl targeturl= KUrl::fromPathOrUrl(tempdir.name()); 
    KIO::NetAccess::dircopy(srcurl,targeturl,0);
    setLocalFilePath(tempdir.name()+dir+"/"+url.fileName());
    openFile();
    return true;
    }
    else return KParts::ReadOnlyPart::openUrl(url);


}

KAboutData* KryoNMR::createAboutData()
{
#warning reimplement
 // KAboutData* aboutData =  new KAboutData(); 
  return NULL;
}

/** No descriptions */
void KryoNMR::InitActions()
{
  KIconLoader *loader = KIconLoader::global();
  //Create  the moving actions
  KAction* upAction= actionCollection()->addAction("Up");
  upAction->setText(i18n("Up"));
  upAction->setIcon(KIcon("up"));
  connect(upAction,SIGNAL(triggered()),m_spectrumwidget,SLOT(OnUp()));
/*  new KAction(i18n("Up"),loader->loadIcon("up",KIconLoader::Toolbar),0,m_spectrumwidget,SLOT(OnUp()),actionCollection(),"Up");
  downAction= new KAction(i18n("Down"),loader->loadIcon("down",KIconLoader::Toolbar),0,m_spectrumwidget,SLOT(OnDown()),actionCollection(),"Down");
  leftAction= new KAction(i18n("Left"),loader->loadIcon("back",KIconLoader::Toolbar),0,m_spectrumwidget,SLOT(OnLeft()),actionCollection(),"Left");
  rightAction= new KAction(i18n("Right"),loader->loadIcon("forward",KIconLoader::Toolbar),0,m_spectrumwidget,SLOT(OnRight()),actionCollection(),"Right");
  plusAction= new KAction(i18n("Increase"),loader->loadIcon("kryomol_plus",KIconLoader::Toolbar),0,m_spectrumwidget,SLOT(OnPlus()),actionCollection(),"Increase");
  minusAction= new KAction(i18n("Decrease"),loader->loadIcon("kryomol_minus",KIconLoader::Toolbar),0,m_spectrumwidget,SLOT(OnMinus()),actionCollection(),"Decrease");

  //Setup whatsThis Information
  upAction->setWhatsThis("Move up the spectrum on screen. You can do also this action \
                         moving away from you the mouse whell or with the up arrow key");

  downAction->setWhatsThis("Move down the spectrum on screen. You can do also this action \
                           moving towards you the mouse whell or with the down arrow key");

  leftAction->setWhatsThis("Move to left screen side the spectrum. You can do also this action \
                           with the left arrow key");

  rightAction->setWhatsThis("Move to right screen side the spectrum. You can do also this action \
                            with the right arrow key");

  plusAction->setWhatsThis("Increase the spectrum scale. You can do also this action \
                           either pressing the Ctrl key and moving away from you the mouse whell or pressing the up arrow key");

  minusAction->setWhatsThis("Increase the spectrum scale. You can do also this action \
                            either pressing the Ctrl key and moving towards you the mouse whell or pressing the down arrow key");


#if KDE_VERSION >= 350
  zoomAction = new KToggleAction(i18n("Zoom"),loader->loadIcon("viewmag",KIconLoader::Toolbar),0,this,SLOT(OnZoom()),actionCollection(),"Zoom");
  //connect(zoomAction,SIGNAL(toggled(bool)),m_spectrumwidget,SLOT(OnZoom(bool)));
  //zoomAction->setExclusiveGroup("process");
  zoomAction->setWhatsThis("Click mouse left button and drag over the spectrum");
  connect(this,SIGNAL(zoomtoggled(bool )),m_spectrumwidget,SLOT(OnZoom(bool )));
#else
  zoomAction = new KToggleAction(i18n("Zoom"),loader->loadIcon("viewmag",KIconLoader::Toolbar),0,actionCollection(),"Zoom");
  connect(zoomAction,SIGNAL(toggled(bool)),m_spectrumwidget,SLOT(OnZoom(bool)));
  zoomAction->setExclusiveGroup("process");
  zoomAction->setWhatsThis("Click mouse left button and drag over the spectrum");
  //connect(this,SIGNAL(toggled(bool )),m_spectrumwidget,SLOT(OnZoom(bool )));
#endif

  fullAction= new KAction(i18n("Full View"),loader->loadIcon("viewmagfit",KIconLoader::Toolbar),0,m_spectrumwidget,SLOT(OnFull()),actionCollection(),"Full");


#if KDE_VERSION >= 350
  infoAction= new KToggleAction(i18n("Info"),loader->loadIcon("messagebox_info",KIconLoader::Toolbar),0,this,SLOT(OnInfo()),actionCollection(),"Info");

  //infoAction->setExclusiveGroup("process");
  infoAction->setWhatsThis("Click mouse left button and a window will pop up \
                           giving you point intensities and chemical shifts ");
  connect(this,SIGNAL(infotoggled(bool)),m_spectrumwidget,SLOT(OnInfo(bool)));
#else
  infoAction= new KToggleAction(i18n("Info"),loader->loadIcon("messagebox_info",KIconLoader::Toolbar),0,actionCollection(),"Info");
  connect(infoAction,SIGNAL(toggled(bool)),m_spectrumwidget,SLOT(OnInfo(bool)));
  infoAction->setExclusiveGroup("process");
  infoAction->setWhatsThis("Click mouse left button and a window will pop up \
                           giving you point intensities and chemical shifts ");

#endif

#if KDE_VERSION >= 350
  phaseAction= new KToggleAction(i18n("Phase"),loader->loadIcon("history",KIconLoader::Toolbar),0,this,SLOT(OnPhase()),actionCollection(),"Phase");

  //phaseAction->setExclusiveGroup("process");
  phaseAction->setWhatsThis("Click left or right button mouse and move mouse to adjust zeroth or \
                            first order respectively. To move the pivot click over the pivot line and drag over the spectrum");
  connect(this,SIGNAL(phasetoggled(bool)),m_spectrumwidget,SLOT(OnPhase(bool)));
#else
  phaseAction= new KToggleAction(i18n("Phase"),loader->loadIcon("history",KIconLoader::Toolbar),0,actionCollection(),"Phase");
  connect(phaseAction,SIGNAL(toggled(bool)),m_spectrumwidget,SLOT(OnPhase(bool)));
  phaseAction->setExclusiveGroup("process");
  phaseAction->setWhatsThis("Click left or right button mouse and move mouse to adjust zeroth or \
                            first order respectively. To move the pivot click over the pivot line and drag over the spectrum");

#endif

#if KDE_VERSION >= 350
  integralAction=new KToggleAction(i18n("Integral"),loader->loadIcon("int",KIconLoader::Toolbar),0,this,SLOT(OnIntegral()),actionCollection(),"Integral");

  //integralAction->setExclusiveGroup("process");
  integralAction->setWhatsThis("Drag over the spectrum to select\
                               integration areas");
  connect(this,SIGNAL(integraltoggled(bool)),m_spectrumwidget,SLOT(OnIntegral(bool)));
#else
  integralAction=new KToggleAction(i18n("Integral"),loader->loadIcon("int",KIconLoader::Toolbar),0,actionCollection(),"Integral");
  connect(integralAction,SIGNAL(toggled(bool)),m_spectrumwidget,SLOT(OnIntegral(bool)));
  integralAction->setExclusiveGroup("process");
  integralAction->setWhatsThis("Drag over the spectrum to select\
                               integration areas");
#endif

#if KDE_VERSION >= 350
  peakpAction=new KToggleAction(i18n("Peak Picking"),QPixmap(icons::peakp),0,this,SLOT(OnPeakPicking()),actionCollection(),"Peak Picking");

  // peakpAction->setExclusiveGroup("process");
  peakpAction->setWhatsThis("Drag over the spectrum. All peaks over the bottom of the\
                            dragged rectangle will be selected");
  connect(this,SIGNAL(peakpickingtoggled(bool)),m_spectrumwidget,SLOT(OnPeakPicking(bool)));
#else

  peakpAction=new KToggleAction(i18n("Peak Picking"),QPixmap(icons::peakp),0,actionCollection(),"Peak Picking");
  connect(peakpAction,SIGNAL(toggled(bool)),m_spectrumwidget,SLOT(OnPeakPicking(bool)));
  peakpAction->setExclusiveGroup("process");
  peakpAction->setWhatsThis("Drag over the spectrum. All peaks over the bottom of the\
                            dragged rectangle will be selected");

#endif

#if KDE_VERSION >= 350

  tmsAction=new KToggleAction(i18n("Reference"),QPixmap(icons::tms),0,this,SLOT(OnTMS()),actionCollection(),"Reference");

  //tmsAction->setExclusiveGroup("process");
  tmsAction->setWhatsThis("Click left button mouse and move cursor over the spectrum, selected\
                          peaks will be marked with a Qt::red line. Do double click and enter the reference value on the opened box");
  connect(this,SIGNAL(tmstoggled(bool)),m_spectrumwidget,SLOT(OnTMS(bool)));

  //baselineAction=new KAction(i18n("Baseline"),QPixmap(icons::tms),0,m_spectrumwidget,SLOT(OnBaseline()),
  //actionCollection(),"Baseline");
  //baselineAction->setWhatsThis("Open Base Line Correction Dialog");
#else

  tmsAction=new KToggleAction(i18n("Reference"),QPixmap(icons::tms),0,actionCollection(),"Reference");
  connect(tmsAction,SIGNAL(toggled(bool)),m_spectrumwidget,SLOT(OnTMS(bool)));
  tmsAction->setExclusiveGroup("process");
  tmsAction->setWhatsThis("Click left button mouse and move cursor over the spectrum, selected\
                          peaks will be marked with a Qt::red line. Do double click and enter the reference value on the opened box");
#endif
  fullAction= new KAction(i18n("handbook"),0,0,this,SLOT(OnHandbook()),actionCollection(),"handbook");
  connect(tmsAction,SIGNAL(toggled(bool)),m_spectrumwidget,SLOT(OnTMS(bool)));

  aboutAction= new KAction(i18n("About KryoNMR"),0,0,this,SLOT(OnAbout()),actionCollection(),"about");
  //now the standard actions
  configureAction=KStandardAction::preferences(this,SLOT(OnPreferences()),actionCollection(),"settings_configure");
  configureAction->setToolTip("Configure KryoNMR");
  configureAction->setWhatsThis("Configure here processing and visual options from the KryoNMR plugin");

  exportAction=new KAction(i18n("Export"),0,0,this,SLOT(OnExport()),actionCollection(),"export");

  // KStandardAction::help_contents(this,SLOT(OnHandbook()),actionCollection());
  //KStandardAction::whatsThis(this,SLOT(OnWhatsThis()),actionCollection(),"whatsthis");


  enableSpectrumActions(false);*/
}

/** No descriptions */
void KryoNMR::OnWhatsThis()
{

  Q3WhatsThis::enterWhatsThisMode ();

}


/** show users manual */
void KryoNMR::OnHandbook()
{

  //Well this should be rewritten using autoconf/automake stuff
  //in order to search for viewers and KDE directory
  //at the moment I dont know how to do it

  /*QProcess* proc= new QProcess(this);
  proc->addArgument("kghostview");
  proc->addArgument("/usr/share/doc/kern/handbook.pdf");
  if(proc->start())
    return;  */

}

KryoNMRExtension::KryoNMRExtension(KryoNMR *parent)
    : KParts::BrowserExtension(parent)
{
  enableAction("print",true);
  m_parent=parent;

}

KryoNMRExtension::~KryoNMRExtension()
{}

/** No descriptions */
void KryoNMRExtension::print()
{

  m_parent->m_spectrumwidget->OnPrint();
}
/** open settings dialog */
void KryoNMR::OnPreferences()
{

  m_settingsdialog->exec();
}
/** show a KAboutDialog */
void KryoNMR::OnAbout()
{

 // KAboutApplicationDialog* dialog= new KAboutApplicationDialog(0,"aboutDialog");
#warning reimplement
  //dialog->setLogo(kryomol.xpm);
  //dialog->setAuthor("Authors:Armando Navarro Vazquez","armando.navarro@uvigo.es","http://magcid.uvigo.es/~armando/software/kryomol","Vigo");
  //dialog->setVersion("Kryomol 0.6.7");
  //dialog->exec();
}
/** call this slot when FT is done to enable spectrum actions like reference.... */
void KryoNMR::enableSpectrumActions(bool b)
{
#warning reimplement
/*  phaseAction->setEnabled(b);
  peakpAction->setEnabled(b);
  tmsAction->setEnabled(b);
  integralAction->setEnabled(b); */
}
/** No descriptions */
void KryoNMR::OnExport()
{

  /*QString s = KFileDialog::getSaveFileName(
              QString::null,
                    "*.svg (SVG files)\n*.qpic (QPicture files)",
                    0,
                    "Save Vector Image" );  */

  KFileDialog d(KUrl(),
                "image/svg image/qpic",
                0,
                0 );

  QString s;

  if(d.exec()==QDialog::Accepted)
    s=d.selectedFile();

  if(s.isEmpty())
    return;

#warning reimplement
  QString filter=d.currentFilter();

/*  StringTokenizer path(std::string(s.toLatin1()),".");
  StringTokenizer::toupper(path.back());
  if( (path.back()!="SVG") && (path.back()!="QPIC") )
  {
    QFile file(s);
    if(filter==filter1)
      s+=".svg";
    if(filter==filter2)
      s+=".qpict";
    file.setName(s);
  }*/

  m_spectrumwidget->OnExport(s);

}

void KryoNMR::ResetActions()
{
#warning reimplement
/*  zoomAction->setChecked(false);
  phaseAction->setChecked(false);
  peakpAction->setChecked(false);
  tmsAction->setChecked(false);
  integralAction->setChecked(false); */
}

#if KDE_VERSION >= 350
void KryoNMR::OnZoom()
{
#warning reimplemnt
/*  if (zoomAction->isChecked())
  {
    infoAction->setChecked(false);
    phaseAction->setChecked(false);
    integralAction->setChecked(false);
    peakpAction->setChecked(false);
    tmsAction->setChecked(false);
  }
  emit zoomtoggled( zoomAction->isChecked() ); */

}

void KryoNMR::OnInfo()
{
#warning reimplement
 /* if (infoAction->isChecked())
  {
    zoomAction->setChecked(false);
    phaseAction->setChecked(false);
    integralAction->setChecked(false);
    peakpAction->setChecked(false);
    tmsAction->setChecked(false);
  }
  emit infotoggled(infoAction->isChecked()); */
}

void KryoNMR::OnPhase()
{
#warning reimplement
/*  if (phaseAction->isChecked())
  {
    zoomAction->setChecked(false);
    infoAction->setChecked(false);
    integralAction->setChecked(false);
    peakpAction->setChecked(false);
    tmsAction->setChecked(false);
  }
  emit phasetoggled(phaseAction->isChecked());*/
}

void KryoNMR::OnIntegral()
{
#warning reimplement
/*  if (integralAction->isChecked())
  {
    zoomAction->setChecked(false);
    infoAction->setChecked(false);
    phaseAction->setChecked(false);
    peakpAction->setChecked(false);
    tmsAction->setChecked(false);
  }
  emit integraltoggled(integralAction->isChecked()); */
}

void KryoNMR::OnPeakPicking()
{
#warning
 /*  if (peakpAction->isChecked())
  {
    zoomAction->setChecked(false);
    infoAction->setChecked(false);
    phaseAction->setChecked(false);
    integralAction->setChecked(false);
    tmsAction->setChecked(false);
  }
  emit peakpickingtoggled(peakpAction->isChecked()); */
}

void KryoNMR::OnTMS()
{
#warning reimplement
 /* if (tmsAction->isChecked())
  {
    zoomAction->setChecked(false);
    infoAction->setChecked(false);
    phaseAction->setChecked(false);
    integralAction->setChecked(false);
    peakpAction->setChecked(false);
  }
  emit tmstoggled(tmsAction->isChecked()); */
}
#endif


