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

char *fore_colour;
char *back_colour;

/* the root tasklist */
static tasklist_t	*roottasklist	= NULL;

/* the button that opens the root tasklist */
static int	tasklist_button	= Button3;

static int window_life(int pcall, client_t *client)
{
   if( client->flags.internal != 1 )
   {
      if( tasklist_addent( roottasklist,
                           POS_LAST,
                           ET_TASK,
                           client->store_name,
                           (void *) client ) != NULL )
      {
         tasklist_size( roottasklist );
      }
      else
      {
         /* bah ! */
      }
   }

	return PLUGIN_OK; /* ---------> */
}

/* when new windows leave */
static int window_death(int pcall, client_t *client)
{
   if( client->flags.internal != 1 )
   {
      tasklist_remove( roottasklist, (void *) client );
      tasklist_size( roottasklist );
   }

	return PLUGIN_OK; /* ---------> */
}


/* root window presses */
static int root_button(int pcall, screen_t *screen, XButtonEvent *e)
{
   log( 0, "root_button");

   if (e->type == ButtonPress && e->button == tasklist_button)
   {
      tasklist_use(roottasklist, screen);
   }

   return PLUGIN_OK;
}

/* entry for x events */
int tasklist_xevent_handler(XEvent *e)
{
	client_t *client;
	tasklist_t *tasklist;
   XClientMessageEvent *cmsg;

	/* try to get client and tasklist_t */
	if (XFindContext(display, e->xany.window, client_context, (XPointer *) &client))
   {
		return PLUGIN_OK;
   }
	if (XFindContext(display, client->frame, tasklist_context, (XPointer *) &tasklist))
   {
		return PLUGIN_OK;
   }

	/* dispatch the event to a handler routine */
	switch (e->type)
   {
	   case ButtonPress:
            tasklist_click(tasklist, client, &e->xbutton);
            break;
	case Expose:
            tasklist_expose(tasklist, client, &e->xexpose);
            break;
      case ClientMessage:
            cmsg = (XClientMessageEvent *) e;
            if( cmsg->message_type == WM_PROTOCOLS )
            {
               if( cmsg->data.l[0] == WM_DELETE_WINDOW )
               {
                  tasklist_use(roottasklist, client->screen);
               }
            }
            break;
	}

	return PLUGIN_OK;
}

/* plugin intialization */
int tasklist_init()
{
	dgroup_t *dgroup;
	pixmap_t *tasklist_bullet;
	char     *fontname;

	/* get parameters */
	OPTIONAL_PARAM(&plugin_this->params, "tasklist_button", int, tasklist_button, Button3);
	OPTIONAL_PARAM(&plugin_this->params, "tasklist_font", string, fontname, NULL);
	OPTIONAL_PARAM(&plugin_this->params, "tasklist_bullet", pixmap, tasklist_bullet, NULL);
	OPTIONAL_PARAM(&plugin_this->params, "tasklist_dgroup", dgroup, dgroup, NULL);
	OPTIONAL_PARAM( &plugin_this->params,"tasklist_stacklayer", stacklayer, tasklist_stacklayer,
                   STACKLAYER_ABOVE);

   OPTIONAL_PARAM( &plugin_this->params, "fore_colour", string, fore_colour,
                   "#FFFFFF" );
   OPTIONAL_PARAM( &plugin_this->params, "back_colour", string, back_colour,
                   "#000000" );


	/* get the tasklist system up */
	if (tasklist2_init( fontname,
                       back_colour,
                       fore_colour,
                       dgroup, tasklist_bullet) == 0 )
   {

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

         // not needed for tasklists ...
         //	tasklist_parseparams( roottasklist, rmparam );

         if (fontname)
         {
            free(fontname);
         }

         return PLUGIN_OK; // ---------->
      }
   }

	if (fontname)
   {
		free(fontname);
   }

	return PLUGIN_UNLOAD;
}

/* clean up */
void tasklist_shutdown()
{
   if (roottasklist)
   {
		tasklist_delete(roottasklist);
   }

	tasklist2_shutdown();
}

/* realize the tasklists */
int tasklist_start()
{
	/* register callback */
	plugin_callback_add(plugin_this, PCALL_ROOT_BUTTON,  root_button);
	plugin_callback_add(plugin_this, PCALL_WINDOW_BIRTH, window_life);
	plugin_callback_add(plugin_this, PCALL_WINDOW_DEATH, window_death);

	if( tasklist_realize(roottasklist) == -1 )
   {
		PERR("unable to realize tasklist");
   }

	return PLUGIN_OK;
}
