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

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


/*This Histogram Abstract Data Type has a number of bins plus a range of
 * values that the bins span, both chosen at creation.
 *
 *One creates a Histogram instance using the makeHistogram function, then
 * updates it with the addToHist function, and prints it out with the
 * printHist 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.
 */


Histogram *
makeHistogram( int numBins, int startOfRange, int endOfRange )
 {
   Histogram *hist;
   int i;

   hist = malloc( sizeof(Histogram) );
   hist->bins = malloc( numBins * sizeof(int) );

   hist->numBins      = numBins;
   hist->binWidth     = (endOfRange - startOfRange) / numBins;
   hist->endOfRange   = startOfRange + hist->binWidth * numBins;
   hist->startOfRange = startOfRange;

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

   return hist;
 }

void
addToHist( int value, Histogram *hist )
 {
   int binIdx;

   if( value < hist->startOfRange )
    { binIdx = 0;
    }
   else if( value > hist->endOfRange )
    { binIdx = hist->numBins - 1;
    }
   else
    {
      binIdx = (value - hist->startOfRange) / hist->binWidth;
    }

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

void
printHist( Histogram *hist )
 {
   int binIdx, i, numBars, maxHeight, barValue, binStart, binEnd;

   maxHeight = 0;
   for( i = 0; i < hist->numBins; i++ )
    {
      if( maxHeight < hist->bins[ i ] ) maxHeight = hist->bins[ i ];
    }
   barValue = maxHeight / 60;  //60 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 - 1;
      printf("bin range: %d - %d", 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");
    }
 }

