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

use strict;
use warnings;

use File::Temp;
use File::Basename;
use Data::Dumper;
use Date::Calc;
use Date::Simple ('date');
use Date::Manip;

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

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

use lib '/app/tools/bookpub/lib';
use BookPub::Analytics::ProductMonitor::Data::UnitsFromRevenueFiles;
use BookPub::Analytics::ProductMonitor::Data::UnitsFromPOSFiles;
use BookPub::Analytics::ProductMonitor::Data::RevenueFromRevenueFiles;
use BookPub::Analytics::ProductMonitor::Data::RevenueFromPOSFiles;
use BookPub::Catalog::Chart::Base;
use BookPub::DB::Item::POSSale;
use BookPub::DB::Item::Sale;

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

sub _generateChartImage {
    my $self = shift;

    # We'll only set this value if we are dealing with revenue, and not units.
    my $currencySymbol;

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

    my $chartType     = $self->{_chartType};
    my $decimalPlaces = 0;
    my $tipType       = 'number';

    # Need to tweak some things depending on whether we are displaying units or revenue.
    #
    if ( $chartType eq 'RevenuePOS' || $chartType eq 'RevenueRevenue' ) {
        $decimalPlaces  = 2;
        $currencySymbol = Common::Client::Current()->Locale()->currencyFormat()->symbol();
        $tipType        = 'money';
    }

    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 );

    # Add a line chart layer using the given data
    my $layer = $c->addLineLayer();

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

    $layer->setLineWidth(2);

    # Force the y-axis to start at zero
    $c->yAxis->setLinearScale( 0, $perlchartdir::NoValue );
    $c->setClipping();

    # 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 );

    # Set the y axis label formatting.
    $c->yAxis()->setLabelFormat( $currencySymbol . "{value|$decimalPlaces" . $thousands . $decimal . "}" );

    if ( $decimalPlaces == 0 ) {

        # Make all ticks integers.
        $c->yAxis()->setMinTickInc(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
    my $tipTitle = 'title="%%{value|' . $decimalPlaces . '}%%"';
    my $imageMap = $c->getHTMLImageMap( '', '', $tipTitle );
    $self->setImageMap( imageMap => $imageMap, type => $tipType );
}

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 $chartType = $self->{_chartType};
    my $serviceID = $self->{_serviceID};

    my $chartData;

# We'll change this based on the chart type.
#
#if ($chartType eq 'UnitRevenue')
#{
#    $chartData = BookPub::Analytics::ProductMonitor::Data::UnitsFromRevenueFiles->new(productID => $productID, serviceID => $serviceID, dateStart => $dateStart, dateEnd => $dateEnd);
#}
    if ( $chartType eq 'UnitPOS' ) {
        $chartData = BookPub::Analytics::ProductMonitor::Data::UnitsFromPOSFiles->new(
            productID => $productID,
            serviceID => $serviceID,
            dateStart => $dateStart,
            dateEnd   => $dateEnd
        );

        #$minDate = BookPub::DB::Item::POSSale->GetMinDate($serviceID);
    }

#elsif ($chartType eq 'RevenueRevenue')
#{
#    $chartData = BookPub::Analytics::ProductMonitor::Data::RevenueFromRevenueFiles->new(productID => $productID, serviceID => $serviceID, dateStart => $dateStart, dateEnd => $dateEnd);
#$minDate = BookPub::DB::Item::Sale->GetMinDate($serviceID);
#}
    elsif ( $chartType eq 'RevenuePOS' ) {
        $chartData = BookPub::Analytics::ProductMonitor::Data::RevenueFromPOSFiles->new(
            productID => $productID,
            serviceID => $serviceID,
            dateStart => $dateStart,
            dateEnd   => $dateEnd
        );

        #$minDate = BookPub::DB::Item::POSSale->GetMinDate($serviceID);
    }

    my $firstNonEmptyElement = '';

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

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

        # If the first element is empty, we need to look into things further
        # to determine if the No Data Available area will be shown.
        #
        if ( @{$serviceData}[0] eq '' ) {

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

            # Now we have to figure out if we need to show the No Data Available grey area.
            #
            #if ($chartType eq 'UnitRevenue' || $chartType eq 'RevenueRevenue')
            #{
            #    $minDate = BookPub::DB::Item::Sale->GetMinDate($_, $productID);
            #}
            #else
            #{
            my $minDate = BookPub::DB::Item::POSSale->GetMinDate( $_, $productID );

            #}

            if ($minDate) {
                my $dateDiff = date($minDate) - date($dateStart);

                if ( $dateDiff > 0 && $dateDiff < $firstNonEmptyElement ) {
                    $firstNonEmptyElement = $dateDiff;
                }
            }
        } else {
            $firstNonEmptyElement = 0;
        }

        # Need to substitue $perlchartdir::NoValue for empty values.
        # Otherwise, chart director treats tham like zeroes.
        #
        $_ ||= $perlchartdir::NoValue for @{$serviceData};

        my $serviceColor = $self->_getServiceColor($_);

        $layer->addDataSet( $serviceData, $serviceColor, "Service Data" );
    }

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

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

###
1;    #
###
