#!/usr/bin/perl -w

use POSIX;

if($#ARGV!=1) {
  print "Usage: perl scale_subs.pl <percent> <dir>\n";
  exit;
}
my $percent=$ARGV[0];
my $sourcedir=$ARGV[1];
my $res_y=1080;

if(!($percent=~/[\d.%]/)) {
  print "Error: Invalid percentage: $percent\n";
  exit;
}
$percent=~s/%//g;

if($percent==100) {
  print "All subtitles are already scaled to 100%.\n";
  exit;
}

if($percent>110 || $percent<33) {
  print "Scaling percentages must be between 33% and 110%.\n";
  exit;
}

if($^O eq "MSWin32") {
  @filelist=glob("\"$sourcedir\\\*.xml\"");
} else {
  @filelist=glob("\"$sourcedir/\*.xml\"");
}
my $listsize=@filelist;
if($listsize==0) {
  print "Error: No XML files found in $sourcedir\n";
  exit;
}

sub round {
  $_[0] > 0 ? int($_[0] + .5) : -int(-$_[0] + .5)
}

FILELOOP: for $sourcefile (@filelist) {
  my $graphic=0;
  my $y=0;
  my $height;
  my $token1="";
  my $token2="";
  my $newimgwidth=0;
  my $newimgheight=0;
  my $imagetype="";
  my @arr;
  my $image_path="";
  if($^O eq "MSWin32") {
    @arr=split(/\\/,$sourcefile);
  } else {
    @arr=split(/\//,$sourcefile);
  }
  my $fname=$arr[-1];
  print "Processing ".$fname."...\n";
  open(OLDXML, "<".$sourcefile);
  foreach my $line (<OLDXML>) {
    if (index($line, '<Event ') != -1) {
      if (index($line, "InTC=") != -1) {
        @arr=split(/InTC="/,$line);
        $in_timecode=$arr[1];
        @arr=split(/"/,$in_timecode);
        $in_timecode=$arr[0];
      }
      if (index($line, "OutTC=") != -1) {
        @arr=split(/OutTC="/,$line);
        $out_timecode=$arr[1];
        @arr=split(/"/,$out_timecode);
        $out_timecode=$arr[0];
      }
    }
    if (index($line, '<Graphic') != -1) {
      $graphic=1;
    }
    if($graphic==1) {
      if (index($line, "Y=") != -1) {
        @arr=split(/Y="/,$line);
        $y=$arr[1];
        @arr=split(/"/,$y);
        $y=$arr[0];
        @arr=split(/Height="/,$line);
        $height=$arr[1];
        @arr=split(/"/,$height);
        $height=$arr[0];
        push(@y_array,$y);
        push(@height_array,$height);
        push(@y_height_array,$y+$height);
      }
    }
  }
  close(OLDXML);
  @arr=sort { $b <=> $a } @height_array;
  $max2_height=$arr[0];
  $height_divider=floor($max2_height*3/5);
  $max1_height=$arr[0];
  $x=1;
  while($max1_height>$height_divider && $x<$#arr) {
    $max1_height=$arr[$x];
    if($max1_height>$height_divider) {
      $x=$x+1;
    }
  }
  if($x>$#arr) {
    $max1_height=$max2_height;
  }
  @arr=sort { $b <=> $a } @y_array;
  $min_y=$arr[-1];
  @arr=sort { $b <=> $a } @y_height_array;
  $max_y=$arr[0];
  if($#y_array>10) {
    @arr=sort { $b <=> $a } @y_array;
    $min2_y=$arr[-1];
    $min1_y=$arr[-1];
    $x=-1;
    while($min1_y<($min2_y+$max2_height-$max1_height) && (0-$x)<$#arr) {
      $min1_y=$arr[$x];
      if($min1_y<($min2_y+$max2_height-$max1_height)) {
        $x=$x-1;
      }
    }
    if((0-$x)>$#arr) {
      $min1_y=$min2_y;
    }
  }
  $graphic=0;
  open(OLDXML, "<".$sourcefile);
  if($^O eq "MSWin32") {
    open(NEWXML, '>' . $sourcedir . '\\_' . $fname);
  } else {
    open(NEWXML, '>' . $sourcedir . '/_' . $fname);
  }
  foreach my $line (<OLDXML>) {
    if (index($line, '<Graphic') != -1) {
      $graphic=1;
    }
    if($graphic==1) {
      if (index($line, ".png") != -1) {
        my $newy=$y;
        @arr=split(/>/,$line);
        $sub_image=$arr[1];
        @arr=split(/</,$sub_image);
        $sub_image=$arr[0];
        if (index($fname,"-match-") == -1 && index($fname,"-alien-") == -1) {
          if($^O eq "MSWin32") {
            $image_path=$sourcedir."\\".$sub_image;
          } else {
            $image_path=$sourcedir."/".$sub_image;
          }
          if(length($imagetype)==0) {
            $imagetype="grayscalealpha";
            if($^O eq "MSWin32") {
              system("identify -format %[type] $image_path > ".$sourcedir."\\_dims.txt");
              open(DIMS, "<".$sourcedir."\\_dims.txt");
            } else {
              system("identify -format %[type] $image_path > ".$sourcedir."/_dims.txt");
              open(DIMS, "<".$sourcedir."/_dims.txt");
            }
            $dims=<DIMS>;
            close(DIMS);
            if(index(lc($dims),"grayscalealpha")==-1) {
              $imagetype="palettealpha";
            }
            if($^O eq "MSWin32") {
              unlink($sourcedir."\\_dims.txt");
            } else {
              unlink($sourcedir."\\_dims.txt");
            }
          }
          if($percent>100) {
            system("convert $image_path -resize $percent% -unsharp 0x1.5 -type $imagetype $image_path");
          } else {
            system("convert $image_path -resize $percent% -unsharp 0x1 -type $imagetype $image_path");
          }
          if($^O eq "MSWin32") {
            system("identify -format %wx%h $image_path > ".$sourcedir."\\_dims.txt");
            open(DIMS, "<".$sourcedir."\\_dims.txt");
          } else {
            system("identify -format %wx%h $image_path > ".$sourcedir."/_dims.txt");
            open(DIMS, "<".$sourcedir."/_dims.txt");
          }
          $dims=<DIMS>;
          close(DIMS);
          if($^O eq "MSWin32") {
            unlink($sourcedir."\\_dims.txt");
          } else {
            unlink($sourcedir."\\_dims.txt");
          }
          @arr=split(/x/,$dims);
          $newimgwidth=$arr[0];
          $newimgheight=$arr[1];
        }
        if (index($line, "Width=") != -1) {
          @arr=split(/Width="/,$line);
          $imgwidth=$arr[1];
          @arr=split(/"/,$imgwidth);
          $imgwidth=$arr[0];
          $token1="Width=\"".$imgwidth;
          $token2="Width=\"".$newimgwidth;
          $line=~s/$token1/$token2/;
        }
        if (index($line, "Height=") != -1) {
          @arr=split(/Height="/,$line);
          $imgheight=$arr[1];
          @arr=split(/"/,$imgheight);
          $imgheight=$arr[0];
          $token1="Height=\"".$imgheight;
          $token2="Height=\"".$newimgheight;
          $line=~s/$token1/$token2/;
        }
        if (index($line, "X=") != -1) {
          @arr=split(/X="/,$line);
          $x=$arr[1];
          @arr=split(/"/,$x);
          $x=$arr[0];
          $token1="X=\"".$x;
          $token2="X=\"".($x+round(($imgwidth-$newimgwidth)/2));
          $line=~s/$token1/$token2/;
        }
        if (index($line, "Y=") != -1) {
          @arr=split(/Y="/,$line);
          $y=$arr[1];
          @arr=split(/"/,$y);
          $y=$arr[0];
          $token1="Y=\"".$y;
          if($y>$res_y/2) {
            $token2="Y=\"".($max_y-$newimgheight-round(($max_y-$y-$imgheight)*$percent/100));
            $line=~s/$token1/$token2/;
          } else {
            $token2="Y=\"".($min_y+round(($y-$min_y)*$percent/100));
            $line=~s/$token1/$token2/;
          }
        }
      }
    } else {
      if (index($line, "VideoFormat") != -1) {
        if (index($line, "1080p") != -1) {
          $res_y=1080;
        }
        if (index($line, "720p") != -1) {
          $res_y=720;
        }
        if (index($line, "480i") != -1) {
          $res_y=480;
        }
        if (index($line, "576i") != -1) {
          $res_y=576;
        }
      }
    }
    print NEWXML $line;
  }
  close(OLDXML);
  close(NEWXML);
  if($^O eq "MSWin32") {
    rename($sourcedir . '\\_' . $fname,$sourcedir . '\\' . $fname);
  } else {
    rename($sourcedir . '/_' . $fname,$sourcedir . '/' . $fname);
  }
}

print "Process complete. Subtitles in $sourcedir have been scaled to $percent%.\n";
