/*
$Id: ElementContainerArray.cc 2295 2011-08-10 02:57:13Z jisuzuki $
*/


#include "ElementContainerArray.hh"

////////////////////////////////////
ElementContainerArray::
ElementContainerArray()
{
}
////////////////////////////////////
ElementContainerArray::
ElementContainerArray( HeaderBase pheader )
  :  NeutronVector<ElementContainer,HeaderBase>( pheader )
     //  :: NeutronVector<ElementContainer,HeaderBase>( pheader )
{
}
////////////////////////////////////
ElementContainerArray::
ElementContainerArray( const ElementContainerArray &ob )
  :  NeutronVector<ElementContainer,HeaderBase>( ob )
     //  :: NeutronVector<ElementContainer,HeaderBase>( ob )
{ }
////////////////////////////////////
ElementContainerArray::
ElementContainerArray( const NeutronVector<ElementContainer, HeaderBase> &ob )
  :  NeutronVector<ElementContainer, HeaderBase>( ob )
     //  :: NeutronVector<ElementContainer, HeaderBase>( ob )
{ }

////////////////////////////////////
std::vector<Double>*
ElementContainerArray::
operator()( UInt4 index, std::string key )
{
  return ( *( PutPointer( index ) ) )( key );
}
////////////////////////////////////
std::vector<Double>*
ElementContainerArray::
operator()( UInt4 index, UInt4 C_index )
{
  return ( *( PutPointer( index ) ) )( C_index );
}
////////////////////////////////////
std::vector<UInt4>
ElementContainerArray::
SaveToBinFile( std::string key, std::string FileName ){
  std::vector<Double> vd;
  std::vector<UInt4> dimensions;

  for( UInt4 i=0; i<PutSize(); i++ ){
    std::vector<Double> temp = PutPointer(i)->Put(key);
    dimensions.push_back( (UInt4)(temp.size()) );
    for( UInt4 j=0; j<temp.size(); j++ ){
      vd.push_back( temp[ j ] );
    }
  }

  NeutronWriteBinaryData<Double> *nw =
    new NeutronWriteBinaryData<Double>();
  nw -> Write( vd, FileName );
  delete nw;

  return dimensions;
}
////////////////////////////////////
PyObject *
ElementContainerArray::
SaveToBinFilePy( std::string key, std::string FileName ){
  std::vector<UInt4> r = SaveToBinFile( key, FileName );
  CppToPython *p = new CppToPython();
  PyObject *po = p->VectorUInt4ToList( r );
  delete p;
  return po;
}
////////////////////////////////////
void
ElementContainerArray::
ReadBinFile( std::string FileName, std::vector<UInt4> dimensions, std::string key ){
  NeutronReadBinaryData<Double> *nr =
    new NeutronReadBinaryData<Double>();
  std::vector<Double> dat = nr->ReadData( FileName );
  delete nr;

  UInt4 counter = 0;

  for( UInt4 i=0; i<dimensions.size(); i++ ){
    std::vector<Double> temp;
    for( UInt4 j=0; j<dimensions[i]; j++ ){
      temp.push_back( dat[ counter++ ] );
    }
    ElementContainer e;
    e.Add( key, temp );
    Add( e );
  }
}
////////////////////////////////////
void
ElementContainerArray::
ReadBinFile( std::string FileName, PyObject *dimensions, std::string key ){
  CppToPython *p = new CppToPython();
  std::vector<UInt4> di = p->ListToUInt4Vector( dimensions );
  delete p;
  ReadBinFile( FileName, di, key );
  return;
}
////////////////////////////////////
void
ElementContainerArray::
AppendErr( std::string Counts, std::string Error, Double ErrorValue ){
  ElementContainerAppendError *e
    = new ElementContainerAppendError( ErrorValue );
  for( UInt4 i=0; i<PutSize(); i++ ){
    e -> Append( PutPointer( i ), Counts, Error );
  }
  delete e;
  return;
}
////////////////////////////////////
////////////////////////////////////
ElementContainerArray
ElementContainerArray::
Mul( Double d ){
  ElementContainerArray result = (*this);
  UInt4 s = result.PutSize();
  for( UInt4 i=0; i<s; i++ ){
    result(i) -> MulMySelf( d );
  }
  return result;
}
////////////////////////////////////////////////////////
ElementContainerArray &ElementContainerArray::
MulMySelf( Double d ){
  UInt4 s = PutSize();
  for( UInt4 i=0; i<s; i++ ){
    PutPointer(i) -> MulMySelf( d );
  }
  return *this;
}
////////////////////////////////////////////////////////
ElementContainerArray
ElementContainerArray::
Mul( Double d, Double e ){
  ElementContainerArray result = (*this);
  UInt4 s = result.PutSize();
  for( UInt4 i=0; i<s; i++ ){
    result(i) -> MulMySelf( d, e );
  }
  return result;
}
////////////////////////////////////////////////////////
ElementContainerArray &ElementContainerArray::
MulMySelf( Double d, Double e ){
  UInt4 s = PutSize();
  for( UInt4 i=0; i<s; i++ ){
    PutPointer(i) -> MulMySelf( d, e );
  }
  return *this;
}
////////////////////////////////////////////////////////

////////////////////////////////////
ElementContainerArray
ElementContainerArray::
Plus( Double d ){
  ElementContainerArray result = (*this);
  UInt4 s = result.PutSize();
  for( UInt4 i=0; i<s; i++ ){
    result(i) -> PlusMySelf( d );
  }
  return result;
}
////////////////////////////////////////////////////////
ElementContainerArray &ElementContainerArray::
PlusMySelf( Double d ){
  UInt4 s = PutSize();
  for( UInt4 i=0; i<s; i++ ){
    PutPointer(i) -> PlusMySelf( d );
  }
  return *this;
}
////////////////////////////////////////////////////////
ElementContainerArray
ElementContainerArray::
Plus( Double d, Double e ){
  ElementContainerArray result = (*this);
  UInt4 s = result.PutSize();
  for( UInt4 i=0; i<s; i++ ){
    result(i) -> PlusMySelf( d, e );
  }
  return result;
}
////////////////////////////////////////////////////////
ElementContainerArray &ElementContainerArray::
PlusMySelf( Double d, Double e ){
  UInt4 s = PutSize();
  for( UInt4 i=0; i<s; i++ ){
    PutPointer(i) -> PlusMySelf( d, e );
  }
  return *this;
}

////////////////////////////////////
ElementContainerArray
ElementContainerArray::
Pow( Double d ){
  ElementContainerArray result = (*this);
  UInt4 s = result.PutSize();
  for( UInt4 i=0; i<s; i++ ){
    result(i) -> PowMySelf( d );
  }
  return result;
}
////////////////////////////////////////////////////////
ElementContainerArray &ElementContainerArray::
PowMySelf( Double d ){
  UInt4 s = PutSize();
  for( UInt4 i=0; i<s; i++ ){
    PutPointer(i) -> PowMySelf( d );
  }
  return *this;
}

////////////////////////////////////////////////////////
ElementContainerArray ElementContainerArray::
MergeWithWeight( ElementContainerArray &eca ){

  ElementContainerArray r = ElementContainerArray( PutHeader() );
  for( UInt4 i=0; i<PutSize(); i++ ){
    r.Add( PutPointer(i)->MergeWithWeight( *( eca(i) ) ) );
  }

  return r;
}
////////////////////////////////////////////////////////
