/*
    This file is part of Kandy.

    Copyright (c) 2000,2001,2002 Cornelius Schumacher <schumacher@kde.org>

    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.

    This program 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 General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

    As a special exception, permission is given to link this program
    with any edition of TQt, and distribute the resulting executable,
    without including the source code for TQt in the source distribution.
*/

#include <tqlineedit.h>
#include <tqprinter.h>
#include <tqprintdialog.h>
#include <tqpainter.h>
#include <tqpaintdevicemetrics.h>

#include <tdeglobal.h>
#include <tdelocale.h>
#include <kiconloader.h>
#include <tdemenubar.h>
#include <kkeydialog.h>
#include <tdeaccel.h>
#include <tdeio/netaccess.h>
#include <tdefiledialog.h>
#include <tdeconfig.h>
#include <kurl.h>
#include <kurlrequesterdlg.h>
#include <kdebug.h>
#include <tdemessagebox.h>
#include <kstandarddirs.h>
#include <kedittoolbar.h>
#include <tdestdaccel.h>
#include <tdeaction.h>
#include <kstdaction.h>
#include <kurldrag.h>

#include "kandyprefsdialog.h"
#include "commandscheduler.h"
#include "kandyprefs.h"
#include "modem.h"

#include "kandy.h"
#include <kstatusbar.h>
#include "kandy.moc"

Kandy::Kandy(CommandScheduler *scheduler)
    : TDEMainWindow( 0, "Kandy" ),
      mPrinter(0)
{
  mScheduler = scheduler;

  mPreferencesDialog = 0;

  mView = new KandyView(mScheduler,this);

  // accept dnd
  setAcceptDrops(true);

  // tell the TDEMainWindow that this is indeed the main widget
  setCentralWidget(mView);

  // then, setup our actions
  setupActions();

  statusBar()->insertItem(i18n(" Disconnected "),0,0,true);

  setAutoSaveSettings();

  // allow the view to change the statusbar and caption
  connect(mView, TQ_SIGNAL(signalChangeStatusbar(const TQString&)),
          this,   TQ_SLOT(changeStatusbar(const TQString&)));
  connect(mView, TQ_SIGNAL(signalChangeCaption(const TQString&)),
          this,   TQ_SLOT(changeCaption(const TQString&)));

  connect(mView,TQ_SIGNAL(modifiedChanged(bool)),TQ_SLOT(setTitle()));

  TDEConfig *config = TDEGlobal::config();
  config->setGroup("General");
  TQString currentProfile = config->readEntry("CurrentProfile",
                                             locate("appdata","default.kandy"));
  if (!currentProfile.isEmpty()) load(currentProfile);
}

Kandy::~Kandy()
{
}

void Kandy::load(const TQString& filename)
{
  if (!mView->loadFile(filename)) {
    KMessageBox::error(this,i18n("Could not load file %1").arg(filename));
  }

  mFilename = filename;
  setTitle();
}

void Kandy::save(const TQString & filename)
{
  if (!filename.isEmpty()) {
    if (!mView->saveFile(filename)) {
      KMessageBox::error(this,i18n("Could not save file %1.").arg(filename));
    } else {
      mFilename = filename;
      setTitle();
    }
  }
}

void Kandy::setupActions()
{
  KStdAction::open(this, TQ_SLOT(fileOpen()), actionCollection());
  KStdAction::save(this, TQ_SLOT(fileSave()), actionCollection());
  KStdAction::saveAs(this, TQ_SLOT(fileSaveAs()), actionCollection());
//  KStdAction::print(this, TQ_SLOT(filePrint()), actionCollection());
  KStdAction::quit(this, TQ_SLOT(close()), actionCollection());

  createStandardStatusBarAction();
  setStandardToolBarMenuEnabled(true);
    
  KStdAction::keyBindings(this, TQ_SLOT(optionsConfigureKeys()), actionCollection());
  KStdAction::configureToolbars(this, TQ_SLOT(optionsConfigureToolbars()), actionCollection());
  KStdAction::preferences(this, TQ_SLOT(optionsPreferences()), actionCollection());

  new TDEAction(i18n("Mobile GUI"),0,this,TQ_SLOT(showMobileGui()),
              actionCollection(),"show_mobilegui");

  mConnectAction = new TDEAction(i18n("Connect"),0,this,TQ_SLOT(modemConnect()),
                               actionCollection(),"modem_connect");
  mDisconnectAction = new TDEAction(i18n("Disconnect"),0,this,
                                  TQ_SLOT(modemDisconnect()),actionCollection(),
                                  "modem_disconnect");

  createGUI();
}

void Kandy::saveProperties(TDEConfig */*config*/)
{
    // the 'config' object points to the session managed
    // config file.  anything you write here will be available
    // later when this app is restored
}

void Kandy::readProperties(TDEConfig */*config*/)
{
    // the 'config' object points to the session managed
    // config file.  this function is automatically called whenever
    // the app is being restored.  read in here whatever you wrote
    // in 'saveProperties'
}

void Kandy::dragEnterEvent(TQDragEnterEvent *event)
{
    // do nothing
    TDEMainWindow::dragEnterEvent(event);

    // accept uri drops only
//    event->accept(KURLDrag::canDecode(event));
}

void Kandy::dropEvent(TQDropEvent *event)
{
    // this is a very simplistic implementation of a drop event.  we
    // will only accept a dropped URL.  the TQt dnd code can do *much*
    // much more, so please read the docs there

    // do nothing
    TDEMainWindow::dropEvent(event);
/*
    KURL::List list;

    // see if we can decode a URI.. if not, just ignore it
    if (KURLDrag::decode(event, list) && !list.isEmpty())
    {
        // okay, we have a URI.. process it
        const KURL &url = uri.first();

        if (url.isLocalFile())
        {
           // load in the file
           load(url.path());
        }
    }
*/
}

void Kandy::fileOpen()
{
    // this slot is called whenever the File->Open menu is selected,
    // the Open shortcut is pressed (usually CTRL+O) or the Open toolbar
    // button is clicked
    TQString filename = KFileDialog::getOpenFileName();
    if (!filename.isEmpty()) load(filename);
}

void Kandy::fileSave()
{
  if (mFilename.isEmpty()) fileSaveAs();
  else save(mFilename);
}

void Kandy::fileSaveAs()
{
  TQString filename = KFileDialog::getSaveFileName();
  save(filename);
}

void Kandy::filePrint()
{
    // this slot is called whenever the File->Print menu is selected,
    // the Print shortcut is pressed (usually CTRL+P) or the Print toolbar
    // button is clicked
    if (!mPrinter) mPrinter = new TQPrinter;
    if (TQPrintDialog::getPrinterSetup(mPrinter))
    {
        // setup the printer.  with TQt, you always "print" to a
        // TQPainter.. whether the output medium is a pixmap, a screen,
        // or paper
        TQPainter p;
        p.begin(mPrinter);

        // we let our view do the actual printing
        TQPaintDeviceMetrics metrics(mPrinter);
        mView->print(&p, metrics.height(), metrics.width());

        // and send the result to the printer
        p.end();
    }
}

void Kandy::optionsConfigureKeys()
{
    KKeyDialog::configure( actionCollection(), this );
}

void Kandy::optionsConfigureToolbars()
{
    // use the standard toolbar editor
    saveMainWindowSettings( TDEGlobal::config(), autoSaveGroup() );
    KEditToolbar dlg(actionCollection());
    connect(&dlg, TQ_SIGNAL(newToolbarConfig()), this, TQ_SLOT(newToolbarConfig()));
    dlg.exec();
}

void Kandy::newToolbarConfig()
{
    // this slot is called when user clicks "Ok" or "Apply" in the toolbar editor.
    // recreate our GUI, and re-apply the settings (e.g. "text under icons", etc.)
    createGUI();
    applyMainWindowSettings( TDEGlobal::config(),  autoSaveGroup() );
}

void Kandy::optionsPreferences()
{
  if (!mPreferencesDialog) {
    mPreferencesDialog = new KandyPrefsDialog(this);
    mPreferencesDialog->readConfig();
  }

  mPreferencesDialog->show();
  mPreferencesDialog->raise();
}

void Kandy::changeStatusbar(const TQString& text)
{
    // display the text on the statusbar
    statusBar()->message(text);
}

void Kandy::changeCaption(const TQString& text)
{
    // display the text on the caption
    setCaption(text);
}

void Kandy::setTitle()
{
  if (mFilename.isEmpty()) {
    setCaption(i18n("New Profile"),mView->isModified());
  } else {
    setCaption(mFilename,mView->isModified());
  }
}

bool Kandy::queryClose()
{
  if (mView->isModified()) {
    switch (KMessageBox::warningYesNoCancel(this,
        i18n("Save changes to profile %1?").arg(mFilename), TQString(), KStdGuiItem::save(), KStdGuiItem::discard())) {
      case KMessageBox::Yes :
        fileSave();
        return true;
      case KMessageBox::No :
        return true;
      default: // cancel
        return false;
    }
  } else {
    return true;
  }
}

void Kandy::modemConnect()
{
  if (!mScheduler->modem()->open()) {
    KMessageBox::sorry(this,
        i18n("Cannot open modem device %1.")
        .arg(KandyPrefs::serialDevice()), i18n("Modem Error"));
    return;
  }

  statusBar()->changeItem(i18n(" Connected "),0);

  emit connectStateChanged(true);
}

void Kandy::modemDisconnect()
{
  mScheduler->modem()->close();

  statusBar()->changeItem(i18n(" Disconnected "),0);

  emit connectStateChanged(false);
}

void Kandy::showMobileGui()
{
  emit showMobileWin();
}

void Kandy::showErrorMessage( const TQString &text )
{
  KMessageBox::error( 0, text );
}
