/*************************************************************************
Copyright(c) 2004-2006 Analog Devices, Inc. All Rights Reserved.

This software is proprietary and confidential.  By using this software you agree
to the terms of the associated Analog Devices License Agreement.

File Name: adi_graph_canvas.c 

Description - Part of 'adi_graph' library.  See readme file for details.

*********************************************************************************/

#include <stdlib.h>
#include <stdio.h>
#include "adi_graph.h"
#include "adi_graph_driver.h"

typedef struct
{
	int width, height;
} canvas_struct;

void ADI_CanvasCopyArea ( ADI_sGraphPrim *src_gp, ADI_sGraphPrim *dest_gp )
{
#ifdef PRINT_TO_CONSOLE	     
	{
		printf ( "SRGP (%d,%d)-(%d,%d) TO (%d,%d)-(%d,%d)\n",
		src_gp->x1, src_gp->y1, src_gp->x2, src_gp->y2,
		dest_gp->x1, dest_gp->y1, dest_gp->x1+( src_gp->x2-src_gp->x1 ), dest_gp->y1+( src_gp->y2-src_gp->y1 ) );
	}
#endif
	
	int xs, ys, xd, yd;
	int src_x1 = src_gp->x1;
	int src_x2 = src_gp->x2;
	int src_y1 = src_gp->y1;
	int src_y2 = src_gp->y2;
	
	/* Note: Not clipping the source rectangle.  Does the user know what their doing? */
	
	int dest_x1 = dest_gp->x1;
	int dest_x2 = dest_x1 + ( src_x2 - src_x1 );
	int dest_y1 = dest_gp->y1;
	int dest_y2 = dest_y1 + ( src_y2 - src_y1 );
	
	/* Clip according to the destination rectangle */

	int clip_x1 = dest_gp->clip_x1;
	int clip_x2 = dest_gp->clip_x2;
	int clip_y1 = dest_gp->clip_y1;
	int clip_y2 = dest_gp->clip_y2;
	
	/* Make sure the "1" values are lower than the "2" values */

	ADI_SwapIfGreaterThan ( src_x1, src_x2 );
	ADI_SwapIfGreaterThan ( src_y1, src_y2 );
	ADI_SwapIfGreaterThan ( dest_x1, dest_x2 );
	ADI_SwapIfGreaterThan ( dest_y1, dest_y2 );
	ADI_SwapIfGreaterThan ( clip_x1, clip_x2 );
	ADI_SwapIfGreaterThan ( clip_y1, clip_y2 );
		
	/* Clip the rectangle as required */
	
	if ( clip_x1 > dest_x1 )
	{
		src_x1 += ( clip_x1 - dest_x1 );
		dest_x1 = clip_x1;
	}
	if ( clip_y1 > dest_y1 )
	{
		src_y1 += ( clip_y1 - dest_y1 );
		dest_y1 = clip_y1;
	}
	if ( clip_x2 < dest_x2 )
	{
		dest_x2 = clip_x2;
	}
	if ( clip_y2 < dest_y2 )
	{
		dest_y2 = clip_y2;
	}
#ifdef PRINT_TO_CONSOLE		
	{
	printf ( "VIDEO POST CLIP (%d,%d)-(%d,%d) TO (%d,%d)-(%d,%d)\n",
		src_x1, src_y1, src_x2, src_y2,
		dest_x1, dest_y1, dest_x2, dest_y2 );
	}
#endif		
	for ( ys = src_y1, yd = dest_y1 ; yd <= dest_y2; ++ys, ++yd )
	{
		for ( xs = src_x1, xd = dest_x1; xd <= dest_x2; ++xs, ++xd )
		{
			int val = ADI_GRAPH_DRV_ReadFromCanvas ( xs, ys, src_gp->canvas );
			ADI_GRAPH_DRV_WriteToCanvas ( xd, yd, val, dest_gp->canvas );
		}
	}
}

void *ADI_CanvasGetScreenCanvas ()
{
	return ADI_GRAPH_DRV_GetScreenCanvas ();
}

void *ADI_CanvasNew ( int width, int height )
{
	int size = ( ( sizeof ( canvas_struct) ) + ( sizeof ( unsigned int ) * width * height ) );
	void *block = malloc ( size );
	if ( block )
	{
		canvas_struct *pcanvas = ( canvas_struct * ) block;
		pcanvas->width = width;
		pcanvas->height = height;
	}

	return block;
}

void ADI_CanvasDelete ( void * canvas )
{
	free ( canvas );
}
