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

/* number of steps for zoomrects and for window birth */
#define NUM_RECTS	10

/* 
 * draws a few lines representing a window: call again with same parms to erase (GXxor).
 * We take a rectangle to draw as, _and_ a client structure.  the client structure gives us
 * information about the decoration spacing for the client's sides, and the rect is what to
 * draw.  this is so we don't have to change the x,y,wid,hei in the client struct.
 */
void draw_winbox(screen_t *screen, client_t *client, int x, int y, int width, int height) {
	XSegment segs[8];
	dgroup_t *dgroup;
	int nsegs = 8;
	int lw, od;
	int dx, dy, dwidth, dheight;

	width--;
	height--;
	dgroup = client->dgroup;
	y += dgroup->top_space;
	x += dgroup->left_space;
	lw = options.linewidth / 2;
	od = options.linewidth % 2 == 0 ? 0 : 1;

	segs[0].x1 = x - lw;			/* top left to top right */
	segs[0].y1 = y;
	segs[0].x2 = x + width + lw + od;
	segs[0].y2 = y;

	segs[1].x1 = x + width;			/* top right to bottom right */
	segs[1].y1 = y + lw + od;
	segs[1].x2 = x + width;
	segs[1].y2 = y + height - lw;

	segs[2].x1 = x + width + lw + od;	/* bottom right to bottom left */
	segs[2].y1 = y + height;
	segs[2].x2 = x - lw;
	segs[2].y2 = y + height;

	segs[3].x1 = x;				/* bottom left to top left */
	segs[3].y1 = y + height - lw;
	segs[3].x2 = x;
	segs[3].y2 = y + lw + od;

	segs[4].x1 = x + lw + od;		/* first horiz midsegment */
	segs[4].y1 = y + (height / 3);
	segs[4].x2 = x + width - lw;
	segs[4].y2 = y + (height / 3);

	segs[5].x1 = x + (width / 3);		/* first vert midsegment */
	segs[5].y1 = y + lw + od;
	segs[5].x2 = x + (width / 3);
	segs[5].y2 = y + height - lw;

	segs[6].x1 = x + lw + od;		/* second horiz midsegment */
	segs[6].y1 = y + (2 * (height / 3));
	segs[6].x2 = x + width - lw;
	segs[6].y2 = y + (2 * (height / 3));

	segs[7].x1 = x + (2 * (width / 3));	/* second vert midsegment */
	segs[7].y1 = y + lw + od;
	segs[7].x2 = x + (2 * (width / 3));
	segs[7].y2 = y + height - lw;

#if 0
	/* this did an X across the windows; needed 6 segs */
	segs[4].x1 = x;			/* top left to bottom right */
	segs[4].y1 = y;
	segs[4].x2 = x + width;
	segs[4].y2 = y + height;

	segs[5].x1 = x;			/* bottom left to top right */
	segs[5].y1 = y + height;
	segs[5].x2 = x + width;
	segs[5].y2 = y;
#endif

	/* draw the segments for the winbox */
	XDrawSegments(display, screen->root, screen->xorgc, segs, nsegs);

	/* draw border at size of the window decoration */
	dx = x - (dgroup->left_space ? dgroup->left_space : 1);
	dy = y - (dgroup->top_space ? dgroup->top_space : 1);
	dwidth = width + (dgroup->left_space ? dgroup->left_space : 1) 
		+ (dgroup->right_space ? dgroup->right_space : 1);
	dheight = height + (dgroup->top_space ? dgroup->top_space : 1) 
		+ (dgroup->bottom_space ? dgroup->bottom_space : 1);
	XDrawRectangle(display, screen->root, screen->xorgc, dx, dy, dwidth, dheight);
}

/* draw zooming rectangles:  the second rect is the destination */
void draw_zoomrects(screen_t *screen, client_t *client, int x1, int y1, int width1, int height1,
		int x2, int y2, int width2, int height2, int usewinbox) {
	float xinc, yinc, widthinc, heightinc;
	float x, y, width, height;
	int i;

	xinc = (x2 - x1) / NUM_RECTS;
	yinc = (y2 - y1) / NUM_RECTS;
	widthinc = (width2 - width1) / NUM_RECTS;
	heightinc = (height2 - height1) / NUM_RECTS;

	x = x1;
	y = y1;
	width = width1;
	height = height1;

	for (i = 0; i < NUM_RECTS; i++) {
		if (usewinbox)
			draw_winbox(screen, client, (int) x, (int) y, (int) width, (int) height);
		else
			XDrawRectangle(display, screen->root, screen->xorgc, (int) x, (int) y, (int) width, (int) height);
		XSync(display, 0);
		usleep(options.anim_delay);
		if (usewinbox)
			draw_winbox(screen, client, (int) x, (int) y, (int) width, (int) height);
		else
			XDrawRectangle(display, screen->root, screen->xorgc, (int) x, (int) y, (int) width, (int) height);

		x += xinc;
		y += yinc;
		width += widthinc;
		height += heightinc;
	}

#if 0
	if (usewinbox)
		draw_winbox(screen, client, x2, y2, width2, height2);
	else
		XDrawRectangle(display, screen->root, screen->xorgc, x2, y2, width2, height2);
	XSync(display, 0);
	usleep(options.anim_delay);
	if (usewinbox)
		draw_winbox(screen, client, x2, y2, width2, height2);
	else
		XDrawRectangle(display, screen->root, screen->xorgc, x2, y2, width2, height2);
#endif
}
