package Bio::EnsEMBL::GlyphSet::Vsynteny;
use strict;
use vars qw(@ISA);
use Bio::EnsEMBL::GlyphSet;
@ISA = qw(Bio::EnsEMBL::GlyphSet);
sub chr_sort {
  my $self = shift;
  my $large_value = 1e10;
  return 
    map { $_ == ($large_value+1) ? 'Y' : ( $_ == $large_value ? 'X' : $_ ) } 
    sort { $a <=> $b }
    map { $_ eq 'Y' ? ($large_value+1) : ( $_ eq 'X' ? $large_value : $_ ) } 
    @_;
}

sub _init {
  my ($self) = @_;

  my $Config = $self->{'config'};

  return unless $Config->container_width()>0; # The container has zero width !!EXIT!!
## FIRSTLY LETS SORT OUT THE COLOURS!!
  my $cmap   = $Config->colourmap();
  my $white  = 'white';
  my $black  = 'black';
  my $grey   = 'grey60';
  my $red    = 'red';
  my $blue   = 'blue';
  my $brown  = 'rust';

    my @BORDERS = map { $cmap->add_hex($_) } qw(00cc00 ff66FF 3333ff 009999 ff9900 993399 cccc00);
    my @COLOURS = map { $cmap->add_hex($_) } qw(99ff99 ffccff 9999ff 99ffff ffcc99 cc99ff ffff99);
    @BORDERS = (@BORDERS,@BORDERS,@BORDERS);
    @COLOURS = (@COLOURS,@COLOURS,@COLOURS);
    my $bg     = $Config->get_parameter( 'bgcolor');

## LETS GRAB THE DATA FROM THE CONTAINER
    my $chr         = $self->{'container'}->{'chr'} || 1;
    my $kba         = $self->{'container'}->{'ka_main'};
    my $kba2        = $self->{'container'}->{'ka_secondary'};
    my $sa         = $self->{'container'}->{'sa_main'};
    my $sa2        = $self->{'container'}->{'sa_secondary'};
    my $synteny_data= $self->{'container'}->{'synteny'};

    my $OTHER       = $self->{'container'}->{'other_species'};
    my $OTHER_T     = $OTHER; $OTHER_T =~s/_/ /g;
    my $SPECIES_T   = $self->{container}{web_species}; $SPECIES_T =~s/_/ /g;
    my $OTHER_SHORT = $self->species_defs->other_species($OTHER,'SPECIES_COMMON_NAME');
    my $SPECIES_SHORT = $self->species_defs->SPECIES_COMMON_NAME;
    $SPECIES_T =~ s/_/ /g;
## This is the list of chromosomes we will be drawing     

    my %other_chrs = map { ($_ , 1) } @{ $self->species_defs->other_species($OTHER,'ENSEMBL_CHROMOSOMES') };
## LETS GRAB THE CHROMOSOME BANDS FOR THE CENTRAL CHROMOSOME

    my $chr_length  = $sa->fetch_by_region( 'toplevel', $chr )->length; 
    my $bands       = $kba->fetch_all_by_chr_name( $chr ) || [];

## NOW LETS GRAB THE IMAGE PARAMETERS
    my $im_width            = $Config->image_width();
    my $length              = $Config->get_parameter('image_height'); 
    my $top_margin          = $Config->get_parameter('top_margin');
    my $main_width          = $Config->get_parameter('main_width');
    my $padding             = $Config->get_parameter('padding');
    my $outer_padding       = $Config->get_parameter('outer_padding');
    my $inner_padding       = $Config->get_parameter('inner_padding');
    my $secondary_width     = $Config->get_parameter('secondary_width');
    my $spacing             = $Config->get_parameter('spacing');
## LET us derive the next set of values....        
    my $h_offset            = $im_width - $top_margin * 2 - $length;
#    my $bpperpx             = $Config->container_width()/$length;
#    my ($w,$h)              = $Config->texthelper->Vpx2bp('Tiny');
    my $v_offset            = $Config->container_width() ; # * ( $top_margin + $length ) /$length; # bottom align each chromosome!

## Finally some parameters for the drawing code...
    my $done_1_acen         = 0;        # flag for tracking place in chromsome
    # max width of band label is 6 characters

## Synteny drawing stage 1....
##   Part 2: Draw the central karyotype

##   Part 1: Draw a box behind the karyotype

    my @chromosomes = ();
    my $highlights_secondary = {};
    my %colour;
    my %side;
    my %border;
    my $side =1;
    my $COL;
    my $SIDE;
    my $BORD;
#    my $this_chr = $synteny_data->[0]->{'chr_name'};
    my $highlights_main      = { $chr => [] };

    my $CANSEE_OTHER = $Config->{'other_species_installed'};

    foreach my $box ( @$synteny_data ) {
      my ($main_dfr, $other_dfr);
      foreach my $dfr (@{$box->children}) {
        if ($dfr->dnafrag->genome_db->name eq $OTHER_T) {
          $other_dfr = $dfr;
        } else {
          $main_dfr = $dfr;
        }
      }
#        my $other_chr = $box->{'hit_chr_name'};
        my $other_chr = $other_dfr->dnafrag->name;
        if(!$other_chrs{$other_chr}) { ## We have a hit on another chromosome 
            $COL = $grey;
            $BORD = $black;
            $SIDE = 0;
        } elsif( exists $highlights_secondary->{$other_chr} ) { ## We have a hit which is on a chr... which we've already positioned
            $COL  = $colour{$other_chr};
            $SIDE = $side{$other_chr};
            $BORD = $border{$other_chr};
        } else { ## We have a hit which is on a chr... which we have already to position
            $highlights_secondary->{$other_chr}=[];
            $COL = shift @COLOURS;
            $BORD = shift @BORDERS;
            push @chromosomes, $other_chr;
            $side *=-1;
            $SIDE = $side;
            $side{$other_chr} = $side;
            $colour{$other_chr} = $COL;
            $border{$other_chr} = $BORD;
        }
        my $url = $self->_url({
	    'action'  => 'Overview',
	    'species' => $self->{container}{web_species},
	    't'       => undef,
	    'r'       => "$chr:".$main_dfr->dnafrag_start.'-'.$main_dfr->dnafrag_end,
	    'r1'      => "$other_chr:".$other_dfr->dnafrag_start.'-'.$other_dfr->dnafrag_end,
	    'sp1'     => $OTHER,
	    'ori'     => '',
	});

#	    '03:Centre gene list' => qq(/@{[$self->{container}{web_species}]}/syntenyview?otherspecies=$OTHER;chr=$chr;loc=).int(($main_dfr->dnafrag_end+$main_dfr->dnafrag_start)/2)

        push @{$highlights_main->{$chr}}, {
            'id' => $box->dbID,
            'start'=> $main_dfr->dnafrag_start,
            'end' => $main_dfr->dnafrag_end,
            'col' => $COL,
            'border' => $BORD,
            'side' => $SIDE,
            'href' => $url,
        };
        if($SIDE) {
            my $marked =
                ($main_dfr->dnafrag_start <= $self->{'container'}->{'line'} && $self->{'container'}->{'line'} <= $main_dfr->dnafrag_end) ? $SIDE : 0;
	    my $ori = ($main_dfr->dnafrag_strand * $other_dfr->dnafrag_strand == 1) ? 'forward' : 'reverse';
	    my $url = $self->_url({
		'action'  => 'Overview',
		'species' => $OTHER,
		't'       => undef,
		'r1'      => "$chr:".$main_dfr->dnafrag_start.'-'.$main_dfr->dnafrag_end,
		'r'       => "$other_chr:".$other_dfr->dnafrag_start.'-'.$other_dfr->dnafrag_end,
		'ori'     => $ori,
		'sp1'      => $self->{container}{web_species},
	    });
            push @{$highlights_secondary->{$other_chr}}, {
                'rel_ori' => $main_dfr->dnafrag_strand * $other_dfr->dnafrag_strand,
                'id' => $box->dbID,
                'start'=> $other_dfr->dnafrag_start,
                'end' => $other_dfr->dnafrag_end,
                'col' => $COL,
                'border' => $BORD,
                'side' => 0,
                'href' => $url,
                'marked' => $marked,
            };
        }
    }
    my %main_coords = $self->draw_chromosome( 
        'bands'         => $bands,
        'h_offset'      => $outer_padding + $inner_padding + $secondary_width,
        'v_offset'      => $h_offset,
        'length'        => $length,
        'chr_length'    => $chr_length,
        'chr'           => $chr,
        'width'         => $main_width,
        'white'         => $white,
        'black'         => $black,
        'grey'          => $grey,
        'red'           => $red,
        'bg'            => $bg,
        'highlights'    => $highlights_main->{$chr},
        'font'          => 'Tiny',
        'ruler'         => ( $chr_length> 10e7 ? 2e7 : 1e7 ),
        'line'          => $self->{'container'}->{'line'}
    );

    my %secondary_coords;
    my $num_chr     = @chromosomes;
    my $flag = 0;
    my $N=0;
    my $FLAG = $num_chr%2 == 0; ## FLAG MEANS THAT EVEN START AT 0...
    return if $num_chr==0;
    my $secondary_length = int( 2 * ( $length + $spacing ) / ($num_chr+1-$FLAG) - $spacing );
    foreach my $chr2 ( @chromosomes ) {
        my $chr_length_2  = $sa2->fetch_by_region( 'toplevel', $chr2 )->length() || 0;
        my $bands_2       = $kba2->fetch_all_by_chr_name( $chr2 );
        my ($h_offset2, $v_offset2) = $flag==0 ?
            ( $h_offset + $N/2 * ( $secondary_length + $spacing ),
              $outer_padding) : # LHS
            ( $h_offset + ($N-$FLAG)/2 * ( $secondary_length + $spacing ),
              2 * $inner_padding + $secondary_width + $main_width + $outer_padding) ; # RHS
        my $mb_p_p = ($chr_length_2 / $secondary_length / 1e6);
        my $ruler = $mb_p_p > 0.75 ? 5e7 : ($mb_p_p > 0.15 ? 2e7 : 1e7);
        my %t = $self->draw_chromosome( 
            'bands'         => $bands_2,
            'h_offset'      => $v_offset2,
            'v_offset'      => $h_offset2,
            'length'        => $secondary_length,
            'chr_length'    => $chr_length_2,
            'width'         => $secondary_width,
            'white'         => $white,
            'black'         => $black,
            'grey'          => $grey,
            'red'           => $red,
            'bg'            => $bg,
            'chr_name'      => "Chr $chr2",
            'font'          => 'Tiny',
            'ruler'         => $ruler,
            'ruler_offset'  => $flag == 0 ? 'l' : 'r',
            'highlights'    => $highlights_secondary->{$chr2}
        );      
        while(my($k,$v)=each(%t)) {
            $secondary_coords{$k}=$v;
        }
        $N++;
        $flag = 1-$flag;
    }        
    foreach(keys %secondary_coords) {
        my($Y1,$Y2);
        my $X1 = ($secondary_coords{$_}->{'top'}+$secondary_coords{$_}->{'bottom'})/2;
        my $X2 = ($main_coords{$_}->{'top'}+$main_coords{$_}->{'bottom'})/2;
        if($secondary_coords{$_}->{'left'} > $main_coords{$_}->{'left'}) {
            ($X1,$X2)=($X2,$X1);
            $Y1 = $main_coords{$_}->{'right'};
            $Y2 = $secondary_coords{$_}->{'left'};
        } else {
            $Y1 = $secondary_coords{$_}->{'right'};
            $Y2 = $main_coords{$_}->{'left'};
        }
        my $COL = $secondary_coords{$_}->{'rel_ori'} == 1 ? $black : $brown;
        $self->push($self->Line({
            'x'       => $X1,
            'y'       => $Y1,
            'width'   => 0,
            'height'  => ($Y2-$Y1)/10,
            'colour'           =>  $COL,
            'absolutey'        => 1, 'absolutex'        => 1,'absolutewidth'=>1,
        }));
        $self->push($self->Line({
            'x'       => $X1,
            'y'       => $Y1 + ($Y2-$Y1)/10,
            'width'   => $X2-$X1,
            'height'  => 4*($Y2-$Y1)/5,
            'colour'           => $COL,
            'absolutey'        => 1, 'absolutex'        => 1,'absolutewidth'=>1,
        }));
        $self->push($self->Line({
            'x'       => $X2,
            'y'       => $Y2 - ($Y2-$Y1)/10,
            'width'   => 0,
            'height'  => ($Y2-$Y1)/10,
            'colour'           =>  $COL,
            'absolutey'        => 1, 'absolutex'        => 1,'absolutewidth'=>1,
        }));
    }
    my $w = $self->{'config'}->texthelper->width('Tiny');
    my $h = $self->{'config'}->texthelper->height('Tiny');
    $self->unshift($self->Text({
            'x'          => $im_width - $h - 2 - $top_margin,
            'y'          => $outer_padding + $secondary_width/2 - $w * length($OTHER_T)/2,
            'font'       => 'Tiny',
            'colour'     => $black,
            'text'       => $OTHER_T,
            'absolutey'  => 1, 'absolutex' => 1,'absolutewidth'=>1,
    }));
    $self->unshift($self->Text({
            'x'          => $im_width - $h - 2 - $top_margin ,
            'y'          => $outer_padding + $inner_padding*2 + $main_width + 3*$secondary_width/2 - $w * length($OTHER_T)/2,
            'font'       => 'Tiny',
            'colour'     => $black,
            'text'       => $OTHER_T,
            'absolutey'  => 1, 'absolutex' => 1,'absolutewidth'=>1,
    }));
    $self->unshift($self->Rect({
            'x'          => 0,
            'y'          => 0,
            'width'      => $im_width,
            'height'     => ($outer_padding + $secondary_width + $inner_padding ) * 2 + $main_width,
            'absolutey'  => 1,
            'absolutex'  => 1,'absolutewidth'=>1,
    }));
}

sub draw_chromosome {
    my $self = shift;
    my %params = @_;
    ## contains hash 'bands', 'h_offset', 'v_offset', 
    ##               'length', 'chr_length', 'width',
    ##               'grey', 'black', 'bg', 'white', 
    ##               'chr_name', 'font' ## will be used for labelling in future
    my $h_offset   = $params{'h_offset'};
    my $v_offset   = $params{'v_offset'};
    my $length     = $params{'length'};
    my $chr_length = $params{'chr_length'};
    my $scale      = $length / $chr_length;
    my $wid        = $params{'width'};
    my $h_wid      = $wid/2;
    my $done_1_acen = 0;
    my $highlights = $params{'highlights'} || [];
    my @bands = sort{$a->start <=> $b->start } @{$params{'bands'}||[]};
    if( @bands ) {
      foreach my $band (@bands ) {
        my $bandname       = $band->name();
        my $vc_band_start  = $band->start() * $scale + $v_offset;
        my $vc_band_end    = $band->end()   * $scale + $v_offset;
        my $stain          = $band->stain();
        if ($stain eq "acen"){
	  my $gband;
	  if ($done_1_acen){
	    $self->push($self->Poly
			({
			  'points'       => [ 
					     $vc_band_start, 
					     $h_offset + $h_wid, 
					     $vc_band_end,   
					     $h_offset,
					     $vc_band_end,   
					     $h_offset+$wid,
					    ],
			  'colour'       => $params{'grey'},
			  'absolutey'    => 1,    
			  'absolutex'    => 1,
			  'absolutewidth'=>1,
                }));
            } else {
                $self->push($self->Poly
			    ({
			      'points' => [ 
					   $vc_band_start, 
					   $h_offset, 
					   $vc_band_end,
					   $h_offset + $h_wid,
					   $vc_band_start, 
					   $h_offset + $wid,
					  ],
			      'colour'       => $params{'grey'},
			      'absolutey'    => 1,    
			      'absolutex'    => 1,
			      'absolutewidth'=>1,
                }));
                $done_1_acen = 1;
            }
        } elsif ($stain eq "stalk"){
            $self->push($self->Poly
			({
			  'points' => [
				       $vc_band_start, 
				       $h_offset, 
				       $vc_band_end,   
				       $h_offset + $wid,
				       $vc_band_end,   
				       $h_offset,
				       $vc_band_start, 
				       $h_offset + $wid, 
				      ],
			  'colour'       => $params{'grey'},
			  'absolutey'    => 1,    
			  'absolutex'    => 1,
			  'absolutewidth'=>1,
            }));
            $self->push($self->Rect
			({
			  'x'            => $vc_band_start,
			  'y'            => $h_offset + int($wid/4),
			  'width'        => $vc_band_end - $vc_band_start,
			  'height'       => $h_wid,
			  'colour'       => $params{'grey'},
			  'absolutey'    => 1,    
			  'absolutex'    => 1,
			  'absolutewidth'=>1,
            }));
	  } else {
            $self->unshift($self->Rect
			   ({
			     'x'          => $vc_band_start,
			     'y'          => $h_offset,
			     'width'      => $vc_band_end - $vc_band_start,
			     'height'     => $wid,
			     'colour'     => ( $stain eq 'tip' ? 
					       $params{'grey'} : 
					       $params{'white'} ),
			     'absolutey'  => 1,
			     'absolutex'  => 1,
			     'absolutewidth'=>1,
            }));
            $self->push($self->Line
			({
			  'x'            => $vc_band_start,
			  'y'            => $h_offset,
			  'width'        => $vc_band_end - $vc_band_start,
			  'height'       => 0,
			  'colour'       => $params{'black'},
			  'absolutey'    => 1, 
			  'absolutex'    => 1,
			  'absolutewidth'=>1,
            }));
            $self->push($self->Line
			({
			  'x'            => $vc_band_start,
			  'y'            => $h_offset+$wid,
			  'width'        => $vc_band_end - $vc_band_start,
			  'height'       => 0,
			  'colour'       => $params{'black'},
			  'absolutey'    => 1, 
			  'absolutex'    => 1,
			  'absolutewidth'=>1,
            }));
	  }
      }
    }
    else {
      $self->unshift($self->Rect
		     ({
		       'x'          => $v_offset,
		       'y'          => $h_offset,
		       'width'      => $chr_length * $scale,
		       'height'     => $wid,
		       'colour'     => $params{'white'},
		       'absolutey'  => 1,
		       'absolutex'  => 1,'absolutewidth'=>1,
		      }));
      foreach my $Y ($h_offset, $h_offset+$wid){
	$self->push($self->Line
		    ({
		      'x'                => $v_offset+1,
		      'y'                => $Y,
		      'width'            => $chr_length * $scale -1,
		      'height'           => 0,
		      'colour'           => $params{'black'},
		      'absolutey'        => 1, 
		      'absolutex'        => 1,'absolutewidth'=>1,
		     }));
      }
    } 
    my @lines = $wid < 16 ? ( [8,6],[4,4],[2,2] ) :
               ( $wid < 30 ? ( [8,5],[5,3],[4,1],[3,1],[2,1],[1,1],[1,1],[1,1] ) :
                ( [8,8],[5,3],[4,1],[3,1],[2,1],[1,1],[1,1],[1,1] ) );

    my $divisor = $wid<30 ? 24 : 30;         
## This is the end of the         

    my @ends;
    if ( @bands ){
	@ends = (( $bands[0]->stain() eq 'tip' ? () : 1 ),
	    ( $bands[-1]->stain() eq 'tip' ? () : -1 ));
    } else {
        @ends = (-1,1);
    }
    foreach my $end (@ends){
        foreach my $I ( 0..$#lines ) {
            my ( $bg_x, $black_x ) = @{$lines[$I]};
            my $xx =  ($end==1 ? $v_offset : $v_offset + $length) + $end * $I;
            $self->push($self->Line({
                    'x'         => $xx,
                    'y'         => $h_offset,
                    'width'     => 0,
                    'height'    => $wid * $bg_x/$divisor -1,
                    'colour'    => 'background1',
                    'absolutey' => 1,   'absolutex' => 1,'absolutewidth'=>1,
            }));
            $self->push($self->Line({
                    'x'         => $xx,
                    'y'         => $h_offset + 1 + $wid * (1-$bg_x/$divisor),
                    'width'     => 0,
                    'height'    => $wid * $bg_x/$divisor -1 ,
                    'colour'    => 'background1',
                    'absolutey' => 1,   'absolutex' => 1,'absolutewidth'=>1,
            }));
            $self->push($self->Line({
                    'x'         => $xx,
                    'y'         => $h_offset + $wid * $bg_x/$divisor,
                    'width'     => 0,
                    'height'    => $wid * $black_x/$divisor -1 ,
                    'colour'    => 'black',
                    'absolutey' => 1, 'absolutex' => 1,'absolutewidth'=>1,
            }));
            $self->push($self->Line({
                    'x'         => $xx,
                    'y'         => $h_offset + 1 + $wid * (1-$bg_x/$divisor-$black_x/$divisor),
                    'width'     => 0,
                    'height'    => $wid * $black_x/$divisor -1 ,
                    'colour'    => 'black',
                    'absolutey' => 1, 'absolutex' => 1,'absolutewidth'=>1,
            }));
        }
    }
    my ($w,$h);
    if($params{'font'}) {
        $w = $self->{'config'}->texthelper->width($params{'font'});
        $h = $self->{'config'}->texthelper->height($params{'font'});
    }
    if($params{'ruler'}) {
        my $X = $params{'ruler'};
        my $flag = $params{'ruler_offset'};
        while($X<$chr_length) {
            my $xx = $X * $scale + $v_offset;
            $self->push($self->Line({
                    'x'         => $xx,
                    'y'         => $h_offset + ($params{'ruler_offset'} eq 'r' ? $wid : ($params{'ruler_offset'} eq 'l' ? -3  : 0)),
                    'width'     => 0,
                    'height'    => 3,
                    'colour'    => $params{'black'},
                    'absolutey' => 1, 'absolutex' => 1,'absolutewidth'=>1,
            }));
            if($params{'font'}) {
                my $TEXT = int($X/1000000)."M";
                $self->push($self->Text({
                    'x'          => $xx-$h/2,
                    'y'          => $h_offset + ($params{'ruler_offset'} eq 'r' ? $wid + 5 : ($params{'ruler_offset'} eq 'l' ? -5-length($TEXT)*$w : 5)), 
                    'font'       => $params{'font'},
                    'colour'     => $params{'black'},
                    'text'       => $TEXT,
                    'absolutey'  => 1, 'absolutex' => 1,'absolutewidth'=>1,
                }));
            }
            $X+=$params{'ruler'};
        }
    }
    if($params{'font'} && $params{'chr_name'}) {
        $self->push($self->Text({
            'x'          => $v_offset + $length +3 ,
            'y'          => $h_offset + $h_wid - $w * length($params{'chr_name'})/2,
            'font'       => $params{'font'},
            'colour'     => $params{'black'},
            'text'       => $params{'chr_name'},
            'absolutey'  => 1, 'absolutex' => 1,'absolutewidth'=>1,
        }));
    }
    my %coords;
    foreach my $box (@$highlights) {
        my $vc_start  = $box->{'start'} * $scale + $v_offset;
        my $vc_end    = $box->{'end'}   * $scale + $v_offset;
        $coords{$box->{'id'}} = {
            'left'  => $h_offset + $box->{'side'} * ($wid+4),
            'right' => $h_offset + $box->{'side'} * ($wid+4) + $wid,
            'top'   => $vc_start,
            'bottom'=> $vc_end,
            'rel_ori' => $box->{'rel_ori'}
        };
        $self->push($self->Rect({
            'x'          => $vc_start,
            'y'          => $h_offset + $box->{'side'} * ($wid+4),
            'width'      => $vc_end - $vc_start,
            'height'     => $wid,
            'colour'     => $box->{'col'},
            'bordercolour'     => $box->{'border'},
            'absolutey'  => 1,
            'absolutex'  => 1,'absolutewidth'=>1,
            'href' => $box->{'href'},
            'zmenu' => $box->{'zmenu'}
        }));
        if($box->{'marked'}==1 || $box->{'marked'}==-1) {
            $self->push($self->Rect({
                'x'          => $vc_start -2,
                'y'          => $h_offset + ($box->{'marked'}==1 ? $wid+3 : -4 ), 
                'width'      => $vc_end - $vc_start + 4,
                'height'     => 2,
                'bordercolour'     => $params{'red'},
                'absolutey'  => 1,
                'absolutex'  => 1,'absolutewidth'=>1,
            }));
        }
    }
    if($params{'line'}) {
	my $start = $params{'line'}-5e5;
	my $stop = $start+1e6-1;
	my $r = $params{'chr'} . ":$start-$stop";
	my $url = $self->_url({
	    'type'    => 'Location',
	    'action'  => 'View',
	    'r'       =>$r,
	    'species' => $self->{container}{web_species}});
        $self->push($self->Rect({
            'x'          => $v_offset + $params{'line'} * $scale - 1,
            'y'          => $h_offset - 2,
            'width'      => 3,
            'height'     => $wid + 4,
            'bordercolour' => $params{'red'},
            'absolutey'  => 1,
            'absolutex'  => 1,'absolutewidth'=>1,
            'href'       => $url,
        }));
    }
    return %coords;
}
1;