//
// C++ Implementation: setupdialogprg
//
// Description: 
//
//
// Author: KoolDock team <radix@kde.cl>, (C) 2004
//
// Copyright: See COPYING file that comes with this distribution
//
//
#include <tdefiledialog.h>
#include <kimageio.h>
#include <kicondialog.h>
#include <tdelocale.h>
#include <tdesimpleconfig.h>
#include <tdemessagebox.h>
#include <tdestandarddirs.h>
#include <kpushbutton.h>
#include <keditlistbox.h>
#include <klineedit.h>
#include <tqlistbox.h>
#include <krun.h>

#include <tqiconview.h>
#include <tqdir.h>
#include <tqstringlist.h>
#include <tqtabwidget.h>

#include "setupdialog.h"
#include "setupdialogprg.h"
#include "apppropprg.h"
#include "appProp.h"
#include "kooldock.h"

SetupDialogPrg::SetupDialogPrg(TQWidget* parent, const char* name)
  : SetupDialog(parent, name)
{
  //Ignore list handlers
  grabbing = 0;
  gwm = new TWinModule();
  connect(gwm, TQ_SIGNAL(activeWindowChanged(WId)), TQ_SLOT(activeWindowChanged(WId)));
  gwm->blockSignals(true);
  in = ignoreBox->lineEdit();
  // Remove useless buttons from widget
  up = ignoreBox->upButton();
  down = ignoreBox->downButton();
  up->hide();
  down->hide();
  //End ignore list handlers

  // some configuration variables
  progPath = locateLocal("data", "kooldock");
  menuPath = progPath + TQString("/menu/");
		
  TDEConfig* config = TDEGlobal::config();
  config->setGroup("kooldock");
	
  appdlg = new appPropPrg();
  appdlg->user->setEnabled(false);
  appdlg->cuser->setChecked(false);
  appdlg->terminal->setChecked(false);
  appdlg->tclose->setChecked(false);
  appdlg->tclose->setEnabled(false);
  connect(appdlg, TQ_SIGNAL(apply()), TQ_SLOT(appRestart()));
   
  // Load the theme List
  TDEStandardDirs sys;
  TQStringList bgPath = sys.findDirs("data", "kooldock/backgrounds");
  for (unsigned int i = 0; i < bgPath.count(); i++) {
    TQDir tmpdir(bgPath[i]);
    TQStringList theme_tmp(tmpdir.entryList(TQDir::Dirs, TQDir::Name));
    // Avoid showing "." and ".." instead of copying TQDir::entryList directly into "theme"
    for (unsigned int j = 2; j < theme_tmp.count(); j++) {
      theme->insertItem(theme_tmp[j]);
    }
  }
}

void SetupDialogPrg::appRestart()
{
  if (!appdlg) {
    return;
  }
  iconsChanged();
  kdDebug(0) << "Refresh applist" << endl;
  appClear();
  appFill();
}

SetupDialogPrg::~SetupDialogPrg()
{
  if (appdlg) {
    delete appdlg;
  }
  if (in) {
    delete in;
  }
  kdDebug(0) << "Destroying..." << endl;
}

// Setup dialog implementation
void SetupDialogPrg::iconsChanged()
{
  toReloadIcons->setChecked(true);
}

void SetupDialogPrg::configOK()
{
  this->hide();
  configApply();
}

void SetupDialogPrg::configApply()
{
  int fhideTimer   = 5;
  int fPriority    = 0;
  int fpercentPos  = 0;
  int fOrientation = 0;
  
  // Stop grabbing window
  gwm->blockSignals(true);
  grabbing = 0;
  grabWin->setText(i18n("Grab Window"));
   
  int fShowTaskbar      = (chk5->isChecked() == true) ? 1 : 0;
  int fMinimizedOnly    = (cbMinimizedOnly->isChecked() == true) ? 1 : 0;
  int fShowNotification = (chk6->isChecked() == true) ? 1 : 0;
  int fShowBorders      = (chk4->isChecked() == true) ? 1 : 0;
  int fShowKMenu        = (chk7->isChecked() == true) ? 1 : 0;
  int fUseKBFX          = (chkUseKBFX->isChecked() == true) ? 1 : 0;
  int fHidden           = (chk1->isChecked() == true) ? 1 : 0;
  fhideTimer            = hideTimer->value();
  int showNames         = (chk2->isChecked() == true) ? 1 : 0;
  int fCleaner          = (cbCleaner->isChecked() == true) ? 1 : 0;
  int fHideOnClick      = (hideOnClick->isChecked() == true) ? 1 : 0;
  int fStayBelow        = (cbStayBelow->isChecked() == true) ? 1 : 0;
  int fSteppy           = (Steppy->isChecked() == true) ? 1 : 0;
  int xinerama          = (xrma->isChecked() == true) ? 1 : 0;
  int fShowNav          = (nav->isChecked() == true) ? 1 : 0;
  int fSystray          = (systray->isChecked() == true) ? 1 : 0;
  int fCurrent          = (currentDesk->isChecked() == true) ? 1 : 0;
  int fClipping         = (chClipping->isChecked() == true) ? 1 : 0;
  int fClipIcons        = (chClipIcons->isChecked() == true) ? 1 : 0;
  int fSpeed            = (chkSpeed->isChecked() == true) ? 1 : 0;
  fPriority             = Priority->value();
  fpercentPos           = percentPos->value();
   
  kdDebug(0) << "Saving preferences..." << endl;
  TDEConfig *config = TDEGlobal::config();
  config->setGroup("kooldock");
  config->writeEntry("ShowTaskbar", fShowTaskbar);
  config->writeEntry("MinimizedOnly", fMinimizedOnly);
  config->writeEntry("ShowNotification", fShowNotification);
  config->writeEntry("BorderColor", kColorCombo3->color().name());
  config->writeEntry("SmallIconSize", iwSmall->value());
  config->writeEntry("BigIconSize", iwBig->value());
  config->writeEntry("BigIconAmount", fAmount->value());
  config->writeEntry("iSpace", sbSpace->value());
  config->writeEntry("BackgroundColor", kColorCombo2->color().name());
  config->writeEntry("SeparatorColor", kColorCombo4->color().name());
  config->writeEntry("ShowKMenu", fShowKMenu);
  config->writeEntry("KBFX", fUseKBFX);
  config->writeEntry("Hidden", fHidden);
  config->writeEntry("HideOnClick", fHideOnClick);
  config->writeEntry("StayBelow", fStayBelow);
  config->writeEntry("fSteppy", fSteppy);
  config->writeEntry("Xinerama", xinerama);
  config->writeEntry("nWideBg", nWideBg->isChecked());
  config->writeEntry("scaleMax", opScale2->isChecked());
  if(xinerama==1) {
    config->writeEntry("leftRes", SleftRes->value());
    config->writeEntry("XinDesiredHeight", SHeight->value());
    config->writeEntry("XinPreviousWidth", PWidth->value());
  }
  config->writeEntry("hideTimer", fhideTimer);
  config->writeEntry("Navigator", fShowNav);
  config->writeEntry("Systray", fSystray);
  config->writeEntry("currentDesktop", fCurrent);
   
  config->writeEntry("Priority", fPriority);
  config->writeEntry("Clipping", fClipping);
  config->writeEntry("ClipIconArea", fClipIcons);
  config->writeEntry("percentPos", fpercentPos);
  if (op1->isChecked()) {
    fOrientation = 1;
  }
  if (op2->isChecked()) {
    fOrientation = 2;
  }
  if (op3->isChecked()) {
    fOrientation = 3;
  }
  config->writeEntry("fOrientation", fOrientation);
  config->writeEntry("zoomSpeed", zoomSpeed->value());
  config->writeEntry("speedControl", fSpeed);

  // kosd config
  config->writeEntry("showNames", showNames);
  config->writeEntry("Cleaner", fCleaner);
  config->writeEntry("xosdFont", xosdFont->currentText());
  config->writeEntry("xosdColor", kColorCombo1->color().name());
  config->writeEntry("xosdShadowColor", kColorCombo_shadow->color().name());
  config->writeEntry("xosdShadowOffset", spinBox2->value());
  config->writeEntry("xosdSize", xosdSize->value());
  if (xosdBold->isChecked()) {
    config->writeEntry("xosdBold", 1);
  }
  else {
    config->writeEntry("xosdBold", 0);
  }
  if (xosdItalic->isChecked()) {
    config->writeEntry("xosdItalic", 1);
  }
  else {
    config->writeEntry("xosdItalic", 0);
  }

  config->writeEntry("ShowSShot", chkSshot->isChecked());
  config->writeEntry("iconGrouping", chkGrouping->isChecked());
   
  // Save background configurations
  if (chkImg->isChecked()) {
    // Find where is the selected theme
    TDEStandardDirs sys;
    TQString theme_dir = "kooldock/backgrounds/" + theme->currentText();
    TQStringList bgPath = sys.findDirs("data", theme_dir);
      
    // Set the images and write the config
    TQString LeftImg = (TQString)bgPath[0] + "background-left.png";
    TQString CenterImg = (TQString)bgPath[0] + "background-center.png";
    TQString RightImg = (TQString)bgPath[0] + "background-right.png";
      
    // Background image enabled
    config->writeEntry("Solid", 0);
    config->writeEntry("Theme", theme->currentText());
    config->writeEntry("LeftImg", LeftImg);
    config->writeEntry("RightImg", RightImg);
    config->writeEntry("CenterImg", CenterImg);
    config->writeEntry("ShowBorders", 0);
    config->writeEntry("DockOpacity", 0);
  }
  else {
   // Background image disabled
    config->writeEntry("Solid", 1);
    config->writeEntry("Theme", "");
    config->writeEntry("LeftImg", "");
    config->writeEntry("RightImg", "");
    config->writeEntry("CenterImg", "");
    config->writeEntry("ShowBorders", fShowBorders);
    config->writeEntry("DockOpacity", spinBox1->value());
  }
	
  config->sync();

  // Write ignore list to file
  TQString progPath = locateLocal("data", "kooldock");
  TQString menuPath = progPath + TQString("/menu/");
  filepath = TQString(progPath + "/ignorelist.conf");
  if(ignoreBox->count() > 0) {
    TQFile out(filepath);
    if (out.open(IO_WriteOnly)) {
      TQTextStream out_s(&out);
      for(int i = 0; i < ignoreBox->count(); i++) {
        out_s << ignoreBox->text(i) << "\n";
      }
      out.close();
    }
  }
  else {
    TQFile::remove(filepath);
  }
  emit apply();
}

void SetupDialogPrg::configCancel()
{
  // Stop grabbing Windows
  gwm->blockSignals(true);
  grabWin->setText(i18n("Grab Window"));
  grabbing = 0;
  this->hide();
}

void SetupDialogPrg::closeEvent(TQCloseEvent* e)
{
  e->ignore();
  configCancel();
}

void SetupDialogPrg::chkFont()
{
  bool tmp; //just to save some code
   
  if(chk2->isChecked()) {
    tmp = true;
  }
  else {
    tmp = false;
  }
  xosdBold->setEnabled(tmp);
  xosdItalic->setEnabled(tmp);
  xosdSize->setEnabled(tmp);
  spinBox2->setEnabled(tmp);
  kColorCombo1->setEnabled(tmp);
  kColorCombo_shadow->setEnabled(tmp);
  xosdFont->setEnabled(tmp);
  cbCleaner->setEnabled(tmp);
}

void SetupDialogPrg::xrma_clicked()
{
  if (xrma->isChecked()==true) {
    SleftRes->setEnabled(true);
    SHeight->setEnabled(true);
    PWidth->setEnabled(true);
  }
  if (xrma->isChecked()==false) {
    SleftRes->setEnabled(false);
    SHeight->setEnabled(false);
    PWidth->setEnabled(false);
  }
}

void SetupDialogPrg::chkTask()
{
  iconsChanged();   
  bool tmp = chk5->isChecked();
  chk6->setEnabled(tmp);
  currentDesk->setEnabled(tmp);
  chkSshot->setEnabled(tmp);
  chkGrouping->setEnabled(tmp);
  cbMinimizedOnly->setEnabled(tmp);
}

void SetupDialogPrg::chkHidden()
{
  bool tmp = chk1->isChecked();
  hideTimer->setEnabled(tmp);
  hideOnClick->setEnabled(tmp);
  cbStayBelow->setEnabled(!tmp);
}

void SetupDialogPrg::applist_dropped(TQDropEvent* e,const TQValueList<TQIconDragItem>&)
{
  TDEIconLoader icon_obj;
  TQStringList lst;
  TQString name;
  int pos;
   
  TQUriDrag::decodeLocalFiles(e, lst);
  name = lst[0];

  // Check if it is a desktop file
  pos = name.findRev(".desktop", -1);
  if(pos != -1) {
    TDESimpleConfig* desktopfile;
    kdDebug(0) << "Desktop file dropped!" << endl;
    desktopfile = new TDESimpleConfig(lst[0], true);
    desktopfile->setGroup("Desktop Entry");
    appdlg->cmdname->setText(desktopfile->readEntry("Name"));
    appdlg->cmdpath->setText(desktopfile->readEntry("Exec"));
    appdlg->iconbutton->setIcon(desktopfile->readEntry("Icon"));
    delete desktopfile;
  }
  else {
    // It was not a dekstop file, so create a new entry
    // Set a default name based on the program name
    pos = name.findRev("/", -1);
    if (pos != -1) {
      name.remove(1, pos);
      name.remove("/", true);
    }
    // Create and show the appProp dialog
    appdlg->cmdname->setText(name);
    appdlg->cmdpath->setText(lst[0]);
      
    //Based on the program name, try to set an icon; if it does
    // not exists, the system will set the "default" icon
    appdlg->iconbutton->setIcon(name);
  }
  appdlg->show();
}

void SetupDialogPrg::removeLauncher()
{
  if (fileName != NULL) {
    TQString question = i18n("Do you want to remove ") + fileName + TQString("?");
    int remove = KMessageBox::questionYesNo(0, question, i18n("Remove Launcher"));
    if (remove != KMessageBox::Yes) {
      return;
    }
    TDESimpleConfig* desktopfile;
    TQDir homeDir = TQDir::home();
    if (homeDir.exists(progPath)) {
      TQDir dir(menuPath);
      TQStringList fileListRemove;
      fileListRemove = dir.entryList("*.desktop");
      for (TQStringList::Iterator it = fileListRemove.begin(); it != fileListRemove.end(); ++it) {
        if (((*it) != ".") && ((*it) != "..")) {
          desktopfile = new TDESimpleConfig(menuPath + (*it), true);
          desktopfile->setGroup("Desktop Entry");
          if (desktopfile->readEntry("Name") == fileName) {
            kdDebug(0) << "Removing " << menuPath + (*it) << endl;
            delete desktopfile;
            if (TQFile::remove(menuPath+(*it)) == true) {
              kdDebug(0) << "Item removed!" << endl;
              // Update the launchers index
              TQString preffix;
              fileListRemove.clear();
              fileListRemove=dir.entryList("*.desktop");
              TQStringList fileListRemove2=fileListRemove;

              for (unsigned int i = 0; i < fileListRemove2.count(); i++) {
                fileListRemove2[i].remove(0, 2);
              }
              // Rename the files so they reflect their new position
              for (unsigned int i = 0; i < fileListRemove.count(); i++) {
                if (i < 10) {
                  preffix = TQString("0%1").arg(i);
                }
                if (i >= 10) {
                  preffix = TQString("%1").arg(i);
                }
                dir.rename(fileListRemove[i], TQString("%1%2").arg(preffix).arg(fileListRemove2[i]));
              }
              // End updating
              appClear();
              appFill();
              iconsChanged();
            }
            else {
              kdDebug(0) << "Unable to remove file!" << endl;
            }
            return;
          }
          delete desktopfile;
        }
      }
    }
  }
}

void SetupDialogPrg::grabWin_clicked()
{
  if (grabbing == 0) {
    grabbing = 1;
    grabWin->setText(i18n("Grabbing..."));
    gwm->blockSignals(false);
  }
  else {
    grabbing = 0;
    grabWin->setText(i18n("Grab Window"));
    gwm->blockSignals(true);
  }
}

void SetupDialogPrg::activeWindowChanged(WId id)
{
  KWin::WindowInfo winfo = KWin::windowInfo(id);
  TQString ninfo = winfo.visibleName();

  if (ninfo != caption()) {
    in->setText(ninfo);
  }
}

void SetupDialogPrg::buttonadd_clicked()
{
  appdlg->cmdpath->setText("");
  appdlg->cmdname->setText("");
  appdlg->iconbutton->setIcon("unknown");
  appdlg->show();
}

void SetupDialogPrg::showEvent(TQShowEvent*)
{
  // Fill the applist
  appFill();
}

void SetupDialogPrg::appFill()
{
  // Fill the application list.
  TDESimpleConfig* desktopfile;
	
  TQDir homeDir = TQDir::home();
  TDEIconLoader icon_obj;
  TQPixmap pixm;
	
  if (homeDir.exists(progPath)) {
    TQDir dir(menuPath);
    fileList.clear();
    fileList = dir.entryList("*.desktop");
    for (TQStringList::Iterator it = fileList.begin(); it != fileList.end(); ++it ) {
      if (((*it) != ".") && ((*it) != "..")) {
        desktopfile = new TDESimpleConfig(menuPath + (*it), true);
        desktopfile->setGroup("Desktop Entry");
        TQPixmap pixm=icon_obj.loadIcon(desktopfile->readEntry("Icon"), TDEIcon::Desktop, 0, TDEIcon::DefaultState, 0L, false);
        new TDEIconViewItem(applist, desktopfile->readEntry("Name"), pixm);
        delete desktopfile;
      }
    }
  }
}

void SetupDialogPrg::hideEvent(TQHideEvent*)
{
  // the application list is erased here.
  appClear();
}

void SetupDialogPrg::appClear()
{
  applist->clear();
}

void SetupDialogPrg::left()
{
  if (oldPos > 0) {
    setnewpos(oldPos - 1);
    oldPos--;
    iconsChanged();
  }
}

void SetupDialogPrg::right()
{
  if ((oldPos != -1) && (oldPos < (int)fileList.count() - 1)) {
    setnewpos(oldPos + 1);
    oldPos++;
    iconsChanged();
  }
}

void SetupDialogPrg::applist_clicked(TQIconViewItem* e, const TQPoint&)
{
  if (e != NULL) {
    oldPos = e->index();
  }
  else {
    oldPos = -1;
  }
}

void SetupDialogPrg::applist_contextMenuRequested(TQIconViewItem* e,const TQPoint&)
{
  if (e != NULL) {
    TDEPopupMenu* popup = new TDEPopupMenu();
    TDEPopupMenu* setpos = new TDEPopupMenu();
 
    fileName = e->text();
    oldPos = e->index();
    connect(setpos, TQ_SIGNAL(activated(int)), this, TQ_SLOT(setnewpos(int)));
            
    // Load desktop data
    TDESimpleConfig* desktopfile;
    TQDir dir(menuPath);
    fileList.clear();
    fileList = dir.entryList("*.desktop");
    int i = 0;
    for (TQStringList::Iterator it = fileList.begin(); it != fileList.end(); ++it) {
      if (((*it) != ".") && ((*it) != "..")) {
        desktopfile = new TDESimpleConfig(menuPath + (*it), true);
        desktopfile->setGroup("Desktop Entry");
        int menustate = setpos->insertItem(TQString("%1").arg(desktopfile->readEntry("Name")),i);
        if (i == oldPos) {
          setpos->setItemEnabled(menustate, false);
          filepath = menuPath + (*it);
        }
        delete desktopfile;
        i++;
      }
    }
    // End Load
      
    popup->insertTitle(e->text());
    popup->insertItem(i18n("Swap with"), setpos);
    popup->insertItem(i18n("&Edit item"), this, TQ_SLOT(editItem()));
    popup->insertItem(i18n("Remove"), this, TQ_SLOT(removeLauncher()));
    popup->exec(TQCursor::pos());
    if (popup) {
      delete popup;
    }
    if (setpos) {
      delete setpos;
    }
  }
  else {
    oldPos = -1;
  }
}

void SetupDialogPrg::editItem()
{
  KRun::runCommand("kfmclient openProperties " + filepath, "kfmclient", "");
}

void SetupDialogPrg::setnewpos(int newpos)
{
  kdDebug(0) << "New pos " << TQString("0%1").arg(newpos) << "requested for: " << fileName<< endl;
  if (newpos == oldPos) {
    return; // Nothing to be done
  }
  computeNewPos(newpos);
}

void SetupDialogPrg::computeNewPos(int pos)
{
  TQString preffix, preffix2;
  TQDir dir(menuPath);
   
  fileList.clear();
  fileList = dir.entryList("*.desktop");
   
  // Remove the prefix of the files from fileList
  for (unsigned int i = 0; i < fileList.count(); i++) {
    fileList[i] = fileList[i].remove(0, 2);
  }
  // Prefix for old position
  preffix.sprintf("%02d", oldPos);
  // Prefix for new position
  preffix2.sprintf("%02d", pos);
  kdDebug(0) << "Old Position: " << oldPos << endl;
  kdDebug(0) << "New Position: " << pos << endl;
   
  dir.rename(TQString("%1%2").arg(preffix).arg(fileList[oldPos]), TQString("%1%2").arg(preffix2).arg(fileList[oldPos]));
  dir.rename(TQString("%1%2").arg(preffix2).arg(fileList[pos]), TQString("%1%2").arg(preffix).arg(fileList[pos]));
   
  appClear();
  appFill();
}

void SetupDialogPrg::chkImgSlot()
{
  chkSolid->setChecked(!chkImg->isChecked());
}

void SetupDialogPrg::chkSolidSlot()
{
  chkImg->setChecked(!chkSolid->isChecked());
}

#include "setupdialogprg.moc"
