#ifndef UTSUSEMICALCCONTAINERS
#define UTSUSEMICALCCONTAINERS

#include "Header.hh"
#include "HeaderBase.hh"
#include "ElementContainer.hh"
#include "ElementContainerArray.hh"
#include "ElementContainerMatrix.hh"
#include "UtsusemiHeader.hh"

//////////////////////////////////
// UtsusemiCalcContainers
/////////////////////////////////

//! Calclation between Manyo Containers
/*!
 *
 */


class UtsusemiCalcContainers
{
private:
    UInt4 _NumOfMulTh;
    StringTools* st;
public:
    UtsusemiCalcContainers();
        //!< Constructor
        /*!<
         *
         */
    ~UtsusemiCalcContainers();
        //!< Destructor
        /*!<
         */

    ElementContainer CalcContainers( Double coef1, ElementContainer* ec1, std::string ope,
                                     Double coef2, ElementContainer* ec2 );
        //!< Calculates between two ElementContainers
        /*!< Formura : coef1*ec1 ["+","-","*","/"] coef2*ec2
         *
         *   @param coef1 (Double) coefficient for ec1
         *   @param ec1   (ElementContainer*) first ElementContainer
         *   @param ope   (std::string) operator between ec1 and ec2 must be "+","-","*" or "/".
         *   @param coef2 (Double) coefficient for ec2
         *   @param ec2   (ElementContainer*) second ElementContainer
         *   @return ElementContainer as calculation result
         */
    ElementContainerArray CalcContainers( Double coef1, ElementContainerArray* eca1, std::string ope,
                                          Double coef2, ElementContainerArray* eca2 );
        //!< Calculates between two ElementContainerArrays
        /*!< Formura : coef1*eca1 ["+","-","*","/"] coef2*eca2
         *
         *   @param coef1 (Double) coefficient for ec1
         *   @param eca1   (ElementContainerArray*) first ElementContainerArray
         *   @param ope   (std::string) operator between ec1 and ec2 must be "+","-","*" or "/".
         *   @param coef2 (Double) coefficient for ec2
         *   @param eca2   (ElementContainerArray*) second ElementContainerArray
         *   @return ElementContainerArray as calculation result
         */
    ElementContainerArray CalcContainers( Double coef1, ElementContainerArray* eca, std::string ope,
                                          Double coef2, ElementContainer* ec );
        //!< Calculates between ElementContainerArray and ElementContainer
        /*!< Formura : coef1*eca ["+","-","*","/"] coef2*ec
         *   ec operates to each ElementContainer in given ElementContainerArray
         *
         *   @param coef1 (Double) coefficient for eca
         *   @param eca   (ElementContainerArray*) ElementContainerArray
         *   @param ope   (std::string) operator between ec1 and ec2 must be "+","-","*" or "/".
         *   @param coef2 (Double) coefficient for ec
         *   @param ec    (ElementContainer*) ElementContainer
         *   @return ElementContainerArray as calculation result
         */
    ElementContainerMatrix CalcContainers( Double coef1, ElementContainerMatrix* ecm1, std::string ope,
                                           Double coef2, ElementContainerMatrix* ecm2 );
        //!< Calculates between two ElementContainerMatrixs
        /*!< Formura : coef1*ecm1 ["+","-","*","/"] coef2*ecm2
         *
         *   @param coef1 (Double) coefficient for ecm1
         *   @param ecm1  (ElementContainerMatrix*) first ElementContainerMatrix
         *   @param ope   (std::string) operator between ec1 and ec2 must be "+","-","*" or "/".
         *   @param coef2 (Double) coefficient for ecm2
         *   @param ecm2  (ElementContainerMatrix*) second ElementContainerMatrix
         *   @return ElementContainerMatrix as calculation result
         */
    ElementContainerMatrix CalcContainers( Double coef1, ElementContainerMatrix* ecm, std::string ope,
                                           Double coef2, ElementContainerArray* eca );
        //!< Calculates between ElementContainerMatrix and ElementContainerArray
        /*!< Formura : coef1*ecm ["+","-","*","/"] coef2*eca
         *   eca operates to each ElementContainerArray in given ElementContainerMatrix
         *
         *   @param coef1 (Double) coefficient for ecm
         *   @param ecm   (ElementContainerMatrix*) ElementContainerMatrix
         *   @param ope   (std::string) operator between ec1 and ec2 must be "+","-","*" or "/".
         *   @param coef2 (Double) coefficient for eca
         *   @param eca   (ElementContainerArray*) ElementContainerArray
         *   @return ElementContainerMatrix as calculation result
         */
    ElementContainerMatrix CalcContainers( Double coef1, ElementContainerMatrix* ecm, std::string ope,
                                           Double coef2, ElementContainer* ec );
        //!< Calculates between ElementContainerMatrix and ElementContainer
        /*!< Formura : coef1*ecm ["+","-","*","/"] coef2*ec
         *   ec operates to each ElementContainer in given ElementContainerMatrix
         *
         *   @param coef1 (Double) coefficient for ecm
         *   @param ecm   (ElementContainerMatrix*) ElementContainerMatrix
         *   @param ope   (std::string) operator between ec1 and ec2 must be "+","-","*" or "/".
         *   @param coef2 (Double) coefficient for ec
         *   @param ec    (ElementContainer*) ElementContainer
         *   @return ElementContainerMatrix as calculation result
         */
    bool CalcContainers( ElementContainerMatrix* ret_ecm,
                         Double coef1, ElementContainerMatrix* ecm1, std::string ope,
                         Double coef2, ElementContainerMatrix* ecm2 );
        //!< Calculates faster between two ElementContainerMatrixs
        /*!< Formura : coef1*ecm1 ["+","-","*","/"] coef2*ecm2
         *
         *   @param ret_ecm (ElementContainerMatrix) Empty ElementContainerMatrix which calculated result is set.
         *   @param coef1 (Double) coefficient for ecm1
         *   @param ecm1  (ElementContainerMatrix*) first ElementContainerMatrix
         *   @param ope   (std::string) operator between ec1 and ec2 must be "+","-","*" or "/".
         *   @param coef2 (Double) coefficient for ecm2
         *   @param ecm2  (ElementContainerMatrix*) second ElementContainerMatrix
         *   @retval true  succeeded
         *   @retval false failed
         */
    bool CalcContainers( ElementContainerArray* ret_eca,
                         Double coef1, ElementContainerArray* eca1, std::string ope,
                         Double coef2, ElementContainerArray* eca2 );
        //!< Calculates faster between two ElementContainerArrays
        /*!< Formura : coef1*eca1 ["+","-","*","/"] coef2*eca2
         *
         *   @param ret_eca (ElementContainerArray) Empty ElementContainerArray which calculated result is set.
         *   @param coef1 (Double) coefficient for ecm1
         *   @param eca1  (ElementContainerArray*) first ElementContainerArray
         *   @param ope   (std::string) operator between ec1 and ec2 must be "+","-","*" or "/".
         *   @param coef2 (Double) coefficient for eca2
         *   @param eca2  (ElementContainerArray*) second ElementContainerArray
         *   @retval true  succeeded
         *   @retval false failed
         */
    bool CalcContainers( ElementContainerMatrix* ret_ecm,
                         Double coef1, ElementContainerMatrix* ecm1, Double pow1, std::string ope,
                         Double coef2, ElementContainerMatrix* ecm2, Double pow2 );
        //!< Calculates faster between two ElementContainerMatrixs
        /*!< Formura : coef1*ecm1^(pow1) ["+","-","*","/"] coef2*ecm2^(pow2)
         *
         *   @param ret_ecm (ElementContainerMatrix) Empty ElementContainerMatrix which calculated result is set.
         *   @param coef1 (Double) coefficient for ecm1
         *   @param ecm1  (ElementContainerMatrix*) first ElementContainerMatrix
         *   @param pow1  (Double) power value for ecm1
         *   @param ope   (std::string) operator between ec1 and ec2 must be "+","-","*" or "/".
         *   @param coef2 (Double) coefficient for ecm2
         *   @param ecm2  (ElementContainerMatrix*) second ElementContainerMatrix
         *   @param pow2  (Double) power value for ecm2
         *   @retval true  succeeded
         *   @retval false failed
         */
    bool CalcContainers( ElementContainerArray* ret_eca,
                         Double coef1, ElementContainerArray* eca1, Double pow1, std::string ope,
                         Double coef2, ElementContainerArray* eca2, Double pow2 );
        //!< Calculates faster between two ElementContainerArrays
        /*!< Formura : coef1*eca1^(pow1) ["+","-","*","/"] coef2*eca2^(pow2)
         *
         *   @param ret_eca (ElementContainerArray) Empty ElementContainerArray which calculated result is set.
         *   @param coef1 (Double) coefficient for ecm1
         *   @param eca1  (ElementContainerArray*) first ElementContainerArray
         *   @param pow1  (Double) power value for eca1
         *   @param ope   (std::string) operator between ec1 and ec2 must be "+","-","*" or "/".
         *   @param coef2 (Double) coefficient for eca2
         *   @param eca2  (ElementContainerArray*) second ElementContainerArray
         *   @param pow2  (Double) power value for eca2
         *   @retval true  succeeded
         *   @retval false failed
         */
    UInt4 CheckOperator( std::string ope );
        //!< Checks whether given operator is valid or not.
        /*!<
         *   @param ope   (std::string) operator between ec1 and ec2 must be "+","-","*" or "/".
         *   @retval true  ope is valid
         *   @retval false invalid
         */
};
#endif
