package ImagesManager;

use strict;
use warnings;

use GD;

use lib qw(Core);

use Configuration;
use Logger;

use TargetsManager;
use GroupsManager;
use ResultsManager;
use String;


my $DEFAULT_FONT = '/usr/share/fonts/truetype/msttcorefonts/Arial_Bold.ttf';
my $DEFAULT_SMALL_FONT = '/usr/share/fonts/truetype/msttcorefonts/Courier_New_Bold.ttf';
my $DEFAULT_TOP_FONT = '/usr/share/fonts/truetype/msttcorefonts/Arial_Bold.ttf';
my $DEFAULT_AXIS_FONT = '/usr/share/fonts/truetype/msttcorefonts/Courier_New_Bold.ttf';

sub new {
    my ($class, $debug) = @_;
    
    my $self = {
        _database => Database->new($CONFIG->{HOSTNAME}, $CONFIG->{PORT}, $CONFIG->{DATABASE}, $CONFIG->{USERNAME}, $CONFIG->{PASSWORD}),
        _logger => Logger->new()
    };
    
    # by default debug mode is turned on
    $self->{_debug} = !defined($debug) ? 1 : $debug;
    
    $self->{_logger}->set_error_log('error.log');
    
    bless $self, $class;
    return $self;
}

# highlight_type can be {show_related, or compare_groups, or not defined value}
# filter:
#   for show_related $filter_params is hash {group, model}
#   for compare_groups $filter_params is array of groups
sub generate_gdt_image {
    my ($self, $target, $gdt_data, $output_file_path, $view_first_only, $highlight_type, $filter_params, $map_url_params) = @_;
    
    my $image = new GD::Image(680, 440);
    
    my $white = $image->colorAllocate(255, 255, 255);
    my $black = $image->colorAllocate(0, 0, 0);
    
    my $red = $image->colorAllocate(255, 0, 0);
    my $darkred = $image->colorAllocate(128, 0, 0);
    my $green = $image->colorAllocate(0, 128, 0);
    my $darkgreen = $image->colorAllocate(0, 64, 0);
    my $yellow = $image->colorAllocate(255, 255, 0);
    my $grey = $image->colorAllocate(204, 204, 204);
    my $blue = $image->colorAllocate(0, 0, 255 );
    my $darkblue = $image->colorAllocate(0, 0, 200 );
    my $darkgrey = $image->colorAllocate(100, 100, 100);
    my $purple = $image->colorAllocate(200, 0, 255);
    my $orange = $image->colorAllocate(255, 128, 0);
    my $whiteblue = $image->colorAllocate(100, 200, 255);
    my $rose = $image->colorAllocate(255,100,80);
    my $darkpurple = $image->colorAllocate(150, 0, 200);
    my $darkyellow = $image->colorAllocate(200, 200, 0);

	my @model_color = (
		[$red, $darkred],
		[$green, $darkgreen],
		[$blue, $darkblue],
	);
    
    #$image->transparent($white);
    $image->interlaced('true');
    
    $image->setThickness(1);
    
    # draw axes
    $image->line(65, 65, 615, 65, $black); # top
    $image->line(65, 375, 615, 375, $black); # bottom
    $image->line(65, 65, 65, 375, $black); # left
    $image->line(615, 65, 615, 375, $black); # right
    
    # draw ruler
    for(my $i = 0; $i < 10; $i++) {
        $image->line(65, 75 + 29*$i, 65 + (($i % 5 == 0) ? 10 : 5), 75 + 29*$i, $black); # left
        $image->line(605 + (($i % 5 == 0) ? 0 : 5), 75 + 29*$i, 615, 75 + 29*$i, $black); # right
        $image->line(75 + 53*($i + 1), 65, 75 + 53*($i + 1), 65 + ((($i + 1) % 2 == 0) ? 10 : 5), $black); # top
        $image->line(75 + 53*($i + 1), 365 + ((($i + 1) % 2 == 0) ? 0 : 5), 75 + 53*($i + 1), 375, $black); # bottom
    }

    # draw titles
    $image->stringFT($black, $DEFAULT_SMALL_FONT, 12, 0, 220, 420, "Percent of Residues (CA)");
    $image->stringFT($black, $DEFAULT_SMALL_FONT, 12, 3.14 / 2, 30, 320, "Distance Cutoff, A");
    $image->stringFT($black, $DEFAULT_SMALL_FONT, 12, 0, 310, 30, $target);
    
    # draw axes rules X
    $image->stringFT($black, $DEFAULT_SMALL_FONT, 12, 0,  60, 395, "0");
    $image->stringFT($black, $DEFAULT_SMALL_FONT, 12, 0, 171, 395, "20");
    $image->stringFT($black, $DEFAULT_SMALL_FONT, 12, 0, 277, 395, "40");
    $image->stringFT($black, $DEFAULT_SMALL_FONT, 12, 0, 383, 395, "60");
    $image->stringFT($black, $DEFAULT_SMALL_FONT, 12, 0, 489, 395, "80");
    $image->stringFT($black, $DEFAULT_SMALL_FONT, 12, 0, 595, 395, "100");

    # draw axes rules Y
    $image->stringFT($black, $DEFAULT_SMALL_FONT, 12, 3.14 / 2, 55, 380, "0");
    $image->stringFT($black, $DEFAULT_SMALL_FONT, 12, 3.14 / 2, 55, 225, "5");
    $image->stringFT($black, $DEFAULT_SMALL_FONT, 12, 3.14 / 2, 55,  75, "10");
    
    my $map_string = '';
    
    my $step = 530 / 100;
    for(my $i = 0; $i < scalar(@{$gdt_data}); $i++) {
        if($view_first_only && $gdt_data->[$i]->{MODEL} != 1) { next; }
        #if($gdt_data->[$i]->{CODE} != 164) { next; } # for test purposes
        
        my @percentage = split(/\s+/, $gdt_data->[$i]->{GDT_CA_PERCENTAGE_4});
        my $percentage_count = scalar(@percentage);
        
        if($percentage_count < 20) { next; } # skip invalid gdt percentage files
        
        #PLEASE! please please! use standard model name function generation!
        #my $model_name = sprintf("%s%s%s_%d", $gdt_data->[$i]->{TARGET}, $gdt_data->[$i]->{PFRMAT}, $gdt_data->[$i]->{CODE}, $gdt_data->[$i]->{MODEL});
        my $r_m = new ResultsManager();        
        my $model_name = $r_m->build_model_name($gdt_data->[$i]->{TARGET}, $gdt_data->[$i]->{PFRMAT}, $gdt_data->[$i]->{CODE}, $gdt_data->[$i]->{MODEL},$gdt_data->[$i]->{PARENT}, $gdt_data->[$i]->{DOMAIN});
        
        
        $map_string .= sprintf('<area href="?%s&model=%s" onmouseover="title=\'%s\';self.status=\'%s\';return false" onmouseout="self.status=\'\';return false" shape="poly" coords="', $map_url_params, $model_name, $model_name, $model_name);
        
        for(my $j = 0; $j < $percentage_count - 1; $j++) {
            $image->line(75 + $percentage[$j] * $step, 365 - 15*$j, 75 + $percentage[$j + 1] * $step, 365 - 15*($j + 1), $orange);
            
            $map_string .= sprintf('%d,%d,', 75 + $percentage[$j] * $step + 1, 365 - 15*$j + 1); # -1 and +1 - to make polygon wider - easier to click
        }
        $map_string .= sprintf('%d,%d,', 75 + $percentage[$percentage_count - 1] * $step, 365 - 15*($percentage_count - 1));
        
        # the second loop only for map logic to build correct polygon with width 3
        for(my $j = $percentage_count - 1; $j > 0; $j--) {
            $map_string .= sprintf('%d,%d,', 75 + $percentage[$j] * $step - 1, 365 - 15*$j - 1); # -1 and +1 - to make polygon wider - easier to click
        }
        $map_string .= sprintf("%d,%d\">\n", 75 + $percentage[0] * $step, 365);
    }
    
    if(open(MAP_FILE, sprintf("> %s.js", $output_file_path))) {
        print(MAP_FILE $map_string);
        close(MAP_FILE);
    }
    
    $image->setThickness(2);
    for(my $i = 0; $i < scalar(@{$gdt_data}); $i++) {
        if($view_first_only && $gdt_data->[$i]->{MODEL} != 1) { next; }
        
        my @percentage = split(/\s+/, $gdt_data->[$i]->{GDT_CA_PERCENTAGE_4});
        my $percentage_count = scalar(@percentage);
        
        if($percentage_count < 20) { next; } # skip invalid gdt percentage files
        
        my $color = $orange;
        if(defined($highlight_type) && ($highlight_type eq 'show_related_small') || ($highlight_type eq 'show_related') || ($highlight_type eq 'compare_groups')) {
            if((($highlight_type eq 'show_related') ||($highlight_type eq 'show_related_small')) && ($filter_params->{GROUP} == $gdt_data->[$i]->{CODE})) {
                if($gdt_data->[$i]->{MODEL} == $filter_params->{MODEL}) {
                    $color = $blue;
                } else {
                    $color = $black;
                }
                
                for(my $j = 0; $j < scalar(@percentage) - 1; $j++) {
                    $image->line(75 + $percentage[$j] * $step, 365 - 15*$j, 75 + $percentage[$j + 1] * $step, 365 - 15*($j + 1), $color);
                }
            }
            
            if($highlight_type eq 'compare_groups') {
                my $highlight = 0;
                for(my $z = 0; $z < scalar(@{$filter_params}); $z++) {
                    if($filter_params->[$z] == $gdt_data->[$i]->{GROUP_ID}) {
						$color = $model_color[$z][$gdt_data->[$i]->{MODEL} != 1];
                        $highlight = 1;
                    }
                }
                
                if($highlight) {
                    for(my $j = 0; $j < scalar(@percentage) - 1; $j++) {
                        $image->line(75 + $percentage[$j] * $step, 365 - 15*$j, 75 + $percentage[$j + 1] * $step, 365 - 15*($j + 1), $color);
                    }
                }
                $highlight = 0;
            }
        }
    }
    
    binmode STDOUT;
    
    my $image_path = $output_file_path;
    
    if (open FILE, "+>", $image_path) {
        print FILE $image->png;
        close(FILE);
    }
    
    # make small pictures
    if(!defined($highlight_type) || ($highlight_type eq '') || ($highlight_type eq 'show_related_small')) {
        my $small_image_path = $output_file_path;
        $small_image_path =~ s/.png/.small.png/g;        
        $self->resize($output_file_path, $small_image_path, 140, 100);
        if($highlight_type eq 'show_related_small') {
            system(sprintf("rm -f %s ",$output_file_path));            
            system(sprintf("rm -f %s.js ",$output_file_path));
        }
    }
    
    return;
}

sub generate_eqv_image {
    my ($self, $eqv_data, $output_file_path) = @_;
    
    my $width = 500;
    my $height = 8;
    
    my $image = new GD::Image($width, $height);
    
    my $white = $image->colorAllocate(255, 255, 255);
    my $red = $image->colorAllocate(255, 0, 0);
    my $green = $image->colorAllocate(0, 255, 0);
    my $yellow = $image->colorAllocate(255, 255, 0);
    
    $image->transparent($white);
    $image->interlaced('true');
    
    my @eqv_data = split(/ /, $eqv_data);
    my $eqv_data_count = scalar(@eqv_data);
    
    if($eqv_data_count == 0) { return; }
    
    $image->filledRectangle(0, 0, $width, $height, $white);
    
    my $step = int($width / $eqv_data_count);
    for(my $i = 0; $i < $eqv_data_count; $i++) {
        my $color = $white;
        if ($eqv_data[$i] == 1) {
            $color = $red;
        } elsif ($eqv_data[$i] == 2) {
            $color = $yellow;
        } elsif ($eqv_data[$i] == 3) {
            $color = $green;
        }
        
        $image->filledRectangle($i*$step, 1, ($i + 1)*$step, $height - 1, $color);
    }
    
    if (open FILE, "+>", $output_file_path) {
        print FILE $image->png;
        close(FILE);
    }
    
    return;
}

sub generate_al_image {
    my ($self, $al0, $al4, $al4x, $nt, $output_file_path) = @_;
    
    my $width = 500;
    my $height = 8;
    
    my $image = new GD::Image($width, $height);
    
    my $white = $image->colorAllocate(255, 255, 255);
    my $red = $image->colorAllocate(255, 0, 0);
    my $green = $image->colorAllocate(0, 255, 0);
    my $yellow = $image->colorAllocate(255, 255, 0);
    
    $image->transparent($white);
    $image->interlaced('true');
    
    $image->filledRectangle(0, 0, $width, $height, $white);
    
    if($nt == 0) { return; }
    
    $image->filledRectangle(0, 1, $width * $al4x / $nt, $height - 1, $red);
    $image->filledRectangle(0, 1, $width * $al4 / $nt, $height - 1, $yellow);
    $image->filledRectangle(0, 1, $width * $al0 / $nt, $height - 1, $green);
    
    if (open FILE, "+>", $output_file_path) {
        print FILE $image->png;
        close(FILE);
    }
    
    return;
}


sub generate_al_small_image {
    my ($self, $target_name, $output_file_path, $highlite_group_code, @results) = @_;
    
    my $results_count = scalar(@results);
    
    my $width = 60;
    my $height_part = 1;
    my $height = (($results_count>0)?($results_count*$height_part):74);
    
    
    my $image = new GD::Image($width, $height);
    
    my $white = $image->colorAllocate(255, 255, 255);
    my $red = $image->colorAllocate(255, 0, 0);
    my $green = $image->colorAllocate(0, 255, 0);
    my $yellow = $image->colorAllocate(255, 255, 0);
    my $black = $image->colorAllocate(0, 0, 0);
    
    $image->transparent($white);
    $image->interlaced('true');
    
    $image->filledRectangle(0, 0, $width, $height, $white);
    
    if (open FILE, "+>", $output_file_path) {
        for(my $i = 0; $i < $results_count; $i++) {
            if($results[$i]->{N2_5} == 0) {
            } elsif(defined($highlite_group_code) && $results[$i]->{CODE} eq $highlite_group_code) {
                $image->filledRectangle(0, $i-2 * $height_part, $width, $i+4*$height_part , $black);
                $i = $i +4;                
            } else {
                $image->filledRectangle(0, $i * $height_part, $width * $results[$i]->{AL4X} / $results[$i]->{N2_5}, $i*$height_part , $red);
                $image->filledRectangle(0, $i * $height_part, $width * $results[$i]->{AL4}  / $results[$i]->{N2_5}, $i*$height_part, $yellow);
                $image->filledRectangle(0, $i * $height_part, $width * $results[$i]->{AL0}  / $results[$i]->{N2_5}, $i*$height_part, $green);
                
            }
        }
        print FILE $image->png;
        close(FILE);
    }
    #$self->resize($output_file_path, $output_file_path, 60, 74); #This resize function set size proportionaly by old W and H but we need custom
    return;
}


sub protein_image {
    my ($self, $input_pdb_file, $output_png_file, $width, $height) = @_;
    
    my $result = 0;
    
    # fix coresponding to OS, this is for ciemniak
    my $PATH_TO_MOLAUTO = '/usr/local/molscript-2.1.2/molauto';
    my $PATH_TO_MOLSCRIPT = '/usr/local/molscript-2.1.2/molscript';
    my $PATH_TO_RASTER3D_RENDER = '/usr/lib/raster3d/render.real';
    
    # /usr/local/molscript-2.1.2/molauto /shared/bystra/data/CASP9/TARGETS/T0387.pdb | /usr/local/molscript-2.1.2/molscript -accum 66 -raster3d 3 -size 500 500 | /usr/lib/raster3d/render.real -size 500x500 -quality 100 -png /home/zenyk/1.png
    # [pdb] -> molauto -> molscript -> render.real -> [png]
    if(system(sprintf("%s %s | %s -accum 66 -raster3d 3 -size %d %d | %s -size %dx%d -quality 100 -png %s"
        , $PATH_TO_MOLAUTO
        , $input_pdb_file
        , $PATH_TO_MOLSCRIPT
        , $width
        , $height
        , $PATH_TO_RASTER3D_RENDER
        , $width
        , $height
        , $output_png_file)) == 0) {
        $result = 1;
    }
    
    return $result;
}

sub resize {
    my ($self, $input_file, $output_file, $new_width, $new_height) = @_;
    
    my $result = 0;
    
    if(system(sprintf("/usr/bin/convert %s -resize %dx%d %s", $input_file, $new_width, $new_height, $output_file)) == 0) {
        $result = 1;
    }
    
    return $result;
}

sub log {
    my ($self, $message) = @_;
    
    $self->{_logger}->error("ImagesManager.pm", $message);
    
    return;
}


######################################### TRERE ARE GOING TO BE OLD FUNCTIONALITY OF TEMPLATES


sub draw_templatesvstargets {
    my ($self, $correct_target_name, $view_templates, $view_models, $view_differences,
        $ranges, $templates, $models, $selected_templates, $selected_models, $main_template_id) = @_;
    
    my $TOP_TITLE = 'Target ' . $correct_target_name;
    my $BOTTOM_TITLE = 'Residue';
    my $LEFT_TITLE = 'CA-CA difference, A';
    
    my $DEFAULT_WIDTH = 800;
    my $DEFAULT_HEIGHT = 300;
    my $LEFT_MARGIN = 50;
    my $RIGHT_MARGIN = 140;
    my $TOP_MARGIN = 30;
    my $BOTTOM_MARGIN = 40;

    my ($target_size) = $$ranges[scalar(@$ranges) - 1];   
        
    my $image = new GD::Image($DEFAULT_WIDTH, $DEFAULT_HEIGHT);
    
    my $white = $image->colorAllocate(255, 255, 255);
    my $black = $image->colorAllocate(0, 0, 0);
    
    my $red = $image->colorAllocate(255, 0, 0);
    my $green = $image->colorAllocate(0, 255, 0);
    my $yellow = $image->colorAllocate(255, 255, 0);
    my $grey = $image->colorAllocate(204, 204, 204);
    my $blue = $image->colorAllocate(0, 0, 255 );
    my $darkgrey = $image->colorAllocate(100, 100, 100);
    my $purple = $image->colorAllocate(200, 0, 255);
    my $orange = $image->colorAllocate(255, 200, 0);
    my $darkgreen = $image->colorAllocate(100, 200, 100);
    my $whiteblue = $image->colorAllocate(100, 200, 255);
    my $rose = $image->colorAllocate(255,100,80);
    my $darkpurple = $image->colorAllocate(150, 0, 200);
    my $darkyellow = $image->colorAllocate(220, 220, 0);
    
    my @colors = ($darkyellow, $darkpurple, $rose, $darkgrey, $green, $whiteblue, $purple, $yellow, $orange, $blue);
    
    #$image->transparent($white);
    $image->interlaced('true');

    #axis
    my $vertical_axis_step = int(($DEFAULT_HEIGHT - $TOP_MARGIN - $BOTTOM_MARGIN) / 10);
    my $horizontal_axis_step = int(($DEFAULT_WIDTH - $LEFT_MARGIN - $RIGHT_MARGIN)/ ($target_size / 10));
    my $coef = int($target_size / 100);
    
    for(my $i = 0; $i <= 10; $i++) {
        $image->line($LEFT_MARGIN, $TOP_MARGIN + $vertical_axis_step * $i, $DEFAULT_WIDTH - $RIGHT_MARGIN, $TOP_MARGIN + $vertical_axis_step * $i, $grey);
    }
    $image->line($LEFT_MARGIN, $TOP_MARGIN, $LEFT_MARGIN, $DEFAULT_HEIGHT - $BOTTOM_MARGIN, $black);
    $image->line($DEFAULT_WIDTH - $RIGHT_MARGIN, $TOP_MARGIN, $DEFAULT_WIDTH - $RIGHT_MARGIN, $DEFAULT_HEIGHT - $BOTTOM_MARGIN, $grey);
    $image->line($LEFT_MARGIN, int(($DEFAULT_HEIGHT - $TOP_MARGIN - $BOTTOM_MARGIN) / 2) + $TOP_MARGIN, $DEFAULT_WIDTH - $RIGHT_MARGIN, int(($DEFAULT_HEIGHT - $TOP_MARGIN - $BOTTOM_MARGIN) / 2) + $TOP_MARGIN, $black);
    
    for(my $i = 0; $i < int($target_size / 10) + 1; $i++) {
        $image->line($LEFT_MARGIN + $i * $horizontal_axis_step, int(($DEFAULT_HEIGHT - $TOP_MARGIN - $BOTTOM_MARGIN) / 2) + $TOP_MARGIN, $LEFT_MARGIN + $i * $horizontal_axis_step, int(($DEFAULT_HEIGHT - $TOP_MARGIN - $BOTTOM_MARGIN) / 2) + $TOP_MARGIN + 5, (($i == 0) ? $black : $grey));
        if($target_size < 100) {
            $image->stringFT($black, $DEFAULT_AXIS_FONT, 10, 0, $LEFT_MARGIN + $i * $horizontal_axis_step - 10, int(($DEFAULT_HEIGHT - $TOP_MARGIN - $BOTTOM_MARGIN) / 2) + $TOP_MARGIN + 18, ($i * 10));
        } else {
            if(($i % $coef) == 0) {
                $image->stringFT($black, $DEFAULT_AXIS_FONT, 10, 0, $LEFT_MARGIN + $i * $horizontal_axis_step - 10, int(($DEFAULT_HEIGHT - $TOP_MARGIN - $BOTTOM_MARGIN) / 2) + $TOP_MARGIN + 18, ($i * 10));
            }
        }
    }
    
    my $horizontal_step = $horizontal_axis_step / 10;
    my $vertical_step = $vertical_axis_step;
    # draw alignment
    
    $image->setThickness(1);

    my $index = 0;
    if($view_templates) {
        foreach my $template_key (@$selected_templates) {
            my @distances = split(/\s+/, trim($$templates[$template_key]{'distances'}));
            my $previous_x = -1;
            my $previous_y = -1;
            
            my $current_color = $colors[$index];
            
            if($template_key eq $main_template_id) {
                $current_color = $darkgreen;
                $image->setThickness(2);
            }
            
            for(my $i = 0; $i < scalar(@distances); $i++) {
                if($distances[$i] ne 'X') {
                    my $current_x = $horizontal_step*$i + $LEFT_MARGIN;
                    my $current_y = int(($DEFAULT_HEIGHT - $TOP_MARGIN - $BOTTOM_MARGIN) / 2) + $TOP_MARGIN - $vertical_step * $distances[$i];
                    
                    if($previous_x >= 0) {
                        $image->line($current_x, $current_y, $previous_x, $previous_y, $current_color);
                    }
                    $image->filledArc($current_x, $current_y, 3, 3, 0, 360, $current_color);
                    
                    $previous_x = $current_x;
                    $previous_y = $current_y;
                } else {
                    $previous_x = -1;
                    $previous_y = -1;
                }
            }

            if($template_key eq $main_template_id) {
                $image->setThickness(1);
            }
            
            $index++;
        }
    }
    
    $image->setThickness(2);
    $index = 0;
    if($view_models) {
        foreach my $model_key (@$selected_models) {
            my @distances = split(/\s+/, trim($$models[$model_key]{'distances'}));
            my $previous_x = -1;
            my $previous_y = -1;
            
            for(my $i = 0; $i < scalar(@distances); $i++) {
                if($distances[$i] ne 'X') {
                    my $current_x = $horizontal_step*$i + $LEFT_MARGIN;
                    my $current_y = int(($DEFAULT_HEIGHT - $TOP_MARGIN - $BOTTOM_MARGIN) / 2) + $TOP_MARGIN - $vertical_step * $distances[$i];
                    
                    if($previous_x >= 0) {
                        $image->line($current_x, $current_y, $previous_x, $previous_y, $blue);
                    }
                    $image->filledArc($current_x, $current_y, 3, 3, 0, 360, $blue); #$colors[9 - $index]
                    
                    $previous_x = $current_x;
                    $previous_y = $current_y;
                } else {
                    $previous_x = -1;
                    $previous_y = -1;
                }
            }
            
            $index++;
        }
    }
    
    $index = 0;
    if($view_differences) {
        foreach my $model_key (@$selected_models) {
            my @models_distances = split(/\s+/, trim($$models[$model_key]{'distances'}));
            my @distances = ();
            for(my $i = 0; $i < scalar(@models_distances); $i++) {
                push(@distances, 'X');
            }
            my $previous_x = -1;
            my $previous_y = -1;
            
            my @templates_distances = split(/\s+/, trim($$templates[$main_template_id]{'distances'}));
            
            for(my $i = 0; $i < scalar(@templates_distances); $i++) {
                if(($models_distances[$i] =~ /^[0-9.]+$/) && ($templates_distances[$i] =~ /^[0-9.]+$/)) {
                    $distances[$i] = $models_distances[$i] - $templates_distances[$i];
                }
            }
            
            for(my $i = 0; $i < scalar(@distances); $i++) {
                if($distances[$i] ne 'X') {
                    my $current_x = $horizontal_step*$i + $LEFT_MARGIN;
                    my $current_y = int(($DEFAULT_HEIGHT - $TOP_MARGIN - $BOTTOM_MARGIN) / 2) + $TOP_MARGIN - $vertical_step * $distances[$i];
                    
                    if($previous_x >= 0) {
                        $image->line($current_x, $current_y, $previous_x, $previous_y, $red);
                    }
                    $image->filledArc($current_x, $current_y, 3, 3, 0, 360, $red); #
                    
                    $previous_x = $current_x;
                    $previous_y = $current_y;
                } else {
                    $previous_x = -1;
                    $previous_y = -1;
                }
            }
            
            $index++;
        }
    }
    
    $image->setThickness(1);
    $image->filledRectangle(0, 0, $DEFAULT_WIDTH, $TOP_MARGIN - 1, $white);
    $image->filledRectangle(0, $DEFAULT_HEIGHT - $BOTTOM_MARGIN + 1, $DEFAULT_WIDTH, $DEFAULT_HEIGHT, $white);

    my $horizontal_length_step = ($horizontal_axis_step / 10);

    for(my $i = 0; $i < $target_size; $i++) {
        if(in_array(($i + 1), @$ranges)) {
            $image->filledRectangle($LEFT_MARGIN + $i*$horizontal_length_step, ($DEFAULT_HEIGHT - $BOTTOM_MARGIN) + 20, $LEFT_MARGIN + $i*$horizontal_length_step + $horizontal_length_step, ($DEFAULT_HEIGHT - $BOTTOM_MARGIN) + 28, $darkgreen);
        }
    }

    for(my $i = 0; $i <= 10; $i++) {
        $image->stringFT($black, $DEFAULT_AXIS_FONT, 10, 0, $LEFT_MARGIN - 22, $TOP_MARGIN + $vertical_axis_step * $i + 5, 5 - $i);
    }
    $image->stringFT($black, $DEFAULT_TOP_FONT, 10, 0, int($DEFAULT_WIDTH / 2) - 80, 20, $TOP_TITLE);
    $image->stringFT($black, $DEFAULT_TOP_FONT, 10, 0, int($DEFAULT_WIDTH / 2) - 50, $DEFAULT_HEIGHT - $BOTTOM_MARGIN + 15, $BOTTOM_TITLE);
    $image->stringFT($black, $DEFAULT_TOP_FONT, 10, (3.14/2), $LEFT_MARGIN - 30, int(($DEFAULT_HEIGHT - $TOP_MARGIN - $BOTTOM_MARGIN) / 2) + 100, $LEFT_TITLE);

    # legend
    my $history_step = 20;
    
    my $index_2 = 0;
    if($view_templates) {
        for(my $i = 0; $i < scalar(@$selected_templates); $i++) {
            my $current_color = $colors[$i];
            if($$selected_templates[$i] == $main_template_id) {
                $image->setThickness(2);
                $current_color = $darkgreen;
            } else {
                $image->setThickness(1);
            }
            
            $image->line($DEFAULT_WIDTH - $RIGHT_MARGIN + 10, $TOP_MARGIN + $history_step*$i + 5, $DEFAULT_WIDTH - $RIGHT_MARGIN + 30, $TOP_MARGIN + $history_step*$i + 5, $current_color);
            $image->filledArc($DEFAULT_WIDTH - $RIGHT_MARGIN + 20, $TOP_MARGIN + $history_step*$i + 5, 3, 3, 0, 360, $current_color);
            $image->stringFT($black, $DEFAULT_TOP_FONT, 9, 0, $DEFAULT_WIDTH - $RIGHT_MARGIN + 37, $TOP_MARGIN + $history_step*$i + 9, $$templates[$$selected_templates[$i]]{'name'});
            $index_2 = $i;
        }
        $index_2++;
    }
    
    my $index_3 = 0;
    if($view_models) {
        $image->setThickness(2);
        for(my $i = 0; $i < scalar(@$selected_models); $i++) {
            $image->line($DEFAULT_WIDTH - $RIGHT_MARGIN + 10, $TOP_MARGIN + $history_step*($i + $index_2) + 5, $DEFAULT_WIDTH - $RIGHT_MARGIN + 30, $TOP_MARGIN + $history_step*($i + $index_2) + 5, $colors[9 - $i]);
            $image->filledArc($DEFAULT_WIDTH - $RIGHT_MARGIN + 20, $TOP_MARGIN + $history_step*($i + $index_2) + 5, 3, 3, 0, 360, $colors[9 - $i]);
            $image->stringFT($black, $DEFAULT_TOP_FONT, 9, 0, $DEFAULT_WIDTH - $RIGHT_MARGIN + 37, $TOP_MARGIN + $history_step*($i + $index_2) + 9, $$models[$$selected_models[$i]]{'name'});
            $index_3 = $i;
        }
        $index_3++;
    }
    
    if($view_differences) {
        $index_3 += $index_2;
        $image->setThickness(2);
        $image->line($DEFAULT_WIDTH - $RIGHT_MARGIN + 10, $TOP_MARGIN + $history_step*$index_3 + 5, $DEFAULT_WIDTH - $RIGHT_MARGIN + 30, $TOP_MARGIN + $history_step*$index_3 + 5, $red);
        $image->filledArc($DEFAULT_WIDTH - $RIGHT_MARGIN + 20, $TOP_MARGIN + $history_step*$index_3 + 5, 3, 3, 0, 360, $red);
        $image->stringFT($black, $DEFAULT_TOP_FONT, 9, 0, $DEFAULT_WIDTH - $RIGHT_MARGIN + 37, $TOP_MARGIN + $history_step*$index_3 + 9, 'Difference');
        $image->stringFT($black, $DEFAULT_TOP_FONT, 8, 0, $DEFAULT_WIDTH - $RIGHT_MARGIN + 10, $TOP_MARGIN + $history_step*$index_3 + 20, '(' . $$models[$$selected_models[0]]{'name'} . ' - ' . $$templates[$main_template_id]{'name'} . ')');
    }
    
    return $image;
}




sub draw_templatesvsmodels_bars {
    my ($self, $TOP_TITLE, $view_templates, $view_models, $view_differences, $ranges, $template_data, $model_data) = @_;

    my @template_range = split(/\s+/, $$template_data{distances});
    my @model_range = split(/\s+/, $$model_data{distances});

    my $DEFAULT_WIDTH = 800;
    my $DEFAULT_HEIGHT = 60;
    my $LEFT_MARGIN = 50;
    my $RIGHT_MARGIN = 140;
    
    my $BAR_HEIGHT = 8;

    my $image = new GD::Image($DEFAULT_WIDTH, $DEFAULT_HEIGHT);

    my $color_white     = $image->colorAllocate(255, 255, 255);
    my $color_black     = $image->colorAllocate(0, 0, 0);
    my $color_blue      = $image->colorAllocate(0, 184, 255); #00b8ff
    my $color_darkblue  = $image->colorAllocate(0, 0, 200); #0000c8
    my $color_sky       = $image->colorAllocate(0, 255, 250); #00fffa
    my $color_yellow    = $image->colorAllocate(255, 255, 0); #ffff00
    my $color_green     = $image->colorAllocate(0, 255, 0); #00ff00
    my $color_orange    = $image->colorAllocate(255, 209, 0); #ffd100
    my $color_red       = $image->colorAllocate(255, 105, 0); #ff6900
    my $color_darkred   = $image->colorAllocate(255, 0, 0); #ff0000
    my $color_grey      = $image->colorAllocate(204, 204, 204);

    my ($target_size) = $$ranges[scalar(@$ranges) - 1];
    my $horizontal_axis_step = int(($DEFAULT_WIDTH - $LEFT_MARGIN - $RIGHT_MARGIN)/ ($target_size / 10));
    my $horizontal_step = $horizontal_axis_step / 10;
    
    my $TOP_MARGIN = 10;
    my $BETWEEN_BARS_DISTANCE = 5;

    my $coef = int($target_size / 100);
    
    for(my $i = 0; $i <= int($target_size / 10); $i++) {
        $image->line($LEFT_MARGIN + $i * $horizontal_axis_step, $TOP_MARGIN - 2, $LEFT_MARGIN + $i * $horizontal_axis_step, $TOP_MARGIN + 1, $color_grey);
        if(($target_size < 100) || (($i % $coef) == 0)) {
            $image->stringFT($color_black, $DEFAULT_AXIS_FONT, 6, 0, $LEFT_MARGIN + $i * $horizontal_axis_step - 4, $TOP_MARGIN - 3, ($i * 10));
        }
    }
    $TOP_MARGIN += 3;
	
    if($view_templates) {
        for(my $i = 0; $i < scalar(@template_range); $i++) {
            my $current_color = $color_white;

            if(!($template_range[$i] =~ /^([\-\.0-9]+)$/)) {
                $current_color = $color_white;
            } elsif($template_range[$i] <= -5) {
                $current_color = $color_darkblue;
            } elsif(($template_range[$i] > -5) && ($template_range[$i] <= -2)) {
                $current_color = $color_sky;
            } elsif(($template_range[$i] > -2) && ($template_range[$i] <= -0.5)) {
                $current_color = $color_green;
            } elsif(($template_range[$i] > -0.5) && ($template_range[$i] <= 0.5)) {
                $current_color = $color_yellow;
            } elsif(($template_range[$i] > 0.5) && ($template_range[$i] <= 2)) {
                $current_color = $color_orange;
            } elsif(($template_range[$i] > 2) && ($template_range[$i] <= 5)) {
                $current_color = $color_red;
            } elsif($template_range[$i] >= 5) {
                $current_color = $color_darkred;
            }
            
            $image->filledRectangle($LEFT_MARGIN + $i*$horizontal_step, $TOP_MARGIN, $LEFT_MARGIN + $horizontal_step * ($i + 1), $TOP_MARGIN + $BAR_HEIGHT, $current_color);
        }
        $image->stringFT($color_black, $DEFAULT_TOP_FONT, 9, 0, $DEFAULT_WIDTH - 120, $TOP_MARGIN + 7, $$template_data{'name'});
        $TOP_MARGIN += $BAR_HEIGHT + $BETWEEN_BARS_DISTANCE;
    }

    if($view_models) {
        for(my $i = 0; $i < scalar(@model_range); $i++) {
            my $current_color = $color_white;

            if(!($model_range[$i] =~ /^([\-\.0-9]+)$/)) {
                $current_color = $color_white;
            } elsif($model_range[$i] <= -5) {
                $current_color = $color_darkblue;
            } elsif(($model_range[$i] > -5) && ($model_range[$i] <= -2)) {
                $current_color = $color_sky;
            } elsif(($model_range[$i] > -2) && ($model_range[$i] <= -0.5)) {
                $current_color = $color_green;
            } elsif(($model_range[$i] > -0.5) && ($model_range[$i] <= 0.5)) {
                $current_color = $color_yellow;
            } elsif(($model_range[$i] > 0.5) && ($model_range[$i] <= 2)) {
                $current_color = $color_orange;
            } elsif(($model_range[$i] > 2) && ($model_range[$i] <= 5)) {
                $current_color = $color_red;
            } elsif($model_range[$i] >= 5) {
                $current_color = $color_darkred;
            }
            
            $image->filledRectangle($LEFT_MARGIN + $i*$horizontal_step, $TOP_MARGIN, $LEFT_MARGIN + $horizontal_step * ($i + 1), $TOP_MARGIN + $BAR_HEIGHT, $current_color);
        }
        $image->stringFT($color_black, $DEFAULT_TOP_FONT, 9, 0, $DEFAULT_WIDTH - 120, $TOP_MARGIN + 7, $$model_data{'name'});
        $TOP_MARGIN += $BAR_HEIGHT + $BETWEEN_BARS_DISTANCE;
    }

    if($view_differences) {
        my @distances = ();
        for(my $i = 0; $i < scalar(@model_range); $i++) {
            push(@distances, 'X');
        }
        my $previous_x = -1;
        my $previous_y = -1;
        
        for(my $i = 0; $i < scalar(@template_range); $i++) {
            if(($model_range[$i] =~ /^[0-9.]+$/) && ($template_range[$i] =~ /^[0-9.]+$/)) {
                $distances[$i] = $model_range[$i] - $template_range[$i];
            }
        }
        
        for(my $i = 0; $i < scalar(@distances); $i++) {
            my $current_color = $color_white;

            if(!($distances[$i] =~ /^([\-\.0-9]+)$/)) {
                $current_color = $color_white;
            } elsif($distances[$i] <= -5) {
                $current_color = $color_darkblue;
            } elsif(($distances[$i] > -5) && ($distances[$i] <= -2)) {
                $current_color = $color_sky;
            } elsif(($distances[$i] > -2) && ($distances[$i] <= -0.5)) {
                $current_color = $color_green;
            } elsif(($distances[$i] > -0.5) && ($distances[$i] <= 0.5)) {
                $current_color = $color_yellow;
            } elsif(($distances[$i] > 0.5) && ($distances[$i] <= 2)) {
                $current_color = $color_orange;
            } elsif(($distances[$i] > 2) && ($distances[$i] <= 5)) {
                $current_color = $color_red;
            } elsif($distances[$i] >= 5) {
                $current_color = $color_darkred;
            }
            
            $image->filledRectangle($LEFT_MARGIN + $i*$horizontal_step, $TOP_MARGIN, $LEFT_MARGIN + $horizontal_step * ($i + 1), $TOP_MARGIN + $BAR_HEIGHT, $current_color);
        }
        $image->stringFT($color_black, $DEFAULT_TOP_FONT, 9, 0, $DEFAULT_WIDTH - 120, $TOP_MARGIN + 7, 'Difference');
        $image->stringFT($color_black, $DEFAULT_TOP_FONT, 8, 0, $DEFAULT_WIDTH - 120, $TOP_MARGIN + 20, '(' . $$template_data{'name'} . ' - ' . $$model_data{'name'} . ')');
    }
    
    return $image;
}


sub draw_templates_coverage_bar {
    my ($self, $ranges, $templates, $models) = @_;
    
    my $DEFAULT_WIDTH = 550;
    my $DEFAULT_HEIGHT = 230;
    my $LEFT_MARGIN = 50;
    my $RIGHT_MARGIN = 5;
    my $TOP_MARGIN = 10;
    my $BOTTOM_MARGIN = 230;

    my ($target_size) = $$ranges[scalar(@$ranges) - 1];
    my $image = new GD::Image($DEFAULT_WIDTH, $DEFAULT_HEIGHT);
    
    my $white = $image->colorAllocate(255, 255, 255);
    my $black = $image->colorAllocate(0, 0, 0);
    my $grey = $image->colorAllocate(204, 204, 204);
    my $darkgreen = $image->colorAllocate(100, 200, 100);
    
    #$image->transparent($white);
    $image->interlaced('true');

    my $diagram_templates_count = scalar(@$templates);

    #axis
    my $horizontal_axis_step = int(($DEFAULT_WIDTH - $LEFT_MARGIN - $RIGHT_MARGIN)/ ($target_size / 10));
    my $coef = int($target_size / 100);
    
    my $horizontal_step = $horizontal_axis_step / 10;
    
    $image->setThickness(1);

    # diagram
    my $DIAGRAM_TOP_Y = $DEFAULT_HEIGHT - $BOTTOM_MARGIN + 20;
    my $DIAGRAM_BOTTOM_Y = $DEFAULT_HEIGHT - 20;
    

    my $diagram_vertical_axis_step = (($diagram_templates_count > 0) ? (int($DIAGRAM_BOTTOM_Y - $DIAGRAM_TOP_Y) / $diagram_templates_count) : 0);

    for(my $i = 0; $i <= $diagram_templates_count; $i++) {
        $image->line($LEFT_MARGIN, $DIAGRAM_TOP_Y + $diagram_vertical_axis_step * $i, $DEFAULT_WIDTH - $RIGHT_MARGIN, $DIAGRAM_TOP_Y + $diagram_vertical_axis_step * $i, $grey);
        $image->stringFT($black, $DEFAULT_AXIS_FONT, 10, 0, $LEFT_MARGIN - 18, $DIAGRAM_TOP_Y + $diagram_vertical_axis_step * $i + 5, ($diagram_templates_count - $i));
    }

    $image->line($LEFT_MARGIN, $DIAGRAM_TOP_Y, $LEFT_MARGIN, $DIAGRAM_BOTTOM_Y, $black);
    $image->line($LEFT_MARGIN, $DIAGRAM_BOTTOM_Y, $DEFAULT_WIDTH - $RIGHT_MARGIN, $DIAGRAM_BOTTOM_Y, $black);
    $image->line($LEFT_MARGIN, $DIAGRAM_TOP_Y, $DEFAULT_WIDTH - $RIGHT_MARGIN, $DIAGRAM_TOP_Y, $grey);
    $image->line($DEFAULT_WIDTH - $RIGHT_MARGIN, $DIAGRAM_TOP_Y, $DEFAULT_WIDTH - $RIGHT_MARGIN, $DIAGRAM_BOTTOM_Y, $grey);
    for(my $i = 0; $i <= int($target_size / 10); $i++) {
        $image->line($LEFT_MARGIN + $i * $horizontal_axis_step, $DIAGRAM_BOTTOM_Y, $LEFT_MARGIN + $i * $horizontal_axis_step, $DIAGRAM_BOTTOM_Y + 5, (($i == 0) ? $white : $grey));
        if($target_size < 100) {
            $image->stringFT($black, $DEFAULT_AXIS_FONT, 10, 0, $LEFT_MARGIN + $i * $horizontal_axis_step - 10, $DIAGRAM_BOTTOM_Y + 18, ($i * 10));
        } else {
            if(($i % $coef) == 0) {
                $image->stringFT($black, $DEFAULT_AXIS_FONT, 10, 0, $LEFT_MARGIN + $i * $horizontal_axis_step - 10, $DIAGRAM_BOTTOM_Y + 18, ($i * 10));
            }
        }
    }

    my @residues_counter = ();
    for(my $i = 0; $i < $target_size; $i++) {
        push(@residues_counter, 0);
    }
    
    for(my $i = 0; $i < ($diagram_templates_count); $i++) {
        my @lga_distances = split(/\s+/, $$templates[$i]{'distances'});
        
        for(my $j = 0; $j < scalar(@lga_distances); $j++) {
            if(trim($lga_distances[$j]) ne 'X') {
                $residues_counter[$j]++;
            }
        }
    }

    for(my $i = 0; $i < $target_size; $i++) {
        $image->filledRectangle($LEFT_MARGIN + $horizontal_step*$i, $DIAGRAM_BOTTOM_Y - $diagram_vertical_axis_step*$residues_counter[$i], $LEFT_MARGIN + $horizontal_step*($i + 1) - 1, $DIAGRAM_BOTTOM_Y, $darkgreen);
        if($horizontal_step > 2) {
            $image->rectangle($LEFT_MARGIN + $horizontal_step*$i, $DIAGRAM_BOTTOM_Y - $diagram_vertical_axis_step*$residues_counter[$i], $LEFT_MARGIN + $horizontal_step*($i + 1), $DIAGRAM_BOTTOM_Y, $black);
        }
    }

    #$image->stringFT($black, $DEFAULT_TOP_FONT, 10, 0, int($DEFAULT_WIDTH / 2) - 150, 20, $TOP_TITLE);
    #$image->stringFT($black, $DEFAULT_TOP_FONT, 10, 0, int($DEFAULT_WIDTH / 2) - 50, $DEFAULT_HEIGHT - 5, $BOTTOM_TITLE);
    #$image->stringFT($black, $DEFAULT_TOP_FONT, 10, (3.14/2), $LEFT_MARGIN - 30, int(($DEFAULT_HEIGHT - $TOP_MARGIN - $BOTTOM_MARGIN) / 2) + 100, $LEFT_TITLE);

    # Bottom graph titles
    $image->stringFT($black, $DEFAULT_TOP_FONT, 10, (3.14/2), 20, $DEFAULT_HEIGHT - 45, "Number of templates");
    
    return $image;
}



sub draw_alignment_bar {
    my ($self, $ranges) = @_;
	
    my $DEFAULT_WIDTH = 500;
    my $DEFAULT_HEIGHT = 8;
    my $DEFAULT_LEFT_MARGIN = 0;

    my $image = new GD::Image($DEFAULT_WIDTH, $DEFAULT_HEIGHT);
	
    my $color_white = $image->colorAllocate(255, 255, 255);
    my $color_grey  = $image->colorAllocate(204, 204, 204);
    my $color_black  = $image->colorAllocate(0, 0, 0);
    #$image->transparent($color_white);
    $image->interlaced('true');
    
    my ($target_size) = $$ranges[scalar(@$ranges) - 1];
    my $coef = int($target_size / 100);    
    my $step = $DEFAULT_WIDTH / $target_size;
    for(my $i = 0; $i <= $target_size; $i++) {
        if(($i % 10) == 0) {
            $image->line($DEFAULT_LEFT_MARGIN + int($i * $step), $DEFAULT_HEIGHT - 3, $DEFAULT_LEFT_MARGIN + int($i * $step), $DEFAULT_HEIGHT, $color_grey);
            if(($target_size < 100) || ($i % (10 * $coef)) == 0) {
                $image->stringFT($color_black, $DEFAULT_AXIS_FONT, 6, 0, $DEFAULT_LEFT_MARGIN + int($i * $step) - 4 + 3, 5, $i);
            }
        }
    }
    
    return $image;
}

sub draw_template_bar {
	my ($self, $data, $ranges) = @_;
	
	my @gamma = ();
	
	my $TOP_LIMIT = 5;
	my $BOTTOM_LIMIT = 0;
	
	my $MAX_HUE = 126;
	
	for(my $i = 0; $i < $MAX_HUE; $i++) {
		my ($r, $g, $b) = $self->HSVtoRGB($i, 1, 255);
		
		push(@gamma, {'red' => $r, 'green' => $g,'blue' => $b});
	}
	
	return $self->draw_bar($data, $ranges, \@gamma, $TOP_LIMIT, $BOTTOM_LIMIT);
}

sub draw_model_bar {
	my ($self, $data, $ranges) = @_;        
	my @gamma = ();
	
	my $TOP_LIMIT = 5;
	my $BOTTOM_LIMIT = -5;
	
	my $MAX_HUE = 256;
	
	for(my $i = 0; $i < $MAX_HUE; $i++) {
		my ($r, $g, $b) = $self->HSVtoRGB($i, 1, 255);
		
		push(@gamma, {'red' => $r, 'green' => $g,'blue' => $b});
	}        
	return $self->draw_bar($data, $ranges, \@gamma, $TOP_LIMIT, $BOTTOM_LIMIT);
}



sub HSVtoRGB {
    my ($self, $hue, $saturation, $v) = @_;
    my ($red, $green, $blue);

    # If there's no saturation, then we're a grey
    unless ($saturation) {
            $red = $green = $blue = $v;
            return ($red, $green, $blue);
    }

    $hue /= 60;
    my $i = int( $hue );
    my $f = $hue - $i;
    my $p = $v * ( 1 - $saturation );
    my $q = $v * ( 1 - $saturation * $f );
    my $t = $v * ( 1 - $saturation * ( 1 - $f ) ); 


    if ($i == 0) { return( $v, $t, $p ) }
    elsif ($i == 1) { return( $q, $v, $p ) }
    elsif ($i == 2) { return( $p, $v, $t ) }
    elsif ($i == 3) { return( $p, $q, $v ) }
    elsif ($i == 4) { return( $t, $p, $v ) }
    else { return( $v, $p, $q ) } 
}

sub draw_bar {
	my ($self, $data, $ranges, $gamma, $TOP_LIMIT, $BOTTOM_LIMIT) = @_;
	
	my $DEFAULT_WIDTH = 500;
	my $DEFAULT_HEIGHT = 8;
	
	my $image = new GD::Image($DEFAULT_WIDTH, $DEFAULT_HEIGHT);
	
	my $color_white = $image->colorAllocate(255, 255, 255);

    my $color_blue      = $image->colorAllocate(0, 184, 255); #00b8ff
    my $color_darkblue  = $image->colorAllocate(0, 0, 200); #0000c8
    my $color_sky       = $image->colorAllocate(0, 255, 250); #00fffa
    my $color_yellow    = $image->colorAllocate(255, 255, 0); #ffff00
    my $color_green     = $image->colorAllocate(0, 255, 0); #00ff00
    my $color_orange    = $image->colorAllocate(255, 209, 0); #ffd100
    my $color_red       = $image->colorAllocate(255, 105, 0); #ff6900
    my $color_darkred   = $image->colorAllocate(255, 0, 0); #ff0000

    $image->transparent($color_white);
	$image->interlaced('true');
	
	my @color_gamma = ();
	
	for(my $i = 0; $i < scalar(@$gamma); $i++) {
		push(@color_gamma, $image->colorAllocate($$gamma[$i]{'red'}, $$gamma[$i]{'green'}, $$gamma[$i]{'blue'}));
	}

	my ($target_size) = $$ranges[scalar(@$ranges) - 1];

	my $step = ($target_size > 0) ? ($DEFAULT_WIDTH / $target_size) : 0;
	
	my $gamma_length = scalar(@color_gamma);

	for(my $i = 0; $i < scalar(@$data); $i++) {
		my $current_color = $color_white;
        #if(!($$data[$i] =~ /^([\-\.0-9]+)$/)) {
        #    $current_color = $color_white;
        #} elsif(($$data[$i] < $TOP_LIMIT) || ($$data[$i] > $BOTTOM_LIMIT)) {
        #    $current_color = $color_gamma[int($$data[$i] * $gamma_length / ($TOP_LIMIT + 1))];
        #} elsif($$data[$i] > $TOP_LIMIT) {
        #    $current_color = $color_gamma[255];
        #} elsif($$data[$i] < $BOTTOM_LIMIT) {
        #    $current_color = $color_gamma[0];
        #}

        if(!($$data[$i] =~ /^([\-\.0-9]+)$/)) {
            $current_color = $color_white;
        } elsif($$data[$i] <= -5) {
            $current_color = $color_darkblue;
        } elsif(($$data[$i] > -5) && ($$data[$i] <= -2)) {
            $current_color = $color_sky;
        } elsif(($$data[$i] > -2) && ($$data[$i] <= -0.5)) {
            $current_color = $color_green;
        } elsif(($$data[$i] > -0.5) && ($$data[$i] <= 0.5)) {
            $current_color = $color_yellow;
        } elsif(($$data[$i] > 0.5) && ($$data[$i] <= 2)) {
            $current_color = $color_orange;
        } elsif(($$data[$i] > 2) && ($$data[$i] <= 5)) {
            $current_color = $color_red;
        } elsif($$data[$i] >= 5) {
            $current_color = $color_darkred;
        }
		
		$image->filledRectangle($step*$i, 0, ($step + 1) * $i, $DEFAULT_HEIGHT - 1, $current_color);
	}
	
	return $image;
}

1;
