/// Volume.h
/**
*/

#ifndef VOLUME_H_
#define VOLUME_H_

#include <map>
#include <vector>
#include <string>
#include <numeric>
#include <algorithm>
#include <string>
#include <iostream>

namespace jcs {

  // Represents an image volume as a map of slices
  // Map is sorted by distance along slice plane normal

  template<class T>
  class Volume {

  public:
    Volume() {}
    Volume(int rows, int columns): 
    mRows(rows), mColumns(columns) {}
    ~Volume() {}

    double GetSpacing();

    // == number of slices in volume
    typename std::map<double, std::vector<T> >::size_type size() const { return mSliceMap.size(); }
    typename std::map<double, std::vector<T> >::iterator begin() { return mSliceMap.begin(); }
    typename std::map<double, std::vector<T> >::iterator end() { return mSliceMap.end(); }
    typename std::map<double, std::vector<T> >::reverse_iterator rbegin() { return mSliceMap.rbegin(); }
    typename std::map<double, std::vector<T> >::reverse_iterator rend() { return mSliceMap.rend(); }

    void AddSlice(const double slice_no, const std::vector<T>& slice, const std::string& name)
    {
      mSliceMap[slice_no] = slice;
      dicomFiles[slice_no] = name;
    }

    // Used only by NewBvOutputter.txx
    std::vector<T>& GetSlice(int slice_number)
    {
      //std::cout << "GetSlice, slice_number: " << slice_number << std::endl;
      typename std::map<double, std::vector<T> >::iterator it = mSliceMap.begin();
      for (int i = 0; i < slice_number; ++i, ++it);
      return it->second;
    }

    std::map<double, std::string> dicomFiles;
    std::map<double, std::vector<T> > mSliceMap;

  private:
    int mRows;
    int mColumns;

  };


  ///
  /** Calculates spacing between slices by taking difference in position of the
  first two slices.
    */
  template <class T> double 
  Volume<T>::GetSpacing() 
  {
    if (mSliceMap.size() < 2) { return 1; }
    typename std::map<double, std::vector<T> >::iterator it = mSliceMap.begin();
    double pos1 = (*it).first;
    double pos2 = (*++it).first;
    return pos2 - pos1;
  }

} // end namespace jcs

#endif

