/* 
   Sequence Plugin: 		zcompose.c
   Made by SirDude              mein@cs.umn.edu
   http://www.cs.umn.edu/~mein/blender
   Created: Wed Aug 22 11:32:08 CDT 2001
   This plugin takes 2 or 3 strips as input and uses the zbuffer to
   select output.  This plugin is for sgefant... ;)
   Its Public Domain
 */

#include "plugin.h"
#include <stdio.h>

/* ******************** GLOBAL VARIABLES ***************** */


char name[24]= "zcompose";	

/* structure for buttons, 
 *  butcode      name           default  min  max  0
 */

VarStruct varstr[]= {
	{ LABEL,	"2or3 strips", 0.0, 0.0, 0.0, ""}, 
	{ TOG|INT,	"Invert", 0.0, 0.0, 1.0, "Invert zbuffer"},
};

/* The cast struct is for input in the main doit function
   Varstr and Cast must have the same variables in the same order */ 

typedef struct Cast {
	int dummy;			/* because of the 'label' button */
        int invert;
} Cast;


/* cfra: the current frame */

float cfra;

void plugin_seq_doit(Cast *, float, float, int, int, ImBuf *, ImBuf *, ImBuf *, ImBuf *);

/* ******************** Fixed functions ***************** */

int plugin_seq_getversion(void) 
{
	return B_PLUGIN_VERSION;
}

void plugin_but_changed(int but) 
{
}

void plugin_init()
{
}

void plugin_getinfo(PluginInfo *info)
{
	info->name= name;
	info->nvars= sizeof(varstr)/sizeof(VarStruct);
	info->cfra= &cfra;

	info->varstr= varstr;

	info->init= plugin_init;
	info->seq_doit= (SeqDoit) plugin_seq_doit;
	info->callback= plugin_but_changed;
}

int getmax(int x, int y, int z) {
   if ((x >= y) && (x >= z)) {
      return 1;
   } else if ((y >= x) && (y >= z)) {
      return 2;
   }
   return 3;
}

int getmin(int x, int y, int z) {
   if ((x <= y) && (x <= z)) {
      return 1;
   } else if ((y <= x) && (y <= z)) {
      return 2;
   }
   return 3;
}

void plugin_seq_doit(Cast *cast, float facf0, float facf1, int x, int y, 
   ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *ibufo, ImBuf *use) {
   int xo, i, i3, mymax;
   char *in1, *in2, *in3, *out;	
   int *zin1, *zin2, *zin3;

   if (!ibuf1->zbuf) {
       printf("Error: input 1 has no z-buffer\n");
       return;
   }
   if (!ibuf2->zbuf) {
       printf("Error: input 2 has no z-buffer\n");
       return;
   }

   xo= x;
   in1=  (char *)ibuf1->rect;
   in2=  (char *)ibuf2->rect;
   in3=  (char *)use->rect;
   out=  (char *)ibufo->rect;
   zin1 = (int *)ibuf1->zbuf;
   zin2 = (int *)ibuf2->zbuf;
	
   if (use->zbuf) {
      i3 = 1;
      zin3 = (int *)use->zbuf;
   } else {
      i3 = 0;
      zin3 = 0;
   }
   while(y--) {
      x= xo;
      while(x--) {
        if (cast->invert == 1) {
           mymax = getmax(zin1[0], zin2[0], zin3[0]);
        } else {
           mymax = getmin(zin1[0], zin2[0], zin3[0]);
        }
        if ((i3 == 1) && (mymax == 3)) {
           for (i=0;i<4;i++) {
              out[i] = in3[i];
           }
        } else if (mymax == 2){
           for (i=0;i<4;i++) {
              out[i] = in2[i];
           }
        } else {
           for (i=0;i<4;i++) {
              out[i] = in1[i];
           }
        }
	in1 +=4; in2 +=4; in3+=4; out +=4;
        zin1++;
        zin2++;
        if (i3 == 1) zin3++;
      }		
   }
}
