/* 
 * split-n-slide.c
 *
 * Split Window & Slide Image off screen
 *
 * Copyleft (c) 2001 Michael P. Shimko shimko@maui.net
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details. 
 *
 */

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


/* ******************** GLOBAL VARIABLES ***************** */
/*              1-------10--------20-24*/
char name[24]= "Split & Slide 0.2";	

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

VarStruct varstr[]= {					/*------10--------20--------30--------40--------50--------60--------70------80*/
	{ LABEL,	 	"2 strips", 	0.0, 0.0, 0.0, 	"" },
	};

/* 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 label1;	/* because of the 'label' button */
} Cast;


/* cfra: the current frame */

float cfra;


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

static void use_ibuf(char src[], char dest[]);
static void use_ibuf2 (float src[], char dest[]);

void mixit (float rgba[], char c1[], char c2[], char dest[], float f, int style, int even, float p);


/* ******************** 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;
}
/************************ End Fixed Functions *******************************/


static void use_ibuf(char src[3], char dest[3]) {
   int i;
   for (i=0; i<=3; i++) dest[i]= src[i];
}

static void use_ibuf2 (float src[3], char dest[3]) {
   int i;
   for (i=0; i<=3; i++) dest[i]= src[i];
}


void plugin_seq_doit(Cast *cast, float facf0, float facf1, int x, int y, ImBuf *ibuf1, ImBuf *ibuf2, ImBuf *out, ImBuf *use)
{
   char *in1, *in1b, 	/* source . */
	*in2, 	/* input from source 2.  This is the image being transitioned to. */
	*dest; /* out put row. */
   int	row, 	/* current row for output. */
	col, 	/* current column. */
	x1, x2; /* col split locations */
   int dy;
   int offset = 0;
   int srow = 0;

   if (!ibuf1 || !ibuf2 || ibuf2==ibuf1) return;


   /* Acording to blender documentation the array is ABGR */

   srow = facf0 * y;
   dy = y - srow;
   offset = srow * x * 4;

      
   dest = (char *) out->rect;
   in2 = (char *) ibuf2->rect;
   in1 = (char *) ibuf1->rect; 
   in1b = (char *) ibuf1->rect;
   in1 += offset;

   x1 = x/3; x2 = x - x1;

   for (row = 0; row < y; row++) 
   {
      for (col = 0; col < x; col++) 
      {	 
        if (row <= dy && (col <= x1 || col >= x2))
	   use_ibuf (in1, dest);
        else if (row < srow && (col > x1 && col < x2)) /* middle strip, background */
	   use_ibuf(in2, dest);
        else if (row >= srow  && (col > x1 && col < x2))  /* middle strip, foreground moving up */
	   use_ibuf(in1b, dest); 
        else if (row >= srow  && (col <= x1 && col >= x2)) /* outside strip, background */ 
	    use_ibuf(in2, dest); 
	else  
	   use_ibuf (in2, dest);

	dest += 4;
	in2 += 4;
        in1 += 4;
        if (row >= srow)
	  in1b += 4;
      }
   }		

} /* plugin_seq_doit */			 
