#!/usr/bin/env perl
#
#  pixiv.pl
#  Pixiv Animation Downloader
#
#  Created by Cure Gecko on 6/29/14.
#  Copyright (c) 2014 Cure Gecko. All rights reserved.
#
#  Version 0.2.1
#

use LWP;
use JSON::Parse 'parse_json';
use Archive::Extract;
use File::Glob ();
use Image::Magick;

use Data::Dumper;

print "Please enter Pixiv IllustID: ";
my $pixivID = <stdin>;
chomp($pixivID);
my $pixivURL = "http://www.pixiv.net/member_illust.php?mode=medium&illust_id=".$pixivID;

my $ua = LWP::UserAgent->new;
my $response = $ua->get($pixivURL);
if (!$response->is_success) {
	print "Error getting response from pixiv.\n";
	exit();
}

my $pixivDataJSON = "";
if ($response->content =~ /pixiv\.context\..*IllustData\s*=\s*([^;]*);/i) {
	$pixivDataJSON = $1;
}
my $pixivData = parse_json($pixivDataJSON);

my $smallZIP = $pixivData->{'src'};
my $bigZIP = $smallZIP;
$bigZIP =~ s/600x600/1920x1080/i;

my $mime = $pixivData->{'mime_type'};
my $ext = "jpg";
if ($mime eq "image/png") {
	$ext = "png";
}

my $ms = $pixivData->{'frames'}->[0]->{'delay'};
my $fps = 1/($ms/1000);

my $constant = 1;
my $minMS = 0;

foreach (@{$pixivData->{'frames'}}) {
	my $frame = $_;
	print Dumper($frame);
	$minMS = ($maxMS>$frame->{'delay'} ? $frame->{'delay'} : $maxMS);
	if ($frame->{'delay'}!=$ms) {
		$constant = 0;
	}
}

print "Pixiv Small: ".$smallZIP."\n";
print "Pixiv Big: ".$bigZIP."\n";
print "Mime: ".$mime."\n";
print "Extension: ".$ext."\n";
print "MS: ".$ms."\n";
print "FPS: ".$fps."\n";
print "Constant: ".$constant."\n";

my $size = $smallZIP;
print "Do you want the large size? [N/y]: ";
my $largeSize = <stdin>;
if ($largeSize =~ /y|t/i) {
	$size = $bigZIP;
}

my $ua = LWP::UserAgent->new;
my $request = HTTP::Request->new("GET" => $size);
$request->header("Referer" => $pixivURL);
$request->header("User-Agent" => "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:31.0) Gecko/20100101 Firefox/31.0 AlexaToolbar/alxf-2.19");
my $response = $ua->request($request, $pixivID.".zip");

my $archive = Archive::Extract->new("archive" => $pixivID.".zip");
my $ok = $archive->extract("to" => $pixivID);
unless ($ok) {
	print "Failed to extract zip\n";
	exit();
}

chdir($pixivID);

my $image = Image::Magick->new;
open(IMAGE, "000000.".$ext);
$image->Read("file" => \*IMAGE);
close(IMAGE);
my $width = $image->Get("width");
if (($width % 2)==1) {
	$width++;
}
my $height = $image->Get("height");
if (($height % 2)==1) {
	$height++;
}

print "What would you like to convert to? Use comma for multiple formats. [mkv|gif|webm|png]: ";
my $codec = <stdin>;
chomp($codec);
@codecs = split(",", $codec);
foreach (@codecs) {
	$_ =~ s/^\s+|\s+$//g;#Incase of space
	$codec = $_;
	unless ($codec eq "mkv" || $codec eq "gif" || $codec eq "webm" || $codec eq "png") {
		print "Invalid Codec: ".$codec."\n";
		next;
	}
	
	if ($codec eq "mkv" || $codec eq "webm") {
		if (!$constant) {
			my $time = 0;
			open(tc, ">tmp.tc") or die "$!";
			print tc "# timecode format v2\n";
			foreach (@{$pixivData->{'frames'}}) {
				my $frame = $_;
				print tc $time."\n";
				$time += $frame->{'delay'};
			}
			close(tc);
		}
		my $vcodec = "libx264 -crf 22";
		my $outExt = "mkv";
		if ($codec eq "webm") {
			$vcodec = "libvpx -crf 22";
			$outExt = "webm";
		}
		system("ffmpeg -f image2 -r ".$fps." -i %06d.".$ext." -s ".$width."x".$height." -r ".$fps." -vcodec ".$vcodec." ".$pixivID.".".$outExt);
		if (!$constant) {
			system("mkvmerge --output ".$pixivID."tc.".$outExt." --timecodes 0:tmp.tc ".$pixivID.".".$outExt);
			unlink("tmp.tc");
			unlink($pixivID.".".$outExt);
			rename($pixivID."tc.".$outExt, $pixivID.".".$outExt);
		}
	} elsif ($codec eq "png") {
		unless ($ext eq "png") {
			@FILES = glob("*.".$ext);
			foreach $file (@FILES) {
				$name = $file;
				$name =~ s/\..*//;
				system("convert ".$file." ".$name.".png");
			}
		}
		system("apngasm ".$pixivID.".png *.png 1 $fps");
	} else {
		if (!$constant) {
			my $image = Image::Magick->new();
			foreach (@{$pixivData->{'frames'}}) {
				my $frame = $_;
				$image->Read("filename" => $frame->{'file'}, "delay" => $frame->{'delay'}/10);
			}
			$image->Write("filename" => $pixivID.".gif");
		} else {
			system("convert -delay 1x".$fps." *.".$ext." -coalesce -layers OptimizeTransparency ".$pixivID.".gif");
		}
	}
}