/*  genpltcd.h   */
/*  Copyright 1989 Mountain Math Software  */
/*  All Rights Reserved                    */
#include <stream.h>

#include "ObjProDSPcom/genpltdef.h"
#include "ObjProComGui/plotdat.h"
#include "ObjProDSP/pltenm.h"
#include "ObjProArith/hrdcmp.h"
#include "ObjProUsr/gpltstr.h"

#include "ObjProArith/hrdarth.h"
#include "ObjProArith/hrdcmp.h"

#include "ObjProGui/sigintfc.h"
#include "ObjProGui/intfc.h"
#include "ObjProGui/user.h"
#include "ObjProGen/outtok.h"
#include "ObjProGui/plotdatd.h"

#include "ObjProShare/shared.h"
#include "ObjProGui/remcom.h"
#include "ObjProDSP/attrib.h"
#include "ObjProDSPint/netlnk.h"
#include "ObjProDSP/pltclr.h"

#include "ObjProUsr/genplot.h"
#include "ObjProGen/mkstr.h"


void GenericPlotStr::SendHeader()
{

/*
 *	LogOut << "In GenericPlotStr::SendHeader, PlotId = " << GetPlotId()
 *		<< "\n";
 */
 
	DataPlotHeader * PlotHead = new
		DataPlotHeader((int16) GetPlotId(),(int16) Channels,
		XScale,(PlottingStreamType)GetStreamType(),DataSpacingUniform);
	PlotHead->GetStructure();
	StrDataPlotHeader * StrPlotHead = PlotHead->GetStructure();
	PacketHeader Head = PlotPacketHeader(PacketWindowPlotControl,
		GetPlotId(),PlotControlHeader,sizeof(*StrPlotHead));
	WriteSeg->WritePacket(Head,(char *) StrPlotHead);
	delete StrPlotHead ;

	SetDataPlot(PlotHead);

	char * to_delete = 0 ;
	if (GetCaption()) PlotCaption = GetCaption();
	else {
		DfNode * driver_node = GetDriverNode();
		PlotCaption = to_delete = Concatenate(GetName(),"_plot_of_",
			driver_node->GetName());
	}
	if (PlotCaption) {
		Head = PlotPacketHeader(PacketWindowPlotControl, GetPlotId(),
			PlotControlCaption,1+strlen(PlotCaption));
		WriteSeg->WritePacket(Head,PlotCaption);

		PlotHead->SetCaption(PlotCaption);
	}
	delete to_delete ;

	Head = PlotPacketHeader(PacketWindowPlotControl,
		GetPlotId(),PlotControlName,1+strlen(GetName()));
	WriteSeg->WritePacket(Head,GetName());

	for (int i = 0 ; i < Channels ; i++) SendChannelHeader(i, PlotHead);

	Head = PlotPacketHeader(PacketWindowPlotControl,GetPlotId(),
		PlotControlComplete, 0);
	WriteSeg->WritePacket(Head,(char *) 0);
}

void GenericPlotStr::SendChannelHeader(int Channel,DataPlotHeader * PlotHead)
{
	int32 Numerator = 1;
	int32 Denominator = 1;
	double FirstTime = 0.0 ;
	double SampleRate = 1.0 ;
	double SampleRateFactor = 1.0 ;
	DfNodeInLink * In = GetInLink(Channel) ;
	if (!In) DbgError("GenericPlotStr::SendHeader", "no input");
	TimingDescription* Timing = In->GetTiming() ;
	const StreamStr * TheStream = GetInLink(0)->GetStreamStr();
	
	if (TheStream) {
		SampleRateFactor = TheStream->GetSampleRateFactor();
		// SampleRate = TheStream->GetSampleRate();
	}
	if (PlotHead->GetStreamType() == PlotPairs)
		SampleRateFactor = 0.0 ;
	// LogOut << "SampleRateFactor = " << SampleRateFactor << "\n" ;
	if (Timing) {
		Numerator = Timing->NumeratorSampling ;
		int Warn = 0 ;
		if (!Numerator) {
			Numerator =1 ;
			Warn=1 ;
		}
		Denominator = Timing->DenominatorSampling ;
		if (!Denominator) {
			Denominator =1 ;
			Warn |= 2 ;
		}
		if (Warn) {
			TheLog << "WARNING**** ZERO SAMPLING Warn = " << Warn
				<< "\n" ;
		
			TheLog << "From GenericPlotStr::SendChannelHeader for `"
				<< GetName() << "', input is `" <<
				In->GetDriverNodeName() << "'\n" ;
		}
		FirstTime = Timing->FirstSample ;
		SampleRate = Timing->GetSampleRate();
		// SampleRateFactor = Timing->GetSampleRateFactor();
		if (SampleRate == 0.0) SampleRate = 1.0 ;
/*
 *		LogOut << "GenericPlotStr::SendChannelHeader for `" <<
 *			GetName() << "'\n" ;
 *		LogOut << "Numerator = " << Numerator << ", Denominator = "
 *			<< Denominator << ", FirstTime = " << FirstTime <<
 *			"\n" ;
 *		LogOut << "SampleRate = " << SampleRate << "\n" ;
 */
	} else TheLog << 
		"GenericPlotStr::SendHeader No timing **********************\n";

	if (Numerator > 32767 || Denominator > 32767) DbgError(
		"GenericPlotStr::SendHeader","resampling factor too large");
/*
 *	LogOut << "Set the ArithType too " << TheArithType << " for " <<
 *		GetCaption() << "\n" ;
 */
			
	PlotChannel * PlotChan = new PlotChannel(YScale, Channel, ElementSize,
		Denominator, Numerator, (int16) TheArithType,
		GetDriverElementSize(Channel),
		GetBlockSize(Channel),SampleRate,FirstTime,SampleRateFactor) ;

/*
 *	LogOut << "Channel = " << Channel << ", GetDriverElementSize = " <<
 *		GetDriverElementSize(Channel) << "\n" ;
 */

	StrPlotChannel * StrPlotChan = &(PlotChan->GetStructure());

	PacketHeader Head = PlotPacketHeader(PacketWindowPlotControl,
		GetPlotId(), PlotControlChannel, sizeof(*StrPlotChan));

	WriteSeg->WritePacket(Head,(char *) StrPlotChan);
	
	PlotHead->SetPlotChannel(*StrPlotChan);
	delete StrPlotChan ;

	int ColorIndex = 0;
	for (int LineMax = 0; LineTypeTable[LineMax] > -1; LineMax++) ;
	int LineTypeIndex = Channel % LineMax ;
	MultiplexedElement * Element ;
	
	for (int EltIndex = 0 ; EltIndex < ElementSize; EltIndex++) {

		int LineColor = ColorTable[ColorIndex++];
		if (LineColor < 0) {
			LineTypeIndex++ ;
			ColorIndex = 0 ;
			LineColor = ColorTable[ColorIndex];
		}
		int LineType = LineTypeTable[LineTypeIndex];
		if (LineType < 0) {
			LineTypeIndex = 0;
			LineType = LineTypeTable[LineTypeIndex];
		}

		Element = new MultiplexedElement(
			DefaultScaleFactor,LineColor,LineType);

		StrMultiplexedElement * StrElement = &(Element->GetStructure());

		Head = PlotPacketHeader(PacketWindowPlotControl,GetPlotId(),
			PlotControlElement, sizeof(*StrElement));
		WriteSeg->WritePacket(Head,(char *) StrElement);

		PlotHead->SetMultiplexedElement(*StrElement);
		delete StrElement ;
	}

}
	
static AxisScalingX * LocSingleChannelXDefaultAxis = 0;
static AxisScalingY * LocSingleChannelYDefaultAxis = 0;


void GenericPlotStr::DynamicInit()
{
	// LogOut << "DynamicInit for `" << GetName() << "'\n" ;
	double maxY;
	double minY;
	const StreamStr* InStream = GetInLink(0)->GetStreamStr();
	ElementSize = InStream->GetElementSize();
	Channels=GetIn();
	if (!LocSingleChannelXDefaultAxis) {
		LocSingleChannelXDefaultAxis = new
			AxisScalingX(PlotScaleAuto,0.0,0.0, LabelingLinear) ;
		LocSingleChannelYDefaultAxis = new
			AxisScalingY(PlotScaleAuto,0.0,0.0,LabelingLinear) ;
	}
	XScale = *LocSingleChannelXDefaultAxis;
	YScale = *LocSingleChannelYDefaultAxis;
	if (GetCaption()) PlotCaption = GetCaption() ;
	else PlotCaption = GetName() ;
	if (GetMax() > GetMin()) {
		if (GetMax() >  MachWord::max_positive) maxY =  MachWord::max_positive ;
		else maxY = GetMax();
		if (GetMin() < MachWord::min_negative) minY = MachWord::min_negative ;
		else minY = GetMin();
		YScale.SetMaximum(maxY);
		YScale.SetMinimum(minY);
		if (GetScaleFlag()) YScale.SetScaleType(PlotScaleRangeAuto);
		else YScale.SetScaleType(PlotScaleFixed);
		// LogOut << "GetScaleFlag() = " << GetScaleFlag() << "\n" ;
		// LogOut << "maxY = " << maxY << ", minY = " << minY << "\n" ;
	}
	int32 BlockSize = InStream->GetBlockSize();
	// LogOut << "BlockSize = " << BlockSize << " " << GetName() << "\n" ;
	if (BlockSize < 1) {
		BlockSize = GetStreamIn()->GetBlockSize();
		// LogOut << "BlockSize = " << BlockSize << "\n" ;
	}
	
	double MaxX = InStream->GetMaximumX();
	double MinX = InStream->GetMinimumX();
	// LogOut<<"StreamIn GetMaximum = "<<MaxX << ", Min = "<<MinX<< ".\n";

	if (MaxX == MinX) if (MinX == 0.0) {
		MaxX = GetStreamIn()->GetMaximumX();
		MinX = GetStreamIn()->GetMinimumX();
	}
	if (MaxX <= MinX) {
		MaxX = GetMaximumX();
		MinX = GetMinimumX();
		// LogOut << "MaxX = " << MaxX << ", MinX = " << MinX << "\n" ;
	}
	if (MaxX <= MinX) {
		MaxX = GetBlockSize() ;
		MinX = 0.0 ;
	}
	if ((GetMinimumX() == 0.0) && (GetMaximumX() == 0.0) &&
		((BlockSize == 1) || !BlockSize) &&
		(GetNumberBlocks() == 1)) return ;
	if (BlockSize > 1) {
		XScale.SetSamplesPerPlot(BlockSize);
		// LogOut << "XScale.SetSamplesPerPlot(" << BlockSize << ")\n" ;
	} else if (GetXYSamplesPerPlot() > 3. )
		XScale.SetSamplesPerPlot( GetXYSamplesPerPlot());
	XScale.SetPlotsPerPage(GetNumberBlocks());
	XScale.SetMaximum(MaxX);
	XScale.SetMinimum(MinX);
	XScale.SetScaleType(PlotScaleFixed);
/*
 * 	LogOut << "SeamplesPerPlot = " << BlockSize << ", NumberBlocks = "
 *		<< GetNumberBlocks() << "\n" ;
 *	LogOut << "MaxX = " << MaxX << ", MinX = " <<
 *		MinX << ": PlotScaleFixed\n" ;
 */
}

