//////////////////////////////////////////////////////////////
//      $Id: updateLoc.cpp,v 1.36.2.1 2002/12/13 15:20:22 toivo Exp $ 
//
// Author: Toivo Pedaste
//
#include "../config.h"

#include "kpackage.h"
#include "updateLoc.h"
#include "pkgInterface.h"
#include "options.h"
#include "cache.h"

#include <qvbox.h>

#include <klocale.h>
#include <kmessagebox.h>
#include <kcombobox.h>

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
dpanel::dpanel(updateLoc *upd,  QString Pfilter, QWidget *parent,
              bool buse, const char * name, bool bsubdirs ) 
   : QWidget( parent, name )   
{
  filter = Pfilter;
  puse = 0;
  psubdirs = 0;

  if (buse && upd->haveBase) {
    base = upd->base;
  } else {
    base = 0;
  }
    
  pack = new QHBoxLayout(this);
  {
    if (buse) {
      puse = new QCheckBox(i18n("Use"),this);
      pack->addWidget(puse,0);
    }

    pent = new QLineEdit(this);
    pent->setMinimumWidth(280);
    pack->addWidget(pent,0);

    if (bsubdirs) {
      psubdirs = new QCheckBox(i18n("Subdirectories"),this);
      psubdirs->setFixedSize(psubdirs->sizeHint());
      pack->addWidget(psubdirs,0);
    }

    pbut = new QPushButton("...",this);
    pack->addWidget(pbut,0);

    if (upd->haveBase && buse)
      connect(pbut, SIGNAL(clicked()), this, SLOT(fileOpen()));
    else
      connect(pbut, SIGNAL(clicked()), this, SLOT(dirOpen()));

  }
}

dpanel::~dpanel()
{
  //  if (psubdirs)
  //    delete psubdirs;
  //  if (puse)
  //    delete puse;
  //  delete pent;
  //  delete pack;
  //  delete pbut;
}

QString dpanel::getText()
{
  QString s = pent->text();
  return s;
}

void dpanel::setText(QString s)
{
 pent->setText(s);
}

bool dpanel::getUse()
{
  if (puse)
    return puse->isChecked();
  else
    return FALSE;
}

void dpanel::setUse(int n)
{
  if (puse) {
    if (n)
      puse->setChecked(TRUE);
    else
      puse->setChecked(FALSE);
  }
}

bool dpanel::getSubdirs()
{
  if (psubdirs)
    return psubdirs->isChecked();
  else
    return FALSE;
}

void dpanel::setSubdirs(int n)
{
  if (psubdirs)
  {
    if (n)
      psubdirs->setChecked(TRUE);
    else
      psubdirs->setChecked(FALSE);
  }
}

void dpanel::fileOpen()
{
  QString st;

  if (base && getText().isEmpty()) {
    st = base->getText();
  } else {
    st = getText();
  }
  if (st.right(8) == "Packages") {
    st.truncate(st.length() - 8);
  }

  KURL url =  KFileDialog::getOpenURL
    (st, filter, 0, i18n("Package File"));
  
  if( url.isEmpty() )
    return;
    
  pent->setText( url.url() );
}

void dpanel::dirOpen()
{
  QString st;

  if (base && getText().isEmpty()) {
    st = base->getText();
  } else {
    st = getText();
  }

  QString dir =  KFileDialog::getExistingDirectory
    (st, 0, i18n("Package Archive"));
  
  if (dir.isEmpty())
    return;

  KURL url;
  url.setPath(dir);

  if( url.isEmpty() )
    return;
    
  pent->setText( url.url() );

}

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
updateLoc::updateLoc(QWidget *p, int panelNumber, int numberLines,
		     pkgInterface *inter, QString options,
		     QString iname, QString filter, QString lmsg, QString bmsg,
		     bool subdirs )
    : QWidget(p,"updateLoc",FALSE)
{
  interName = iname;
  interface = inter;
  panNumber = panelNumber;
  haveBase = !bmsg.isNull();
  if (numberLines > PNUM)
    numLines = PNUM;
  else
    numLines = numberLines;

  combo[0] = 0;
  dp[0] = 0;

  QString pn;
  pn.setNum(panNumber);
  pn += "_";

  packL = "Package_L_";
  packL += pn;
  packC = "Package_C_";
  packC += pn;
  packU = "Package_U_";
  packU += pn;
  packS = "Package_S_";
  packS += pn;
  availB = "Available_Base";
  availB += pn;

  vf = new QVBoxLayout( this, 15, 10, "vf");

  if (haveBase) {
    fbase = new QGroupBox(bmsg, this);
    vbase = new QVBoxLayout(fbase, 15, 10, "vbase");
    vf->addWidget(fbase,1);
    base = new dpanel(this, filter,  fbase, FALSE, NULL, subdirs);
    vbase->addWidget(base,0);
    vbase->activate();
  }

  if (!options.isEmpty()) {

    QStringList kc = QStringList::split('\n',lmsg);
    QStringList::Iterator kcIt = kc.begin();

    QStringList oc = QStringList::split('\n',options);
    QStringList::Iterator ocIt = oc.begin();

    for (int i = 0; i < numLines; i++) {
      QGroupBox *floc = new QGroupBox(*kcIt, this);
      vf->addWidget(floc,1);
      QVBoxLayout *vloc = new QVBoxLayout(floc, 15, 10, "vloc");

      combo[i] = new KComboBox( true, floc);
      KCompletion *comp = combo[i]->completionObject();
      connect(combo[i],SIGNAL(returnPressed(const QString&))
		    ,comp,SLOT(addItem(const QString&)));
      combo[i]->insertStringList(QStringList::split(' ',*ocIt));
      vloc->addWidget(combo[i]);
      if (kcIt != kc.end()) {
        ++kcIt;
      }
      if (ocIt != oc.end()) {
        ++ocIt;
      }
    }
  } else {
    QGroupBox *floc = new QGroupBox(lmsg, this);
    vf->addWidget(floc,1);
    QVBoxLayout *vloc = new QVBoxLayout(floc, 15, 10, "vloc");

    for (int i = 0; i < numLines; i++) {
      dp[i] = new dpanel(this, filter,  floc, TRUE, NULL, subdirs);
      vloc->addWidget(dp[i],0);
    }
  }
  readSettings();
}

updateLoc::~updateLoc()
{
  //  for (int i = 0; i < numLines && dp[i]; i++) {
  //    delete dp[i];
  //  }
  //  for (int i = 0; i < numLines && combo[i]; i++) {
  //    delete combo[i];
  //  }
}

void updateLoc::applyS(LcacheObj *slist) 
{
  QString t,pn,cn,pv,prev,opts;
  cacheObj *CObj;
  KConfig *config = kapp->config();
  config->setGroup(interName);

  cn = interface->head;
  cn += "_";
  cn += pn.setNum(panNumber);
  cn += "_";

  if (combo[0]) {
    if (!base->getText().isEmpty()) {
      for (int i = 0; i < numLines; i++) {
	opts +=  combo[i]->currentText();
	opts += "\n";
      }
      CObj = new cacheObj(base->getText(),
			  "", cn + ":", opts);
      slist->append(CObj);
    }
  } else {
    for (int i = 0; i < numLines; i++) {
      // delete chached dir if text changed
      pv = packL + pn.setNum(i); 
      prev = config->readEntry(pv,"");
      if (prev != dp[i]->getText())
	cacheObj::rmDCache(QString(cn + pn.setNum(i)));

      // create cache object corresponding to this entry
      if (dp[i]->getUse()) {
	t = dp[i]->getText();
	if (!t.isEmpty()) {
	  //	  if (t.left(5) == "file:") {
	  //	    t.remove(0,5);
	  //	  } 
	  CObj = new cacheObj(haveBase ? base->getText() : QString::null,
			      t, cn + pn.setNum(i), "", dp[i]->getSubdirs());
	  slist->append(CObj);
	  //	printf("T=%s\n",t.data());
	}
      } 
    }
  }
  writeSettings();
}

void updateLoc::readSettings()
{
  QString pv, pn;
  
  KConfig *config = kapp->config();

  config->setGroup(interName);

  if (haveBase)
    base->setText(config->readEntry(availB));

  for (int i = 0; i < numLines; i++) {
    if (!dp[i])
      break;
    pv = packL + pn.setNum(i);
    dp[i]->setText(config->readEntry(pv,""));
    pv = packU + pn.setNum(i);
    dp[i]->setUse(config->readNumEntry(pv));
    pv = packS + pn.setNum(i);
    dp[i]->setSubdirs(config->readNumEntry(pv));
  }

  for (int i = 0; i < numLines; i++) {
    if (!combo[i])
      break;
    pv = packC + pn.setNum(i);
    if (!config->readEntry(pv,"").isEmpty()) {
      combo[i]->insertItem(config->readEntry(pv,""), 0);
    }
  }

  wdth = config->readNumEntry("Width",500);
}

void updateLoc::writeSettings()
{
  QString pv, pn;

  KConfig *config = kapp->config();

  config->setGroup(interName);
  if (haveBase) {
    //    if (!base->getText().isEmpty())
      config->writeEntry(availB,base->getText());
  }

  for (int i = 0; i < numLines; i++) {
    if (!dp[i])
      break;
    pv = packL + pn.setNum(i);
    config->writeEntry(pv,dp[i]->getText());
    pv = packU + pn.setNum(i);
    config->writeEntry(pv,(int)dp[i]->getUse());
    pv = packS + pn.setNum(i);
    config->writeEntry(pv,(int)dp[i]->getSubdirs());
  }

  for (int i = 0; i < numLines; i++) {
    if (!combo[i])
      break;
    pv = packC + pn.setNum(i);
    config->writeEntry(pv,combo[i]->currentText());
  }


  config->writeEntry("Width",width());
}

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
Locations::Locations(QString msg)
    : KDialogBase(Tabbed, msg, Ok | Apply | Cancel, Ok, 0, "updateLoc", false)
{
  QString nm, mp;

  numPanels = 0;

  connect( this, SIGNAL(applyClicked()), SLOT(apply_slot()) );
  connect( this, SIGNAL(okClicked()), SLOT(apply_slot()) );
}

void Locations::dLocations(int numberDirs,  int numberLines,
		     pkgInterface *inter, QString label,
		     QString iname, QString filter, QString dirMsg,
		     bool subdirs)
{
  QString nm;

  for (int i = numPanels ; (i <  numPanels + numberDirs) && (i < PANNUM); i++) {

    QString mp = label;
    nm.setNum(i+1);
    mp += nm;
    QVBox *page = addVBoxPage(mp);
    pn[i] = new updateLoc(page,i,numberLines,inter, "", iname,
			  filter, dirMsg, NULL, subdirs);
  }
  numPanels += numberDirs;
}

void Locations::pLocations(int numberDirs,  int numberLines,
		     pkgInterface *inter, QString label, QString iname,
		     QString filter, 
		     QString packMsg, QString baseMsg, bool subdirs)
{
  QString nm;

  for (int i = numPanels; (i < numPanels + numberDirs) && (i < PANNUM); i++) {
    QString mp = label;
    nm.setNum(i+1);
    mp += nm;
    QVBox *page = addVBoxPage(mp);
    pn[i] = new updateLoc(page,i,numberLines,inter, "", iname,
		      filter, packMsg, baseMsg, subdirs);
  }
  numPanels += numberDirs;
}

void Locations::cLocations(int numberDirs,   int numberLines,
		     pkgInterface *inter, QString label, QString iname,
		     QString filter, 
		     QString packMsg, QString baseMsg, QString options)
{
  QString nm;

  for (int i = numPanels; (i < numPanels + numberDirs) && (i < PANNUM); i++) {
    QString mp = label;
    nm.setNum(i+1);
    mp += nm;
    QVBox *page = addVBoxPage(mp);
    pn[i] = new updateLoc(page,i, numberLines ,inter, options, iname,
		      filter, packMsg, baseMsg);
  }
  numPanels += numberDirs;
}

Locations::~Locations() {
  //  for (int i = 0; (i < numPanels) && (i < PANNUM) && pn[i]; i++) {
  //    delete pn[i];
  //  }
}

void Locations::restore() 
{
  show();
}

void Locations::apply_slot() 
{
   LcacheObj *slist = new LcacheObj();

  for (int i = 0; (i <  numPanels) && (i < PANNUM); i++) {
    pn[i]->applyS(slist);
  }
  emit returnVal(slist);
}

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
#include "updateLoc.moc"
