#!/usr/bin/perl -w

use experimental 'smartmatch';

if($#ARGV==-1) {
  print "Usage: perl prep_subs-rtl.pl [compat] <filename...>\n";
  exit;
}

my @filelist=();
my @tmplist;
my $sourcefile;
my @add_rlm=(".", "?", "!", ",", ":", "-", "\x{2013}", "\x{201c}", "\x{201d}", "\x{060c}");
my @arabic_numerals=("\x{0660}", "\x{0661}", "\x{0662}", "\x{0663}", "\x{0664}", "\x{0665}", "\x{0666}", "\x{0667}", "\x{0668}", "\x{0669}", "\x{066a}", "\x{066b}", "\x{066c}", );
my @end_punct=("?", "\x{061f}", ".", "!", ",", ":", "\x{060c}");
my @rtl_punct=("\x{061f}", "\x{060c}");
my @rtl_punct_no_rlm=("\x{061f}");

# right-alignment using our customized vsfilter.dll currently seems to work okay with the files created by this script
# if problems are found, set this token to an empty string and use the ralign_rtl.pl script instead
my $centerright_token="\x1d";
#my $centerright_token="";
my $extra_lf_token="";
if(length($centerright_token)==0) {
# if not using the centerright token, add extra spacing between lines and use the ralign_rtl.pl script afterwards
  $extra_lf_token="\x1f\n";
}
my $ltr_mark="\x{200e}";
my $rtl_mark="\x{200f}";
my $compat=0;

for $sourcefile (@ARGV) {
  if(-e $sourcefile) {
    push(@filelist,$sourcefile);
  } else {
    if(lc($sourcefile) eq "compat") {
      $compat=1;
    } else {
      @tmplist=glob($sourcefile);
      my $listsize=@tmplist;
       if($listsize==0) {
        print "Error: Could not find $sourcefile\n";
        exit;
      }
      push(@filelist,@tmplist);
    }
  }
}

if($compat==1) {
  $centerright_token="";
  $extra_lf_token="";
}

sub compat_ltr_begin {
  my $in_text=$_[0];
  my $out_text="";
  my @chars=split(//, $in_text);
  my $ltr_begin=1;
  for $currentchar (@chars) {
    if($ltr_begin==1 && !(($currentchar=~/^[A-Za-z0-9]+$/) || ($currentchar ~~ @arabic_numerals) || ($currentchar eq '-'))) {
      $out_text=$out_text.$ltr_mark;
      $ltr_begin=0;
    }
    $out_text=$out_text.$currentchar;
    if($currentchar ~~ @rtl_punct) {
      $out_text=$out_text.$ltr_mark;
    }
  }
  if(($chars[0]=~/^[A-Za-z0-9]+$/) || ($chars[0] ~~ @arabic_numerals)) {
    $out_text=$ltr_mark." ".$out_text;
  }
  return $out_text;
}

sub compat_ltr_end {
  my $in_text=$_[0];
  my $out_text="";
  my @chars=split(//, $in_text);
  my $all_rtl=1;
  for $currentchar (@chars) {
    if(!($currentchar ~~ @add_rlm) && !($currentchar ~~ @end_punct) && !($currentchar=~/^[A-Za-z0-9]+$/) && !($currentchar ~~ @arabic_numerals) && $currentchar ne ' ') {
      $all_rtl=0;
      last;
    }
  }
  for $currentchar (@chars) {
    if($all_rtl==1) {
      $out_text=$out_text.$currentchar.$ltr_mark;
    } else {
      $out_text=$out_text.$currentchar;
    }
  }
  return $out_text;
}

sub reverse_ltr_words {
  my @in_arr=reverse(@_);
  my @tmp_arr=();
  my $tmp2_arr=();
  my @tmp3_arr=();
  my $count=0;
  my $allpunct=1;
  for $currentword (@in_arr) {
    $count=$count+1;
    @tmp2_arr=split(//,$currentword);
    $allpunct=1;
    for $letter (@tmp2_arr) {
      if(!(($letter ~~ @end_punct) || ($letter ~~ @add_rlm) || ($letter ~~ @arabic_numerals) || ($letter=~/^[A-Za-z0-9]+$/)) || ($letter ~~ @rtl_punct_no_rlm)) {
        $allpunct=0;
        last;
      }
    }
    if($allpunct==0 && ($tmp2_arr[-1] ~~ @end_punct)) {
      @tmp_arr=();
      if(($count-1)<$#in_arr) {
        if($tmp2_arr[-1] ~~ @rtl_punct) {
          push(@tmp_arr,$ltr_mark);
        }
      }
      push(@tmp_arr,$tmp2_arr[-1]);
      if($tmp2_arr[-1] ~~ @rtl_punct) {
        push(@tmp_arr,$ltr_mark);
      }
      push(@tmp_arr,@tmp2_arr[0..($#tmp2_arr-1)]);
    } else {
      @tmp_arr=@tmp2_arr;
    }
    push(@tmp3_arr,' ');
    if($allpunct==1) {
      push(@tmp3_arr,reverse(@tmp_arr));
    } else {
      push(@tmp3_arr,@tmp_arr);
    }
  }
  @out_arr=@tmp3_arr;
  return @out_arr;
}

sub compat_reverse {
  my @in_arr=@_;
  my @out_arr=();
  my @tmp_arr=();
  my $ltr_begin=0;
  my $all_ltr=1;
  for $currentchar (@in_arr) {
    if(!(($currentchar=~/^[A-Za-z0-9]+$/) || ($currentchar eq '-') || ($currentchar eq ' '))) {
      $all_ltr=0;
    }
  }
  if($all_ltr==1) {
    return @in_arr;
  }
  for $currentchar (@in_arr) {
    if(($currentchar ~~ @add_rlm) || ($currentchar eq '-') || ($currentchar eq ' ')) {
      if($ltr_begin==0) {
        push(@out_arr,reverse(@tmp_arr));
        @tmp_arr=();
      }
      $ltr_begin=1;
      push(@tmp_arr,$currentchar);
    } else {
      if($ltr_begin==1) {
        push(@out_arr,@tmp_arr);
        @tmp_arr=();
      }
      $ltr_begin=0;
      push(@tmp_arr,$currentchar);
    }
  }
  $all_ltr=1;
  for $currentchar (@out_arr) {
    if(!(($currentchar=~/^[A-Za-z0-9]+$/) || ($currentchar eq '-') || ($currentchar eq ' '))) {
      $all_ltr=0;
    }
  }
  if($all_ltr==1) {
    @new_arr=();
    @my_arr1=split(/ /,join('',@out_arr));
    for $currentword (@my_arr1) {
      if(index($currentword,"-")>-1) {
        @my_arr2=split(/-/,$currentword);
        @my_arr2=reverse(@my_arr2);
      } else {
         @my_arr2=($currentword);
      }
      push(@new_arr,join('-',@my_arr2));
    }
    @out_arr=split(//,join(' ',@new_arr));
  }
  push(@out_arr,@tmp_arr);
  $tmp_text=join('',@out_arr);
  @tmp_arr=split(/ /,$tmp_text);
  @tmp_arr=reverse_ltr_words(@tmp_arr);
  $tmp_text=join('',@tmp_arr);
  @out_arr=split(//,$tmp_text);
  return @out_arr;
}

sub format_rtl_text {
  my $in_text=$_[0];
  my $out_text="";
  my $char_count=0;
  $in_text=~s/^\s+|\s+$//g;
  my $textbegin="";
  my $textmiddle="";
  my $textend="";
  my @chars=split(//, $in_text);
  if($#chars>0) {
    if(($chars[0] ~~ @add_rlm) || (($chars[0]=~/^[A-Za-z0-9]+$/) || ($chars[0] ~~ @arabic_numerals))) {
      for $currentchar (@chars) {
        $char_count=$char_count+1;
        if(((!($currentchar ~~ @add_rlm)) && !($currentchar ~~ @end_punct) && ($currentchar ne ' ')) && (!(($currentchar=~/^[A-Za-z0-9]+$/) || ($currentchar ~~ @arabic_numerals)))) {
          $textend=join('',compat_reverse(@chars[0..($char_count-2)]));
          if(($chars[0]=~/^[A-Za-z0-9]+$/) || ($chars[0] ~~ @arabic_numerals)) {
            $textend=compat_ltr_begin($textend);
          }
          splice(@chars,0,$char_count-1);
          $textmiddle=join('',@chars);
          last;
        }
      }
      if(($textbegin eq "") && ($textmiddle eq "") && ($textend eq "")) {
        $textend=join('',compat_reverse(@chars));
        if(($chars[0]=~/^[A-Za-z0-9]+$/) || ($chars[0] ~~ @arabic_numerals)) {
          $textend=compat_ltr_begin($textend);
        }
      }
    } else {
      $textmiddle=$in_text;
    }
    @chars=split(//, $textmiddle);
    my @revchars=reverse(@chars);
    if($#revchars>0) {
      $char_count=0;
      if(($revchars[0] ~~ @add_rlm) || (($revchars[0]=~/^[A-Za-z0-9]+$/) || ($revchars[0] ~~ @arabic_numerals)) ||
         (($revchars[0] ~~ @end_punct) && (($revchars[1] ~~ @add_rlm) || (($revchars[1]=~/^[A-Za-z0-9]+$/) || ($revchars[1] ~~ @arabic_numerals))))
         ) {
        for $currentchar (@revchars) {
          $char_count=$char_count+1;
          if(((!($currentchar ~~ @add_rlm)) && ($currentchar ne ' ')) && (!(($currentchar=~/^[A-Za-z0-9]+$/) || ($currentchar ~~ @arabic_numerals))) &&
             ($char_count!=1 || !($currentchar ~~ @end_punct))
             ) {
            $textbegin=join('',compat_reverse(@chars[-($char_count-1)..-1]));
            $textbegin=compat_ltr_end($textbegin);
            $textmiddle=join('',@chars[0..($#chars-$char_count+1)]);
            last;
          }
        }
      }
    }
  }
  $out_text=$textbegin.$textmiddle.$textend;
  $out_text=~s/^\s+|\s+$//g;
  $out_text=~s/^\x{200e}\s+/\x{200e}/g;
  $out_text=~s/^\x{200f}\s+/\x{200f}/g;
  $out_text=~s/\s+\x{200e}$/\x{200e}/g;
  $out_text=~s/\s+\x{200f}$/\x{200f}/g;
  $out_text=~s/  / /g;
# all the kludges go here
# at some point i gave up on good code, and just wanted good results
  $out_text=~s/ \x{201c}$/\x{201c}/g;
  $out_text=~s/ \x{201c} \x{2013}$/\x{201c} \x{2013}/g;
  $out_text=~s/ \x{201c} ...$/\x{201c} .../g;
  $out_text=~s/ \x{201d}$/\x{201d}/g;
  $out_text=~s/ \x{201d} \x{2013}$/\x{201d} \x{2013}/g;
  $out_text=~s/ \x{201d} ...$/\x{201d} .../g;
  $out_text=~s/3PO-C/C-3PO/g;
  $out_text=~s/C-\x{061f}OP3/\x{200e}\x{061f}C-3PO/g;
  $out_text=~s/\x{061f}\x{200e}2/\x{061f}\x{200e}2\x{200e}/g;
  $out_text=~s/D2-R2/R2-D2/g;
  $out_text=~s/TV16/VT-16/g;
  $out_text=~s/28.17/17.28/g;
  $out_text=~s/0\x{200e}0\x{200e}0\x{200e},\x{200e}2\x{200e}5/25,000/g;
  $out_text=~s/000,25/25,000/g;
  $out_text=~s/0\x{200e}0\x{200e}0\x{200e},\x{200e}5\x{200e}0/50,000/g;
  $out_text=~s/000,50/50,000/g;
  $out_text=~s/0\x{200e}0\x{200e}0\x{200e},\x{200e}3\x{200e}5/35,000/g;
  $out_text=~s/000,35/35,000/g;
  if(index($out_text," TIE ")>-1) {
    @arr=split(/ TIE /,$out_text);
    $out_text=$arr[1]." TIE ".$arr[0];
  }
  return $out_text;
}

FILELOOP: for $sourcefile (@filelist) {
  my $pathdel;
  my @bits;
  if(!(-e $sourcefile)) {
    print "File not found: $sourcefile\n";
    next FILELOOP;
  }
  if($^O eq "MSWin32") {
    $pathdel="\\";
    @bits=split(/\\/,$sourcefile);
  } else {
    $pathdel="/";
    @bits=split(/\//,$sourcefile);
  }
  my $bitssize=@bits;
  my $fname=$bits[$bitssize-1];
  pop(@bits);
  my $path=join($pathdel,@bits);
  if(length($path)>0) {
    $path=$path.$pathdel;
  }
  if(index($fname,"X-")==0 || index($fname,"-compat.srt")>-1) {
    next FILELOOP;
  }
  my $destfile=$path."X-$fname";
  my $txtlines=0;
  my $txtnext=0;
  my $trimdata="";
  my $subcount=0;
  my @times;
  my $lasttime="";
  my $x;
  my $y;
  my $topalign_pad="";
  my $lineending="\n";

  if($compat==1) {
    @bits=split(/-rtl/,$fname);
    $destfile=$path.$bits[0]."-compat.srt";
  }

  open(FILE1,$sourcefile);
  open(FILE2,">$destfile");
  binmode(FILE1, ":utf8");
  binmode(FILE2, ":utf8");

  while(<FILE1>) {
    $data=$_;
    $data=~s/$ltr_mark//g;
    $data=~s/$rtl_mark//g;
    if(index($data," --> ")!=-1) {
      $txtlines=0;
      $txtnext=1;
      $subcount=$subcount+1;
      @times=split(" --> ",$data);
      $lasttime=$times[1];
      chomp($lasttime);
      $lasttime=~s/^\s+|\s+$//g;
    } else {
      if($txtnext==1) {
        $txtlines=$txtlines+1;
        $trimdata=$data;
        chomp($trimdata);
        $trimdata=format_rtl_text($trimdata);
        if(length($trimdata)>0) {
          $data2=<FILE1>;
          if(!$data2) {
            $data2="";
          }
          $data2=~s/$ltr_mark//g;
          $data2=~s/$rtl_mark//g;
          $trimdata2=$data2;
          chomp($trimdata2);
          $trimdata2=format_rtl_text($trimdata2);
          if(length($trimdata2)>0) {
            if(substr($data,0,1) eq "[" || substr($data,0,1) eq "\x{2013}" || substr($data,0,4) eq "<i>\x{2013}" ||
               substr($data2,0,1) eq "[" || substr($data2,0,1) eq "\x{2013}" || substr($data2,0,4) eq "<i>\x{2013}") {
              $data=$centerright_token.$trimdata.$lineending.$extra_lf_token;
              print FILE2 $data;
              $data=$centerright_token.$trimdata2.$lineending;
            } else {
              print FILE2 $trimdata.$lineending;
              $data=$trimdata2.$lineending;
              $txtnext=0;
            }
          } else {
            print FILE2 $trimdata.$lineending;
            $data=$trimdata2.$topalign_pad.$lineending;
            $txtnext=0;
          }
        } else {
          $txtnext=0;
        }
      }
    }
    print FILE2 $data;
  }
  if($txtnext==1 && $txtlines==1) {
    $subcount=$subcount+1;
    print FILE2 "\n$subcount\n$lasttime --> $lasttime\n\n";
  }
  close(FILE1);
  close(FILE2);
  print "Converted $sourcefile to $destfile.\n";
}
exit;