#include "ninox.h"

#define Influence 0.9

double *
create_weight_buffer_decrease_lr(int w, int h)
	{
	double *ptr,*buf = ZeroMalloc(w * h * sizeof(double));
	int x,y,W;

	W = w * Influence;
	for(y=0; y<h; ++y) {
	   ptr=buf + y*w;
	   for(x=0; x<W; ++x) *(ptr++) = 1.0 - (double)x/(double)W;
	   }

	return buf;
	}

double *
create_weight_buffer_increase_lr(int w, int h)
	{
	double *ptr,*buf = ZeroMalloc(w * h * sizeof(double));
	int x,y,W;

	W = w * Influence;
	for(y=0; y<h; ++y) {
	   ptr = buf + y*w+w-W;
	   for(x=w-W; x<w; ++x) *(ptr++) = (double)(x-w+W)/(double)W;
	   }

	return buf;
	}

double *
create_weight_buffer_decrease_ud(int w, int h)
	{
	double *ptr,*buf = ZeroMalloc(w * h * sizeof(double));
	int x,y,H;

	H = h * Influence;
	for(y=0; y<H; ++y) {
	   ptr = buf + y*w;
	   for(x=0; x<w; ++x) *(ptr++) = 1.0 - (double)y/(double)H;
	   }

	return buf;
	}

double *
create_weight_buffer_increase_ud(int w, int h)
	{
	double *ptr,*buf = ZeroMalloc(w * h * sizeof(double));
	int x,y,H;

	H = h * Influence;
	for(y=h-H; y<h; ++y) {
	   ptr = buf + y*w;
	   for(x=0; x<w; ++x) *(ptr++) = (double)(y-h+H)/(double)H;
	   }

	return buf;
	}

static double
curvepoint(int x, int y, int w, int h)
	{
	double d = sqrt(x*x + y*y);
	double L = sqrt(w*w + h*h) * 0.707;
	
	if (d>L) d=L;

	return 1.0 - d/L;
	}

double *
create_weight_buffer_decrease_tl(int w, int h)
	{
	double W,H,M,*ptr,*buf = ZeroMalloc(w * h * sizeof(double));
	int x,y,inc;

	W = w * Influence; H = Influence * h;
	M = W+H; inc = w-W;
	ptr=buf;
	for(y=0; y<H; ++y,ptr+=inc) 
	   for(x=0; x<W; ++x)
		*(ptr++) = curvepoint(x,y,W,H);

	return buf;
	}

double *
create_weight_buffer_decrease_tr(int w, int h)
	{
	double M,*ptr,*buf = ZeroMalloc(w * h * sizeof(double));
	int x,y,W,H;

	// width & height of region
	W = w * Influence; H = Influence * h;
	M = W+H;
	for(y=0; y<H; ++y) {
	   ptr = buf + y*w + (w-W);
	   for(x=w-W; x<w; ++x)
		*(ptr++) = curvepoint(w-x,y,W,H);
	   }

	return buf;
	}

double *
create_weight_buffer_decrease_bl(int w, int h)
	{
	double M,*ptr,*buf = ZeroMalloc(w * h * sizeof(double));
	int x,y,W,H;

	W = w * Influence; H = Influence * h;
	M = W+H;
	for(y=h-H; y<h; ++y) {
	   ptr = buf + y*w;
	   for(x=0; x<W; ++x)
		*(ptr++) = curvepoint(x,h-y,W,H);
	   }

	return buf;
	}

double *
create_weight_buffer_decrease_br(int w, int h)
	{
	double M,*ptr,*buf = ZeroMalloc(w * h * sizeof(double));
	int x,y,W,H;

	W = w * Influence; H = Influence * h;
	M = W+H;
	for(y=h-H; y<h; ++y) {
	   ptr = buf + y*w + (w-W);
	   for(x=w-W; x<w; ++x)
		*(ptr++) = curvepoint(w-x,h-y,W,H);
	   }

	return buf;
	}

int
draw_point(struct Image *img, int x, int y, unsigned int val)
	{
	int o = y*img->width + x;
	unsigned char *ptr;

	if (x<0 || y<0 || x >= img->width || y >= img->height)
	   return 0;

	if (val<0) val=0; if (val>255) val=255;

	switch(img->depth) {
	   case 8:
		ptr = img->data+o;
		*ptr ^= val;
		break;
	   case 16:
		ptr = img->data+o*2;
		*(ptr++) ^= val; *(ptr++) ^= val;
		break;
	   case 24:
		ptr = img->data+o*3;
		*(ptr++) ^= val; *(ptr++) ^= val; *(ptr++) ^= val;
		break;
	   }

	return 1;
	}

int
map_control_points(struct morph_point *m, int npoints, struct Image *img)
	{
	struct morph_point *pt;
	int i;

	Print("Mapping %d control points\n",npoints);
	for(i=0; i<npoints; ++i) {
	   pt = m + i;
	   if (pt->w || pt->h) {
		//draw_point(img,pt->x,pt->y,0xff);
	   	draw_point(img,pt->x+pt->x_offset,pt->y+pt->y_offset,0xff);
		}
	   }
	return 1;
	}

