#!/usr/bin/perl

#######################################################################
# LiVES image_overlay plugin, version 1.7
# RFX version 1.8
# autogenerated from script by DgMvEcuador|

# rendered plugins should accept:
# <plugin_name> version (return <plugin_name> version <version>)
# <plugin_name> get_define
# <plugin_name> get_capabilities
# <plugin_name> get_description (e.g. "Edge detect|Edge detecting|1|1|")
# <plugin_name> clear (clean up any plugin generated temp files)
# and optionally any of: 
# <plugin_name> get_parameters
# <plugin_name> get_param_window
# <plugin_name> get_onchange
# <plugin_name> onchange_<when> (for any triggers, e.g. onchange_init)
#
# they must accept:
# <plugin_name> process <parameters>

# You should not skip any frames, if a frame is not changed you must do:
# `cp $in $out`
#
# for *non-Perl* plugins, LiVES will call:
# <plugin_name> process "<dir>" <in_ext> <out_ext> <start> <end>
#  <width> <height> <parameters>
# first you should chdir to <dir>
# then you should create all output frames %8d$out_ext in numerical 
# from start to end inclusive,
# each time calling sig_progress (see smogrify) - writes current frame number to 
# <dir>/.status
# and checking for pause
#
# Any errors should be transmitted as in sig_error - 
# write "error|msg1|msg2|msg3|" to <dir>/.status
# msgn must not contain "\n", but can be omitted

# output frames should be named %8d$out_ext in the same directory
# after processing, you should leave no gaps in out frames, you should not resize
# or change the palette from RGB24 (LiVES will check and autocorrect this soon)

# Also you must implement your own: &sig_error and &sig_progress


#######################################################################

use POSIX;

my $command=$ARGV[0];

if ($command eq "get_capabilities") {
    # capabilities is a bitmap field
    # 0x0001 == slow (hint to GUI)
    # 0x0002 == may resize (all frames to  x )
    # 0x0004 == block mode generator
    # 0x8000 == reserved
    print "32768\n";
    exit 0;
}

if ($command eq "version") {
    print "image_overlay version 2 : builder version 2.0.3\n";
    exit 0;
}

if ($command eq "get_define") {
    print "|1.7\n";
    exit 0;
}

if ($command eq "get_description") {
    #format here is "Menu entry|Action description|min_frames|number_of_in_channels|"
    # min_frames==-1 indicates a special "no processing" effect. This allows more
    #general parameter windows which are not really effects (e.g. frame_calculator)
    print "Image overlay|Overlaying an image onto video|1|1|\n";
    exit 0;
}


if ($command eq "get_parameters") {
    # "name|label|type|other fields..."
    # eg. print "radius|_radius|num0|1|1|100|";
    # types can be numx,colRGB24,bool,string or string_list
    print "iposX|Init pos_X:|num0|0|-10000|10000|\n";
    print "iposY|Init pos_Y:|num0|0|-10000|10000|\n";
    print "isizeX|_Init Size X:|num0|0|0|1000000|\n";
    print "isizeY|_Init Size Y:|num0|0|0|1000000|\n";
    print "ns1|Use _Natural Size|bool|0|\n";
    print "a1|Init _Alpha:|num0|100|0|100|\n";
    print "img|_Image|string||80|\n";
    print "anim|Active _animation|bool|0|\n";
    print "eposX|End pos_X:|num0|0|-10000|10000|\n";
    print "eposY|End pos_Y:|num0|0|-10000|10000|\n";
    print "esizeX|_End Size X:|num0|0|0|1000000|\n";
    print "esizeY|_End Size Y:|num0|0|0|1000000|\n";
    print "ns2|Use _Natural Size|bool|0|\n";
    print "a1|End _Alpha:|num0|100|0|100|\n";
    print "aspect|Keep image aspect _ratio|bool|1|\n";
    exit 0;
}

if ($command eq "get_param_window") {
    print "layout|p0|p1||\n";
    print "layout|p2|p3||\n";
    print "layout|p4||\n";
    print "layout|p5|\n";
    print "layout|p6||\n";
    print "layout|p14||\n";
    print "layout|hseparator||\n";
    print "layout|p7||\n";
    print "layout|p8|p9||\n";
    print "layout|p10|p11||\n";
    print "special|fileread|6||\n";
    exit 0;
}

if ($command eq "get_onchange") {
    print "init|\n";
    exit 0;
}

#######################################################

if ($command eq "process") {

# in case of error, you should do:
# &sig_error("msg1","msg2","msg3","msg4"); [ msg's are optional, but must not
# contain newlines (\n) ]

##### check requirements first #######
    if (&location("composite") eq "") {
      &sig_error("You must install 'composite' before you can use this effect.");
      exit 1;
    }
    if (&location("convert") eq "") {
      &sig_error("You must install 'convert' before you can use this effect.");
      exit 1;
    }

###### handle parameters #############
# autogenerated from get_parameters

    unless (defined($ARGV[1])) {
      $p0=0;
    }
    else {
      $p0=$ARGV[1];
    }
    unless (defined($ARGV[2])) {
      $p1=0;
    }
    else {
      $p1=$ARGV[2];
    }
    unless (defined($ARGV[3])) {
      $p2=0;
    }
    else {
      $p2=$ARGV[3];
    }
    unless (defined($ARGV[4])) {
      $p3=0;
    }
    else {
      $p3=$ARGV[4];
    }
    unless (defined($ARGV[5])) {
      $p4=0;
    }
    else {
      $p4=$ARGV[5];
    }
    unless (defined($ARGV[6])) {
      $p5=100;
    }
    else {
      $p5=$ARGV[6];
    }
    unless (defined($ARGV[7])) {
      $p6="";
    }
    else {
      $p6=$ARGV[7];
    }
    unless (defined($ARGV[8])) {
      $p7=0;
    }
    else {
      $p7=$ARGV[8];
    }
    unless (defined($ARGV[9])) {
      $p8=0;
    }
    else {
      $p8=$ARGV[9];
    }
    unless (defined($ARGV[10])) {
      $p9=0;
    }
    else {
      $p9=$ARGV[10];
    }
    unless (defined($ARGV[11])) {
      $p10=0;
    }
    else {
      $p10=$ARGV[11];
    }
    unless (defined($ARGV[12])) {
      $p11=0;
    }
    else {
      $p11=$ARGV[12];
    }
    unless (defined($ARGV[13])) {
      $p12=0;
    }
    else {
      $p12=$ARGV[13];
    }
    unless (defined($ARGV[14])) {
      $p13=100;
    }
    else {
      $p13=$ARGV[14];
    }
    unless (defined($ARGV[15])) {
      $p14=1;
    }
    else {
      $p14=$ARGV[15];
    }
    $!=0;
    if ($p0>=0) {
        $p0=int(POSIX::strtod($p0)*1+.5)/1;
    } else {
        $p0=int(POSIX::strtod($p0)*1-.5)/1;
    }
    if ($p0<-10000) {
       &sig_error("iposX must be >= -10000");
       exit 1;
    }
    if ($p0>10000) {
       &sig_error("iposX must be <= 10000");
       exit 1;
    }
    $!=0;
    if ($p1>=0) {
        $p1=int(POSIX::strtod($p1)*1+.5)/1;
    } else {
        $p1=int(POSIX::strtod($p1)*1-.5)/1;
    }
    if ($p1<-10000) {
       &sig_error("iposY must be >= -10000");
       exit 1;
    }
    if ($p1>10000) {
       &sig_error("iposY must be <= 10000");
       exit 1;
    }
    $!=0;
    if ($p2>=0) {
        $p2=int(POSIX::strtod($p2)*1+.5)/1;
    } else {
        $p2=int(POSIX::strtod($p2)*1-.5)/1;
    }
    if ($p2<0) {
       &sig_error("isizeX must be >= 0");
       exit 1;
    }
    if ($p2>1000000) {
       &sig_error("isizeX must be <= 1000000");
       exit 1;
    }
    $!=0;
    if ($p3>=0) {
        $p3=int(POSIX::strtod($p3)*1+.5)/1;
    } else {
        $p3=int(POSIX::strtod($p3)*1-.5)/1;
    }
    if ($p3<0) {
       &sig_error("isizeY must be >= 0");
       exit 1;
    }
    if ($p3>1000000) {
       &sig_error("isizeY must be <= 1000000");
       exit 1;
    }
    $p4=~(~$p4);
    $!=0;
    if ($p5>=0) {
        $p5=int(POSIX::strtod($p5)*1+.5)/1;
    } else {
        $p5=int(POSIX::strtod($p5)*1-.5)/1;
    }
    if ($p5<0) {
       &sig_error("a1 must be >= 0");
       exit 1;
    }
    if ($p5>100) {
       &sig_error("a1 must be <= 100");
       exit 1;
    }
    $p7=~(~$p7);
    $!=0;
    if ($p8>=0) {
        $p8=int(POSIX::strtod($p8)*1+.5)/1;
    } else {
        $p8=int(POSIX::strtod($p8)*1-.5)/1;
    }
    if ($p8<-10000) {
       &sig_error("eposX must be >= -10000");
       exit 1;
    }
    if ($p8>10000) {
       &sig_error("eposX must be <= 10000");
       exit 1;
    }
    $!=0;
    if ($p9>=0) {
        $p9=int(POSIX::strtod($p9)*1+.5)/1;
    } else {
        $p9=int(POSIX::strtod($p9)*1-.5)/1;
    }
    if ($p9<-10000) {
       &sig_error("eposY must be >= -10000");
       exit 1;
    }
    if ($p9>10000) {
       &sig_error("eposY must be <= 10000");
       exit 1;
    }
    $!=0;
    if ($p10>=0) {
        $p10=int(POSIX::strtod($p10)*1+.5)/1;
    } else {
        $p10=int(POSIX::strtod($p10)*1-.5)/1;
    }
    if ($p10<0) {
       &sig_error("esizeX must be >= 0");
       exit 1;
    }
    if ($p10>1000000) {
       &sig_error("esizeX must be <= 1000000");
       exit 1;
    }
    $!=0;
    if ($p11>=0) {
        $p11=int(POSIX::strtod($p11)*1+.5)/1;
    } else {
        $p11=int(POSIX::strtod($p11)*1-.5)/1;
    }
    if ($p11<0) {
       &sig_error("esizeY must be >= 0");
       exit 1;
    }
    if ($p11>1000000) {
       &sig_error("esizeY must be <= 1000000");
       exit 1;
    }
    $p12=~(~$p12);
    $!=0;
    if ($p13>=0) {
        $p13=int(POSIX::strtod($p13)*1+.5)/1;
    } else {
        $p13=int(POSIX::strtod($p13)*1-.5)/1;
    }
    if ($p13<0) {
       &sig_error("a1 must be >= 0");
       exit 1;
    }
    if ($p13>100) {
       &sig_error("a1 must be <= 100");
       exit 1;
    }
    $p14=~(~$p14);

   if ($img_ext eq ".png") {
        $img_prefix="PNG32:";
   } else {
        $img_prefix="";
   }

   if ($out_ext eq ".png") {
        $out_prefix="PNG32:";
   } else {
        $out_prefix="";
   }

    $actualX=$p0;
    $actualY=$p1;
    $actualSizeX=$p2;
    $actualSizeY=$p3;
    
    $ns1=$p4;
    $alfa1=$p5;
    
    $img=$p6;
    $ani=$p7;
    
    $finalX=$p8;
    $finalY=$p9;
    $finalSizeX=$p10;
    $finalSizeY=$p11;
    
    $ns2=$p12;
    $alfa2=$p13;
    
    if ($p14) {
    	$asp="";
    }
    else {
    	$asp="!";
    }
    
    
    if ( $ns1 )
    {
    	&get_image_size($img);
    	$actualSizeX=$hsize;
    	$actualSizeY=$vsize;
    }
    
    if ( $ns2 )
    {
    	&get_image_size($img);
    	$finalSizeX=$hsize;
    	$finalSizeY=$vsize;
    }
    
    if ( $ani )
    {
    	$pasos=$end-$start+1;
    	$deltaX=($finalX-$actualX)/$pasos;
    	$deltaY=($finalY-$actualY)/$pasos;
    	$deltaSizeX=($finalSizeX-$actualSizeX)/$pasos;
    	$deltaSizeY=($finalSizeY-$actualSizeY)/$pasos;
    	$deltaAlfa=($alfa2-$alfa1)/$pasos;
    } else {
    	$deltaX=0;
    	$deltaY=0;
    	$deltaSizeX=0;
    	$deltaSizeY=0;
    	$deltaAlfa=0;
    }
    

    if ($start==0) {$start = 1;}


################# loop through frames #################
   if ($img_ext eq ".png") {
        $img_prefix="PNG32:";
   } else {
        $img_prefix="";
   }

   if ($out_ext eq ".png") {
        $out_prefix="PNG32:";
   } else {
        $out_prefix="";
   }

    for ($frame=$start;$frame<=$end;$frame++) {
	# sig progress will update the progress bar from $start->$end
	$name=&mkname($frame);
	$in="$name$img_ext";

     if (!defined($end) || $end==0) {
         print STDERR "WARNING: generator plugin did not set $end !";
         &sig_error("Generator plugin did not set $end.");
     }
	$out="$name$out_ext";

# wait for front end to create 
 while (!-f $in) {
     sleep 1;
 }

##################### the all-important bit #######################

        system("$composite_command -alpha on -dissolve $alfa1 -geometry $actualSizeX$asp"."x"."$actualSizeY$asp"."+"."$actualX"."+"."$actualY \"$img\" \"$img_prefix$in\" \"$out_prefix$out\"");
        if ( $ani )
        {
        	$actualX+=$deltaX;
        	$actualY+=$deltaY;
        	$actualSizeX+=$deltaSizeX;
        	$actualSizeY+=$deltaSizeY;
        	$alfa1+=$deltaAlfa;
        }

###################################################################
        $opfailed=0;
        if (! -f $out) {
            print STDERR "Warning: effect plugin image_overlay skipped frame $frame !\n";
            print STDERR "Retrying\n";
            $frame--;
            $opfailed=1;
        }
        unless ($opfailed) {
	    &sig_progress($frame);
        }
    }
    return 1;
}



########## Post loop code ############
if ($command eq "clear") {
    $start=$ARGV[1];
    $end=$ARGV[2];
    $img_ext=$ARGV[3];

    exit 0;
}

########## Triggers ############

if ($command eq "onchange_init") {
    $p0=@ARGV[1];
    $p0_min=@ARGV[2];
    $p0_max=@ARGV[3];
    $p1=@ARGV[4];
    $p1_min=@ARGV[5];
    $p1_max=@ARGV[6];
    $p2=@ARGV[7];
    $p2_min=@ARGV[8];
    $p2_max=@ARGV[9];
    $p3=@ARGV[10];
    $p3_min=@ARGV[11];
    $p3_max=@ARGV[12];
    $p4=@ARGV[13];
    $p5=@ARGV[14];
    $p5_min=@ARGV[15];
    $p5_max=@ARGV[16];
    $p6=@ARGV[17];
    $p7=@ARGV[18];
    $p8=@ARGV[19];
    $p8_min=@ARGV[20];
    $p8_max=@ARGV[21];
    $p9=@ARGV[22];
    $p9_min=@ARGV[23];
    $p9_max=@ARGV[24];
    $p10=@ARGV[25];
    $p10_min=@ARGV[26];
    $p10_max=@ARGV[27];
    $p11=@ARGV[28];
    $p11_min=@ARGV[29];
    $p11_max=@ARGV[30];
    $p12=@ARGV[31];
    $p13=@ARGV[32];
    $p13_min=@ARGV[33];
    $p13_max=@ARGV[34];
    $p14=@ARGV[35];
    $width=@ARGV[36];
    $height=@ARGV[37];
    $start=@ARGV[38];
    $end=@ARGV[39];
    $last=@ARGV[40];
    $length=$end-$start+1;

    $p0_max=$p8_max=$width;
    $p1_max=$p9_max=$height;
    $p6=~ s/\"/\\\"/g;

    print "$p0 $p0_min $p0_max $p1 $p1_min $p1_max $p2 $p2_min $p2_max $p3 $p3_min $p3_max $p4 $p5 $p5_min $p5_max \"$p6\" $p7 $p8 $p8_min $p8_max $p9 $p9_min $p9_max $p10 $p10_min $p10_max $p11 $p11_min $p11_max $p12 $p13 $p13_min $p13_max $p14 ";
    exit 0;
}
