#include "Stepmstr.h"
#include "Stepper.h"

// global Stepmaster:
Stepmaster gStepmaster;


Stepmaster::Stepmaster()			// constructor
{
	itsListHead = itsListTail = 0;
	itsCurIdx = 0;
}

Stepmaster::~Stepmaster()			// destructor
{
	// destroy all attached Steppers before we die
	
	StepperNode *nextNode, *curNode;
	for (curNode = itsListHead; curNode; curNode = nextNode) {
		nextNode = curNode->itsNext;
		delete curNode;
	}

	// now we can die peacefully
}


void Stepmaster::Attach( Stepper& pStepper)
{
	// first, if the Stepper is already attached to another Stepmaster,
	// then remove it
	if (pStepper.itsMaster) pStepper.itsMaster->Remove( pStepper );
	
	// now add the given stepper to the tail of the list
	StepperNode *node = new StepperNode( itsListTail, pStepper );
	itsListTail = node;
	if (!itsListHead) itsListHead = node;
	
	// and set its pointer to point to us
	pStepper.itsMaster = this;
}

void Stepmaster::StepAll( const real dt )
{
	// call the Step(dt) method for all attached Steppers
	
	for (StepperNode *node=itsListHead; node; node = node->itsNext) {
		node->itsStepper->Step(dt);
	}

	// now update itsCurIdx
	itsCurIdx = !itsCurIdx;
}

void Stepmaster::Remove( Stepper& pStepper )
{
	// the given Stepper is either dying or attaching to another master
	// so remove it from our list, and update its pointer
	
	StepperNode *curNode, *lastNode=0;
	for (curNode = itsListHead; curNode;
				lastNode = curNode, curNode = curNode->itsNext) {
		if ( curNode->itsStepper == &pStepper ) {
			// found it!  now remove it from the list
			if (lastNode) lastNode->itsNext = curNode->itsNext;
			if (curNode==itsListHead) itsListHead = curNode->itsNext;
			if (curNode==itsListTail) itsListTail = lastNode;
			delete curNode;
			pStepper.itsMaster = 0;
			return;
		}
	}
	
	// if we get to this point, it means we didn't find the given Stepper
	// this should never happen -- if you want to throw an exception,
	// do it here
}

