/*
		graphic effect lib.
		  Video Digitize Smoother

		h. Toda 1994 4 23
*/

#include <stdio.h>
#include <stdlib.h>
#include <egb.h>
#include "g_eff.h"

#define NOERR 0		/* no error */

static int mx ;
static int aSen ;
static int mSen ;
static int cMax ;
static int aMax ;
static int x1 ;
static int y1 ;
static int x2 ;
static int y2 ;
static int (*read1)() ;
static int (*write)() ;
static int (*mask)() ;

g_videoDigitizeSmoother( BASICPARA *para, int mode, int line )
{
	mx = para->mix ;
	aSen = para->alphaSen ;
	mSen = para->maskSen ;
	cMax = para->colorMax ;
	aMax = para->alphaMax ;
	x1 = para->lupx ;
	y1 = para->lupy ;
	x2 = para->rdwx ;
	y2 = para->rdwy ;
	read1 = para->read1 ;
	write = para->write ;
	mask = para->mask ;

	line = ( line & 1 ) ^ 1 ;

	switch( mode )
	{
	case 0:
		normal( line ) ;
		break ;
	case 1:
		deep( line ) ;
		break ;
	default:
		normal( line ) ;
		break ;
	}

	return NOERR ;
}

static normal( int line )
{
	unsigned char a[4][4] ;
	int i, x, y ;
	int n ;

	for( y = y1 ; y <= y2 ; y++ )
	{
		if( (y % 2) == line )
		{
			for( x=x1 ; x <= x2 ; x++ )
			{
				if( y >= 1 )
					read1( x, y-1, a[0] ) ;
				else
					read1( x, 1, a[0] ) ;
				read1( x, y,   a[1] ) ;
				read1( x, y+1, a[2] ) ;

				for( i=0 ; i<3 ; i++ )
				{
					n = ck3( a[0][i], a[1][i], a[2][i] ) ;
					a[3][i] = a[n][i] ;
				}
				mixWrite( x, y, a[3], a[1] ) ;
			}
		}
		else
		{
			for( x=x1 ; x <= x2 ; x++ )
			{
				read1( x, y, a[1] ) ;
				mixWrite( x, y, a[1], a[1] ) ;
			}
		}
	}

	return NOERR ;
}

static deep( int line )
{
	unsigned char a[8][4] ;
	int i, x, y ;
	int n ;

	for( y = y1 ; y <= y2 ; y++ )
	{
		if( (y % 2) == line )
		{
			for( x=x1 ; x <= x2 ; x++ )
			{
				if( y >= 1 )
				{
					read1( x-1, y-1, a[0] ) ;
					read1( x,   y-1, a[1] ) ;
					read1( x+1, y-1, a[2] ) ;
				}
				else
				{
					read1( x-1, 1, a[0] ) ;
					read1( x,   1, a[1] ) ;
					read1( x+1, 1, a[2] ) ;
				}
				read1( x,   y,   a[3] ) ;
				read1( x-1, y+1, a[4] ) ;
				read1( x,   y+1, a[5] ) ;
				read1( x+1, y+1, a[6] ) ;

				for( i=0 ; i<3 ; i++ )
				{
					n = ck7( a[0][i], a[1][i], a[2][i],
							 a[3][i], a[4][i], a[5][i], a[6][i] ) ;

					a[7][i] = a[n][i] ;
				}
				mixWrite( x, y, a[7], a[3] ) ;
			}
		}
		else
		{
			for( x=x1 ; x <= x2 ; x++ )
			{
				read1( x, y, a[3] ) ;
				mixWrite( x, y, a[3], a[3] ) ;
			}
		}
	}

	return NOERR ;
}

/* 書き込むデータ a[4]   書き込まれる所にあるデータ b[4] */

static mixWrite( int x, int y, unsigned char *a, unsigned char *b )
{
	unsigned char c[4] ;
	int mix ;

	if( mSen )
	{
		if( mask( x, y ) >= mSen )
			return NOERR ;
	}

	mix = mx ;
	if( aSen )
	{
		mix = mix * b[3] / aMax ;
	}

	c[0] = ( a[0] * mix + b[0] * ( 256 - mix ) + 0x80 ) >> 8 ;
	c[1] = ( a[1] * mix + b[1] * ( 256 - mix ) + 0x80 ) >> 8 ;
	c[2] = ( a[2] * mix + b[2] * ( 256 - mix ) + 0x80 ) >> 8 ;
	c[3] = b[3] ;

	if( mix )
	{
		write( x, y, c ) ;
	}

	return NOERR ;
}

static ck3( int a, int b, int c )
{
	int temp ;
	int n0, n1, n2 ;

	n0 = 0 ; n1 = 1 ; n2 = 2 ;

	if( a > b )
	{
		temp = a ;
		a = b ;
		b = temp ;

		temp = n0 ;
		n0 = n1 ;
		n1 = temp ;
	}

	if( a > c )
	{
		temp = a ;
		a = c ;
		c = temp ;

		temp = n0 ;
		n0 = n2 ;
		n2 = temp ;
	}

	if( b > c )
	{
		temp = b ;
		b = c ;
		c = temp ;

		temp = n1 ;
		n1 = n2 ;
		n2 = temp ;
	}

	return n1 ;
}

static ck7( int a0, int a1, int a2, int a3, int a4, int a5, int a6 )
{
	int temp ;
	int m[7] ;
	int a[7] ;
	int i, j ;

	for( i=0 ; i<7 ; i++ )m[i] = i ;

	a[0] = a0 ; a[1] = a1 ; a[2] = a2 ; a[3] = a3 ;
	a[4] = a4 ; a[5] = a5 ; a[6] = a6 ;

	for( j=1 ; j<5 ; j++ )
	{
		for( i=j ; i<7 ; i++ )
		{
			if( a[j-1] > a[i] )
			{
				temp = a[i] ;
				a[i] = a[j-1] ;
				a[j-1] =temp ;

				temp = m[i] ;
				m[i] = m[j-1] ;
				m[j-1] =temp ;
			}
		}
	}

	return m[3] ;
}

/*
static ck9( int a0, int a1, int a2, int a3,
			int a4, int a5, int a6, int a7, int a8 )
{
	int temp ;
	int m[9] ;
	int a[9] ;
	int i, j ;

	for( i=0 ; i<9 ; i++ )m[i] = i ;

	a[0] = a0 ; a[1] = a1 ; a[2] = a2 ; a[3] = a3 ; a[4] = a4 ;
	a[5] = a5 ; a[6] = a6 ; a[7] = a7 ; a[8] = a8 ;

	for( j=1 ; j<6 ; j++ )
	{
		for( i=j ; i<9 ; i++ )
		{
			if( a[j-1] > a[i] )
			{
				temp = a[i] ;
				a[i] = a[j-1] ;
				a[j-1] =temp ;

				temp = m[i] ;
				m[i] = m[j-1] ;
				m[j-1] =temp ;
			}
		}
	}

	return m[4] ;
}
*/

