//   ___________		     _________		      _____  __
//   \_	  _____/______   ____   ____ \_   ___ \____________ _/ ____\/  |_
//    |    __) \_  __ \_/ __ \_/ __ \/    \  \/\_  __ \__  \\   __\\   __|
//    |     \   |  | \/\  ___/\  ___/\     \____|  | \// __ \|  |   |  |
//    \___  /   |__|    \___  >\___  >\______  /|__|  (____  /__|   |__|
//	  \/		    \/	   \/	     \/		   \/
//  ______________________                           ______________________
//			  T H E   W A R   B E G I N S
//	   FreeCraft - A free fantasy real time strategy game engine
//
/** name _clip_rectangle	-	Clip rectangle mechanism */
//
//	(c) Copyright 2001 by Lutz Sammer, Stephan Rasenberg
//
//	FreeCraft 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.
//
//	FreeCraft 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.
//
//	$Id: _clip_rectangle,v 1.5 2002/12/17 06:40:51 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, left, right, top, 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);
  }
}

//@}
