//       _________ __                 __                               
//      /   _____//  |_____________ _/  |______     ____  __ __  ______
//      \_____  \\   __\_  __ \__  \\   __\__  \   / ___\|  |  \/  ___/
//      /        \|  |  |  | \// __ \|  |  / __ \_/ /_/  >  |  /\___ |
//     /_______  /|__|  |__|  (____  /__| (____  /\___  /|____//____  >
//             \/                  \/          \//_____/            \/ 
//  ______________________                           ______________________
//			  T H E   W A R   B E G I N S
//	   Stratagus - A free fantasy real time strategy game engine
//
/** name _clip_rectangle	-	Clip rectangle mechanism */
//
//	(c) Copyright 2001 by Lutz Sammer, Stephan Rasenberg
//
//      This program is free software; you can redistribute it and/or modify
//      it under the terms of the GNU General Public License as published by
//      the Free Software Foundation; only version 2 of the License.
//
//      This program is distributed in the hope that it will be useful,
//      but WITHOUT ANY WARRANTY; without even the implied warranty of
//      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//      GNU General Public License for more details.
//
//      You should have received a copy of the GNU General Public License
//      along with this program; if not, write to the Free Software
//      Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
//      02111-1307, USA.
//
//	$Id: _clip_rectangle,v 1.11 2004/03/30 00:51:24 nehalmistry Exp $

//@{

/*----------------------------------------------------------------------------
--      Documentation
----------------------------------------------------------------------------*/
/**
**  THIS FILE IS NOT A SOURCE-FILE OR HEADER-FILE ON ITS OWN,
**  IT CAN BE INCLUDED AT MULTIPLE LOCATIONS BY ANY SOURCE-FILE IN VIDEO !!!
**  
**  IN SUCH IT CAN ONLY REPRESENT ONE MECHANISM, WHICH CAN BE RE-USED AT
**  SEVERAL LOCATIONS WITHOUT INTRODUCING DUPLICATE CODE AND STILL BE FAST.
*/


/*----------------------------------------------------------------------------
--      Includes
----------------------------------------------------------------------------*/
#include "intern_video.h"


/*----------------------------------------------------------------------------
--	Mechanism
----------------------------------------------------------------------------*/
/**
**    Clip the sides of a general rectangle, drawing the visible sides with
**    pre-delivered horizontal and vertical drawing routines..
**
**
**  For this to work the following pre-conditions should be followed before
**  including this file:
**
**    Define int _x
**      The x coordinate of the upper-left corner of the given rectangle
**
**    Define int _y
**      The y coordinate of the upper-left corner of the given rectangle
**
**    Define int _w
**      The width of the given rectangle
**
**    Define int _h
**      The height of the given rectangle
**
**    Define void _hline(x,y,w)
**      A routine that can draw a horizontal line (unclipped) with:
**      int x, y		(x,y) position on the screen
**      unsigned int w		width of the line (0=don't draw)
**
**    Define void _vline(x,y,h)
**      A routine that can draw a vertical line (unclipped) with:
**      int x, y		(x,y) position on the screen
**      unsigned int h		heeight of the line (0=don't draw)
**
**
**  Example of this usage:
**    global void VideoDrawTransRectangleClip(SysColors color,int x,int y,
**                  unsigned width,unsigned height,unsigned char alpha)
**    {
**      #define _x		x
**      #define _y		y
**      #define _w		width
**      #define _h		height
**      #define _hline(x,y,w)	VideoDrawTransHLine(color,x,y,w)
**      #define _vline(x,y,h)	VideoDrawTransVLine(color,x,y,h)
**
**      #include "_clip_rectangle"
**
**      #undefine _x
**      #undefine _y
**      #undefine _w
**      #undefine _h
**      #undefine _hline
**      #undefine _vline
**    }
*/
{
	int f;
	int left;
	int right;
	int top;
	int bottom;

	// Ensure non-empty rectangle
	if (!(_w && _h)) {
		return;                      // rectangle is `void'
	}

	// Clip rectangle boundary
	left = right = top = bottom = 1;

	if (_x < ClipX1) {            // no left side
		f = ClipX1 - _x;
		if (_w <= f) {
			return;                    // entire rectangle left --> not visible
		}
		_w -= f;
		_x = ClipX1;
		left = 0;
	}
	if ((_x + _w) > ClipX2 + 1) {     // no right side
		if (_x > ClipX2) {
			return;                    // entire rectangle right --> not visible
		}
		_w = ClipX2 - _x + 1;
		right = 0;
	}
	if (_y < ClipY1) {               // no top
		f = ClipY1 - _y;
		if (_h <= f) {
			return;                    // entire rectangle above --> not visible
		}
		_h -= f;
		_y = ClipY1;
		top = 0;
	}
	if ((_y + _h) > ClipY2 + 1) {    // no bottom
		if (_y > ClipY2) {
			return;                  // entire rectangle below --> not visible
		}
		_h = ClipY2 - _y + 1;
		bottom = 0;
	}

	// Draw (part of) rectangle sides
	// Note: _hline and _vline should be able to handle zero width/height
	if (top) {
		_hline(_x, _y, _w);
		if (!--_h) {
			return;                    // rectangle as horizontal line
		}
		++_y;
	}
	if (bottom) {
		_hline(_x, _y + _h - 1, _w);
		--_h;
	}
	if (left) {
		_vline(_x, _y, _h);
		if (!--_w) {
			return;                    // rectangle as vertical line
		}
		++_x;
	}
	if (right) {
		_vline(_x + _w - 1, _y, _h);
	}
}

//@}
