#ifndef UTSUSEMIWIRINGINFOEDITORTEMPLATE_CC
#define UTSUSEMIWIRINGINFOEDITORTEMPLATE_CC
#include "UtsusemiWiringInfoEditorTemplate.hh"
//////////////////////////////////////////////////////////
template <typename T1>
UtsusemiWiringInfoEditorTemplate<T1>::UtsusemiWiringInfoEditorTemplate(){
    Initialize();
}
//////////////////////////////////////////////////////////
template <typename T1>
UtsusemiWiringInfoEditorTemplate<T1>::~UtsusemiWiringInfoEditorTemplate(){
    if (_stools!=NULL) delete _stools;
    if (_WD!=NULL) delete _WD;
    if (_WE!=NULL) delete _WE;
}
//////////////////////////////////////////////////////////
template <typename T1>
void UtsusemiWiringInfoEditorTemplate<T1>::Initialize(){
    _stools = new StringTools();
    _MessageTag = "UtsusemiWiringInfoEditorTemplate<T1>::";
    _Status = true;
    _WD = new WiringInfoConversionDictionary();
    _WE = NULL;
    UtsusemiCheckLogQuiet();

    _runNo = 0;
    _runNos.clear();
    _DetType = UTSUSEMI_KEY_HEAD_DETTYPE_PSD;
    _tofBinPtnId = 0;
    _tofOffset = 0;
    _tofMaskPtnId = -1;

    _tofOriginShiftByLambda_type = -1;
    _tofOriginShiftByLambda_params.clear();
    _tofOriginShiftByLambda_lambda.clear();

    _wiringInfoPath = "";
    _maskInfoPath = "";

}
//////////////////////////////////////////////////////////
template <typename T1>
bool UtsusemiWiringInfoEditorTemplate<T1>::
SetRunNo( UInt4 runNo, UInt4 mode_no, std::string env_file ){
    return SetRunNo( _stools->UInt4ToString( runNo ),
                     _stools->UInt4ToString( mode_no ),
                     env_file );
}
//////////////////////////////////////////////////////////
template <typename T1>
bool UtsusemiWiringInfoEditorTemplate<T1>::
SetRunNo( std::string runNos, std::string mode_no, std::string env_file ){
    bool ret = false;
    if (runNos.empty()){
        UtsusemiError(_MessageTag+"SetRunNo >> run number argument is empty");
        return false;
    }

    /*
    std::vector<std::string> st_runNos = _stools->SplitString( runNos, "," );
    if (st_runNos.empty()){
        std::cout << _MessageTag+"SetRunNo >> given runNo is invalid (params="+runNos+")"<<std::endl;
        return false;
    }
    */
    std::vector<UInt4> vec_runNos = DivMultiContUInt4( runNos );
    if (vec_runNos.empty()){
        UtsusemiError( _MessageTag+"SetRunNo >> given runNo is invalid (params="+runNos+")");
        return false;
    }

    _runNos.clear();
    //for (UInt4 i=0; i<(st_runNos.size()); i++) _runNos.push_back( _stools->StringToUInt4( st_runNos[i] ) );
    for (UInt4 i=0; i<vec_runNos.size(); i++) _runNos.push_back( vec_runNos[i] );

    _runNo = _runNos[0];

    UInt4 modeNo = _stools->StringToUInt4( mode_no );
    UtsusemiAnaEnvironReader *UAR = new UtsusemiAnaEnvironReader( _runNo, true );
    if (UAR->_Status){
    }else{
        delete UAR;
        UAR = new UtsusemiAnaEnvironReader( env_file );
    }
    if (UAR->_Status){
        std::vector<std::string> pfiles = UAR->PutParamFiles( _runNo, modeNo,true );
        if (pfiles.empty()){
        }else{
            _wiringInfoPath = pfiles[0];
            if (pfiles.size()>2)
                _maskInfoPath = pfiles[2];
            ret = true;
        }
    }else{
        delete UAR;
        return false;
    }
    UtsusemiMessage(_MessageTag+"SetRunNo > _wiringInfoPath = "+_wiringInfoPath);
    if (_WE!=NULL) delete _WE;
    _WE = new T1();
    if (_WE->Read(_wiringInfoPath)){
        ret = true;
    }else{
        ret = false;
    }
    delete UAR;
    /*
    _AnaEnvironFile = "";
    if (env_file!=""){
        _AnaEnvironFile=env_file;
        std::string::size_type ind_sl = _AnaEnvironFile.find_last_of("/");
        if (ind_sl!=std::string::npos){
            _UtsusemiUserXmlPath = _AnaEnvironFile.substr(0, ind_sl);
            std::cout << "introduced Xml Path = "+_UtsusemiUserXmlPath << std::endl;
        }
    }else{
        char pathc[200];
        std::sprintf( pathc, "%s/%s", _UtsusemiUserXmlPath.c_str(), _defaultAnaEnvironFile.c_str() );
        std::string path( pathc );
        _AnaEnvironFile = path;
    }
    std::cout << "_AnaEnvironFile ="+_AnaEnvironFile<<std::endl;
    UtsusemiAnaEnvironReader *UAR = new UtsusemiAnaEnvironReader( _AnaEnvironFile );
    if (UAR->_Status){
        std::vector<std::string> pfiles = UAR->PutParamFiles( _runNo );
        if (pfiles.empty()){
        }else{
            _wiringInfoName = pfiles[0];
            ret = true;
        }
    }else{
        delete UAR;
        return false;
    }
    delete UAR;

    if (_WE!=NULL) delete _WE;
    _WE = new T1();
    char pathc2[200];
    std::sprintf( pathc2, "%s/%s", _UtsusemiUserXmlPath.c_str(), _wiringInfoName.c_str() );
    std::string path2( pathc2 );
    if (_WE->Read(path2)){
        ret = true;
    }else{
        ret = false;
    }
    */
    return ret;
}
//[inamura 160830]-->
//////////////////////////////////////////////////////////
template <typename T1>
bool UtsusemiWiringInfoEditorTemplate<T1>::
SetRunNo( UInt4 runNo, std::string wfile ){
    if (wfile=="-") return SetRunNo( runNo ); //[inamura 161225]

    bool ret = true;

    _runNos.clear();
    _runNos.push_back( runNo );

    _runNo = _runNos[0];

    _wiringInfoPath = FindParamFilePath( wfile );
    if (_wiringInfoPath=="") ret = false;

    if (ret){
        if (_WE!=NULL) delete _WE;
        _WE = new T1();
        if (_WE->Read(_wiringInfoPath)){
            ret = true;
        }else{
            ret = false;
        }
    }else{
        UtsusemiError( _MessageTag+"Failed to read WiringInfo="+_wiringInfoPath );
        _wiringInfoPath = "";
    }
    return ret;
}
//<--[inamura 160830]
//[inamura 170404]-->
//////////////////////////////////////////////////////////
template <typename T1>
bool UtsusemiWiringInfoEditorTemplate<T1>::
SetRunNoWithWiringInfo( std::string runNos, std::string wfile ){
    if ((wfile=="-")||(wfile=="")) return SetRunNo( runNos );

    bool ret = false;
    if (runNos.empty()){
        UtsusemiError(_MessageTag+"SetRunNo >> run number argument is empty");
        return false;
    }

    std::vector<UInt4> vec_runNos = DivMultiContUInt4( runNos );
    if (vec_runNos.empty()){
        UtsusemiError( _MessageTag+"SetRunNo >> given runNo is invalid (params="+runNos+")");
        return false;
    }

    _runNos.clear();

    for (UInt4 i=0; i<vec_runNos.size(); i++) _runNos.push_back( vec_runNos[i] );

    _runNo = _runNos[0];

    _wiringInfoPath = FindParamFilePath( wfile );
    if (_wiringInfoPath!=""){
        if (_WE!=NULL) delete _WE;
        _WE = new T1();
        if (_WE->Read(_wiringInfoPath)){
            ret = true;
        }else{
            ret = false;
        }
    }else{
        UtsusemiError( _MessageTag+"Failed to read WiringInfo="+_wiringInfoPath );
        _wiringInfoPath = "";
    }
    return ret;
}
//<--[inamura 170404]
//////////////////////////////////////////////////////////
template <typename T1>
bool UtsusemiWiringInfoEditorTemplate<T1>::
SetConversionParameter( std::string params, UInt4 _ptnId ){
    if (_WE==NULL){
        UtsusemiError( _MessageTag+"SetConversionParameter >> SetRunNo must be done at first." );
        return false;
    }

    if (_WE->SetConversionParameter( params, _ptnId )){
        _tofBinPtnId = _ptnId;
        return true;
    }else{
        UtsusemiError( _MessageTag+"SetConversionParameter >> Some Parameters are invalid." );
        return false;
    }

}
//////////////////////////////////////////////////////////
template <typename T1>
bool UtsusemiWiringInfoEditorTemplate<T1>::
SetDetRange( std::string params ){
    if (_WE==NULL){
        UtsusemiError( _MessageTag+"SetDetRange >> SetRunNo must be done at first." );
        return false;
    }

    return _WE->SetDetRange( params );

}
//////////////////////////////////////////////////////////
template <typename T1>
bool UtsusemiWiringInfoEditorTemplate<T1>::
SetFrameInfo( std::string params ){
    if (_WE==NULL){
        UtsusemiError( _MessageTag+"SetFrameInfo >> SetRunNo must be done at first." );
        return false;
    }
    UtsusemiFrameBoundaryInfo uf;
    std::vector<std::string> tmp = _stools->SplitString( params, "," );
    if (tmp.size()==1){
        std::string a_word( tmp[0] );
        transform( tmp[0].begin(), tmp[0].end(), a_word.begin(), ::toupper);
        if (a_word.find("NONE")!=std::string::npos){
            return true;
        }else{
            UtsusemiError(_MessageTag+"SetFrameInfo : Wrong parameters ( "+a_word+" )");
            return false;
        }
    }else if (tmp.size()==2){
        UInt4 frame_no = 0;
        Double boundary = _stools->StringToDouble( tmp[1] );
        std::string _type(tmp[0]);

        transform( tmp[0].begin(), tmp[0].end(), _type.begin(), ::tolower);
        if (_type==uf.BOUNDARYTYPE_LAMBDA) frame_no = 1;
        else if (_type==uf.BOUNDARYTYPE_ENERGY) frame_no = 1;
        else if (_type==uf.BOUNDARYTYPE_EI) frame_no = 1;
        else if (_type==uf.BOUNDARYTYPE_TOF) frame_no = 1;
        else{
            _type = uf.BOUNDARYTYPE_TOF;
            frame_no = _stools->StringToUInt4( tmp[0] );
            boundary = _stools->StringToDouble( tmp[1] );
        }
        if (frame_no>3){
            UtsusemiError( _MessageTag+"SetFrameInfo params are invalid "+params );
            return false;
        }
        return _WE->SetFrameInfo( frame_no, boundary, _type );
    }

    return false;
}
//////////////////////////////////////////////////////////
template <typename T1>
bool UtsusemiWiringInfoEditorTemplate<T1>::
SetMaskInfo( std::string params, UInt4 _ptnId ){
    if (_WE==NULL){
        UtsusemiError( _MessageTag+"SetMaskParam >> SetRunNo must be done at first." );
        return false;
    }

    if (_WE->SetMaskInfo( params, _ptnId )){
        if (_WE->_maskXmlFilePath!="") {
            if ((_WE->_maskXmlFilePath)!=(_WE->KEY_USE_DEF_MASK)){
                std::string runParam = FindEnvironFolderInRunData(_runNo);
                if (runParam==""){
                    _maskInfoPath = FindParamFilePath( _WE->_maskXmlFilePath );
                }else{
                    _maskInfoPath = FindParamFilePath( _WE->_maskXmlFilePath, runParam );
                }
                if (_maskInfoPath==""){
                    UtsusemiError( _MessageTag+"SetMaskParam >> mask file is not found ("+_WE->_maskXmlFilePath+")");
                    return false;
                }
            }// _WE->_maskXmlFilePath=="DEFAUT" -> use MaskInfo from environ_ana.xml
        }else{
            _maskInfoPath = "";
        }
        _tofMaskPtnId = _ptnId;
        return true;
    }else{
        _tofMaskPtnId = -1;
        UtsusemiError( _MessageTag+"SetMaskParam >> Failed to SetMaskInfo." );
        return false;
    }
}
//[inamura 160809]-->
//////////////////////////////////////////////////////////
template <typename T1>
bool UtsusemiWiringInfoEditorTemplate<T1>::
SetTimeDependBackGroundInfo( std::string params ){
    if (_WE==NULL){
        UtsusemiError( _MessageTag+"SetTimeDependBackGroundInfo >> SetRunNo must be done at first." );
        return false;
    }
    return _WE->SetTimeDependBackGroundInfo( params );
}
//<--[inamura 160809]
//////////////////////////////////////////////////////////
template <typename T1>
std::string UtsusemiWiringInfoEditorTemplate<T1>::
MakeTempWiringInfo( std::string _path, bool asFile ){
    if ((_WE==NULL)||(_WE->_Status==false)){
        UtsusemiError( _MessageTag+" MakeTempWiringInfo >> No SetRunNo ");
        return "";
    }

    _WE->DeleteAllTofBinInfo();
    _WE->SetTofBinInfo( _tofBinPtnId, _tofOffset, _tofMaskPtnId );

    if ((!UtsusemiEnvGetDebugMode())&&(!asFile))
        return _WE->OutXml();

    time_t timer;
    time(&timer);
    UInt4 t_timer = ((UInt4)timer)%1000000;

    std::string clock_st( _stools->UInt4ToString(t_timer) );
    pid_t proc_id = getpid();
    UInt4 procid(proc_id);
    std::string procid_st( _stools->UInt4ToString(procid) );

    char pathc[200];
    //std::snprintf( pathc, sizeof(pathc), "%s/%s/wiringinfo_tmp_%s.xml", _UtsusemiUserPrivPath.c_str(), "ana/xml", clock_st.c_str() );
    char temp[100];
    std::snprintf( temp, sizeof(temp), UTSUSEMIUSERPRIVTEMPWIRINGINFOBASE.c_str(), procid_st.c_str(), clock_st.c_str() );
    if (_path!=""){
        std::snprintf( pathc, sizeof(pathc), "%s/%s", _path.c_str(), temp );
    }else{
        std::string path_found = FindTempFilePath();
        if (path_found==""){
            UtsusemiError( _MessageTag+" MakeTempWiringInfo >> Not found temporal directory. Maybe you did not set Utsusemi environment variables ");
            return "";
        }else{
            std::snprintf( pathc, sizeof(pathc), "%s/%s", path_found.c_str(), temp );
        }
    }
    std::string path( pathc );
    //std::cout << "Output path="+path<<std::endl;

    if (_WE->Write( path )){
        UtsusemiMessage( _MessageTag+"MakeTempWiringInfo : Temporal WiringInfo file path = "+path );
    }else{
        UtsusemiError(_MessageTag+" Fails to save temporal wiring info file as "+path);
        path = "";
    }

    return path;
}

//////////////////////////////////////////////////////////
template <typename T1>
bool UtsusemiWiringInfoEditorTemplate<T1>::
SetDetParam( std::string params ){
    if (_WE==NULL){
        UtsusemiError( _MessageTag+"SetDetParam >> SetRunNo must be done at first." );
        return false;
    }

    if (_WE->SetDetParam( params )){
        _DetType = _WE->_detType;
        return true;
    }else{
        return false;
    }
}
//////////////////////////////////////////////////////////
template <typename T1>
UInt4 UtsusemiWiringInfoEditorTemplate<T1>::
PutNumOfPixelForDet(UInt4 _detId){
    return _WE->PutNumOfPixelForDet(_detId);
}

#endif
