#include "MlfHeader.hh"
////////////////////////////////////////////////
UInt4 MlfGetNumOfMulTh(){
    // copied from UtsusemiHeader.cc
    const char *multh_c = getenv("MLF_MULTH");
    if (multh_c!=NULL){
        std::string multh_s(multh_c);
        if (multh_s!=""){
            StringTools st;
            return st.StringToUInt4( multh_s );
        }
    }
#ifdef MULTH
    return std::min( MULTH, omp_get_num_procs() );
#else
    return 1;
#endif
}
const Double MLF_NEUNET_CLOCK_MICROSEC=0.025;  // [microsec]
const Double MLF_NEUNET_CLOCK_SEC=2.5e-8;      // [sec]
const Double MLF_TARGET_FRAME_MICROSEC=40000.0;// [microsec]
const Double MLF_TARGET_FRAME_MILLISEC=40.0;   // [millisec]

//////////////////////////////////////////////////////////
std::vector<UInt4> DivMultiContUInt4( std::string conts ){
    StringTools st;
    std::vector<UInt4> ret;
    std::vector<std::string> cont_list_s = st.SplitString( conts, "," );

    for (std::vector<std::string>::iterator it=cont_list_s.begin(); it!=cont_list_s.end(); ++it){
        if (((*it).find(":")==std::string::npos)&&((*it).find("-")==std::string::npos)){
            if (((*it)=="ALL")||((*it)=="All")) {
                ret.clear();
                break;
            }else{ // single detector number
                ret.push_back( st.StringToUInt4( (*it) ) );
            }
        }else if (((*it).find(":"))!=std::string::npos){
            std::string::size_type c = (*it).find(":");
            UInt4 start_id = st.StringToUInt4( (*it).substr(0,c) );
            UInt4 end_id = st.StringToUInt4( (*it).substr(c+1,(*it).size()-1) );
            for (UInt4 i=start_id; i<(end_id+1); i++)
                ret.push_back(i);
        }else{
            int c=(int)( (*it).find('-') );
            UInt4 start_id = st.StringToUInt4( (*it).substr(0,c) );
            UInt4 end_id = st.StringToUInt4( (*it).substr(c+1,(*it).size()-1) );
            for (UInt4 i=start_id; i<(end_id+1); i++)
                ret.push_back(i);
        }
    }
    return ret;
}
//////////////////////////////////////////////////////////
std::vector<Double> DivMultiContDouble( std::string conts ){
    StringTools st;
    std::vector<Double> ret;
    std::vector<std::string> cont_list_s = st.SplitString( conts, "," );

    for (std::vector<std::string>::iterator it=cont_list_s.begin(); it!=cont_list_s.end(); ++it){
        if ((*it).find(":")==std::string::npos){
            if (((*it)=="ALL")||((*it)=="All")){
                ret.clear();
                break;
            }else{
                ret.push_back( st.StringToDouble( (*it) ) ); //start value
                ret.push_back( st.StringToDouble( (*it) ) ); //end value
            }
        }else{
            int c=(int)( (*it).find(':') );
            Double start_val = st.StringToDouble( (*it).substr(0,c) );
            Double end_val = st.StringToDouble( (*it).substr(c+1,(*it).size()-1) );
            ret.push_back( start_val );
            ret.push_back( end_val );
        }
    }
    return ret;
}
//////////////////////////////////////////////////////////
std::vector<Double> CalcRangeAsBinCenterZero( Double v_min, Double v_max, Double v_step, bool isZeroCenter ){
    std::vector<Double> ret(3,0);

    if (isZeroCenter || (v_min<=0.0)){
    }else{
        ret[0] = v_min-(v_step/2.0);
        Double p = ret[0];
        UInt4 counts = 0;
        while( p<v_max ) {
            p += v_step;
            counts++;
        }
        ret[1] = p;
        ret[2] = Double(counts);
        return ret;
    }

    if (v_min<=0.0){
        Double p = -v_step/2.0;
        while( p>v_min ) p -= v_step;
        ret[0]= p;
    }else{
        Double p = v_step/2.0;
        while( p<v_min ) p += v_step;
        p-=v_step;
        ret[0] = p;
    }

    if (ret.size()==0){
        ret[0] = v_min;
    }

    Double p = ret[0];
    UInt4 counts = 0;
    while( p<v_max ) {
        p += v_step;
        counts++;
    }
    ret[1] = p;

    ret[2] = Double(counts);

    return ret;
}
//////////////////////////////////////////////////////////
std::vector<Double> PutVectorAsBinCenterZero( Double v_min, Double v_max, Double v_step ){
    std::vector<Double> p = CalcRangeAsBinCenterZero( v_min, v_max, v_step );

    std::vector<Double> ret((int)p[2],0.0);
    for (UInt4 i=0; i<ret.size(); i++)
        ret[i] = p[0] + (Double)i*v_step;

    return ret;
}
//////////////////////////////////////////////////////////
std::string MlfEnvGetProtonServerHostName(){
    const char *tmp_c = getenv(MLF_ENV_PROTONSERV_HOSTNAME);
    if (tmp_c!=NULL){
        std::string tmp_s(tmp_c);
        return tmp_s;
    }else{
        if (!MlfEnvGetIsQuiet())
            std::cout << "MlfEnvGetProtonServerHostName : Not set "<<"MLF_ENV_PROTONSERV_HOSTNAME" << std::endl;;
        return "";
    }
}
//////////////////////////////////////////////////////////
bool MlfEnvGetIsQuiet(){
    const char *q = getenv(MLF_ENV_LOG_QUIET);
    if (q!=NULL){
        std::string qst(q);
        if (qst!="")
            if ((qst.find("y")!=std::string::npos) || (qst.find("Y")!=std::string::npos) )
                return true;
    }
    return false;
}
//////////////////////////////////////////////////////////
bool MlfEnvGetT0PidCheckIgnored(){
    const char *q = getenv(MLF_ENV_T0PIDCHECK_IGNORED);
    if (q!=NULL){
        std::string qst(q);
        if (qst!="")
            if ((qst.find("y")!=std::string::npos) || (qst.find("Y")!=std::string::npos) )
                return true;
    }
    return false;
}
