//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
// 
// You should have received a copy of the GNU Lesser General Public License
// along with this program.  If not, see http://www.gnu.org/licenses/.
// 

#include <iostream>
#include "myroad.h"
#define debugEV_clear EV
#define debugEV EV << logName() << "::" << getClassName() << ": "
#include <omnetpp.h>

using namespace omnetpp;

Define_Module(Veins::myroad);



void Veins::myroad::initialize(int stage) {
    BaseWaveApplLayer::initialize(stage);
    if (stage == 0) {




        std :: cout <<"ampel    " <<this->myId << endl;
	
    }
    else if (stage == 1) {

            // initMsg = new cMessage("traffic light init",77);
             phaseMsg = new cMessage("phase msg",88);
            // scheduleAt(simTime()+0.1, initMsg);

    }
    debugEV << "????????????????????";
}

void Veins::myroad::onBSM(BasicSafetyMessage* bsm) {
    //Your application has received a beacon message from another car or RSU
    //code for handling the message goes here

    if (!messageReceived) {
               Coord cJunctionPosition;
               cJunctionPosition.x = 425;
               cJunctionPosition.y = 425;
               cJunctionPosition.z = 0;

        //Coord cJunctionPosition = mobility->getCommandInterface()->junction("2").getPosition();
        Coord cSenderPosition = bsm->getSenderPos();
        double distance = cJunctionPosition.distance(cSenderPosition);
        std :: cout << distance << endl;
        if(distance <= 300) {
            manager = TraCIScenarioManagerAccess().get();
                    traci = manager->getCommandInterface();
					                  
                    messageReceived = true;
                    scheduleAt(simTime() + 10, phaseMsg);    //set a timer to return the traffic light to program2 after 10 sec

           }

    }


}


void Veins::myroad::onWSM(WaveShortMessage* wsm) {





//    if (wsm->getSenderAddress() == 28){
//
//        // if ((curPosition-wsm->getSenderPos()).length() < 20) {
//                if (!phaseMsg->isScheduled()) {
//                    trafficLightId = "light1";
//                    traci->trafficlight(trafficLightId).setProgram("program1");
//                    //traci->trafficlight(trafficLightId).setPhaseIndex(0);
//                    scheduleAt(simTime()+5,phaseMsg);
//                }
//           // }
//    }
    //Your application has received a data message from another car or RSU
    //code for handling the message goes here, see TraciDemo11p.cc for examples
}

void Veins::myroad::onWSA(WaveServiceAdvertisment* wsa) {
    //Your application has received a service advertisement from another car or RSU
    //code for handling the message goes here, see TraciDemo11p.cc for examples
}

void Veins::myroad::handleSelfMsg(cMessage* msg) {
    BaseWaveApplLayer::handleSelfMsg(msg);
	//BasicSafetyMessage* bsm = dynamic_cast<BasicSafetyMessage *>(msg);
	//scheduleAt(simTime()+0.1, initMsg);
    //this method is for self messages (mostly timers)
    //it is important to call the BaseWaveApplLayer function for BSM and WSM transmission



	switch (msg->getKind())
	 {
	  case 88:
	   manager = TraCIScenarioManagerAccess().get();
	   traci = manager->getCommandInterface();
		trafficLightId = "light1";
		traci->trafficlight(trafficLightId).setProgram("program2");
		//traci->trafficlight(trafficLightId).setPhaseIndex(2);
	   break;
	//   case 88:
	//    traci->trafficlight(trafficLightId).setProgram("program2");
	//    //traci->trafficlight(trafficLightId).setPhaseIndex(2);
	//    break;
	  default:
	   assert(0);
	   break;
	 }
    
}
				



