#!/usr/bin/perl

#######################################################################
# LiVES transition_checkerboard plugin, version 1
# Compiled with Builder version 3.2.0
# autogenerated from script by Salsaman|

# 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 [<in2_prefix> [<in_prefix>]] <out_prefix> <out_ext> <start> <end>
#  <width> <height> <img_ext> <fps> [<img2_ext> <start2> <handle2>]  <parameters>
# you should create all output frames $out_prefix%08d$out_ext in numerical 
# from start to end inclusive,
# using $in_prefix%08d$in_ext and $in2_prefix%08d$img2_ext as applicable.
# in / out images are in current dir, In2 images can be located in ../handle2 and numbered from 
# Each time calling sig_progress (see smogrify) - writes current frame number to 
# <dir>/.status
# and checking for pause (test for a file of that name in current dir - if present just sleep until deleted)
#
# Any errors - 
# write "error|msg1|msg2|msg3|" to .status
# msgn must not contain "\n", but can be omitted

# 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;
setlocale(LC_NUMERIC, "C");

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 "transition_checkerboard version 1 : builder version 3.2.0\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 "Checkerboard|Checkerboarding|0|2|\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 "hseg|_Horizontal segments|num0|2|1|1000000|\n";
    print "vseg|_Vertical segments|num0|2|1|1000000|\n";
    print "tl|_Top left is clipboard|bool|0|\n";
    exit 0;
}

if ($command eq "get_param_window") {
    print "layout|p0|fill||\n";
    print "layout|p1|fill||\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("convert") eq "") {
      &sig_error("You must install 'convert' before you can use this effect.");
      exit 1;
    }
    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 = 2;
    }
    else {
      $p0 = $ARGV[1];
    }
    unless (defined($ARGV[2])) {
      $p1 = 2;
    }
    else {
      $p1 = $ARGV[2];
    }
    unless (defined($ARGV[3])) {
      $p2 = 0;
    }
    else {
      $p2 = $ARGV[3];
    }
    $! = 0;
    if ($p0 >= 0) {
        $p0 = int(POSIX::strtod($p0) * 1 + .5) / 1;
    } else {
        $p0 = int(POSIX::strtod($p0) * 1 - .5) / 1;
    }
    if ($p0 < 1) {
       &sig_error("hseg must be >= 1");
       exit 1;
    }
    if ($p0 > 1000000) {
       &sig_error("hseg must be <= 1000000");
       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 < 1) {
       &sig_error("vseg must be >= 1");
       exit 1;
    }
    if ($p1 > 1000000) {
       &sig_error("vseg must be <= 1000000");
       exit 1;
    }
    $p2 = ~(~$p2);
    if ($img_ext eq ".png") {
        $img_prefix = "PNG32:";
    } else {
        $img_prefix = "";
    }

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

    unless (defined($img_ext2)) {
        $img_ext2 = $img_ext;
    }

    if ($img_ext2 eq ".png") {
        $img_prefix2 = "PNG32:";
    } else {
        $img_prefix2 = "";
    }

    #make a transparent frame the size of the output image
    `$convert_command -size $width!x$height! xc:transparent -matte mask.png`;
    
    # draw rectangles on it
    $bwidth=int($width/$p0+.5);
    $bheight=int($height/$p1+.5);
    
    $x=0;
    $idraw=$p2;
    
    # draw our opaque areas
    while ($x<$width) {
    	$x1=$x+$bwidth;
    	$y=0;
    	$draw=$idraw;
    	$idraw=!$idraw;
    	while ($y<$height) {
    		$y1=$y+$bheight;
    		if ($draw) {
    			`$convert_command mask.png -fill white -draw \"rectangle $x,$y $x1,$y1\" mask.png`;
    		}
    		$draw=!$draw;
    		$y=$y1+1;
    	}
    	$x=$x1+1;
    }

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


################# loop through frames #################
    $frame2 = $start2;
    if (!($img_ext2 eq $img_ext) && &location("convert") eq "") {
        &sig_error("'convert' is required by this plugin.", "Please install imagemagick and try again.");
        exit 1;
    }

    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.");
        }
        $name2 = &mkname($frame2);
        $in2 = "$clipboard/$name2$img_ext2";
        unless (-f $in2) {
            # end of clipboard reached, loop back to start
            $frame2 = $start2;
            $name2 = &mkname($frame2);
            $in2 = "$clipboard/$name2$img_ext2";
        }
        unless ($img_ext2 eq $img_ext) {
            system("$convert_command $img_prefix2\"$in2\" $img_prefix\"$clipboard/$name2$img_ext\"");
            $img_prefix2 = $img_prefix;
        }
        $out = "$name$out_ext";

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

        `flock $in true`;
        # wait for front end to create 
        while (! -s $in2) {
            sleep 1;
        }

        `flock $in2 true`;
##################### the all-important bit #######################

        `$composite_command -compose plus -dissolve 100 -resize $width!x$height! $img_prefix2$in2 $in mask.png $out_prefix$out.png`;
        `$convert_command $out_prefix$out.png $out$img_ext`;
        rename "$out_prefix$out$img_ext","$out";
        unlink "$out_prefix$out.png";

###################################################################
        unless ($img_ext2 eq $img_ext) {
            unlink $in2;
        }
        $frame2++;
        for (my $i = 0; $i < 5; $i++) {
            if (! -s $out) {
                sleep 1;
            }
        }

        if (! -s $out) {
            print STDERR "Warning: effect plugin transition_checkerboard skipped frame $frame !\n";
            return 1;
        }

        &sig_progress($frame);

        }
    return 1;
}



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

    unlink <mask.png>;
    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];
    $width = @ARGV[8];
    $height = @ARGV[9];
    $start = @ARGV[10];
    $end = @ARGV[11];
    $last = @ARGV[12];
    $length = $end - $start + 1;
    $width2 = @ARGV[13];
    $height2 = @ARGV[14];

    $p0_max=$width;
    $p1_max=$height;

    print "$p0 $p0_min $p0_max $p1 $p1_min $p1_max $p2 ";
    exit 0;
}
