bool
MSTLLogicControl::WAUTSwitchProcedure::isPosAtGSP(SUMOTime currentTime, const MSTrafficLightLogic& logic) {
    SUMOTime gspTime = TIME2STEPS(getGSPValue(logic)) % logic.getDefaultCycleTime();
    SUMOTime programTime = logic.getOffsetFromIndex(logic.getCurrentPhaseIndex())
                           + (logic.getCurrentPhaseDef().duration - (logic.getNextSwitchTime() - currentTime));
    return gspTime == programTime;
}
GUIGLObjectPopupMenu*
GUITrafficLightLogicWrapper::getPopUpMenu(GUIMainWindow& app,
        GUISUMOAbstractView& parent) {
    myApp = &app;
    GUIGLObjectPopupMenu* ret = new GUITrafficLightLogicWrapperPopupMenu(app, parent, *this);
    buildPopupHeader(ret, app);
    buildCenterPopupEntry(ret);
    //
    const MSTLLogicControl::TLSLogicVariants& vars = myTLLogicControl.get(myTLLogic.getID());
    std::vector<MSTrafficLightLogic*> logics = vars.getAllLogics();
    if (logics.size() > 1) {
        std::vector<MSTrafficLightLogic*>::const_iterator i;
        size_t index = 0;
        for (i = logics.begin(); i != logics.end(); ++i, ++index) {
            if (!vars.isActive(*i)) {
                new FXMenuCommand(ret, ("Switch to '" + (*i)->getProgramID() + "'").c_str(),
                                  GUIIconSubSys::getIcon(ICON_FLAG_MINUS), ret, (FXSelector)(MID_SWITCH + index));
            }
        }
        new FXMenuSeparator(ret);
    }
    new FXMenuCommand(ret, "Switch off", GUIIconSubSys::getIcon(ICON_FLAG_MINUS), ret, MID_SWITCH_OFF);
    new FXMenuCommand(ret, "Track Phases", 0, ret, MID_TRACKPHASES);
    new FXMenuCommand(ret, "Show Phases", 0, ret, MID_SHOWPHASES);
    new FXMenuSeparator(ret);
    MSTrafficLightLogic* tll = myTLLogicControl.getActive(myTLLogic.getID());
    buildNameCopyPopupEntry(ret);
    buildSelectionPopupEntry(ret);
    new FXMenuCommand(ret, ("phase: " + toString(tll->getCurrentPhaseIndex())).c_str(), 0, 0, 0);
    new FXMenuSeparator(ret);
    buildPositionCopyEntry(ret, false);
    return ret;
}
// ===========================================================================
// method definitions
// ===========================================================================
bool
TraCIServerAPI_TLS::processGet(TraCIServer& server, tcpip::Storage& inputStorage,
                               tcpip::Storage& outputStorage) {
    // variable & id
    int variable = inputStorage.readUnsignedByte();
    std::string id = inputStorage.readString();
    // check variable
    if (variable != ID_LIST && variable != TL_RED_YELLOW_GREEN_STATE && variable != TL_COMPLETE_DEFINITION_RYG
            && variable != TL_CONTROLLED_LANES && variable != TL_CONTROLLED_LINKS
            && variable != TL_CURRENT_PHASE && variable != TL_CURRENT_PROGRAM
            && variable != TL_NEXT_SWITCH && variable != TL_PHASE_DURATION && variable != ID_COUNT) {
        server.writeStatusCmd(CMD_GET_TL_VARIABLE, RTYPE_ERR, "Get TLS Variable: unsupported variable specified", outputStorage);
        return false;
    }
    // begin response building
    tcpip::Storage tempMsg;
    //  response-code, variableID, objectID
    tempMsg.writeUnsignedByte(RESPONSE_GET_TL_VARIABLE);
    tempMsg.writeUnsignedByte(variable);
    tempMsg.writeString(id);
    if (variable == ID_LIST) {
        std::vector<std::string> ids = MSNet::getInstance()->getTLSControl().getAllTLIds();
        tempMsg.writeUnsignedByte(TYPE_STRINGLIST);
        tempMsg.writeStringList(ids);
    } else if (variable == ID_COUNT) {
        std::vector<std::string> ids = MSNet::getInstance()->getTLSControl().getAllTLIds();
        tempMsg.writeUnsignedByte(TYPE_INTEGER);
        tempMsg.writeInt((int) ids.size());
    } else {
        if (!MSNet::getInstance()->getTLSControl().knows(id)) {
            server.writeStatusCmd(CMD_GET_TL_VARIABLE, RTYPE_ERR, "Traffic light '" + id + "' is not known", outputStorage);
            return false;
        }
        MSTLLogicControl::TLSLogicVariants& vars = MSNet::getInstance()->getTLSControl().get(id);
        switch (variable) {
            case ID_LIST:
                break;
            case TL_RED_YELLOW_GREEN_STATE: {
                tempMsg.writeUnsignedByte(TYPE_STRING);
                std::string state = vars.getActive()->getCurrentPhaseDef().getState();
                tempMsg.writeString(state);
            }
            break;
            case TL_COMPLETE_DEFINITION_RYG: {
                std::vector<MSTrafficLightLogic*> logics = vars.getAllLogics();
                tempMsg.writeUnsignedByte(TYPE_COMPOUND);
                tcpip::Storage tempContent;
                unsigned int cnt = 0;
                tempContent.writeUnsignedByte(TYPE_INTEGER);
                tempContent.writeInt((int) logics.size());
                ++cnt;
                for (unsigned int i = 0; i < logics.size(); ++i) {
                    MSTrafficLightLogic* logic = logics[i];
                    tempContent.writeUnsignedByte(TYPE_STRING);
                    tempContent.writeString(logic->getProgramID());
                    ++cnt;
                    // type (always 0 by now)
                    tempContent.writeUnsignedByte(TYPE_INTEGER);
                    tempContent.writeInt(0);
                    ++cnt;
                    // subparameter (always 0 by now)
                    tempContent.writeUnsignedByte(TYPE_COMPOUND);
                    tempContent.writeInt(0);
                    ++cnt;
                    // (current) phase index
                    tempContent.writeUnsignedByte(TYPE_INTEGER);
                    tempContent.writeInt((int) logic->getCurrentPhaseIndex());
                    ++cnt;
                    // phase number
                    unsigned int phaseNo = logic->getPhaseNumber();
                    tempContent.writeUnsignedByte(TYPE_INTEGER);
                    tempContent.writeInt((int) phaseNo);
                    ++cnt;
                    for (unsigned int j = 0; j < phaseNo; ++j) {
                        MSPhaseDefinition phase = logic->getPhase(j);
                        tempContent.writeUnsignedByte(TYPE_INTEGER);
                        tempContent.writeInt(phase.duration);
                        ++cnt;
                        tempContent.writeUnsignedByte(TYPE_INTEGER);
                        tempContent.writeInt(phase.minDuration);
                        ++cnt; // not implemented
                        tempContent.writeUnsignedByte(TYPE_INTEGER);
                        tempContent.writeInt(phase.maxDuration);
                        ++cnt; // not implemented
                        const std::string& state = phase.getState();
                        //unsigned int linkNo = (unsigned int)(vars.getActive()->getLinks().size());
                        tempContent.writeUnsignedByte(TYPE_STRING);
                        tempContent.writeString(state);
                        ++cnt;
                    }
                }
                tempMsg.writeInt((int) cnt);
                tempMsg.writeStorage(tempContent);
            }
            break;
            case TL_CONTROLLED_LANES: {
                const MSTrafficLightLogic::LaneVectorVector& lanes = vars.getActive()->getLanes();
                tempMsg.writeUnsignedByte(TYPE_STRINGLIST);
                std::vector<std::string> laneIDs;
                for (MSTrafficLightLogic::LaneVectorVector::const_iterator i = lanes.begin(); i != lanes.end(); ++i) {
                    const MSTrafficLightLogic::LaneVector& llanes = (*i);
                    for (MSTrafficLightLogic::LaneVector::const_iterator j = llanes.begin(); j != llanes.end(); ++j) {
                        laneIDs.push_back((*j)->getID());
                    }
                }
                tempMsg.writeStringList(laneIDs);
            }
            break;
            case TL_CONTROLLED_LINKS: {
                const MSTrafficLightLogic::LaneVectorVector& lanes = vars.getActive()->getLanes();
                const MSTrafficLightLogic::LinkVectorVector& links = vars.getActive()->getLinks();
                //
                tempMsg.writeUnsignedByte(TYPE_COMPOUND);
                tcpip::Storage tempContent;
                unsigned int cnt = 0;
                tempContent.writeUnsignedByte(TYPE_INTEGER);
                unsigned int no = (unsigned int) lanes.size();
                tempContent.writeInt((int) no);
                for (unsigned int i = 0; i < no; ++i) {
                    const MSTrafficLightLogic::LaneVector& llanes = lanes[i];
                    const MSTrafficLightLogic::LinkVector& llinks = links[i];
                    // number of links controlled by this signal (signal i)
                    tempContent.writeUnsignedByte(TYPE_INTEGER);
                    unsigned int no2 = (unsigned int) llanes.size();
                    tempContent.writeInt((int) no2);
                    ++cnt;
                    for (unsigned int j = 0; j < no2; ++j) {
                        MSLink* link = llinks[j];
                        std::vector<std::string> def;
                        // incoming lane
                        def.push_back(llanes[j]->getID());
                        // approached non-internal lane (if any)
                        def.push_back(link->getLane() != 0 ? link->getLane()->getID() : "");
                        // approached "via", internal lane (if any)
#ifdef HAVE_INTERNAL_LANES
                        def.push_back(link->getViaLane() != 0 ? link->getViaLane()->getID() : "");
#else
                        def.push_back("");
#endif
                        tempContent.writeUnsignedByte(TYPE_STRINGLIST);
                        tempContent.writeStringList(def);
                        ++cnt;
                    }
                }
                tempMsg.writeInt((int) cnt);
                tempMsg.writeStorage(tempContent);
            }
            break;
            case TL_CURRENT_PHASE:
                tempMsg.writeUnsignedByte(TYPE_INTEGER);
                tempMsg.writeInt((int) vars.getActive()->getCurrentPhaseIndex());
                break;
            case TL_CURRENT_PROGRAM:
                tempMsg.writeUnsignedByte(TYPE_STRING);
                tempMsg.writeString(vars.getActive()->getProgramID());
                break;
            case TL_PHASE_DURATION:
                tempMsg.writeUnsignedByte(TYPE_INTEGER);
                tempMsg.writeInt((int) vars.getActive()->getCurrentPhaseDef().duration);
                break;
            case TL_NEXT_SWITCH:
                tempMsg.writeUnsignedByte(TYPE_INTEGER);
                tempMsg.writeInt((int) vars.getActive()->getNextSwitchTime());
                break;
            case TL_CONTROLLED_JUNCTIONS: {
            }
            break;
            default:
                break;
        }
    }
    server.writeStatusCmd(CMD_GET_TL_VARIABLE, RTYPE_OK, "", outputStorage);
    server.writeResponseWithLength(outputStorage, tempMsg);
    return true;
}