/*****************************************************************

   Copyright (c) 1996-2000 the kicker authors. See file AUTHORS.
   Copyright (c) 2006 Debajyoti Bera <dbera.web@gmail.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.

   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
    General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; see the file COPYING.  If not, write to
   the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
   Boston, MA 02110-1301, USA.

******************************************************************/

#ifndef __k_new_mnu_h__
#define __k_new_mnu_h__

#include <dcopobject.h>
#include <qintdict.h>
#include <qpixmap.h>
#include <qframe.h>
#include <qtoolbutton.h>
#include <qscrollview.h>
#include <qtimer.h>
#include <qbitmap.h>
#include <qvbox.h>
#include <qregexp.h>

#include <kabc/addressbook.h>
#include <kabc/stdaddressbook.h>
#include "../interfaces/kickoff-search-plugin.h"

#include "kmenubase.h"
#include "service_mnu.h"
#include "query.h"

class KickerClientMenu;
class KBookmarkMenu;
class KActionCollection;
class KBookmarkOwner;
class Panel;
class QWidgetStack;
class KHistoryCombo;
class QScrollView;
class PopupMenuTitle;
class MediaWatcher;
class KURIFilterData;
class KBookmarkGroup;
class KBookmarkManager;
class ItemView;
class FlipScrollView;
class QListViewItem;
class KMenuItem;
class QListView;

static QString categories[14] = {I18N_NOOP("Actions"), I18N_NOOP("Applications"), I18N_NOOP("Bookmarks"),
                                 I18N_NOOP("Notes"), I18N_NOOP("Emails"),  I18N_NOOP("Files"), I18N_NOOP("Music"),
                                 I18N_NOOP("Browsing History"), I18N_NOOP("Chat Logs"), I18N_NOOP("Feeds"),
                                 I18N_NOOP("Pictures"), I18N_NOOP("Videos"), I18N_NOOP("Documentation"),
                                 I18N_NOOP("Others")};

static QString kerry_categories[14] = {"contacts", "applications", "webpages", "everything", "conversations",
                                       "everything", "media", "webpages", "conversations", "webpages", "images",
                                       "media", "everything", "everything"};

enum MenuOrientation { Uninitialized, TopDown, BottomUp };
enum OverflowCategoryState { None, Filling, NotNeeded };

class KMenu : public KMenuBase
{
    Q_OBJECT

public:
    KMenu();
    ~KMenu();

    int insertClientMenu(KickerClientMenu *p);
    void removeClientMenu(int id);

    virtual void showMenu();
    virtual bool eventFilter(QObject*, QEvent*);

    void clearRecentAppsItems();
    void clearRecentDocsItems();
    bool highlightMenuItem(const QString& /*id*/) { return false;}

    void selectFirstItem() {}
    void popup(const QPoint&, int indexAtPoint);

    enum MaskEffect { Plain, Dissolve };

    virtual QSize sizeHint() const;
    virtual QSize minimumSizeHint() const;

    void searchOver();
    void initCategoryTitlesUpdate();
    bool anotherHitMenuItemAllowed(int cat, bool count=true);
    void addHitMenuItem(HitMenuItem*);
    void insertSearchResult(HitMenuItem* item);

    void updateCategoryTitles();

signals:
    void aboutToHide();
    void aboutToShow();

public slots:
    virtual void initialize();

    virtual void hide();
    virtual void show();

    void stackWidgetRaised(QWidget*);

protected slots:
    void slotLock();
    void slotOpenSUSE();
    void slotLogout();
    void slotPopulateSessions();
    void slotSessionActivated( int );
    void slotGoSubMenu(const QString& relPath);
    void slotGoBack();
    void slotGoExitMainMenu();
    void slotGoExitSubMenu(const QString& url);

    void paletteChanged();
    virtual void configChanged();
    void updateRecent();

    void initSearch();
    void searchAccept();
    void searchChanged(const QString &);
    // when timeout happens or doQueryNow calls
    void doQuery (bool return_pressed = false);
    void searchActionClicked(QListViewItem*);

    void slotStartService(KService::Ptr);
    void slotStartURL(const QString&);
    void slotContextMenuRequested( QListViewItem * item, const QPoint & pos, int col );

    void clearedHistory();

    void slotBrowserButton();
    void slotSystemButton();
    void slotExitButton();
    void slotRecentlyButton();
    void slotFavoritesButton();
    void slotSloppyTimeout();

    void slotContextMenu(int);
    void slotFavoritesMoved( QListViewItem*, QListViewItem*, QListViewItem* );

    void updateMedia();
    void slotFavDropped(QDropEvent * e, QListViewItem *after );
    void slotSuspend(int id);

signals:
    void clickedBrowserButton();
    void clickedSystemButton();
    void clickedExitButton();
    void clickedRecentlyButton();
    void clickedFavoritesButton();

protected:
    virtual void paintEvent(QPaintEvent *);
    virtual void resizeEvent ( QResizeEvent * );
    virtual void mousePressEvent ( QMouseEvent * e );
    virtual void mouseReleaseEvent ( QMouseEvent * e );
    virtual void mouseMoveEvent ( QMouseEvent * e );

    bool loadSidePixmap();
    void doNewSession(bool lock);
    void createRecentMenuItems();
    void insertStaticItems();
    void insertSuspendOption( int &id, int &index );
    virtual void clearSubmenus();
    void raiseStackWidget( QWidget *view );

    bool runCommand();

    void setupUi();

    void saveConfig();
    void searchProgramList(QString relPath);
    void searchBookmarks(KBookmarkGroup);
    void searchAddressbook();

    void createNewProgramList();
    void createNewProgramList(QString relPath);

    void paintTab( QFrame *tab, bool active );
    void paintSearchTab( bool active );

    void goSubMenu(const QString& relPath, bool keyboard = false);
    void setOrientation(MenuOrientation orientation);

private:
    int serviceMenuStartId() { return 5242; }
    int serviceMenuEndId() { return 5242; }

    void fillMenu( KServiceGroup::Ptr &_root, KServiceGroup::List &_list,
		   const QString &_relPath, ItemView* view, int & id );

    void fillSubMenu(const QString& relPath, ItemView *view);

    QPopupMenu                 *sessionsMenu;
    QPixmap                     sidePixmap;
    QPixmap                     sideTilePixmap;
    int                         client_id;
    bool                        delay_init;
    QIntDict<KickerClientMenu>  clients;
    KActionCollection          *actionCollection;
    PopupMenuList               dynamicSubMenus;

    QTimer                       m_sloppyTimer;
    QTimer                       m_mediaFreeTimer;
    MediaWatcher               * m_mediaWatcher;
    QRegion                      m_sloppyRegion;
    QFrame                     * m_sloppyFrame;
    QWidget                    * m_sloppyWidget;
    ItemView                   * m_recentlyView;
    ItemView                   * m_favoriteView;
    ItemView                   * m_searchResultsWidget;
    QListView                  * m_searchActions;
    FlipScrollView             * m_browserView;
    ItemView                   * m_systemView;
    FlipScrollView             * m_exitView;
    QVBox                      * m_searchWidget;
    QLabel                     * m_resizeHandle;

    bool                       m_isresizing;
    // timer for search without pressing enter feature
    QTimer *input_timer, *init_search_timer;

    Query current_query;

    bool dontQueryNow(const QString &);

    // start timeout timer to call doQuery is enough time has passed since last keypress
    void checkToDoQuery (const QString &);
    // when return is pressed
    void doQueryNow ();
    void clearSearchResults(bool showHelp = true);

    int *max_category_id; // maximum id in this category: max_category_id - base_category_id gives the current number of hits displayed in this category
    int *categorised_hit_total; // current number of hits returned in each category

    bool ensureServiceRunning(const QString & service);

    QString iconForHitMenuItem(HitMenuItem *hit_item);

    int getHitMenuItemPosition (HitMenuItem *hit_item);
    QMap<QString, QString> mimetype_iconstore;
    QMap<QString, QString> media_mimetypes;
    // report error as a menu item
    void reportError (QString err);
    void addToHistory();

    int max_items(int category) const;
    QString TOP_CATEGORY_STRING;
    bool *already_added;

    void notifyServiceStarted(KService::Ptr service);
    void parseLine( bool final );
    QString m_iconName;
    QStringList m_middleFilters;
    QStringList m_finalFilters;
    KURIFilterData* m_filterData;
    QPtrList<HitMenuItem> m_current_menu_items;
    QListViewItem *m_searchIndex, *m_searchInternet;

    bool checkUriInMenu(const QString &uri);

    QRegExp emailRegExp,uriRegExp,uri2RegExp,authRegExp;

    KBookmarkManager *bookmarkManager;
    KABC::AddressBook* m_addressBook;

    QFrame *m_activeTab;

    enum ContextMenuEntry { AddItemToPanel, EditItem, AddMenuToPanel, EditMenu,
                            AddItemToDesktop, AddMenuToDesktop, PutIntoRunDialog,
                            AddToFavorites, RemoveFromFavorites, ClearRecentlyUsedApps, ClearRecentlyUsedDocs };
    struct PopupPath { QString title, description, icon, path, menuPath; };

    KPopupMenu* m_popupMenu;
    KService* m_popupService;
    PopupPath m_popupPath;

    QString newDesktopFile(const KURL& url, const QString &directory);
    void updateRecentlyUsedApps(KService::Ptr &service);

    QPixmap main_border_lc;
    QPixmap main_border_rc;
    QPixmap main_border_tl;
    QPixmap main_border_tr;
    QPixmap button_box_left;

    QPixmap tab_bottom_left;
    QPixmap tab_bottom_right;
    QPixmap tab_center;
    QPixmap tab_left_center;
    QPixmap tab_right_center;
    QPixmap tab_top_left;
    QPixmap tab_top_right;

    QPixmap search_tab_left;
    QPixmap search_tab_right;
    QPixmap search_tab_center;

    QWidgetStack *m_stacker;

    QStringList m_programsInMenu;
    QStringList m_newInstalledPrograms, m_seenPrograms;
    bool m_seenProgramsChanged;
    QString m_currentDate;

    MenuOrientation m_orientation;
    bool m_toolTipsEnabled;
    int m_media_id;

    bool m_recentDirty, m_browserDirty, m_kerryInstalled, m_isShowing;

    KickoffSearch::Plugin* m_search_plugin;
    QObject* m_search_plugin_interface;

    OverflowCategoryState m_overflowCategoryState;
    QPtrList<HitMenuItem> m_overflowList;
    int m_overflowCategory;

    void resetOverflowCategory();
    void fillOverflowCategory();
};

#endif
