/*
 *  Copyright 2010 OpenSourceStewardshipFoundation.org
 *  Licensed under GNU General Public License version 2
 *
 * Author: seanhalle@yahoo.com
 *
 */

#include <stdio.h>
#include "Histogram.h"


/*This Histogram Abstract Data Type has a number of bins, the starting
 * value, and the width of each bin, as a float, all chosen at creation.
 *
 *One creates a Histogram instance using the makeFloatHistogram function, then
 * updates it with the addToFloatHist function, and prints it out with the
 * printFloatHist function.
 *
 *Note, the bin width is an integer, so the end of the range is adjusted
 * accordingly.  Use the bin-width to calculate the bin boundaries.
 */


DblHist *
makeDblHistogram( int32 numBins, float64 startOfRange, float64 binWidth )
 {
   DblHist *hist;
   int i;

   hist = VMS__malloc( sizeof(DblHist) );
   hist->bins = VMS__malloc( numBins * sizeof(int) );

   hist->numBins      = numBins;
   hist->binWidth     = binWidth;
   hist->endOfRange   = startOfRange + hist->binWidth * numBins;
   hist->startOfRange = startOfRange;

   for( i = 0; i < hist->numBins; i++ )
    {
      hist->bins[ i ] = 0;
    }

   return hist;
 }


/*All values higher than or equal to a bin's start value and less than the
 * start value of the next higher are put into that bin.
 */
void
addToDblHist( float64 value, DblHist *hist )
 {
   int binIdx;

   if( value < hist->startOfRange )
    { binIdx = 0;
    }
   else if( value > hist->endOfRange )
    { binIdx = hist->numBins - 1;
    }
   else
    {    //truncate so bin holds:   binStartVal =< values < nextBinStartVal
      binIdx = (int32)((value - hist->startOfRange) / hist->binWidth);
    }

   hist->bins[ binIdx ] += 1;
 }

void
printDblHist( DblHist *hist )
 {
   int32   binIdx, i, numBars, maxHeight;
   float64 barValue, binStart, binEnd;

   maxHeight = 0;
   for( i = 0; i < hist->numBins; i++ )
    {
      if( maxHeight < hist->bins[ i ] ) maxHeight = hist->bins[ i ];
    }
   barValue = maxHeight / 40;  //40 spaces across page for tallest bin

   printf( "histogram: \n" );
   if( barValue == 0 ) printf( "error printing histogram\n" );
   for( binIdx = 0; binIdx < hist->numBins; binIdx++ )
    {
      binStart = hist->startOfRange + hist->binWidth * binIdx;
      binEnd = binStart + hist->binWidth;
      printf( "bin range: %.6fl - %.6fl", binStart, binEnd );

      numBars = hist->bins[ binIdx ] / barValue;
         //print one bin, height of bar is num dashes across page
      for( i = 0; i < numBars; i++ )
       {
         printf("-");
       }
      printf("\n");
    }
 }


void
freeDblHist( DblHist *hist )
 {
   VMS__free( hist->bins );
   VMS__free( hist );
 }
