/*
 *  repack.C from ObjectProDSP 0.1
 *  Copyright (C) 1994, Mountain Math Software. All rights reserved.
 *  
 *  This file is part of ObjectProDSP, a tool for Digital Signal
 *  Processing design, development and implementation. It is free
 *  software provided you use and distribute it under the terms of
 *  version 2 of the GNU General Public License as published
 *  by the Free Software Foundation. You may NOT distribute it or
 *  works derived from it or code that it generates under ANY
 *  OTHER terms.  In particular NONE of the ObjectProDSP system is
 *  licensed for use under the GNU General Public LIBRARY License.
 *  Mountain Math Software plans to offer a commercial version of
 *  ObjectProDSP for a fee. That version will allow redistribution
 *  of generated code under standard commercial terms.
 *  
 *  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 General Public License for more details.
 *  
 *  You should have received a copy of version 2 of the GNU General
 *  Public License along with this program. See file COPYING. If not
 *  or if you wish information on commercial versions and licensing
 *  write Mountain Math Software, P. O. Box 2124, Saratoga, CA 95070,
 *  USA, or send us e-mail at: support@mtnmath.com.
 *  
 *  You may also obtain the GNU General Public License by writing the
 *  Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
 *  USA.  However if you received a copy of this program without the
 *  file COPYING or without a copyright notice attached to all text
 *  files, libraries and executables please inform Mountain Math Software.
 *  
 *  ObjectProDSP is a trademark of Mountain Math Software.
 */
#include <complex.h>
#include <signal.h>
#include "ObjProDSP/portable.h"
#include "ObjProComGui/cgidbg.h"
#include "ObjProGen/gcd.h"
#include "ObjProGen/nbits.h"
#include "ObjProNet/dfnode.h"

#include "ObjProUsr/repack.h"
#include "ObjProGen/outtok.h"
#include "ObjProGui/intfc.h"
#include "ObjProGui/remmen.h"
#include "ObjProGui/user.h"
#include "ObjProGui/dynmnu.h"
#include "ObjProArith/typout.h"
#include "ObjProGui/array.h"
#include "ObjProGui/interinit.h"
#include "ObjProGen/stattyp.h"
static EntityList * RepackWordNodeList = 0 ;
static InteractiveEntity * IntEntRepackWord ;
void RepackWordNodesInit();
RepackWord::RepackWord (const char * Name, int16 OutputWordSize, int16 InputWordSize):
	ProcessNode(Name, 1, 1, 1, 0, 
	OutputWordSize / GreatestCommonDivisor(OutputWordSize , InputWordSize), 
	InputWordSize / GreatestCommonDivisor(OutputWordSize , InputWordSize), 0, 0, 0, 0, TimingTypeLinear, 
	(ArithType::ArithCapabilities)(ArithType::ArithInt32), (ArithType::ArithCapabilities)(ArithType::ArithInt32))
,
	OutputWordSize_1(OutputWordSize),
	InputWordSize_2(InputWordSize)
{
	if (!RepackWordNodeList) RepackWordNodesInit() ;
	RepackWordNodeList->Append(MakeDeclaredEntity(this, IntEntRepackWord)) ;
	InitArithType(TheArithType);
	NewMenuItem("RepackWord",GetName());
#line 43 "../repack.usr"
 
	MaskIn = 1 ;
	for (int i = 1 ; i < GetInputWordSize(); i++)
		MaskIn = (MaskIn << 1) | 1 ;
	BitsLeftInWord = 0 ;
#line 50 "../repack.C"
} // end constructor

RepackWord::~RepackWord()
{
	TheMenuServer->DeleteMenuItem("RepackWord",GetName());
	RepackWordNodeList->Delete(GetName()) ;
} // end destructor

int RepackWord::CheckSafeDelete()
{
	int Safe_Check_Return = DfNode::CheckSafeDelete();
	if (!Safe_Check_Return) return 0;
	return 1;
} // end check safe delete

RepackWord * RepackWordDef;

ErrCode RepackWord::DoNode(int32 k)
{
#line 63 "../repack.usr"
 
	WordsOut = GetIncrementOut(0) * GetEltSize() ;
	int32 Limit = k * WordsOut ;
	// TheLog << "RepackWord::Kernel Limit = " << Limit << "\n" ;
	for (int32 i = 0 ; i < Limit ; i++ )  WriteBinary(GetNextOutWord());
	return OK ;
#line 77 "../repack.C"
} // end kernel code

static UserEntity * MakeRepackWord(OutTokens& Out, EntityReq Request,
	InteractiveEntity& IntNode,
	ArithType::ArithCapabilities arith = (ArithType::ArithCapabilities) TheArithType) ;
int RepackWord::CppList(OutTokens& Out, CppListCmds Cmd)
{
	return IntEntRepackWord->CppList(Out,Cmd,this);
}

void RepackWord::Describe(OutTokens& Out, ListEntity Option)
{
	switch(Option) {
case ListSingleEntity:
		Out.NewLine();
		MakeRepackWord(Out,EntityReqDescribeFull,*IntEntRepackWord,TheArithType);
		Out.NewLine();
		Out.NextQuoteOut("OutputWordSize");
		Out.NextFillOut("(");
		Out.NextFillOut(TypeToString(GetOutputWordSize()));
		Out.NextFillOut(")");
		Out.NextFillOut("is the number of bits in the output");
		Out.NextFillOut("word.");
		Out.NextQuoteOut("InputWordSize");
		Out.NextFillOut("(");
		Out.NextFillOut(TypeToString(GetInputWordSize()));
		Out.NextFillOut(")");
		Out.NextFillOut("is the number of bits in the input");
		Out.NextFillOut("word.");
		Out.NewLine();
		break;
case ListEntityMembers:
		Out.NextOut(GetName());
		break;
case ListGlobalClasses:
case ListEntityClasses:
		break ;
case ListSetParameterValues:
		IntEntRepackWord->GetOneParameter("OutputWordSize")->
			IntP->CurrentValue = OutputWordSize_1;
		IntEntRepackWord->GetOneParameter("InputWordSize")->
			IntP->CurrentValue = InputWordSize_2;
		break;
	}
} // end  list entity switch

void RepackWordNodesInit()
{
	if (RepackWordNodeList)  return ;

	static StringParam RepackWordNameParam =
		{"RepackWord", MakeNewEntityName, 0, LegalEntityName};
	static IntParam RepackWordOutputWordSizeParam = {
		 1, 0, 0, -32767,  0,  32};
	static IntParam RepackWordInputWordSizeParam = {
		 8, 0, 0, -32767,  0,  32};

	static OneParameter RepackWordParArray[] = {
		{"Name", 0, "node name", 0, 0, &RepackWordNameParam},
		{"OutputWordSize", 0, 
			"size in bits of output word",
			&RepackWordOutputWordSizeParam},
		{"InputWordSize", 0, 
			"size in bits of input word",
			&RepackWordInputWordSizeParam},
		{0}
	};

	RepackWordNodeList = new EntityList;
	IntEntRepackWord = new InteractiveEntity("RepackWord", RepackWordNodeList,
		MakeRepackWord, InteractiveNode, "repack.h",
		0, "ProcessNode");
	IntEntRepackWord->SetParameters(new UserParameters(RepackWordParArray));
	TheNodes->Append(IntEntRepackWord);
} // end initalization

static UserEntity * MakeRepackWord(OutTokens& Out, EntityReq Request,
	InteractiveEntity& IntNode,
	ArithType::ArithCapabilities arith)
{
	switch(Request) {
case EntityReqDescribe:

case EntityReqDescribeFull:
		Out.NextQuoteOut("RepackWord");
		Out.NextFillOut("repacks a bit stream of words of");
		Out.NextQuoteOut("InputWordSize");
		Out.NextFillOut("bits");
		Out.NextFillOut("to a stream of");
		Out.NextQuoteOut("OutputWordSize");
		Out.NextFillOut("bits.");
		Out.NextFillOut("Both these values must be");
		Out.NextFillOut("less than or equal 32.");
		Out.NextFillOut("In both streams the least");
		Out.NextFillOut("significant bits occur first.");
		Out.NewLine();
		break;

case EntityReqCreate:
	{
		const char * Name = IntNode.GetStringParameterValue("Name");
		int16 OutputWordSize =
			IntNode.GetIntParameterValue("OutputWordSize");
		int16 InputWordSize =
			IntNode.GetIntParameterValue("InputWordSize");
		return new RepackWord(Name, OutputWordSize, InputWordSize);

	}
	}
	return 0;
}

static InitObj LocalInit(RepackWordNodesInit, "RepackWord", "ProcessNode");

