#include <exec/types.h>
#include <graphics/rastport.h>
#include "picture.h"
#include "sizedefs.h"
#include "rectcopy.h"

int ClipLeft	= 0;
int ClipTop	= 0;
int ClipWidth	= WIDTH;
int ClipHeight	= HEIGHT;

#define PICX		ClipLeft
#define PICY		ClipTop
#define FrameWidth	ClipWidth
#define FrameHeight	ClipHeight

#if USE_RECTCOPY
/*
 * This routines copies a rectangular area from one RastPort to another.
 * It is almost the same as the operating system routine ClipBlit ()
 * Except this routine checks to make sure it has something to do and
 * it clips to copy to the defined screen size.
 *
 * SYNTAX:
 *  RectCopy (SrcRp, SrcX, SrcY, DestRp, DestX, DestY, width, height);
 *
 *    SrcRp = a pointer to the Source RastPort
 *    SrcX, SrcY = top,left corner to start copying from
 *    DestRp = pointer to the Destination RastPort
 *    DestX, DestY = top,left corner to start copying to
 *    width,height = width and height of rectangle to copy
 */
RectCopy (From, FLeft, FTop, To, TLeft, TTop, width, height)
struct RastPort *From;
int FLeft, FTop;
struct RastPort *To;
int TLeft, TTop;
int width, height;
{
	if (width && height) {
		ClipCopy (From, FLeft, FTop,
			  To  , TLeft, TTop,
			  width, height,
		   	  0xC0, USECLIPBLIT);
	}
}
#endif

/*
 * This routine copies a Rectangular area from a 'Shape' to a RastPort with
 * 'Transparency'  The transparent color is defined by the color that was
 * transparent when the brush/shape was save from DPaint.
 *
 * SYNTAX:
 *  ShapeCopy (Shape, SrcX, SrcY, RastPort, DestX, DestY, width, height);
 *
 *    Shape = a pointer to a Shape
 *    SrcX, SrcY = top,left corner to start copying from
 *    RastPort = Destination RastPort
 *    DestX, DestY = top,left corner to start copying to
 *    width,height = width and height of rectangle to copy
 */

#if USE_SHAPECOPY
ShapeCopy (shape, FLeft, FTop, To, TLeft, TTop, width, height)
Shape *shape;
int FLeft, FTop;
struct RastPort *To;
int TLeft, TTop;
int width, height;
{
	if (width > 0 && height > 0) {
		ClipCopy (ShapePic(shape), FLeft, FTop,
			  To        , TLeft, TTop,
			  width, height,
			  0xE0, USEBLTMASKBITMAPRASTPORT, NULL,
			  shape->MaskBm.Planes[0]);
	}
}
#endif

/*
 * ClipCopy copies a rectanglar area from the Source RastPort to the
 * Destination RastPort and clips the copy to the defined area.
 *
 * SYNTAX:
 *  ClipCopy (SrcRp, SrcX, SrcY, DestRp, DestX, DestY, width, height);
 *
 *    SrcRp = a pointer to the Source RastPort
 *    SrcX, SrcY = top,left corner to start copying from
 *    DestRp = pointer to the Destination RastPort
 *    DestX, DestY = top,left corner to start copying to
 *    width,height = width and height of rectangle to copy
 *
 *  PICX = left side of area to clip to
 *  PICY = top side of area to clip to
 *  FrameWidth = width of area to clip to
 *  FrameHeight = height to area to clip to
 */

ClipCopy (From, FLeft, FTop, To, TLeft, TTop, InWidth, InHeight, minterm,
 type, planemask, bitmask)
struct RastPort *From;
int FLeft, FTop;
struct RastPort *To;
int TLeft, TTop;
int InWidth, InHeight;
int minterm;
UBYTE type;
UBYTE planemask;
UWORD *bitmask;
{
	int width = InWidth; 
	int height = InHeight;

	if (TLeft < PICX) {
		width = InWidth - (PICX - TLeft);
		TLeft = PICX;
		FLeft += InWidth - width;
	} else if (TLeft > PICX + FrameWidth - InWidth) {
		width = (PICX + FrameWidth) - TLeft;
	}

	if (TTop < PICY) {
		height = InHeight - (PICY - TTop);
		TTop = PICY;
		FTop += InHeight - height;
	} else  if (TTop > PICY + FrameHeight - InHeight) {
		height = (PICY + FrameHeight) - TTop;
	}

	if (width > 0 && height > 0) {
		switch (type) {
			case USECLIPBLIT:
				ClipBlit (From, FLeft, FTop,
					  To  , TLeft, TTop,
					  width, height,
				   	  minterm);
				break;
			case USEBLTBITMAP:
				BltBitMap (From->BitMap, FLeft, FTop,
					   To->BitMap  , TLeft, TTop,
					   width, height,
					   minterm, planemask,
					   NULL); /* May need "temp rast" */
				break;
			case USEBLTBITMAPRASTPORT:
				BltBitMapRastPort (From->BitMap, FLeft, FTop,
						   To          , TLeft, TTop,
						   width, height,
						   minterm);
				break;
			case USEBLTMASKBITMAPRASTPORT:
				BltMaskBitMapRastPort (From->BitMap, FLeft, FTop,
						       To          , TLeft, TTop,
						       width, height,
						       minterm, bitmask);
				break;
                }

	}
}

#if USE_ERASESHAPE
/*
 * EraseShape draws a rectangle in the specified rastport the size of
 * the entire shape specified in the specified color at the specified
 * place.
 *
 * SYNTAX:
 *   EraseShape (DestRp, Shape, DestX, DestY, Color)
 *
 *    DestRp = pointer to the Destination RastPort
 *    Shape = pointer to a Shape
 *    DestX, DestY = top,left corner to start drawing rectangle
 *    Color = Color to draw rectangle with
 */

EraseShape (rp, shape, left, top, color)
struct RastPort *rp;
Shape		*shape;
int 		left;
int		top;
int		color;
{
	SetAPen (rp, color);
	ClipRectFill (rp, left, top,
		ShapeWidth(shape),
		ShapeHeight(shape));
}
#endif

#if USE_DRAWSHAPE
/*
 * DrawShape transparently copies an entire shape to a desired rastport
 *
 * SYNTAX:
 *   DrawShape (DestRp, Shape, DestX, DestY);
 *
 *     DestRp = pointer to destination rastport
 *     Shape = pointer to a shape
 *     DestX, DestY = top,left corner to copy shape to
 */

DrawShape (rp, shape, left, top)
struct RastPort *rp;
Shape		*shape;
int 		left;
int		top;
{
	ShapeCopy (shape, 0, 0,
		rp, left, top,
		ShapeWidth(shape),
		ShapeHeight(shape));
}
#endif

#if USE_DRAWPIC
/*
 * DrawPic copies an entire picture to a desired rastport
 *
 * SYNTAX:
 *   DrawPic (DestRp, Pic, DestX, DestY);
 *
 *     DestRp = pointer to destination rastport
 *     Pic = pointer to a picture
 *     DestX, DestY = top,left corner to copy shape to
 */

DrawPic (rp, pic, left, top)
struct RastPort *rp;
Picture		*pic;
int 		left;
int		top;
{
	RectCopy (pic, 0, 0,
		rp, left, top,
		PicWidth(pic),
		PicHeight(pic));
}
#endif

#if USE_CLIPRECTFILL
/*
 * ClipRectFill draws a solid rectangle to the specified rastport in the
 * current foreground color.  It is the same as the OS routine RectFill()
 * except ClipRectFill clips to the defined area.
 *
 * SYNTAX:
 *   ClipRectFill (Rp, left, top, width, height)
 *
 *   Rp = pointer to rastport to draw rectangle into
 *   left,top = top,left corner of rectangle
 *   width,height = width and height to rectangle
 */

ClipRectFill (rp, left, top, width, height)
struct RastPort	*rp;
int		left;
int		top;
int		width;
int		height;
{
	if (left < PICX) left = PICX;
	if (left >= PICX + FrameWidth) return;
	if (top < PICY) top = PICY;
	if (top >= PICY + FrameHeight) return;
	if (left + width > PICX + FrameWidth) width = (PICX + FrameWidth) - left;
	if (left + width < PICX) return;
	if (top + height > PICY + FrameHeight) height = (PICY + FrameHeight) - top;
	if (top + height < PICY) return;

	RectFill (rp, left, top, left + width - 1, top + height - 1);
}
#endif

#if USE_MATTE
void Matte (shape, fleft, ftop, rp, tleft, ttop, width, height)
	Shape		*shape;
	int 		fleft;
	int		ftop;
	struct RastPort *rp;
	int 		tleft;
	int		ttop;
	int		width;
	int		height;
{
	UBYTE oldmask;

	oldmask = rp->Mask;
	rp->Mask = ~rp->FgPen;
	ClipCopy (shape, fleft, ftop,
		  rp   , tleft, ttop, width, height,
		  0x20, USECLIPBLIT);
	rp->Mask = rp->FgPen;
	ClipCopy (shape, fleft, ftop,
		  rp   , tleft, ttop, width, height,
		  0xE0, USECLIPBLIT);
	rp->Mask = oldmask;
}
#endif

#if USE_DRAWMATTE
void DrawMatte (rp, shape, left, top)

	struct RastPort *rp;
	Shape		*shape;
	int 		left;
	int		top;
{
	Matte (shape, 0, 0,
		rp, left, top,
		ShapeWidth(shape),
		ShapeHeight(shape));
}
#endif
