/***************************************************************************
                          kbpickicondlg.cpp  -  description
                             -------------------
    begin                : Sat Jul 21 2001
    copyright            : (C) 2001 by Leonid Zeitlin
    email                : lz@europe.com
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   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 "kbpickicondlg.h"

#include <tqvbox.h>
#include <tqdir.h>
#include <tqwhatsthis.h>
#include <tqpushbutton.h>
#include <tqimage.h>

#include <tdeversion.h>
#include <tdelocale.h>
#include <tdestandarddirs.h>
#include <tdeglobal.h>
#include <tdefiledialog.h>
#include <tdemessagebox.h>

#include "kbconfig.h"
#include "pathlistboxitem.h"

KBPickIconDlg::KBPickIconDlg(const TQString &currentPath, const TQPixmap &currentPixmap,
  TQWidget *parent, const char *name )
  : KDialogBase(parent, name, true /*modal*/, i18n("Pick an icon") /*caption*/, Ok | Cancel) {
  TQVBox *page = makeVBoxMainWidget();
  
  lbIcons = new TDEListBox(page);
  TQObject::connect(lbIcons, TQ_SIGNAL(doubleClicked(TQListBoxItem*)),
    this, TQ_SLOT(slotOk()));
  TQObject::connect(lbIcons, TQ_SIGNAL(returnPressed(TQListBoxItem*)),
    this, TQ_SLOT(slotOk()));
  TQWhatsThis::add(lbIcons, i18n("Select one of the icons"));  

  TQPushButton *btnBrowse = new TQPushButton(i18n("&Browse..."), page);
  TQObject::connect(btnBrowse, TQ_SIGNAL(clicked()), this, TQ_SLOT(slotBrowseForIcon()));
  TQWhatsThis::add(btnBrowse, i18n("Browse for an image file to use as an icon"));
  
  loadCountryFlags();
      
	// I am told in Red Hat 9 standard KDE flag pixmaps are missing.
  // Workaround: we have to simulate them by rescaling GKB's pixmaps
  if (lbIcons->count() == 0) {
		loadGkbCountryFlags();
	}
	lbIcons->sort();
	showCurrentPath(currentPath, currentPixmap);
  lbIcons->setFocus();
}

KBPickIconDlg::~KBPickIconDlg(){
}

/** Get the path name of the selected icon. Returns empty string if no icon selected */
TQString KBPickIconDlg::getIconPath(){
  TQListBoxItem *item = lbIcons->selectedItem();
	if (item) 
		return dynamic_cast<PathListBoxItem*>(item)->path;
	else return TQString::null; // should not happen
}

/** No descriptions */
const TQPixmap* KBPickIconDlg::getIcon(){
  if (lbIcons->currentItem() != -1)
    return lbIcons->pixmap(lbIcons->currentItem());
  else return NULL;
}

/** Browse for an arbitrary icon file */
void KBPickIconDlg::slotBrowseForIcon()
{
	TQString iconPath = KFileDialog::getOpenFileName(TQString::null,
	  i18n("*.png *.jpg *.gif *.xpm|Icon files (*.png, *.jpg, *.gif, *.xpm)\n*.*|All files (*.*)"));
	if (iconPath.isEmpty()) return;  
  TQImage img;
  if (img.load(iconPath)) {
		double aspectRatio = img.width() / img.height();
		TQString message = TQString::null;
		bool too_big, too_wide, too_narrow;
		too_narrow = aspectRatio < FLAG_ICON_WIDTH / FLAG_ICON_HEIGHT - 0.1;
		too_wide = aspectRatio > FLAG_ICON_WIDTH / FLAG_ICON_HEIGHT + 0.1;
		too_big = img.width() > FLAG_ICON_WIDTH * 2;
		if (too_big || too_narrow || too_wide) {
  		message = i18n("The size of this image (%1 by %2) is not good.\n"
	  	  "Preferred size for the layout icons is %3 by %4.\n")
		    .arg(img.width()).arg(img.height()).arg(FLAG_ICON_WIDTH).arg(FLAG_ICON_HEIGHT);
      if (too_big) {
        TQString msg_tail = "";
        if (too_wide) msg_tail = i18n(" and also too wide");
				else if (too_narrow) msg_tail += i18n(" and also too narrow");
				message += i18n("This image is too big%1.").arg(msg_tail);
			}
			else if (too_wide) message += i18n("This image is too wide.");
			else if (too_narrow) message += i18n("This image is too narrow.");
  		message += "\n";
      message += i18n("KKBSwitch will scale it to appropriate size, but the result may not look very good.\n"
        "Are you sure you want to use this image?");
      if (KMessageBox::questionYesNo(this, message)	!= KMessageBox::Yes) return;
		}    	  
		if (img.width() > FLAG_ICON_WIDTH + 3 || img.height() > FLAG_ICON_HEIGHT + 3)
		  img = img.smoothScale(FLAG_ICON_WIDTH, FLAG_ICON_HEIGHT);
		TQPixmap pix;
		pix.convertFromImage(img);
    PathListBoxItem *item = new PathListBoxItem(lbIcons, pix, TQFileInfo(iconPath).fileName(), 
      iconPath);
    lbIcons->setSelected(item, true);
    lbIcons->centerCurrentItem();
  }
  else KMessageBox::error(this, i18n("Cannot read icon from file %1. "
    "Either it is not an image file or it is corrupt.").arg(iconPath));
}

void KBPickIconDlg::loadCountryFlags()
{
  TQPixmap pix;
  TQDir dir;
  TQStringList locales;
  TQString path;
  TQStringList dirs = TDEGlobal::dirs()->findDirs("locale", "l10n");
  
  for (TQStringList::Iterator dirIter = dirs.begin(); dirIter != dirs.end(); dirIter++) {
    dir.setPath(*dirIter);
    locales = dir.entryList(TQDir::Dirs, TQDir::Name);
    for (TQStringList::Iterator iter = locales.begin(); iter != locales.end(); iter++) {
      path = dir.path() + "/" + *iter + "/flag.png";
      if (*iter != "." && *iter != ".." && pix.load(path)) {
				TDEConfig config(dir.path() + "/" + *iter + "/entry.desktop", true, false,
				  "locale" /*doesn't really matter*/);
        config.setGroup("KCM Locale");
        new PathListBoxItem(lbIcons, pix, config.readEntry("Name"), path);
      }
    }
  }
}
	
void KBPickIconDlg::loadGkbCountryFlags()
{
  TQDir dir;
  TQString path, code, name;
  TQPixmap pix;
  TQImage img;
	
  dir.setPath("/usr/share/pixmaps/gkb");
  const TQFileInfoList *icons = dir.entryInfoList(TQDir::Files, TQDir::Name);
  if (icons) {
		TQFileInfoListIterator iter(*icons);
		TQFileInfo *info;
    for (; (info = iter.current()); ++iter) {
      path = info->filePath();
      code = info->baseName();
      if (img.load(path)) {
				TDEConfig config("l10n/" + code + "/entry.desktop", true, false, "locale");
				config.setGroup("KCM Locale");
				name = config.readEntry("Name");
				if (!name.isNull()) {
					pix.convertFromImage(img.smoothScale(FLAG_ICON_WIDTH, FLAG_ICON_HEIGHT));
          new PathListBoxItem(lbIcons, pix, name, path);
        }
      }
    }
  }
}

void KBPickIconDlg::showCurrentPath(const TQString &currentPath,
  const TQPixmap &currentPixmap)
{
	PathListBoxItem *item = NULL;
  bool itemFound = false;
  for (unsigned i = 0; i < lbIcons->count(); i++) {
		item = dynamic_cast<PathListBoxItem*>(lbIcons->item(i));
		if (item->path == currentPath) {
      itemFound = true;
      break;
    }  
	}
  // why this strange manipulation of HScrollBarMode?
  // Strangely, without it, if the selected item is the last in the listbox, it ends up
  // being obscured by the horizontal scrollbar
  lbIcons->setHScrollBarMode(TQScrollView::AlwaysOn);
  if (!itemFound) item = new PathListBoxItem(lbIcons, currentPixmap, 
    TQFileInfo(currentPath).fileName(), currentPath);
  lbIcons->updateScrollBars();  
  lbIcons->setSelected(item, true);
	lbIcons->ensureCurrentVisible();
  lbIcons->setHScrollBarMode(TQScrollView::Auto);  
}

#include "kbpickicondlg.moc"
