/***************************************************************************
 *   Copyright (C) 2006-2007 Nicolas Hadacek <hadacek@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.                                   *
 ***************************************************************************/
#ifndef KEY_GUI_H
#define KEY_GUI_H

#include <tqcombobox.h>
#include <tqwidgetstack.h>
#include <tqpopupmenu.h>

#include "common/gui/misc_gui.h"
#include "common/common/misc.h"

//-----------------------------------------------------------------------------
template <typename KeyType, typename Type, typename WidgetType>
class KeyWidget
{
public:
  typedef TQMapConstIterator<KeyType, int> ConstIterator;

public:
  KeyWidget(TQWidget *parent) { _widget = new WidgetType(parent); }
  virtual ~KeyWidget() { delete _widget; }
  virtual WidgetType *widget() { return _widget; }
  virtual void clear() { _ids.clear(); }
  ConstIterator begin() const { return _ids.begin(); }
  ConstIterator end() const { return _ids.end(); }
  uint count() const { return _ids.count(); }
  void appendItem(const KeyType &key, Type type) {
    CRASH_ASSERT( !_ids.contains(key) );
    _ids[key] = append(type);
  }
  KeyType currentItem() const { return key(currentId()); }
  void setCurrentItem(const KeyType &key) {
    if ( _ids.contains(key) ) setCurrentId(_ids[key]);
  }
  bool contains(const KeyType &key) const { return _ids.contains(key); }
  Type item(const KeyType &key) const {
    CRASH_ASSERT( _ids.contains(key) );
    return get(_ids[key]);
  }
  Type item(ConstIterator it) const {
    CRASH_ASSERT( it!=end() );
    return get(it.data());
  }
  KeyType key(int id) const {
    for (ConstIterator it=begin(); it!=end(); it++)
      if ( it.data()==id ) return it.key();
    return KeyType();
  }

protected:
  virtual int append(Type type) = 0;
  virtual int currentId() const = 0;
  virtual void setCurrentId(int id) = 0;
  virtual Type get(int id) const = 0;

  TQWidget *_parent;
  TQMap<KeyType, int> _ids;
  WidgetType *_widget;
};

//-----------------------------------------------------------------------------
template <typename KeyType>
class KeyComboBox : public KeyWidget<KeyType, TQString, TQComboBox>
{
public:
  typedef KeyWidget<KeyType, TQString, TQComboBox> ParentType;
  KeyComboBox(TQWidget *parent = 0) : ParentType(parent) {}
  virtual void clear() {
    ParentType::clear();
    ParentType::_widget->clear();
  }
  void fixMinimumWidth() {
    ParentType::_widget->setMinimumWidth(ParentType::_widget->sizeHint().width());
  }

protected:
  virtual int append(TQString label) { ParentType::_widget->insertItem(label); return ParentType::_widget->count()-1; }
  virtual int currentId() const { return ParentType::_widget->currentItem(); }
  virtual void setCurrentId(int id) { ParentType::_widget->setCurrentItem(id); }
  virtual TQString get(int id) const { return ParentType::_widget->text(id); }
};

//-----------------------------------------------------------------------------
template <typename KeyType>
class KeyWidgetStack : public KeyWidget<KeyType, TQWidget *, TQWidgetStack>
{
public:
  typedef KeyWidget<KeyType, TQWidget *, TQWidgetStack> ParentType;
  KeyWidgetStack(TQWidget *parent = 0) : ParentType(parent) {}

protected:
  virtual int append(TQWidget *widget) { return ParentType::_widget->addWidget(widget); }
  virtual int currentId() const { return ParentType::_widget->id(ParentType::_widget->visibleWidget()); }
  virtual void setCurrentId(int id) { ParentType::_widget->raiseWidget(id); }
  virtual TQWidget *get(int id) const { return ParentType::_widget->widget(id); }
};

//-----------------------------------------------------------------------------
template <typename KeyType>
class KeyPopupButton : public KeyWidget<KeyType, TQString, PopupButton>
{
public:
  typedef KeyWidget<KeyType, TQString, PopupButton> ParentType;
  KeyPopupButton(TQWidget *parent = 0) : ParentType(parent) {}

protected:
  virtual int append(TQString label) { return ParentType::_widget->appendItem(label, TQPixmap()); }
  virtual TQString get(int id) const { return ParentType::_widget->popup()->text(id); }

private:
  // disabled
  TQString currentItem() const;
  void setCurrentItem(const TQString &key);
  virtual int currentId() const { return 0; }
  virtual void setCurrentId(int) {}
};

#endif
