#------------------------------------------------------------
# Copyright (C) 2010 RoyaltyShare, Inc.   All Rights Reserved
#------------------------------------------------------------
package BookPub::Catalog::Chart::Rank;

use strict;
use warnings;

use File::Temp;
use File::Basename;
use Data::Dumper;

use lib '/app/tools/common/lib';
use Common::Assert;

use lib '/app/tools/raptor/lib';
use Raptor::DB::Item::PeriodMonth;

use lib '/usr/local/chart_director/lib';
use perlchartdir;

use lib '/app/tools/bookpub/lib';
use BookPub::Analytics::ProductMonitor::Data::Rankings;
use BookPub::Catalog::Chart::Base;

use base 'BookPub::Catalog::Chart::Base';

sub _generateChartImage {
    my $self = shift;

    my $currencySymbol = Common::Client::Current()->Locale()->currencyFormat()->symbol();
    my $thousands      = Common::Client::Current()->Locale()->numericFormat()->thousands();
    my $decimal        = Common::Client::Current()->Locale()->numericFormat()->decimal();

    my $c = new XYChart( 640, 250 );

    # Set the plotarea at (30, 20) and of size 400 x 200 pixels
    $c->setPlotArea( 85, 20, 490, 200 );

    my $layer     = $c->addLineLayer2();
    my $chartData = $self->_getChartData($layer);

    $layer->setLineWidth(2);

    # Set the colors
    $c->setColor( $perlchartdir::TextColor, BookPub::Catalog::Chart::Base::kTextColor );

    # Set the labels on the x axis.
    $c->xAxis()->setLabels( $chartData->{labels} );

    # Set the label step (allows us to limit number of labels displayed).
    $c->xAxis()->setLabelStep( $self->{_labelStep} );

    # Set the label gap (spacing between the label and the chart).
    $c->xAxis()->setLabelGap(BookPub::Catalog::Chart::Base::kLabelGap);

    # Grey out the area without data.
    $c->xAxis()->addZone( 0, $chartData->{firstNonEmptyElement}, BookPub::Catalog::Chart::Base::kNoDataColor );

    # Reverse the y axis (since ranks descend).
    $c->yAxis()->setReverse();

    # Make all ticks integers.
    $c->yAxis()->setMinTickInc(1);

    # Set the y axis label formatting.
    # Adding one so that it will be the uppper limit on the chart labels.
    $c->yAxis()->setLabelFormat("{={value}+1}");

    # Set the label gap (spacing between the label and the chart).
    $c->yAxis()->setLabelGap(BookPub::Catalog::Chart::Base::kLabelGap);

    my $chartName = $self->_getChartFilename();

    $self->{ChartSource} = sprintf( "%s/%s", BookPub::Catalog::Chart::Base::kChartImgDir, basename($chartName) );

    # Output the chart
    my $result = $c->makeChart($chartName);

    # Create the image map
    $self->setImageMap( imageMap => $c->getHTMLImageMap( '', '', 'title="%%{={value|0}+1}%%"' ), type => 'number' );
}

sub _getChartData {
    my $self  = shift;
    my $layer = shift;

    my $productID = $self->{_productID};
    my $offset    = $self->{_offset};
    my $dateStart = $self->{_dateStart};
    my $dateEnd   = $self->{_dateEnd};
    my $serviceID = $self->{_serviceID};

    my $chartData = BookPub::Analytics::ProductMonitor::Data::Rankings->new(
        productID => $productID,
        serviceID => $serviceID,
        dateStart => $dateStart,
        dateEnd   => $dateEnd
    );

    my @serviceIDArray;
    if ( 'ARRAY' eq ref($serviceID) ) {
        @serviceIDArray = @$serviceID;
    } else {
        push( @serviceIDArray, $serviceID );
    }

    my $firstNonEmptyElement = '';

    foreach (@serviceIDArray) {
        my $rankings = $chartData->getServiceDataForProductID( $_, $productID );

        my @decrementedRankings;

        # By default, we'll assume there is no data, and then change this value if we find something
        if ( $firstNonEmptyElement eq '' ) {
            $firstNonEmptyElement = @{$rankings};
        }

        my $arrayElement = 0;

        # In order to force the top of the chart to be 1, we have to increment the display values later.
        # So, we will decrement them now, and it should all come out even.
        foreach ( @{$rankings} ) {
            if ( !defined $_ || $_ eq '' ) {
                push( @decrementedRankings, $perlchartdir::NoValue );
            } else {
                push( @decrementedRankings, $_ - 1 );
                if ( $arrayElement < $firstNonEmptyElement ) {
                    $firstNonEmptyElement = $arrayElement;
                }
            }
            $arrayElement++;
        }

        my $serviceColor = $self->_getServiceColor($_);
        $layer->addDataSet( \@decrementedRankings, $serviceColor, "Rankings" );
    }

    # Grab the dates to use as labels
    #
    my $labels = $chartData->getDates();

    return { labels => $labels, firstNonEmptyElement => $firstNonEmptyElement };
}

###
1;    #
###
