#!/usr/bin/env perl
## Pombert Lab, Illinois Tech 2023

my $name = 'clusters2links.pl';
my $version = '0.2c';
my $updated = '2023-04-20';

use strict;
use warnings;
use Getopt::Long qw(GetOptions);
use File::Basename;
use File::Path qw(make_path);
use Math::Round;

my $usage = <<"USAGE";
NAME        ${name}
VERSION     ${version}
UPDATED     ${updated}
SYNOPSIS    Parses the output of clusters generated with SYNY to create links for Circos

COMMAND     ${name} \\
              -c *.clusters \\
              -l *.list \\
              -o Circos

OPTIONS:
-c (--cluster)      Cluster file(s) to parse
-l (--list)         Annotations list(s) generated by SYNY list_maker.pl
-o (--outdir)       Output directory [Default: Circos]
--clusters          Color by cluster [Default: off]
--custom_file       Load custom colors from file
--custom_preset     Use a custom color preset; e.g.
                    # chloropicon - 20 colors - Lemieux et al. (2019) https://pubmed.ncbi.nlm.nih.gov/31492891/
                    # encephalitozoon - 11 colors - Pombert et al. (2012) https://pubmed.ncbi.nlm.nih.gov/22802648/
USAGE

unless (@ARGV){
	print "\n$usage\n";
	exit(0);
};

my @clusters;
my @lists;
my $outdir = 'Circos';
my $clusters;
my $custom_file;
my $custom_cc;
GetOptions(
    'c|cluster=s@{1,}' => \@clusters,
    'l|list=s@{1,}' => \@lists,
    'o|outdir=s' => \$outdir,
    'clusters' => \$clusters,
    'custom_file=s' => \$custom_file,
    'custom_preset=s' => \$custom_cc
);

### Check if output directory / subdirs can be created
$outdir =~ s/\/$//;
unless (-d $outdir) {
	make_path($outdir,{mode => 0755}) or die "Can't create $outdir: $!\n";
}
my $catdir = $outdir.'/concatenated';
unless (-d $catdir) {
	make_path($catdir,{mode => 0755}) or die "Can't create $catdir: $!\n";
}

my %loci_db;
### Iterating through annotations lists
while (my $list = shift @lists){

    open LIST, '<', $list or die "Can't open $list: $!\n";
    while (my $line = <LIST>){

        chomp $line;

        my @data = split("\t", $line);
        my $locus = $data[0];
        my $contig = $data[1];
        my $start = $data[2] - 1; ## Adjusting position for Circos (starts at zero)
        my $end = $data[3] - 1; ## Same
        my $strand = $data[4];
        my $gene_number = $data[5];

        $loci_db{$locus}{'contig'} = $contig;
        $loci_db{$locus}{'start'} = $start;
        $loci_db{$locus}{'end'} = $end;

    }
    close LIST;

}

#################### Circos colors

my @reds = ('vvlred','vlred','lred','red','dred','vdred','vvdred');
my @oranges = ('vvlorange','vlorange','lorange','orange','dorange','vdorange','vvdorange');
my @yellows = ('vlyellow','lyellow','yellow','dyellow','vdyellow','vvdyellow');
my @greens = ('vvlgreen','vlgreen','lgreen','green','dgreen','vdgreen','vvdgreen');
my @blues = ('vvlblue','vlblue','lblue','blue','dblue','vdblue','vvdblue');
my @purples = ('vvlpurple','vlpurple','lpurple','purple','dpurple','vdpurple','vvdpurple');
my @greys = ('vvlgrey','vlgrey','lgrey','grey','dgrey','vdgrey','vvdgrey','vvvdgrey');

my @rainbow = (@reds,@oranges,@yellows,@greens,@blues,@purples); ## 41 colors total
my @bowgrey = (@rainbow,@greys); ## 49 colors total

my @color_set = @bowgrey;

# Custom color set(s)
my %custom_colors = cc_colors();

if ($custom_file){

	@color_set = ();

	open CC, '<', $custom_file or die "Can't read $custom_file: $!\n";
	my ($basename) = fileparse($custom_file);
	$custom_cc = $basename;

	while (my $line = <CC>){
		chomp $line;
		unless ($line =~ /^#/){
			my ($color,$rgb) = split("\t", $line);
			$custom_colors{$basename}{$color} = $rgb;
			push(@color_set, $color);
		}

	}

}

if ($custom_cc){
	@color_set = sort (keys %{$custom_colors{$custom_cc}});
} 

### Iterating through cluster files
my $dflag;
my $zdepth = 1;
my $color = 'grey_a5';
my $color_number = 0;

while (my $cluster = shift@clusters){

    $color_number = 0;

    my ($filename,$path) = fileparse($cluster);
    my ($gap) = $path =~ /(gap_\d+)/;
    my ($prefix) = $filename =~ /^(\w+)/;
    my ($query) = $prefix =~ /^([^_]+)/;
    my $subdir = $outdir.'/pairwise/'.$prefix;

    unless (-d $subdir) {
        make_path($subdir,{mode => 0755})  or die "Can't create $subdir: $!\n";
    }

    my $outlinks = $subdir.'/'.$prefix.'.'.$gap.'.links';
    my $catlinks = $catdir.'/concatenated.'.$gap.'.links';

    open NUM, "<", $cluster or die "Can't open $cluster: $!\n";
    my $line_num = 0;
    while (my $line = <NUM>){
        if ($line =~ /^### Cluster (\d+)/){
            $line_num++;
        }
    }
    close NUM;

    ## Creating an increment so that it will use the full range of colors
    ## not just the start
    my $increment = (scalar(@color_set))/$line_num;
    my $rounded_increment = round($increment);

    ## Making sure that the increment is >= 1
    if ($rounded_increment < 1){
        $rounded_increment = 1;
    }


    open CLUSTER, "<", $cluster or die "Can't open $cluster: $!\n";
    open OUT, ">", $outlinks or die "Can't create $outlinks: $!\n";
    print OUT "#locus1 start end locus2 start end\n";

    my $diamond;
    if ($dflag){
        $diamond = '>>';
    }
    else {
        $diamond = '>';
        $dflag = 1;
    }

    open CAT, "$diamond", $catlinks or die "Can't create $catlinks: $!\n";
    print CAT "#locus1 start end locus2 start end\n";

    my %queries;

    while (my $line = <CLUSTER>){

        chomp $line;

        if ($line =~ /^### Cluster (\d+)/){

            if ($clusters){
                $color = $color_set[$color_number];
                $color_number += $rounded_increment;
                if ($color_number >= scalar(@color_set)){
                    $color_number = 0;
                }
            }

            my @data = split ("; ", $line);
            my $cluster_num = $data[0];
            my $query = $data[1];
            my $subject = $data[2];
            my $size = $data[3];

            my ($qstart,$qend) = $query =~ /^(\w+) to (\w+)/;
            my ($sstart,$send) = $subject =~ /^(\w+) to (\w+)/;

            for my $fh (\*OUT,\*CAT){

                # query
                my $query_start = $loci_db{$qstart}{'start'};
                my $query_end = $loci_db{$qend}{'end'};

                print $fh $loci_db{$qstart}{'contig'}.' ';
                print $fh $query_start.' ';
                print $fh $query_end.' ';

                # subject
                my $subject_start = $loci_db{$sstart}{'start'};
                my $subject_end = $loci_db{$send}{'end'};

                print $fh $loci_db{$sstart}{'contig'}.' ';
                print $fh $subject_start.' ';
                print $fh $subject_end.' ';
                print $fh 'color='.$color;
                print $fh ',z='.$zdepth."\n";

            }

        }

    }

    close OUT;
    close CAT;

}

####################################################################
### Subroutine(s)
####################################################################

sub cc_colors {
	%custom_colors = (
		'chloropicon' => { # from Lemieux et al. (2019) https://www.nature.com/articles/s41467-019-12014-x
			'c01' => '202,75,75',
			'c02' => '239,60,104',
			'c03' => '241,102,140',
			'c04' => '245,152,162',
			'c05' => '245,126,47',
			'c06' => '250,166,55',
			'c07' => '255,197,61',
			'c08' => '255,228,67',
			'c09' => '210,213,76',
			'c10' => '147,195,84',
			'c11' => '18,178,89',
			'c12' => '0,179,127',
			'c13' => '0,180,161',
			'c14' => '0,182,204',
			'c15' => '0,183,241',
			'c16' => '0,157,218',
			'c17' => '64,131,196',
			'c18' => '94,104,176',
			'c19' => '108,82,162',
			'c20' => '122,42,144'
		},
		'encephalitozoon' => { # from Pombert et al. (2012) https://pubmed.ncbi.nlm.nih.gov/22802648/
			'ei-01' => '0,162,120',
			'ei-02' => '0,165,180',
			'ei-03' => '91,202,244',
			'ei-04' => '139,162,211',
			'ei-05' => '121,97,169',
			'ei-06' => '162,25,141',
			'ei-07' => '235,0,139',
			'ei-08' => '240,102,129',
			'ei-09' => '241,101,80',
			'ei-10' => '245,138,32',
			'ei-11' => '164,115,11'
		},
		'blues' => { # A simple blue gradient (13 hues)
			'bl-01' => '245,255,255',
			'bl-02' => '190,233,244',
			'bl-03' => '180,212,233',
			'bl-04' => '170,191,222',
			'bl-05' => '160,171,211',
			'bl-06' => '149,150,200',
			'bl-07' => '138,130,190',
			'bl-08' => '127,111,179',
			'bl-09' => '115,91,168',
			'bl-10' => '103,71,157',
			'bl-11' => '91,52,146',
			'bl-12' => '77,30,136',
			'bl-13' => '63,0,125'
		},
		### add custom colors as desired
		# 'custom_name_2' => {
		# 	'key_1' => 'rgb_value_1',
		# 	'key_2' => 'rgb_value_2',
		# 	'key_3' => 'rgb_value_3',
		# },
		# 'custom_name_2' => {
		# 	'key_1' => 'rgb_value_1',
		# 	'key_2' => 'rgb_value_2',
		# 	'key_3' => 'rgb_value_3',
		# },
	)
}