#include <time.h>
#include <stream.h>
#include <fstream.h>
#include "hrdarth.h"
#include "arthfnc.h"
#include "ascfle.h"
#include "yacintfc.h"
#include "cgidbg.h"
#include "mkstr.h"
#include "noderep.h"

#ifdef INTERACTIVE
#include "tarparm.h"

DfNode * AsciiFile::target_replacement(const char * target)
{
	if (!strcmp(target,generic_cpp_name)) return 0 ;
	if (!strcmp(target,NodeReplacement::validate_compare_replace)) return 0 ;
	if (!strcmp(target,NodeReplacement::validate_output_replace)) return 0 ;
    return default_output_replacement(target);
}
#endif


void AsciiFile::Ctor()
{
	exp_file_name = delete_file_name = 0 ;
	TheFile = 0 ;
	HeaderOut = 0 ;	
	if (State.IsInteractive()) OpenFile();
}

void AsciiFile::Dtor()
{
	delete TheFile ;
	delete delete_file_name ;
	delete exp_file_name ;
}




void AsciiFile::OpenFile()
{
	const char * new_file_name = GetFileName() ;
	if (!new_file_name) new_file_name = GetName();
    const char * exp_name = TargetNode::create_file(
        &new_file_name,TheFile,"ascii output file",0);
    if (!exp_name) return ;
    delete exp_file_name ;
    exp_file_name = 0 ;
    if (exp_name != new_file_name) exp_file_name = Concatenate(exp_name);
    if (GetFileName() != new_file_name) {
        delete delete_file_name ;
		FileName_1 = delete_file_name = Concatenate(new_file_name);
    }
}

void AsciiFile::WriteHeader()
{
	if (!TheFile) OpenFile();
	if (!TheFile) return ;
	SampleSize = GetInEltSize();
	BlockSize = GetBlockSize() ;
	const char * arith_type = ArithTypeName ;
	if (integer_read_flag) arith_type = "integer" ;
	if (!GetNoHeader()) {
		long TheTime = time((long *) 0);

		*TheFile << "`" << GetFileName() << "' written by `" << GetName()
			<< "' on " ;
		*TheFile << ctime(&TheTime) ;
		*TheFile << "Data is type " << arith_type ;
		if (GetHex()) *TheFile << " written in hexadecimal format" ;
		*TheFile << ".\nSample size is " << SampleSize << "." ;
		if (BlockSize > 1) *TheFile << "BlockSize = " << BlockSize <<
			" samples." ;
		*TheFile << "\nData generated by `" <<
			GetDriverNode()->GetName() ;
#ifdef INTERACTIVE
		*TheFile << "' in network `" <<
			GetNetName()  << "'.\n" ;
#else
		*TheFile << "'.\n" ;
#endif
			
	}
	HeaderOut = 1 ;
	// TheLog << "Wrote header\n" ;
}

ErrCode AsciiFile::Kernel(int32 k)
{
	if (State.IsError()) return FatalError ;
/*
 *	TheLog << "AsciiFile::Kernel(" << k << "), HeaderOut = " << HeaderOut
 *		<< " \n" ;
 */
	if (!HeaderOut) {
		WriteHeader();
		if (!HeaderOut) return FatalError;
	}
	int block_group = (BlockSize > 1) && !GetNoGroup();
	int sample_group = (SampleSize > 1) && !GetNoGroup();
	int block_tail_out = 0 ;
	uint32 mask = 0xffffffff ;
	if (TheArithType == ArithType::ArithInt16) mask = 0xffff ;
	for (int32 i = 0 ; i < k ; i++) {
	  for (int32 b = 0 ; b < BlockSize ; b++) {
			int new_line_last = 0 ;
			if (!b && block_group) {
				*TheFile << "{" ;
				block_tail_out = 1 ;
			} else *TheFile << " " ;
			for (int32 j = 0 ; j < SampleSize ; j++) {
				new_line_last = 0 ;
				MachWordCast Temp ;
				IntegerMachWord IntTemp ;
				if (State.IsError()) return FatalError ;
			
				if (integer_read_flag) IntTemp = ReadInteger() ;
				else Temp = ReadWord();

				if (GetHex()) {
					int32 val ;
					if (integer_read_flag) val = IntTemp ;
					else val = MachWord::convert_int32_check(Temp) ;
					unsigned long v = val & mask ;
					*TheFile << "0x" << hex << v << dec ;
				} else {
					MachWordCast val ;
					if (integer_read_flag) val =
						MachWord::convert_MachWord_check(IntTemp) ;
					else val = Temp ;
					*TheFile << val ;
				}
				if (GetNoGroup() || ((j%20==19) && j != SampleSize-1 )) {
					*TheFile << "\n" ;
					new_line_last = 1 ;
				} else if (j < SampleSize-1) *TheFile << " " ;
			} // loop on j
			if (!new_line_last && (!block_tail_out || (b < BlockSize -1)))
				*TheFile << "\n" ;
		} // loop on b
		if (block_tail_out) *TheFile << "}\n" ;
	} // loop on k	
	return OK ;
}

