/* vi:set ts=8 sts=4 sw=4:
 *
 * VIM - Vi IMproved		by Bram Moolenaar
 *
 * Do ":help uganda"  in Vim to read copying and usage conditions.
 * Do ":help credits" in Vim to see a list of people who contributed.
 */

/*
 * Porting to KDE(2) was done by
 *
 *  (C) 2000 by Thomas Capricelli <orzel@freehackers.org>
 *
 *  Please visit http://freehackers.org/kvim for other vim- or
 *  kde-related coding. (URL currently doesn't work...)
 *
 *  $Id$
 *
 */
#include <assert.h>
#include <errno.h>
#include <string.h>
#include <kmenubar.h>
#include <kfiledialog.h>
#include <kiconloader.h>

#include <qscrollbar.h>
#include <qcursor.h>
#include <qmessagebox.h>
#include <qiconset.h>
#include <qtextcodec.h>
#include "gui_kde_wid.h"

extern "C" {
#include "vim.h"
}

#undef dbf
#undef db
#undef mputs

#if 1
#define dbf(format, args...) { printf("%s" " : " format "\n" , __FUNCTION__ , ## args ); fflush(stdout); }
#define db()       { printf("%s\n", __FUNCTION__ );fflush(stdout); }
#else
#define dbf(format, args... )
#define db()
#endif


#ifdef FEAT_TOOLBAR
#ifndef FEAT_KDETOOLBAR
/*
 * Icons used by the toolbar code.
 *///{{{
#include "../pixmaps/tb_new.xpm"
#include "../pixmaps/tb_open.xpm"
#include "../pixmaps/tb_close.xpm"
#include "../pixmaps/tb_save.xpm"
#include "../pixmaps/tb_print.xpm"
#include "../pixmaps/tb_cut.xpm"
#include "../pixmaps/tb_copy.xpm"
#include "../pixmaps/tb_paste.xpm"
#include "../pixmaps/tb_find.xpm"
#include "../pixmaps/tb_find_next.xpm"
#include "../pixmaps/tb_find_prev.xpm"
#include "../pixmaps/tb_find_help.xpm"
#include "../pixmaps/tb_exit.xpm"
#include "../pixmaps/tb_undo.xpm"
#include "../pixmaps/tb_redo.xpm"
#include "../pixmaps/tb_help.xpm"
#include "../pixmaps/tb_macro.xpm"
#include "../pixmaps/tb_make.xpm"
#include "../pixmaps/tb_save_all.xpm"
#include "../pixmaps/tb_jump.xpm"
#include "../pixmaps/tb_ctags.xpm"
#include "../pixmaps/tb_load_session.xpm"
#include "../pixmaps/tb_save_session.xpm"
#include "../pixmaps/tb_new_session.xpm"
#include "../pixmaps/tb_blank.xpm"
#include "../pixmaps/tb_maximize.xpm"
#include "../pixmaps/tb_split.xpm"
#include "../pixmaps/tb_minimize.xpm"
#include "../pixmaps/tb_shell.xpm"
#include "../pixmaps/tb_replace.xpm"
#include "../pixmaps/tb_vsplit.xpm"
#include "../pixmaps/tb_maxwidth.xpm"
#include "../pixmaps/tb_minwidth.xpm"
//}}}
/*
 * These are the pixmaps used for the default buttons.
 * Order must exactly match toolbar_names[] in menu.c!
 *///{{{
static char **(built_in_pixmaps[]) =
{
	tb_new_xpm,
	tb_open_xpm,
	tb_save_xpm,
	tb_undo_xpm,
	tb_redo_xpm,
	tb_cut_xpm,
	tb_copy_xpm,
	tb_paste_xpm,
	tb_print_xpm,
	tb_help_xpm,
	tb_find_xpm,
	tb_save_all_xpm,
	tb_save_session_xpm,
	tb_new_session_xpm,
	tb_load_session_xpm,
	tb_macro_xpm,
	tb_replace_xpm,
	tb_close_xpm,
	tb_maximize_xpm,
	tb_minimize_xpm,
	tb_split_xpm,
	tb_shell_xpm,
	tb_find_prev_xpm,
	tb_find_next_xpm,
	tb_find_help_xpm,
	tb_make_xpm,
	tb_jump_xpm,
	tb_ctags_xpm,
	tb_vsplit_xpm,
	tb_maxwidth_xpm,
	tb_minwidth_xpm,
	tb_exit_xpm
};//}}}
#else
const char *kdeicons[] = {
	"filenew",
	"fileopen",
	"filesave",
	"undo",
	"redo",
	"editcut",
	"editcopy",
	"editpaste",
	"fileprint",
	"contents2",
	"filefind",
	"save_all",
	"fileexport",
	"filenew",
	"fileimport",
	"run",
	"edit",
	"fileclose",
	"",
	"",
	"split",
	"openterm",
	"previous",
	"next",
	"help",
	"make",
	"goto",
	"run",
	"vsplit",
	"maxwidth",
	"minwidth",
	"quit"
};
#endif
/*
 * creates a blank pixmap using tb_blank
 */
    QPixmap
pixmap_create_from_xpm(char **xpm)//{{{
{
    return (QPixmap((const char **)xpm));
}//}}}

/*
 * creates a pixmap by using a built-in number
 */
    QPixmap
pixmap_create_by_num(int pixmap_num)//{{{
{
#ifdef FEAT_KDETOOLBAR
    if (pixmap_num >= 0 && (unsigned)pixmap_num < (sizeof(kdeicons)
						   / sizeof(kdeicons[0])) - 1)
    {

	KIconLoader *il = kapp->iconLoader(); //new KIconLoader();
	QString icon;
	icon = QString(kdeicons[pixmap_num]);
	return il->loadIcon(icon, KIcon::MainToolbar);
    }
    return QPixmap();
#else
    if (pixmap_num >= 0 && (unsigned)pixmap_num < (sizeof(built_in_pixmaps)
					   / sizeof(built_in_pixmaps[0])) - 1)
	return pixmap_create_from_xpm(built_in_pixmaps[pixmap_num]);
    else
	return QPixmap();
#endif
}//}}}

/*
 * Creates a pixmap by using the pixmap "name" found in 'runtimepath'/bitmaps/
 */
    QPixmap
pixmap_create_by_dir(char_u *name)//{{{
{
    char_u full_pathname[MAXPATHL + 1];

    if (gui_find_bitmap(name, full_pathname, "xpm") == OK)
	return QPixmap((const char *)full_pathname);
    else
	return QPixmap();
}//}}}


    QPixmap
pixmap_create_from_file(char_u *file)
{
    return QPixmap((const char *)file);
}
#endif

    void
gui_mch_add_menu(vimmenu_T *menu, int idx)//{{{
{
#ifdef FEAT_MENU
    QPopupMenu *me;
    vimmenu_T *parent = menu->parent;

    if (menu_is_popup(menu->name))
    {
	menu->widget = new QPopupMenu(vmw , QSTR(menu->name));
	QObject::connect(menu->widget, SIGNAL(activated(int)), vmw,
						   SLOT(menu_activated(int)));
	return;
    }

    if (!menu_is_menubar(menu->name))
	return;

    if (parent)
    {
	idx++; // for tearoffs to be first in menus
	me = new QPopupMenu(parent->widget, QSTR(menu->name));
	parent->widget->insertItem(QSTR(menu->name), me, (long)me, idx);
    }
    else
    {
	me = new QPopupMenu(vmw->menuBar(), QSTR(menu->name));
	vmw->menuBar()->insertItem(QSTR(menu->name), me, (long)me, idx);
    }

    me->setCaption((const char *)(menu->dname));
    if (vmw->have_tearoff)
	me->insertTearOffHandle(0, 0);
    QObject::connect(me, SIGNAL(activated(int)), vmw,
						   SLOT(menu_activated(int)));
    menu->widget = me;
#endif
}//}}}


    void
gui_mch_add_menu_item(vimmenu_T *menu, int idx)//{{{
{
#ifdef FEAT_MENU
    vimmenu_T *parent = menu->parent;
#ifdef FEAT_TOOLBAR
    if (menu_is_toolbar(parent->name))
    {
	QPixmap pix;

	if (menu_is_separator(menu->name))
	{
	    vmw->toolBar()->insertSeparator();
	    return;
	}
	if (menu->iconfile != NULL)
	{
	    pix = pixmap_create_from_file(menu->iconfile);
	}
	if (!menu->icon_builtin)
	{
	    pix = pixmap_create_by_dir(menu->name);
	}
	if (pix.isNull() && menu->iconidx >= 0)
	{
	    pix = pixmap_create_by_num(menu->iconidx);
	}
#ifndef FEAT_KDETOOLBAR
	if (pix.isNull())
	{
	    pix = pixmap_create_from_xpm(tb_blank_xpm);
	}
#endif
	if (pix.isNull())
	    return; // failed
	vmw->toolBar()->insertButton(
		pix,
		(long)menu, // id
		true,
		QSTR(menu->strings[MENU_INDEX_TIP]), // tooltip or text
		idx);
	menu->parent=parent;
	return;
    }
#endif // FEAT_TOOLBAR

    idx++;
    if (menu_is_separator(menu->name))
    {
	parent->widget->insertSeparator();
	return;
    }
    parent->widget->insertItem(QSTR(menu->name), (long)menu, idx);
#endif
}//}}}


    void
gui_mch_set_text_area_pos(int x, int y, int w, int h)//{{{
{
    int X = 0;
    int Y = 0;

    if (vmw->menuBar()->isVisible() && vmw->menuBar()->isEnabled()
#if QT_VERSION>=300
	    && !vmw->menuBar()->isTopLevelMenu()
#endif
       )
	Y += vmw->menuBar()->height();
#ifdef FEAT_TOOLBAR
    if (vmw->toolBar()->isVisible() && vmw->toolBar()->isEnabled()
				   && vmw->toolBar()->barPos()==KToolBar::Top)
	Y += vmw->toolBar()->height();

    if (vmw->toolBar()->isVisible() && vmw->toolBar()->isEnabled()
				  && vmw->toolBar()->barPos()==KToolBar::Left)
	X += vmw->toolBar()->width();
#endif // FEAT_TOOLBAR

    gui.w->setGeometry(x + X, y + Y, w, h);
}//}}}


#if defined(FEAT_MENU) || defined(PROTO)
/*
 * Enable or disable mnemonics for the toplevel menus.
 */
    void
gui_gtk_set_mnemonics(int enable)//{{{ // TO BE REMOVED
{
}//}}}

    void
toggle_tearoffs(vimmenu_T *menu, int enable)//{{{
{
    while (menu != NULL)
    {
	if (!menu_is_popup(menu->name))
	{
	    if (menu->widget != 0)
	    {
		if (enable)
		    menu->widget->insertTearOffHandle(0,0);
		else
		    menu->widget->removeItem(0);
	    }
	    toggle_tearoffs(menu->children, enable);
	}
	menu = menu->next;
    }
}//}}}

	void
gui_mch_toggle_tearoffs(int enable)//{{{
{
    vmw->have_tearoff=enable;
    toggle_tearoffs(root_menu, enable);
}//}}}
#endif


#if defined(FEAT_MENU) || defined(PROTO)
/*
 * Destroy the machine specific menu widget.
 */
    void
gui_mch_destroy_menu(vimmenu_T *menu)//{{{
{
#ifdef FEAT_TOOLBAR
    if (menu->parent && menu_is_toolbar(menu->parent->name))
    {
	vmw->toolBar()->removeItem((long)menu);
	return;
    }
#endif
    if (menu->parent)
	menu->parent->widget->removeItem((long)menu);
    if (menu->widget)
	delete menu->widget;
    menu->widget = 0;
}//}}}
#endif /* FEAT_MENU */


/*
 * Scrollbar stuff.
 */

    void
gui_mch_set_scrollbar_thumb(scrollbar_T *sb, long val, long size, long max)//{{{
{
    if (!sb->w)
	return;

    sb->w->setRange(0, max + 1 - size);
    sb->w->setValue(val);

    sb->w->setLineStep(1);
    sb->w->setPageStep(size);
}//}}}

    void
gui_mch_set_scrollbar_pos(scrollbar_T *sb, int x, int y, int w, int h)//{{{
{
    if (!sb->w)
	return;

    //we add the menubar and toolbar height/width
    int X = 0;
    int Y = 0;

    if (vmw->menuBar()->isVisible() && vmw->menuBar()->isEnabled()
#if QT_VERSION>=300
					  && !vmw->menuBar()->isTopLevelMenu()
#endif
       )
	Y += vmw->menuBar()->height();
#ifdef FEAT_TOOLBAR
    if (vmw->toolBar()->isVisible() && vmw->toolBar()->isEnabled()
				   && vmw->toolBar()->barPos()==KToolBar::Top)
	Y += vmw->toolBar()->height();

    if (vmw->toolBar()->isVisible() && vmw->toolBar()->isEnabled()
				  && vmw->toolBar()->barPos()==KToolBar::Left)
	X += vmw->toolBar()->width();
#endif //FEAT_TOOLBAR
    if (sb->w->orientation() == Qt::Vertical)
    {
	bool leftscroll=gui.which_scrollbars[SBAR_LEFT];
	bool rightscroll=gui.which_scrollbars[SBAR_RIGHT];

	if (x < 20)
	    leftscroll = true;
	else
	    rightscroll = true;
	if (x < 20)
	    sb->w->setGeometry(X, y+Y, w, h);
	else
	    sb->w->setGeometry(vmw->width() - w - 1 + X, y + Y, w, h);
    }
    else
    {
	sb->w->setGeometry(x + X, y + Y, w, h);
    }
}//}}}

/* SBAR_VERT or SBAR_HORIZ */
    void
gui_mch_create_scrollbar(scrollbar_T *sb, int orient)//{{{
{
    sbpool->create(sb,orient);
    if (orient == SBAR_VERT)
	gui.scrollbar_width = sb->w->sizeHint().width();
    else
	gui.scrollbar_height = sb->w->sizeHint().height();
}//}}}

    void
gui_mch_destroy_scrollbar(scrollbar_T *sb)//{{{
{
    sbpool->destroy(sb);
}//}}}

#if defined(FEAT_BROWSE) || defined(PROTO)
/*
 * Implementation of the file selector related stuff
 */

/*
 * Convert the Vim-style filter specification 's' to the KDE-style
 * filter specification.
 *      Vim-style:      {label}\t{pattern1};{pattern2}\n
 *      KDE-style:      {pattern1} {pattern2}|{label}\n
 *
 * The newly constructed filter is returned in allocated memory and
 * must be freed by the calling program.
 */
    static char *
convert_filter(char_u *s)
{
    char	*res;
    unsigned	i;
    unsigned	pattern_len;
    char	*filter_label;
    char	*filter_pattern;

    // The conversion generates a string of equal length to the original
    // pattern, so allocate enough memory to hold the original string.
    res = new char[STRLEN(s) + 1];
    s = vim_strsave(s);
    if (res != NULL && s != NULL)
    {
	// Make sure the first byte is a NUL so that strcat()
	// will append at the beginning of the string.
	res[0] = '\0';
	filter_label = strtok((char *) s, "\t");
	while (filter_label != NULL)
	{
	    filter_pattern = strtok( 0L, "\n");
	    if (filter_pattern != NULL)
	    {
		pattern_len = (unsigned) STRLEN(filter_pattern);
		for (i = 0; i < pattern_len; ++i)
		    if (filter_pattern[i] == ';')
			filter_pattern[i] = ' ';

		strcat(res, filter_pattern);
		strcat(res, "|");
		strcat(res, filter_label);
		strcat(res, "\n");
	    }
	    filter_label = strtok(0L, "\t");
	}
    }
    if (s)
	vim_free(s);
    return res;
}

/*
 * Put up a file requester.
 * Returns the selected name in allocated memory, or NULL for Cancel.
 * saving,			select file to write
 * title			title for the window
 * dflt				default name
 * ext				not used (extension added)
 * initdir			initial directory, NULL for current dir
 * filter			not used (file name filter)
 */
/*ARGSUSED*/
    char_u *
gui_mch_browse(int saving,//{{{
		char_u *title,
		char_u *dflt,
		char_u *ext,
		char_u *initdir,
		char_u *filter)
{
    char *filt_glob;

    filt_glob = convert_filter(filter);

    gui_mch_mousehide(FALSE);

    QString s;
    if (!saving)
	s = KFileDialog::getOpenFileName(QSTR(initdir), QSTR(filt_glob),
							  vmw, QSTR(title));
    else
	s = KFileDialog::getSaveFileName();

    if (filt_glob)
	delete filt_glob;

    if (s.isNull())
	return NULL;
    QCString unistring = vmw->codec->fromUnicode(s);
    char_u *s2 = (char_u *)(const char *)unistring;
    if (s2)
	s2 = vim_strsave(s2);

    return s2;
}//}}}

#endif	/* FEAT_BROWSE */

#ifdef FEAT_GUI_DIALOG

/* ARGSUSED */
    int
gui_mch_dialog(int type,		/* type of dialog *///{{{
		char_u *title,		/* title of dialog */
		char_u *message,	/* message text */
		char_u *buttons,	/* names of buttons */
		int    def_but,		/* default button */
		char_u *textfield)
{
    gui_mch_mousehide(FALSE);
    VimDialog vd(type, title, message, buttons, def_but,textfield);
    int ret = vd.exec();
    return ret;
}//}}}


#endif	/* FEAT_GUI_DIALOG */

#if defined(FEAT_MENU) || defined(PROTO)
    void
gui_mch_show_popupmenu(vimmenu_T *menu)//{{{
{
    menu->widget->popup(QCursor::pos());
}//}}}

void
gui_make_popup (char_u *pathname)//{{{
{
    vimmenu_T *menu = gui_find_menu(pathname);

    if (menu != NULL)
	menu->widget->popup(QCursor::pos());
}//}}}
#endif



/* Find and Replace implementations */
    void
gui_mch_find_dialog(exarg_T *eap)//{{{
{
    // char_u* entry_text;
    //int exact_word=FALSE;
    //    entry_text = get_find_dialog_text(eap->arg,&exact_word);

    vmw->finddlg->setCaseSensitive(true);

    /*    if (entry_text!=NULL)
     *    {
	  vmw->finddlg->setText(QString((char *)entry_text));
    // exact match should go there, hopefully KDE old KEdFind/KEdReplace will be replaced in KDE 4 as pple wanted KDE 3's Find/Replace to be kept
    }*/ // Don't use it, KDE keeps old search in memory and vim give \\Csearch, which is difficult to handle
    //   vim_free(entry_text);

    vmw->finddlg->show();
}//}}}

    void
gui_mch_replace_dialog(exarg_T *eap)//{{{
{
    //  char_u* entry_text;
    //int exact_word=FALSE;

    //    entry_text = get_find_dialog_text(eap->arg,&exact_word);

    /*    if (entry_text!=NULL)
     *    {
     vmw->repldlg->setText(QString((char *)entry_text));
    // exact match should go there, hopefully KDE old KEdFind/KEdReplace will be replaced in KDE 4 as pple wanted KDE 3's Find/Replace to be kept
    }*/
    //vim_free(entry_text);

    vmw->repldlg->show();
}//}}}

    void
ex_helpfind(exarg_T *eap)//{{{
{
    do_cmdline_cmd((char_u *)"emenu ToolBar.FindHelp");
}//}}}
