/*  plotdatd.c   */
/*  Copyright 1989 Mountain Math Software  */
/*  All Rights Reserved                    */
#include "hrdarth.h"
#include "portable.h"
#include "shared.h"
#include "remcom.h"
#include "slist.h"
#include "plotdatd.h"

#include "plotnd.h"


PlotController ThePlotController ;

AxisScalingX SingleChannelXDefaultAxis(PlotScaleAuto,0.0,0.0,
	LabelingLinear) ;
	
AxisScalingY SingleChannelYDefaultAxis(PlotScaleAuto,0.0,0.0,
	LabelingLinear) ;
	

// This is the only member of PlotDataHeader not defined in the
// common file plotdat.h - it needs to be different for Dsp and Gui
// because we have a devrived class in Gui that contains additional
// information for PlotChannel

/*
 * PlotChannel ** DataPlotHeader::InitPlotChannels()
 * {
 *		ThePlotChannels = new PlotChannel * [GetNumberOfChannels()] ;
 *		LogForm("InitPlotChannels channels = %d",GetNumberOfChannels());
 *		for (int i = 0; i < GetNumberOfChannels() ; i ++) {
 *			ThePlotChannels[i] = new PlotChannel ;
 *		((PlotChannelPointer *) ThePlotChannels[i])->SetIndex(i);
 *		((PlotChannelPointer *)
 *			ThePlotChannels[i])->SetPlot((DataPlot *) this);
 *		LogForm("Inited(%d) 0x%x to Plot 0x%x", i,
 *			(long) ThePlotChannels[i], (long) this);
 *		}
 *		return ThePlotChannels ; 
 * }
 */


class PlotNodeList: public SingleList {
public:
	ErrCode Insert(PlotNode *nt) {return SingleList::Insert(nt);}
	ErrCode Append(PlotNode *nt) {return SingleList::Append(nt);}
	ErrCode RemoveEntry(PlotNode *nt) {return SingleList::RemoveEntry(nt);}
	PlotNode * Get()   {return (PlotNode *) SingleList::Get();}
	PlotNode * Pop() {return (PlotNode *) SingleList::Pop();}
	PlotNode * GetNFromTop(int N) ;
	PlotNode * GetNthEntry(int N) ;
	PlotNodeList(){;}
	int Size(){return SingleList::Size();}
} ;

class PlotNodeListIterator: public SingleListIterator {
public:
	PlotNodeListIterator(PlotNodeList& df):
		SingleListIterator((SingleList&) df){}
	PlotNode * operator()()
		{return (PlotNode *) Next();}
};

PlotController::PlotController()
{
	WaitingPlotId = new PlotNodeList ;
	WaitingHeaderComplete = new PlotNodeList ;
}

PlotController::~PlotController()
{
	delete WaitingPlotId ;
	delete WaitingHeaderComplete ;
}

void PlotController::GetPlotId(class PlotNode * Requestor)
{
	// Send remote message to get plot Id
	PacketHeader Header = PlotPacketHeader(PacketWindowPlotControl,
		PlotGlobalCommand,PlotControlGetId);
	WriteSeg->WritePacket(Header) ;
	WaitingPlotId->Append(Requestor) ;
	WaitingHeaderComplete->Append(Requestor);
}

void PlotController::SetPlotId(int Id)
{
	PlotNode * ToSet = WaitingPlotId->Get();
	if (!ToSet) DbgError("PlotController", "no node");
	ToSet->SetPlotId(Id);
	// LogOut << "PlotId set to " << Id << "\n" ;
}

void PlotController::SendComplete(int Id)
{
	PlotNodeListIterator Next(*WaitingHeaderComplete);
	PlotNode * PltNd ;
	while (PltNd =Next()) {
		// LogForm("Checking Entry Id = %d",PltNd->GetPlotId());
		if (PltNd->GetPlotId() == Id) {
			PltNd->SendComplete();
			WaitingHeaderComplete->RemoveEntry(PltNd);
			return ;
		}
	}
	TheLog << "PlotController::SendComplete ","*****************No such plot\n";
}

void PlotController::PlotServer(PacketHeader& Head, const char * Data)
{
	int PlotId = Head.GetPlotId();
	int PlotChannel = Head.GetPlotChannel();
/*
 *	LogOut << "PlotController::PlotServer Id = " << PlotId <<
 *		", Channel = " << PlotChannel << "\n" ;
 */
	if (PlotId == PlotGlobalCommand && PlotChannel == PlotControlSendId)
	{
		if (Head.DataSize != sizeof(int16)) DbgError(
			"PlotController::PlotServer","bad size");
		int Temp = * (int16 *) Data ;
		// LogForm("Got PlotId = %d",Temp);
		SetPlotId(Temp);
	}  else if (PlotChannel == PlotControlComplete) {
		SendComplete(PlotId);
	} else DbgError("PlotController::PlotServer","bad control packet");
}

 

