//---------------------------------------------------------------------------
//
//             kPPP: A pppd front end for the KDE project
//
//---------------------------------------------------------------------------
//
// (c) 1997-1998 Bernd Johannes Wuebben <wuebben@kde.org>
// (c) 1997-1999 Mario Weilguni <mweilguni@kde.org>
// (c) 1998-1999 Harri Porten <porten@kde.org>
//
// derived from Jay Painters "ezppp"
//
//---------------------------------------------------------------------------
//
//  This program 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 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
//  Library General Public License for more details.
//
//  You should have received a copy of the GNU Library 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.
//
//---------------------------------------------------------------------------


#include <tqdir.h>
#include <tqlabel.h>
#include <tqlayout.h>
#include <tqregexp.h>
#include <tdelocale.h>
#include <kstandarddirs.h>
#include <kdebug.h>
#include "providerdb.h"
#include "newwidget.h"
#include "pppdata.h"
#include <tqlistbox.h>
#include <tqlineedit.h>
#include <ksimpleconfig.h>


#define UNENCODED_CHARS "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789_"

TQWizard* ProviderDB::wiz = 0L;

ProviderDB::ProviderDB(TQWidget *parent) :
  KWizard(parent, "", true),
  cfg(0)
{
  setCaption(i18n("Create New Account"));

  wiz = this;

  page1 = new PDB_Intro(this);
  addPage(page1, "");
  setHelpEnabled(page1, false);
  // TODO  p1->w->setFocusPolicy(StrongFocus);

  page2 = new PDB_Country(this);
  addPage(page2, "");
  setHelpEnabled(page2, false);

  page3 = new PDB_Provider(this);
  addPage(page3, "");
  setHelpEnabled(page3, false);

  page4 = new PDB_UserInfo(this);
  addPage(page4, "");
  setHelpEnabled(page4, false);

  page5 = new PDB_DialPrefix(this);
  addPage(page5, "");
  setHelpEnabled(page5, false);

  page9 = new PDB_Finished(this);
  addPage(page9, "");
  setHelpEnabled(page9, false);
  setFinish(page9, true);
  setFinishEnabled(page9, true);

  connect((const TQObject *)nextButton(), TQ_SIGNAL(clicked()),
  	  this, TQ_SLOT(pageSelected()));
  connect((const TQObject *)backButton(), TQ_SIGNAL(clicked()),
  	  this, TQ_SLOT(pageSelected()));

  //  resize(minimumSize());
  adjustSize();
}


ProviderDB::~ProviderDB() {
  delete cfg;
}


void ProviderDB::pageSelected() {
  bool prev = true;
  bool next = true;

  TQWidget *page = currentPage();
  if(page == page2) {
    next = page2->lb->currentItem() != -1;
  } else if(page == page3) {
    page3->setDir(*page2->list->at(page2->lb->currentItem()));
    next = page3->lb->currentItem() != -1;
  } else if(page == page4) {
    loadProviderInfo();
    next = !page4->username().isEmpty() &&
      !page4->password().isEmpty();
  }

  setBackEnabled(page, prev);
  setNextEnabled(page, next);
}


void ProviderDB::loadProviderInfo() {
  delete cfg;

  TQString loc = *page2->list->at(page2->lb->currentItem());
  TQString provider = page3->lb->text(page3->lb->currentItem());
  urlEncode(provider);
  TQString prov = "Provider/" + loc;
  prov += "/" + provider;
  TQString fname = locate("appdata", prov);
  kdDebug(5002) << "Providerfile=" << fname << endl;

  cfg = new KSimpleConfig(fname, true);
}


void ProviderDB::accept() {
  TQRegExp re_username("%USERNAME%");
  TQRegExp re_password("%PASSWORD%");

  TQMap <TQString, TQString> map(cfg->entryMap("<default>"));
  TQMap <TQString, TQString>::Iterator it(map.begin());
  while(it != map.end()) {
    TQString key = it.key();
    TQString value = *it;
    if(value.contains(re_username))
      value.replace(re_username, page4->username());

    if(value.contains(re_password))
      value.replace(re_password, page4->password());

    gpppdata.writeConfig(gpppdata.currentAccountGroup(), key, value);

    if(key == "Name")
      gpppdata.setAccname(value);
    ++it;
  }

  gpppdata.writeConfig(gpppdata.currentAccountGroup(), "DialPrefix", page5->prefix());
  done(Accepted);
}


/////////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////////
PDB_Intro::PDB_Intro(TQWidget *parent) : TQWidget(parent) {
  TQLabel *l = new TQLabel(i18n("You will be asked a few questions on information\n"
			    "which is needed to establish an Internet connection\n"
			    "with your Internet Service Provider (ISP).\n\n"
			    "Make sure you have the registration form from your\n"
			    "ISP handy. If you have any problems, try the online\n"
			    "help first. If any information is missing, contact\n"
			    "your ISP."),
		       this);
  TQVBoxLayout *tl = new TQVBoxLayout(this, 10, 10);
  tl->addWidget(l);
  tl->activate();
}


/////////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////////
PDB_Country::PDB_Country(TQWidget *parent) : TQWidget(parent) {
  TQLabel *l = new TQLabel(i18n("Select the location where you plan to use this\n"
			    "account from the list below. If your country or\n"
			    "location is not listed, you have to create the\n"
			    "account with the normal, dialog based setup.\n\n"
			    "If you click \"Cancel\", the dialog based setup\n"
			    "will start."),
		       this);
  TQVBoxLayout *tl = new TQVBoxLayout(this, 10, 10);
  tl->addWidget(l);

  TQHBoxLayout *l1 = new TQHBoxLayout;
  tl->addLayout(l1);
  l1->addStretch(1);

  lb = new TQListBox(this);
  connect(lb, TQ_SIGNAL(highlighted(int)),
	  this, TQ_SLOT(selectionChanged(int)));
  lb->setMinimumSize(220, 100);
  l1->addWidget(lb, 2);
  l1->addStretch(1);

  list = new TQStringList;

  // fill the listbox
  // set up filter
  TQDir d(TDEGlobal::dirs()->findDirs("appdata", "Provider").first());
  d.setFilter(TQDir::Dirs);
  d.setSorting(TQDir::Name);

  // read the list of files
  const TQFileInfoList *flist = d.entryInfoList();
  if(flist) {
    TQFileInfoListIterator it( *flist );
    TQFileInfo *fi;
    // traverse the flist and insert into a map for sorting
    TQMap<TQString, TQString> countries;
    for(; (fi = it.current()) != 0; ++it) {
      if(fi->fileName() != "." && fi->fileName() != "..") {
        TQString dirFile(fi->absFilePath()+"/.directory");
        TQString entryName;
        if(TQFile::exists(dirFile)){
          KSimpleConfig config(dirFile);
          config.setDesktopGroup();
          entryName = config.readEntry("Name");
        }
        if (entryName.isNull()) entryName = fi->fileName();
	countries.insert(entryName, fi->fileName());
      }
    }
    // insert sorted entries into list box and string list
    TQMap<TQString, TQString>::const_iterator mit = countries.begin();
    TQMap<TQString, TQString>::const_iterator mend = countries.end();
    while(mit != mend) {
        lb->insertItem(mit.key());
        list->append(*mit);
	++mit;
    }
  }

  tl->activate();
}

PDB_Country::~PDB_Country()
{
  delete list;
}

void PDB_Country::selectionChanged(int idx) {
  //  TQWizard *wizard = (TQWizard *)parent(); Why doesn't this work ?
  ProviderDB::wiz->setNextEnabled(this, (idx != -1));
}


/////////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////////
PDB_Provider::PDB_Provider(TQWidget *parent) : TQWidget(parent) {
  TQVBoxLayout *tl = new TQVBoxLayout(this, 10, 10);
  TQLabel *l = new TQLabel(i18n("Select your Internet Service Provider (ISP) from\n"
			    "the list below. If the ISP is not in this list,\n"
			    "you have to click on \"Cancel\" and create this\n"
			    "account using the normal, dialog-based setup.\n\n"
			    "Click on \"Next\" when you have finished your\n"
			    "selection."), this);
  tl->addWidget(l);

  TQHBoxLayout *l1 = new TQHBoxLayout;
  tl->addLayout(l1);
  l1->addStretch(1);

  lb = new TQListBox(this);
  connect(lb, TQ_SIGNAL(highlighted(int)),
	  this, TQ_SLOT(selectionChanged(int)));
  lb->setMinimumSize(220, 100);
  l1->addWidget(lb, 2);
  l1->addStretch(1);
}

void PDB_Provider::selectionChanged(int idx) {
  ProviderDB::wiz->setNextEnabled(this, idx != -1);
}


void PDB_Provider::setDir(const TQString &_dir) {
  if(dir != _dir) {
    lb->clear();

    // fill the listbox
    // set up filter
    dir = _dir;

    TQString dir1 = TDEGlobal::dirs()->findDirs("appdata", "Provider").first();
    TQRegExp re1(" ");
    dir = dir.replace(re1, "_");
    dir1 += dir;

    TQDir d(dir1);
    d.setFilter(TQDir::Files);
    d.setSorting(TQDir::Name);

    // read the list of files
    const TQFileInfoList *list = d.entryInfoList();
    TQFileInfoListIterator it( *list );
    TQFileInfo *fi;

    // traverse the list and insert into the widget
    TQRegExp re("_");
    while((fi = it.current()) != NULL) {
      TQString fname = fi->fileName();
      if(fname.length() && fname[0] != '.') {
	urlDecode(fname);
	lb->insertItem(fname);
      }
      ++it;
    }

    // TODO: TQt 1.x needs this if list is empty
    lb->update();
  }
}


TQString PDB_Provider::getDir() {
  return dir;
}



/////////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////////
PDB_UserInfo::PDB_UserInfo(TQWidget *parent) : TQWidget(parent) {
  TQVBoxLayout *tl = new TQVBoxLayout(this, 10, 10);
  TQLabel *l = new TQLabel(i18n("To log on to your ISP, kppp needs the username\n"
			    "and the password you got from your ISP. Type\n"
			    "in this information in the fields below.\n\n"
			    "Word case is important here."),
		       this);
  tl->addWidget(l);

  TQGridLayout *l1 = new TQGridLayout(2, 2);
  tl->addLayout(l1);
  l = new TQLabel(i18n("Username:"), this);
  l1->addWidget(l, 0, 0);
  l = new TQLabel(i18n("Password:"), this);
  l1->addWidget(l, 1, 0);
  _username = newLineEdit(24, this);
  connect(_username, TQ_SIGNAL(textChanged(const TQString &)),
	  this, TQ_SLOT(textChanged(const TQString &)));
  l1->addWidget(_username, 0, 1);
  _password = newLineEdit(24, this);
  _password->setEchoMode(TQLineEdit::Password);
  connect(_password, TQ_SIGNAL(textChanged(const TQString &)),
	  this, TQ_SLOT(textChanged(const TQString &)));
  l1->addWidget(_password, 1, 1);
  tl->activate();
}


void PDB_UserInfo::textChanged(const TQString &) {
  ProviderDB::wiz->setNextEnabled(this, !_password->text().isEmpty() &&
                      !_username->text().isEmpty());
}


TQString PDB_UserInfo::username() {
  TQString s = _username->text();
  return s;
}


TQString PDB_UserInfo::password() {
  TQString s = _password->text();
  return s;
}


void PDB_UserInfo::activate() {
  _username->setFocus();
}


/////////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////////
PDB_DialPrefix::PDB_DialPrefix(TQWidget *parent) : TQWidget(parent) {
  TQVBoxLayout *tl = new TQVBoxLayout(this, 10, 10);
  TQLabel *l = new TQLabel(i18n("If you need a special dial prefix (e.g. if you\n"
			    "are using a telephone switch) you can specify\n"
			    "it here. This prefix is dialed just before the\n"
			    "phone number.\n\n"
			    "If you have a telephone switch, you probably need\n"
			    "to write \"0\" or \"0,\" here."),
		       this);
  tl->addWidget(l);

  TQGridLayout *l1 = new TQGridLayout(1, 2);
  tl->addLayout(l1);
  l = new TQLabel(i18n("Dial prefix:"), this);
  l1->addWidget(l, 0, 0);
  _prefix = newLineEdit(24, this);
  l1->addWidget(_prefix, 0, 1);
  tl->activate();
}


TQString PDB_DialPrefix::prefix() {
  TQString s = _prefix->text();

  return s;
}


void PDB_DialPrefix::activate() {
  _prefix->setFocus();
}


/////////////////////////////////////////////////////////////////////////////
//
/////////////////////////////////////////////////////////////////////////////
PDB_Finished::PDB_Finished(TQWidget *parent) : TQWidget(parent) {
  TQVBoxLayout *tl = new TQVBoxLayout(this, 10, 10);
  TQLabel *l = new TQLabel(i18n("Finished!\n\n"
			    "A new account has been created. Click \"Finish\" to\n"
			    "go back to the setup dialog. If you want to\n"
			    "check the settings of the newly created account,\n"
			    "you can use \"Edit\" in the setup dialog."),
		       this);
  tl->addWidget(l);
  tl->addStretch(1);
}


void urlDecode(TQString &s) {
  TQString s1;

  for(uint i = 0; i < s.length(); i++) {
    if(s[i] == '%') {
      s1 += 100*s[i+1].digitValue() + 10*s[i+2].digitValue()
        + s[i+3].digitValue();
      i += 3;
    } else {
      s1 += s[i];
    }
  }

  s = s1;
}


void urlEncode(TQString &s) {
  TQString s1, tmp;

  for(uint i = 0; i < s.length(); i++) {
    if(TQString(UNENCODED_CHARS).find(s[i]) >= 0)
      s1 += s[i];
    else {
      tmp.sprintf("%%%03i", s[i].unicode());
      s1 += tmp;
    }
  }
  s = s1;
}


#include "providerdb.moc"

