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

/*
 * all of our animations work by calling the anim handler
 * from the appropriate golem callback function; the handler
 * can do whatever it wants; it should be noted that some handlers
 * may call XMapWindow to do opaque movements of windows for
 * entry or whatever; the main code will call map on it again, but
 * it's no big deal.
 */
static animhandler_t	a_iconify;
static animhandler_t	a_restore;
static animhandler_t	a_zoom;
static animhandler_t	a_unzoom;
static animhandler_t	a_birth;
static animhandler_t	a_death;

/*
 * relatively noninteresting; callbacks just pass their
 * stuffs on to a handler.
 */

/* new windows being born */
static int anim_birth(int pcall, client_t *client) {
	if (a_birth)
		a_birth(client, EV_BIRTH);

	return PLUGIN_OK;
}

/* window death: old clients departing */
static int window_death(int pcall, client_t *client) {
	if (a_death)
		a_death(client, EV_DEATH);

	return PLUGIN_OK;
}

/* client iconification */
static int iconify_notify(int pcall, client_t *client) {
	if (a_iconify)
		a_iconify(client, EV_ICONIFY);

	return PLUGIN_OK;
}

/* client restoration */
static int restore_notify(int pcall, client_t *client) {
	if (a_restore)
		a_restore(client, EV_RESTORE);

	return PLUGIN_OK;
}

/* clients getting zoomed */
static int zoom_notify(int pcall, client_t *client) {
	if (a_zoom)
		a_zoom(client, EV_ZOOM);

	return PLUGIN_OK;
}

/* clients getting unzoomed */
static int unzoom_notify(int pcall, client_t *client) {
	if (a_unzoom)
		a_unzoom(client, EV_UNZOOM);

	return PLUGIN_OK;
}


/* parse parameters */
int animations_init() {
	char *iconname;
	char *restname;
	char *birthname;
	char *deathname;
	char *zoomname;
	char *unzoomname;

	/* get parameters describing which handlers to use for what */
	OPTIONAL_PARAM(&plugin_this->params, "iconify", string, iconname, NULL);
	OPTIONAL_PARAM(&plugin_this->params, "restore", string, restname, NULL);
	OPTIONAL_PARAM(&plugin_this->params, "birth", string, birthname, NULL);
	OPTIONAL_PARAM(&plugin_this->params, "death", string, deathname, NULL);
	OPTIONAL_PARAM(&plugin_this->params, "zoom", string, zoomname, NULL);
	OPTIONAL_PARAM(&plugin_this->params, "unzoom", string, unzoomname, NULL);

	/* get handler pointers where the handlers were specified */
	if (iconname)
		a_iconify = animbyname(iconname);
	if (restname)
		a_restore = animbyname(restname);
	if (birthname)
		a_birth = animbyname(birthname);
	if (deathname)
		a_death = animbyname(deathname);
	if (zoomname)
		a_zoom = animbyname(zoomname);
	if (unzoomname)
		a_unzoom = animbyname(unzoomname);

	/* free up strings and ret */
	if (iconname)	free(iconname);
	if (restname)	free(restname);
	if (birthname)	free(birthname);
	if (deathname)	free(deathname);
	if (zoomname)	free(zoomname);
	if (unzoomname)	free(unzoomname);

	return PLUGIN_OK;
}

/* add some callbacks */
int animations_start() {
	plugin_callback_add(plugin_this, PCALL_ANIM_BIRTH, anim_birth);
	plugin_callback_add(plugin_this, PCALL_WINDOW_DEATH, window_death);
	plugin_callback_add(plugin_this, PCALL_ICONIFY_NOTIFY, iconify_notify);
	plugin_callback_add(plugin_this, PCALL_RESTORE_NOTIFY, restore_notify);
	plugin_callback_add(plugin_this, PCALL_ZOOM_NOTIFY, zoom_notify);
	plugin_callback_add(plugin_this, PCALL_UNZOOM_NOTIFY, unzoom_notify);

	return PLUGIN_OK;
}

/* stuff we don't care about */
void animations_shutdown() {}
void animations_xevent_handler(XEvent *e) {}
