/*
$Id: TwoDimElementContainer.hh 1647 2006-10-20 08:39:13Z suzuki $
*/


#ifndef TWODIMELEMENTCONTAINER
#define TWODIMELEMENTCONTAINER

#include "ElementContainer.hh"
#include "NeutronVector.hh"
#include "ElementContainerMatrix.hh"

//! Define a two dimensional detector with ElementContainer
/*! A two dimensional area detector will be defined with this class.
  Because the dimension, the number of detector elements, is defined in the
  constructor, you should not use the constructor without its argument.
  If you construct this class with std::vector<UInt4> v = [3,4,5], this class will have
  3+4+5 detector elements. When you want to access the data,
  use operator()( UInt4 Xindex, UInt4 Yindex ) or Put( UInt4 Xindex, UInt4 Yindex ).
  Put(2,3) will returns the fourth ElementContainer of third group.
 */

class TwoDimElementContainer
{
private:
  HeaderBase *header;
  std::vector<UInt4> Dim;
  NeutronVector< NeutronVector< ElementContainer,HeaderBase >, HeaderBase > *TwoDimStorage;
  void MakeStorage( std::vector<UInt4> Dimension );
protected:
public:
  TwoDimElementContainer( std::vector<UInt4> Dimension );
  /*!< Constructor. */
  TwoDimElementContainer();
  /*!< Constructor. Probably, you does not need this constructor.  */
 ~TwoDimElementContainer();
  /*!< Destructor. */

  TwoDimElementContainer( const TwoDimElementContainer &ob );
  /*!<Override the copy constructor. */

  TwoDimElementContainer operator=( const TwoDimElementContainer ob );
  /*!<Override the operator of "=".  */

  HeaderBase PutHeader(){ return *header; }
  /*!< Returns header object.*/
  HeaderBase* PutHeaderPointer(){ return header; }
  /*!< Returns the pointer of header object.*/
  void InputHeader( HeaderBase Header );
  /*!< this method set a header object. If header object has already input
   in this class, the existing object will be deleted, and set with the argument.*/

  ElementContainer* operator()( UInt4 Xindex, UInt4 Yindex );
  /*!< Return the pointer of ElementContainer. The meaning of the arguments
   was written in the manual of this class. */
  ElementContainer Put( UInt4 Xindex, UInt4 Yindex );
  /*!< Return the object of ElementContainer. The meaning of the arguments
   was written in the manual of this class. */
  std::vector<UInt4> PutDimension(){ return Dim; }
  /*!< Returns the dimension of the detector.
    The return value is the same as the argument of the constructor.
   */

  ElementContainerMatrix ConvertToMatrix();
  /*!< Convert to ElementContainerMatrix from the object of this class */

  std::vector<ElementContainer> PutPackedContainer();
  /*!< This method is called from the NeXus and network distributing APIs. */
  void InputPackedContainer( std::vector<ElementContainer> obj );
  /*!< This method is called from the NeXus and network distributing APIs. */
};

#endif
