//
// 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 "DataGeneratorLayer.h"


Define_Module(DataGeneratorLayer);

/**
 * First we have to initialize the module from which we derived ours,
 * in this case BaseLayer.
 *
 * Then we have to intialize the gates and - if necessary - some own
 * variables.
 **/
void DataGeneratorLayer::initialize(int stage)
{

	BaseApplLayer::initialize(stage);

    if(stage==0){
    	sensingTime = par("sensingTime");
        delayTimer = new cMessage( "Delay timer data", SEND_DATA_TIMER);
    }

    else
    	if(stage==1)
    		scheduleAt(simTime() + sensingTime/2 + dblrand()*10, delayTimer);
}


void DataGeneratorLayer::handleSelfMsg(cMessage *msg) {
    switch( msg->getKind() ){

    case SEND_DATA_TIMER:
        sendData();
        delete msg;
        delayTimer = new cMessage( "Delay timer data", SEND_DATA_TIMER);
		scheduleAt(simTime() + sensingTime, delayTimer);

	break;
    default:
    	EV << "Unknown selfmessage! -> delete, kind: "<<msg->getKind() <<endl;
	delete msg;
    }
}


void DataGeneratorLayer::sendData()
{
	//TODO: Implementation for direct transmission tests. Please remove line 64 when finished
	switchHostState(HostState::ACTIVE);

    ApplPkt *pkt = new ApplPkt("DATA_MESSAGE", DATA_MESSAGE);
    pkt->setDestAddr(L3BS);
    // we use the host modules getIndex() as a appl address
    pkt->setSrcAddr( myApplAddr() );
    pkt->setBitLength(headerLength);

    pkt->setControlInfo( new NetwControlInfo(L3BS) );

    EV << "Sending DATA packet to the BS\n";
    sendDown( pkt );
}


void DataGeneratorLayer::finish()
{
    BaseApplLayer::finish();
	cancelAndDelete(delayTimer);
	delayTimer = NULL;
}

const int DataGeneratorLayer::myApplAddr() {
	return this->findHost()->getIndex();
}

void DataGeneratorLayer::handleHostState(const HostState& state)
{
	if(notAffectedByHostState)
		return;

	if(state.get() == HostState::FAILED)
	{
		cancelAndDelete(delayTimer);
		delayTimer = NULL;
	}
}




