import math;
import os

import constants;
import crData;
import pyCreeper;

def createFolder(folderPath_):
    if not os.path.exists(folderPath_):
        print("CREATED FOLDER " + folderPath_)
        os.makedirs(folderPath_)

def saveArrayToFile(array_, filePath_):
    """

    :param array_: 2D array, where each row is a line in the file
    :param filePath_:

    """

    outp = ""
    for i in range(len(array_)):
        for j in range(len(array_[i])):
            outp += str(array_[i][j]);
            if (j < len(array_[i])-1):
                outp += "\t";
        if (i < len(array_)-1):
            outp += "\n";

    with open(filePath_, "w") as text_file:
        text_file.write(outp)

def removeControllerNameFromString(string_):
    str = string_.replace("beeRecruiter","");
    str = str.replace("solitary","");
    str = str.replace("localBroadcaster","")
    str = str.replace("__","_")
    return str;

def getScenarioFolderExtraParameterStrings(scenarioFolders_, NRs_ = [], experimentType_=""):
    environmentExtraParamStrings = [];
    #print("Get extra param string for exp type {} ".format(experimentType_))
    for i in range(len(scenarioFolders_)):
        if ("A" == scenarioFolders_[i][0] or "0" == scenarioFolders_[i][0]):
            extraParamsStr = ""
        elif ("C" == scenarioFolders_[i][0]):
            extraParamsStr = "[" + experimentType_ + "]";

        #-- put it all together
        if ("solitary" in scenarioFolders_[i].lower()):
            if (len(NRs_) > 0):
                environmentExtraParamStrings.append("_solitary" + extraParamsStr + "_NR" + str(NRs_[i]));
            else:
                environmentExtraParamStrings.append("_solitary" + extraParamsStr);

        elif ("localbroadcaster" in scenarioFolders_[i].lower()):
            if (len(NRs_) > 0):
                environmentExtraParamStrings.append("_localBroadcaster" + extraParamsStr + "_NR" + str(NRs_[i]));
            else:
                environmentExtraParamStrings.append("_localBroadcaster" + extraParamsStr);

        elif ("beerecruiter" in scenarioFolders_[i].lower()):
            if (len(NRs_) > 0):
                environmentExtraParamStrings.append("_beeRecruiter" + extraParamsStr + "_NR" + str(NRs_[i]));
            else:
                environmentExtraParamStrings.append("_beeRecruiter" + extraParamsStr);


    return environmentExtraParamStrings;

def getMaxMinCollectedResurce(scenarioType_,fP_):
    if (fP_ == 100):
        return [300,400];
        #
        # if (scenarioType_ == "group2"):
        #     return [300,400];
        # elif (scenarioType_ == "group4"):
        #     return [300,400]
    elif (fP_ == 200):
        return [150,250];

def getMaxMinEnergy(scenarioType_,fP_):
    return [10000,15000];

def getMaxMinResourceEnergyCost(scenarioType_,fP_):
    if (fP_ == 100):
        return [30,45];
    elif(fP_ == 200):
        return [60,75]

def getTimeSeriesGraphSize(timeBinLength_, totalTime_, hasNegativeVals_=False):
    height = 6;
    if (hasNegativeVals_):
        height = 6;

    size=(12,height);

    if (timeBinLength_ == 300 and totalTime_ > 14400):
        size=(24,height);

    if (totalTime_ == 61200):
        size=(14,height);

    if (timeBinLength_ == 300 and totalTime_ >= 61200):
        size=(45,height);

    if (timeBinLength_ == 300 and totalTime_ >= 93600):
        size=(60,height);

    if (timeBinLength_ >= 50 and totalTime_ > 7200):
        size=(24,height);

    return size;

def getPlotGraphSize(numOfItems_):
    height = 6;
    if (constants.DO_LARGE_GRAPHS):
        height = 8;

    if (numOfItems_ <= 6):
        size = (7, height);
    elif (numOfItems_ <= 12):
        #size = (20, height);
        size = (10, height);
    else:
        size = (25, height);

    if (constants.PUBLICATION_TYPE == constants.PUBLICATION_TYPE_CP01):
        size = (12,4.6);

    return size;

def getMaxTimeByNR(NR_, experimentId_="A", extraParamsStr_="" ):
    #print("Get max time by NR {} expId {} extraParamStr{}".format(NR_, experimentId_, extraParamsStr_))
    if (experimentId_ == "A"):
        maxTime=14400;
        if (NR_ == 10):
            maxTime =  36000;
        elif (NR_ == 50):
            maxTime =  10800;

        return maxTime;
    elif (experimentId_ == "B"):
        return 25200;
    elif (experimentId_ == "C"):
        maxTime=36000;
        if (NR_ == 10):
            maxTime =  63000;
        elif (NR_ == 50):
            maxTime =  27000;
        return maxTime;

    elif (experimentId_ == "0"):
        return 3600;

    raise ValueError("getMaxTimeByNR: Unknown experiment ID: {}".format(experimentId_))

def getYmaxYmin_forCU(folder_, analysisName_):
    import crGraphs;
    yMax =  crGraphs.INVALID_VALUE;
    yMin = 0;

    if ("Crel_" in folder_ or "dynamicRelU" in folder_):
        if ("solitary" in analysisName_ and "fast" in analysisName_ and "NR10" in analysisName_ and "COLLECT" in analysisName_ ):
            yMax = 350000;
            yMin = 100000;
        elif ("solitary" in analysisName_ and "fast" in analysisName_ and "NR10" in analysisName_ and "PERFORM" in analysisName_ ):
            yMax = 350000;
            yMin = 200000;
        elif ("solitary" in analysisName_ and "fast" in analysisName_ and "NR25" in analysisName_ and "COLLECT" in analysisName_ ):
            yMax = 200000;
            yMin = 40000;
        elif ("solitary" in analysisName_ and "fast" in analysisName_ and "NR25" in analysisName_ and "PERFORM" in analysisName_ ):
            yMax = 200000;
            yMin = 120000;
        elif ("solitary" in analysisName_ and "fast" in analysisName_ and "NR50" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 140000;
            yMin = 20000;
        elif ("solitary" in analysisName_ and "fast" in analysisName_ and "NR50" in analysisName_ and "PERFORM" in analysisName_):
            yMax = 140000;
            yMin = 60000;
        elif ("solitary" in analysisName_ and "slow" in analysisName_ and "NR10" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 700000;
            yMin = 100000;
        elif ("solitary" in analysisName_ and "slow" in analysisName_ and "NR10" in analysisName_ and "PERFORM" in analysisName_):
            yMax = 650000;
            yMin = 250000;
        elif ("solitary" in analysisName_ and "slow" in analysisName_ and "NR25" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 400000;
            yMin = 0;
        elif ("solitary" in analysisName_ and "slow" in analysisName_ and "NR25" in analysisName_ and "PERFORM" in analysisName_):
            yMax = 400000;
            yMin = 100000;
        elif ("solitary" in analysisName_ and "slow" in analysisName_ and "NR50" in analysisName_ and "COLLECT" in analysisName_ ):
            yMax = 300000;
            yMin = 0;
        elif ("solitary" in analysisName_ and "slow" in analysisName_ and "NR50" in analysisName_ and "PERFORM" in analysisName_ ):
            yMax = 300000;
            yMin = 50000;


        elif ("localBroadcaster" in analysisName_ and "fast" in analysisName_ and "NR10" in analysisName_):
            yMax = 400000;
            yMin = 100000;
        elif ("localBroadcaster" in analysisName_ and "fast" in analysisName_ and "NR25" in analysisName_ and "COLLECT" in analysisName_ ):
            yMax = 200000;
            yMin = 40000;
        elif ("localBroadcaster" in analysisName_ and "fast" in analysisName_ and "NR25" in analysisName_ and "PERFORM" in analysisName_ ):
            yMax = 200000;
            yMin = 80000;
        elif ("localBroadcaster" in analysisName_ and "fast" in analysisName_ and "NR50" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 140000;
            yMin = 20000;
        elif ("localBroadcaster" in analysisName_ and "fast" in analysisName_ and "NR50" in analysisName_ and "PERFORM" in analysisName_):
            yMax = 140000;
            yMin = 80000;
        elif ("localBroadcaster" in analysisName_ and "slow" in analysisName_ and "NR10" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 700000;
            yMin = 100000;
        elif ("localBroadcaster" in analysisName_ and "slow" in analysisName_ and "NR10" in analysisName_ and "PERFORM" in analysisName_):
            yMax = 650000;
            yMin = 250000;
        elif ("localBroadcaster" in analysisName_ and "slow" in analysisName_ and "NR25" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 400000;
            yMin = 50000;
        elif ("localBroadcaster" in analysisName_ and "slow" in analysisName_ and "NR25" in analysisName_ and "PERFORM" in analysisName_):
            yMax = 400000;
            yMin = 100000;
        elif ("localBroadcaster" in analysisName_ and "slow" in analysisName_ and "NR50" in analysisName_ ):
            yMax = 300000;
            yMin = 0;


        elif ("beeRecruiter" in analysisName_ and "fast" in analysisName_ and "NR10" in analysisName_):
            yMax = 350000;
            yMin = 150000;
        elif ("beeRecruiter" in analysisName_ and "fast" in analysisName_ and "NR25" in analysisName_ ):
            yMax = 200000;
            yMin = 100000;
        elif ("beeRecruiter" in analysisName_ and "fast" in analysisName_ and "NR50" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 140000;
            yMin = 50000;
        elif ("beeRecruiter" in analysisName_ and "fast" in analysisName_ and "NR50" in analysisName_ and "PERFORM" in analysisName_):
            yMax = 140000;
            yMin = 80000;
        elif ("beeRecruiter" in analysisName_ and "slow" in analysisName_ and "NR10" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 700000;
            yMin = 0;
        elif ("beeRecruiter" in analysisName_ and "slow" in analysisName_ and "NR10" in analysisName_ and "PERFORM" in analysisName_):
            yMax = 650000;
            yMin = 300000;
        elif ("beeRecruiter" in analysisName_ and "slow" in analysisName_ and "NR25" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 400000;
            yMin = 50000;
        elif ("beeRecruiter" in analysisName_ and "slow" in analysisName_ and "NR25" in analysisName_ and "PERFORM" in analysisName_):
            yMax = 400000;
            yMin = 200000;
        elif ("beeRecruiter" in analysisName_ and "slow" in analysisName_ and "NR50" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 300000;
            yMin = 0;
        elif ("beeRecruiter" in analysisName_ and "slow" in analysisName_ and "NR50" in analysisName_ and "PERFORM" in analysisName_):
            yMax = 300000;
            yMin = 150000;

    return(yMin, yMax);

def getYmaxYmin_forCO(folder_, analysisName_):
    import crGraphs;
    yMax =  crGraphs.INVALID_VALUE;
    yMin = 0;
    if ("A_" in folder_ or "basic/" in folder_ or "staticCollect/" in folder_):
        if ("NR10" in analysisName_):
            yMax = 150000;

        elif ("NR25" in analysisName_):
            yMax = 40000;
        elif ("NR50" in analysisName_):
            if ("PERFORM" in analysisName_):
                yMax = 20000;
            else:
                yMax = 40000;

    if ("solitary" in analysisName_ or "localBroadcaster" in analysisName_ or "beeRecruiter" in analysisName_):
        yMax = crGraphs.INVALID_VALUE;

    if ("C_" in folder_ or "dynamic/" in folder_):
        if ("C_fast" in folder_):
            if ("NR10" in analysisName_):
                yMax = 80000;
            elif ("NR25" in analysisName_):
                yMax = 45000;
            elif ("NR50" in analysisName_):
                yMax = 35000;
        elif ("C_slow" in folder_):
            if ("NR10" in analysisName_):
                yMax = 160000;
            elif ("NR25" in analysisName_):
                yMax = 100000;
            elif ("NR50" in analysisName_):
                yMax = 80000;

        if ("localBroadcaster" in analysisName_ and "NR10" in analysisName_):
            yMax = 160000;
        elif ("localBroadcaster" in analysisName_ and "NR25" in analysisName_):
            yMax = 100000;
        elif ("localBroadcaster" in analysisName_ and "NR50" in analysisName_):
            yMax = 80000;
        elif ("beeRecruiter" in analysisName_ and "NR10" in analysisName_ and "PERFORM" in analysisName_):
            yMax = 7000;
        elif ("beeRecruiter" in analysisName_ and "NR25" in analysisName_ and "PERFORM" in analysisName_):
            yMax = 15000;
        elif ("beeRecruiter" in analysisName_ and "NR50" in analysisName_ and "PERFORM" in analysisName_):
            yMax = 20000;
        elif ("beeRecruiter" in analysisName_ and "NR10" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 50000;
        elif ("beeRecruiter" in analysisName_ and "NR25" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 45000;
        elif ("beeRecruiter" in analysisName_ and "NR50" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 45000;
        elif ("solitary" in analysisName_ and "NR10" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 14000;
        elif ("solitary" in analysisName_ and "NR25" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 10000;
        elif ("solitary" in analysisName_ and "NR50" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 7000;
        elif ("solitary" in analysisName_ and "PERFORM" in analysisName_):
            yMax = crGraphs.INVALID_VALUE;



    if ("Crel_" in folder_ or "dynamicRelU" in folder_):
        if ("solitary" in analysisName_ and "NR10" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 14000;
        elif ("solitary" in analysisName_ and "NR25" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 10000;
        elif ("solitary" in analysisName_ and "NR50" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 8000;

        elif ("localBroadcaster" in analysisName_ and "fast" in analysisName_ and "NR10" in analysisName_):
            yMax = 80000;
        elif ("localBroadcaster" in analysisName_ and "fast" in analysisName_):
            yMax = 50000;
        elif ("localBroadcaster" in analysisName_ and "slow" in analysisName_ and "NR10" in analysisName_  and "PERFORM" in analysisName_):
            yMax = 160000;
        elif ("localBroadcaster" in analysisName_ and "slow" in analysisName_ and "NR10" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 140000;
        elif ("localBroadcaster" in analysisName_ and "slow" in analysisName_ and "NR25" in analysisName_):
            yMax = 100000;
        elif ("localBroadcaster" in analysisName_ and "slow" in analysisName_ and "NR50" in analysisName_  and "PERFORM" in analysisName_):
            yMax = 80000;
        elif ("localBroadcaster" in analysisName_ and "slow" in analysisName_ and "NR50" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 60000;

        elif ("beeRecruiter" in analysisName_ and "fast" in analysisName_ and "NR25" in analysisName_ and "PERFORM" in analysisName_):
            yMax = 15000;
        elif ("beeRecruiter" in analysisName_ and "fast" in analysisName_ and "NR50" in analysisName_ and "PERFORM" in analysisName_):
            yMax = 25000;
        elif ("beeRecruiter" in analysisName_ and "fast" in analysisName_ and "PERFORM" in analysisName_):
            yMax = 8000;
        elif ("beeRecruiter" in analysisName_ and "fast" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 40000;
        elif ("beeRecruiter" in analysisName_ and "slow" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 50000;
        elif ("beeRecruiter" in analysisName_ and "slow" in analysisName_ and "NR25" in analysisName_ and "PERFORM" in analysisName_):
            yMax = 30000;
        elif ("beeRecruiter" in analysisName_ and "slow" in analysisName_ and "NR50" in analysisName_ and "PERFORM" in analysisName_):
            yMax = 45000;
        elif ("beeRecruiter" in analysisName_ and "slow" in analysisName_ and "PERFORM" in analysisName_):
            yMax = 10000;

    if ("Copp_" in folder_ or "dynamicOpp" in folder_):
        if ("beeRecruiter" in analysisName_ and "fast" in analysisName_ and "PERFORM" in analysisName_):
            yMax = 12000;
        elif ("beeRecruiter" in analysisName_ and "fast" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 40000;
        elif ("beeRecruiter" in analysisName_ and "slow" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 50000;
        elif ("beeRecruiter" in analysisName_ and "slow" in analysisName_ and "NR50" in analysisName_ and "PERFORM" in analysisName_):
            yMax = 35000;
        elif ("beeRecruiter" in analysisName_ and "slow" in analysisName_ and "PERFORM" in analysisName_):
            yMax = 10000;
        elif ("localBroadcaster" in analysisName_ and "fast" in analysisName_ and "NR10" in analysisName_):
            yMax = 80000;
        elif ("localBroadcaster" in analysisName_ and "fast" in analysisName_):
            yMax = 50000;
        elif ("localBroadcaster" in analysisName_ and "slow" in analysisName_ and "NR10" in analysisName_  and "PERFORM" in analysisName_):
            yMax = 160000;
        elif ("localBroadcaster" in analysisName_ and "slow" in analysisName_ and "NR10" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 140000;
        elif ("localBroadcaster" in analysisName_ and "slow" in analysisName_ and "NR25" in analysisName_):
            yMax = 100000;
        elif ("localBroadcaster" in analysisName_ and "slow" in analysisName_ and "NR50" in analysisName_  and "PERFORM" in analysisName_):
            yMax = 80000;
        elif ("localBroadcaster" in analysisName_ and "slow" in analysisName_ and "NR50" in analysisName_ and "COLLECT" in analysisName_):
            yMax = 60000;


    if (yMax != crGraphs.INVALID_VALUE):
        yMin = - yMax*0.05

    return (yMin, yMax);

def getYmaxYmin_forScoutingAbility(folder_, analysisName_, outputFilePrefix_):
    yMin = 0; # - getYTickStep_forScoutingAbility(folder_, analysisName_);
    import crGraphs;
    yMax =  crGraphs.INVALID_VALUE;

    if ("dynamicOpp" in folder_):
        if ("Scatter25" in analysisName_):
            if ("PERFORM" in analysisName_):
                if ("NR10" in analysisName_):
                    yMax = 0.2 * 3600;
                elif ("NR25" in analysisName_):
                    yMax = 0.1 * 3600;
                else:
                    yMax = 0.05 * 3600;
            else:
                if ("NR10" in analysisName_):
                    yMax = 0.15 * 3600;
                elif ("NR50" in analysisName_):
                    yMax = 0.05 * 3600;
                else:
                    if ("slow" in outputFilePrefix_):
                        yMax = 0.1 * 3600;
                    else:
                        yMax = 0.05 * 3600;

        yMin = -yMax * 0.05;

    elif ("dynamic" in folder_):
        if ("Heap1" in analysisName_):
            if ("slow" in outputFilePrefix_ and ("NR10" in analysisName_ or "NR25" in analysisName_)):
                yMax = 2*3600;
            else:
                yMax = 1*3600;

        elif ("Heap2" in analysisName_):
            if ("slow" in outputFilePrefix_ and ("NR10" in analysisName_)):
                yMax = 2*3600;
            else:
                yMax = 1*3600;

        elif ("Scatter25" in analysisName_):
            yMax = 0.25*3600;


        yMin = -yMax * 0.05;

    return (yMin, yMax);

def getYTickStep_forScoutingAbility(folder_, analysisName_):
    if ("Scatter25" in analysisName_):
        if ("Copp" in folder_ or "Crel" in folder_ or "dynamicOpp" in folder_ or "dynamicRelU" in folder_):
            return 180;
        else:
            return 900;
    if ("dynamic" in folder_):
        return 1800;

    else:
        return 3600;

def getScenariosBasedOnTypes(numOfRobots, taskTypes_ = [], scenarioTypes_ = [], distances_ = [], extraParameterString_ = "", scenarioExtraParamStrs_ = [], includeExtraParameterStringInGraphNames_ = False):
    print("get scenarios based on types " + str(taskTypes_) + " scs " + str(scenarioTypes_) + " xtraStrs" + str(extraParameterString_ + " scenario extraStrs = " + str(scenarioExtraParamStrs_) + " NR=" + str(numOfRobots)));
    scenarioLabels = [];
    scenarios = [];
    scenarioLabelsForGraph = [];


    counter = 0;
    for i in range(len(distances_)):
        scenarioLabels.extend(scenarioTypes_);

        for st in range(len(scenarioTypes_)):
            scType = scenarioTypes_[st];
            taskTypeIndex = counter%len(taskTypes_);

            if ('H1' in scType) or ("Heap1" in scType):
                scenarios.extend(["group1-" + str(distances_[i]+3)]);
            elif scType == 'H2' or scType == "Heap2":
                scenarios.extend(["group2-" + str(distances_[i]+3)]);
            elif scType == "HeapBig2":
                scenarios.extend(["groupBig2-" + str(distances_[i]+3)]);

            elif scType == 'H4' or scType == "Heap4":
                scenarios.extend(["group4-" + str(distances_[i]+3)]);
            elif scType == "HeapBig4":
                scenarios.extend(["groupBig4-" + str(distances_[i]+3)]);

            elif scType == 'S10' or scType == "Scatter10":
                scenarios.extend(["rand10-" + str(distances_[i]+3)]);
            elif scType == 'S25' or scType == "Scatter25":
                scenarios.extend(["rand25-" + str(distances_[i]+3)]);
            elif scType == 'SB25' or scType == "ScatterBig25":
                scenarios.extend(["randBig25-" + str(distances_[i]+3)]);
            elif scType == 'S100' or scType == "Scatter100":
                scenarios.extend(["rand100-" + str(distances_[i]+3)]);

            elif scType == 'H2w' or scType == 'Heap2w':
                scenarios.extend(["group2_05|15-" + str(distances_[i]+3)]);
            elif scType == 'H2s' or scType == 'Heap2s':
                scenarios.extend(["group2_01|19-" + str(distances_[i]+3)]);
            elif scType == 'H4s' or scType == 'Heap4s':
                scenarios.extend(["group4_05|15|01|19-" + str(distances_[i]+3)]);
            elif scType == 'H4w' or scType == 'Heap4w':
                scenarios.extend(["group4_05|05|05|25-" + str(distances_[i]+3)]);

            scenarioLabelsForGraph.append(scType + "-" + str(distances_[i]));

            scenarios[counter] = taskTypes_[taskTypeIndex] + "_" + scenarios[counter] + extraParameterString_;


            scenarioLabelsForGraph[counter] = getTaskShortName(taskTypes_[taskTypeIndex]) + "\n" + scenarioLabelsForGraph[counter];

            if (includeExtraParameterStringInGraphNames_):
                scenarioLabelsForGraph[counter] += "\n" + extraParameterString_;

            if (len(scenarioExtraParamStrs_) > 0):
                scenarios[counter] += scenarioExtraParamStrs_[st];
                scenarioLabelsForGraph[counter] += scenarioExtraParamStrs_[st];

            #-- replace placeholder strings
            if ("[C_fast]" in scenarios[counter] ):
                if (numOfRobots == 25):
                    replacementStr = "__DR1800";
                elif (numOfRobots == 50):
                    replacementStr = "__DR1350";
                elif (numOfRobots == 10):
                    replacementStr = "__DR3150";
                scenarios[counter] = scenarios[counter].replace("[C_fast]" , replacementStr);

            if ("[C_slow]" in scenarios[counter] ):
                replacementStr = "";
                if (numOfRobots == 25):
                    replacementStr = "__DR3600";
                elif (numOfRobots == 50):
                    replacementStr = "__DR2700";
                elif (numOfRobots == 10):
                    replacementStr = "__DR6300";
                scenarios[counter] = scenarios[counter].replace("[C_slow]" , replacementStr);
            counter += 1;

    return [scenarioLabels, scenarios, scenarioLabelsForGraph];

def getTaskShortName(taskType_):
    shortName = "";
    if ("PERFORM" in taskType_):
        shortName = "Perf.";
    elif ("COLLECT" in taskType_):
        shortName = "Forage";

    if ("1-1" in taskType_):
        shortName += "(1)";
    elif ("2-2" in taskType_):
        shortName += "(2)";
    elif ("5-5" in taskType_):
        shortName += "(5)";

    return shortName;

def getTaskInfo(scenarioNames_):

    taskUtilities = [];
    scenarioTypes = [];
    for sc in range(len(scenarioNames_)):
        if ('group2_01|19' in scenarioNames_[sc]):
            taskUtilities.append([1.9,0.1]);
            scenarioTypes.append("Heap2s");
        elif ('group2_05|15' in scenarioNames_[sc]):
            taskUtilities.append([1.5,0.5]);
            scenarioTypes.append("Heap2w")
        elif ('group4_05|15|01|19' in scenarioNames_[sc]):
            taskUtilities.append([0.5,1.5,0.1,1.9]);
            scenarioTypes.append("Heap4s");
        elif ('group4_05|05|05|25' in scenarioNames_[sc]):
            taskUtilities.append([0.5,0.5,0.5,2.5]);
            scenarioTypes.append("Heap4w");
        elif ('rand25' in scenarioNames_[sc]):
            taskUtilities.append([1.0 for i in range(25)]);
            scenarioTypes.append("Scatter25");
        elif ('randBig25' in scenarioNames_[sc]):
            taskUtilities.append([1.0 for i in range(25)]);
            scenarioTypes.append("ScatterB25");
        elif ('group1' in scenarioNames_[sc]):
            taskUtilities.append([1]);
            scenarioTypes.append("Heap1");
        elif ('group2' in scenarioNames_[sc]):
            taskUtilities.append([1.0 for i in range(4)]);
            scenarioTypes.append("Heap2");
        elif ('group4' in scenarioNames_[sc]):
            taskUtilities.append([1.0 for i in range(4)]);
            scenarioTypes.append("Heap4");
        elif ('groupBig4' in scenarioNames_[sc]):
            taskUtilities.append([1.0 for i in range(4)]);
            scenarioTypes.append("HeapB4");
        elif ('groupBig2' in scenarioNames_[sc]):
            taskUtilities.append([1.0 for i in range(4)]);
            scenarioTypes.append("HeapB2");

        #-- append scenario info after '-'
        scenarioTypes[sc] += scenarioNames_[sc][scenarioNames_[sc].index('-'):];


    return [taskUtilities, scenarioTypes];


def getColorByControllerName(controllerName_):
    if ('solitary' in controllerName_.lower()):
        return 'b';
    elif ('localbroadcaster' in controllerName_.lower()):
        return 'r';
    elif ('beerecruiter' in controllerName_.lower()):
        return 'g';

def getMarkerShapeByEnvironmentName(environmentName_):
    if ('heap1' in environmentName_.lower() or 'group1' in environmentName_.lower()):
        return 's';
    if ('heap2' in environmentName_.lower() or 'group2' in environmentName_.lower()):
        return '^';
    if ('heap4' in environmentName_.lower() or 'group4' in environmentName_.lower()):
        return 'd';
    if ('scatter25' in environmentName_.lower() or 'rand25' in environmentName_.lower()):
        return 'x';

def getMarkerColorByController(controllerName_):
    if ('localbroadcaster' in controllerName_.lower()):
        return 'r';
    if ('beerecruiter' in controllerName_.lower()):
        return 'g';
    if ('solitary' in controllerName_.lower()):
        return 'b';
    return 'k';




def getTaskVolumeByRunDataPrefix(runDataPrefix_):
    if ('heap1' in runDataPrefix_.lower()):
        return 48;
    if ('heap3' in runDataPrefix_.lower()):
        return 16;
    if ('scatter12' in runDataPrefix_.lower()):
        return 4;

def getTotalRewardByScenario(scenario_, NR_):
    scenario = scenario_.lower();

    if ('groupbig4' in scenario):
        return 400;
    elif ('groupbig2' in scenario):
        return 200;
    elif ('dr' in scenario):
        maxTime = getMaxTimeByNR(NR_, "C")
        DR = getEnvironmentChangeInterval(scenario_)
        totalResource = 100* (maxTime/DR);
        #print("max time = {} DR  = {} res = {}".format(maxTime, DR, totalResource))
        return totalResource;
    else:
        return 100;

def getEnvironmentChangeInterval(scenario_):
    scenario = scenario_.lower();
    DR = 180;
    if ('dr360_' in scenario):
        DR=360;
    elif ('dr900_' in scenario):
        DR=900;
    elif ('dr1800_' in scenario):
        DR=1800;
    elif ('dr3600_' in scenario):
        DR=3600;
    elif ('dr7200_' in scenario):
        DR=7200;
    elif ('dr1350_' in scenario):
        DR=1350;
    elif ('dr2700_' in scenario):
        DR=2700;
    elif ('dr3150_' in scenario):
        DR=3150;
    elif ('dr6300_' in scenario):
        DR=6300;
    return DR;

def getTotalTaskValueByScenario(scenario_):
    if ('heap1' in scenario_.lower() or 'group1' in scenario_.lower()):
        return 1;
    if ('heap2' in scenario_.lower() or 'group2' in scenario_.lower()):
        return 2;
    if ('heap4' in scenario_.lower() or 'group4' in scenario_.lower()):
        return 4;
    if ('scatter25' in scenario_.lower() or 'rand25' in scenario_.lower()):
        return 25;

def getMinTaskValueByScenario(scenario_, completedTaskList_=[]):
    """
    (in current experiments) min value is always 1, unless all tasks are completed, in which case it's 0.
    """
    numOfWorksites = getNumOfWorksitesByScenario(scenario_);
    if (len(completedTaskList_) == numOfWorksites):
        return 0;
    else:
        return 1;


def getNumOfWorksitesByScenario(scenario_):
    if ('heap1' in scenario_.lower() or 'group1' in scenario_.lower()):
        return 1;
    if ('heap2' in scenario_.lower() or 'group2' in scenario_.lower()):
        return 2;
    if ('heap4' in scenario_.lower() or 'group4' in scenario_.lower()):
        return 4;
    if ('scatter25' in scenario_.lower() or 'rand25' in scenario_.lower()):
        return 25;
    raise Exception("!!! ERROR: unhlandled scenario in getNumOfWorksitesByScenario: " + str(scenario_));



def getArenaMinusBaseSizeByScenario(scenario_):
    distance = 0;
    if ('-8' in scenario_.lower()):
        distance = 8;
    elif ('-12' in scenario_.lower()):
        distance = 12;
    elif ('-16' in scenario_.lower()):
        distance = 16;
    elif ('-20' in scenario_.lower()):
        distance = 20;
    elif ('-24' in scenario_.lower()):
        distance = 24;
    else:
        raise Exception("!!! ERROR: unhlandled distance in getArenaSizeByScenario ");

            #total size                     #base size
    return math.pi * math.pow(distance,2) - math.pi * 9



def getNumOfRobotsFromListByScenario(numOfRobotsList_, scenarioIndex_):
    nrIndex = scenarioIndex_ % len(numOfRobotsList_)
    return numOfRobotsList_[nrIndex];





#======================================================================================================
#=============================== INFO EVENTS ANALYSIS DATA SPECIFIC ===================================
#======================================================================================================

def clearAllRobotToAbandonRecords(scenario_, currentTaskId, robotId, numOfTasks, tasksRobotsToAbandon, tasksSubscribedRobots, tasksSubscribedRobotsByRecruitment, tasksReachedRobots, tasksLadenRobots, tasksEarningRobots, robotsTaskSubscriptions, printEvents, allowOpportunism):
    for checkingTaskId in range(numOfTasks):

        if (robotId in tasksRobotsToAbandon[checkingTaskId]):
            if (printEvents):
                print("   robot {} still has reward from task {} , removing the 'to abandon' records ".format(robotId, checkingTaskId))
            tasksRobotsToAbandon[checkingTaskId].remove(robotId);

            if (currentTaskId != checkingTaskId):
                if (robotId in tasksSubscribedRobots[checkingTaskId]):
                    tasksSubscribedRobots[checkingTaskId].remove(robotId);
                if (robotId in tasksSubscribedRobotsByRecruitment[checkingTaskId]):
                    tasksSubscribedRobotsByRecruitment[checkingTaskId].remove(robotId);
                if (robotId in tasksReachedRobots[checkingTaskId]):
                    tasksReachedRobots[checkingTaskId].remove(robotId);
                if (checkingTaskId in robotsTaskSubscriptions[robotId]):
                    robotsTaskSubscriptions[robotId].remove(checkingTaskId);


                if (robotId in tasksLadenRobots[checkingTaskId]):
                    if (printEvents):
                        print("      also removing from laden robots")
                    tasksLadenRobots[checkingTaskId].remove(robotId);

                if ("PERFORM" in scenario_):
                    removeElementFromArray(robotId, tasksEarningRobots[checkingTaskId], "    also removing from earning robots", printEvents )



def clearRobotToAbandonRecordsForTask(robotId, taskId, tasksRobotsToAbandon, tasksSubscribedRobots, tasksSubscribedRobotsByRecruitment, tasksReachedRobots, robotsTaskSubscriptions):
    if (robotId in tasksRobotsToAbandon[taskId]):
        tasksRobotsToAbandon[taskId].remove(robotId);
        if (robotId in tasksSubscribedRobots[taskId]):
            tasksSubscribedRobots[taskId].remove(robotId);
        if (robotId in tasksSubscribedRobotsByRecruitment[taskId]):
            tasksSubscribedRobotsByRecruitment[taskId].remove(robotId);
        if (robotId in tasksReachedRobots[taskId]):
            tasksReachedRobots[taskId].remove(robotId);
        if (taskId in robotsTaskSubscriptions[robotId]):
            robotsTaskSubscriptions[robotId].remove(taskId);





def handleTaskValueNotRecorded(robotId, numOfTasks, taskId, runNo, eventType, tasksSubscribedRobots, tasksReachedRobots, tasksLadenRobots, tasksSubscribedRobotsOldRecords):
    """
    Attempts to find a task id for an info event, if a task has not been recorded yet. Specific event types allow this based on previous records.
    :return: task Id, if the logic allows it. Otherwise throws an error.
    """
    if (eventType == "TASK_ABANDONED" or eventType == "TASK_MISSING"):
        print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! {} RUN {} t {} robotId {} ".format(eventType, runNo, t, robotId))
        print(tasksSubscribedRobots)
        print(tasksReachedRobots)
        print(tasksLadenRobots)
        for existingTaskId in range(numOfTasks):
            if (robotId in tasksSubscribedRobots[existingTaskId]):
                print("      change task id {} to {} ".format(taskId, existingTaskId))
                return existingTaskId;
            if (robotId in tasksSubscribedRobotsOldRecords[existingTaskId]):
                print("      change task id {} to {} ".format(taskId, existingTaskId))
                return existingTaskId;

    elif (eventType == "REWARD_STARTED" or eventType == "REWARD_FINISHED"):
        print("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" + eventType)
        for existingTaskId in range(numOfTasks):
            if (robotId in tasksLadenRobots[existingTaskId]):
                print("      change task id {} to {} ".format(taskId, existingTaskId))
                return existingTaskId;
            if (robotId in tasksSubscribedRobotsOldRecords[existingTaskId]):
                print("      change task id {} to {} ".format(taskId, existingTaskId))
                return existingTaskId;
    else:
        raise ValueError(" Task value not recorded yet for task id " + str(taskId) + " Run" + str(runNo) + " t=" + str(t) + " event=" + eventType)


def cleanupRecordsAfterSubscription(taskId, robotId,  tasksSubscribedRobots, tasksSubscribedRobotsByRecruitment, tasksReachedRobots, tasksLadenRobots, tasksEarningRobots, robotsTaskSubscriptions, printTaskInfo, allowOpportunism):
    for checkingTaskId in robotsTaskSubscriptions[robotId]:
        #print("checking {} robot {} ".format(checkingTaskId, robotId))
        if (checkingTaskId != taskId):
            debugMessage = "  automaticaly remove previous subscribed robot id {} from task {}".format(robotId, checkingTaskId)
            removeElementFromArray(robotId, tasksSubscribedRobots[checkingTaskId], debugMessage, printTaskInfo);
            removeElementFromArray(robotId, tasksSubscribedRobotsByRecruitment[checkingTaskId], debugMessage, printTaskInfo);
            debugMessage = "  ! automaticaly remove previous reached robot id {} from task {}".format(robotId, checkingTaskId)
            removeElementFromArray(robotId, tasksReachedRobots[checkingTaskId], debugMessage, printTaskInfo);

            #if (not allowOpportunism):
            debugMessage = "  !! automaticaly remove previous laden robot id {} from task {}".format(robotId, checkingTaskId)
            removeElementFromArray(robotId, tasksLadenRobots[checkingTaskId], debugMessage, printTaskInfo);
            debugMessage = "  !!!! automaticaly remove previous earning robot id {} from task {}".format(robotId, checkingTaskId)
            removeElementFromArray(robotId, tasksEarningRobots[checkingTaskId], debugMessage, printTaskInfo);

    robotsTaskSubscriptions[robotId] = [];
    addUniqueElementToArray(taskId, robotsTaskSubscriptions[robotId]);




