/*-
 * Copyright (c) 2001 Jordan DeLong
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the author nor the names of contributors may be
 *    used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */
#include "menu.h"

/* the root menu */
static menu_t	*rootmenu	= NULL;

/* the button that opens the root menu */
static int	menu_button	= Button3;

/* root window presses */
static int root_button(int pcall, screen_t *screen, XButtonEvent *e) {
	if (e->type == ButtonPress && e->button == menu_button)
		menu_use(rootmenu, screen);

	return PLUGIN_OK;
}

/* entry for x events */
int xevent_handler(XEvent *e) {
	client_t *client;
	menu_t *menu;

	/* try to get client and menu_t */
	if (XFindContext(display, e->xany.window, client_context, (XPointer *) &client))
		return PLUGIN_OK;
	if (XFindContext(display, client->frame, menu_context, (XPointer *) &menu))
		return PLUGIN_OK;

	/* dispatch the event to a handler routine */
	switch (e->type) {
	case ButtonPress:
		menu_click(menu, client, &e->xbutton);
		break;
	case Expose:
		menu_expose(menu, client, &e->xexpose);
		break;
	}

	return PLUGIN_OK;
}

/* plugin intialization */
int init() {
	param_t *rmparam;
	dgroup_t *dgroup;
	pixmap_t *submenu_bullet;
	char *fontname;

	/* get parameters */
	OPTIONAL_PARAM(&plugin_this->params, "menu_button", int, menu_button, Button3);
	OPTIONAL_PARAM(&plugin_this->params, "menu_font", string, fontname, NULL);
	OPTIONAL_PARAM(&plugin_this->params, "submenu_bullet", pixmap, submenu_bullet, NULL);
	OPTIONAL_PARAM(&plugin_this->params, "menu_dgroup", dgroup, dgroup, NULL);
	OPTIONAL_PARAM(&plugin_this->params, "menu_stacklayer", stacklayer, menu_stacklayer, STACKLAYER_ABOVE);

	/* get the menu system up */
	if (menu_init(fontname, dgroup, submenu_bullet) != 0)
		goto failure;

	/* build the rootmenu */
	if ((rootmenu = menu_create()) == NULL)
		goto failure;

	/* build the rootmenu from parameters */
	if ((rmparam = plugin_find_param(&plugin_this->params, "rootmenu")) == NULL)
		PERR("required block 'rootmenu' not present");
	parseparams(rootmenu, rmparam);

	if (fontname)
		free(fontname);
	return PLUGIN_OK;

failure:
	if (fontname)
		free(fontname);
	return PLUGIN_UNLOAD;
}

/* clean up */
void shutdown() {
	if (rootmenu)
		menu_delete(rootmenu);
	menu_shutdown();
}

/* realize the menus */
int start() {
	/* register callback */
	plugin_callback_add(plugin_this, PCALL_ROOT_BUTTON, root_button);

	if (menu_realize(rootmenu) == -1)
		PERR("unable to realize menus");

	return PLUGIN_OK;
}
