/*
 *  fileios.h 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.
 */
#ifndef FILEIOS_DOT_H
#define FILEIOS_DOT_H
#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
#include "ObjProGen/stack.h"
struct ObjectsForFile ;

class LineOfstream : public ofstream {
public:
	enum HeaderOptions {None=0,NoCopyrightBit=4,HeaderOnceBit=2,
		Both=3,UserCopyrightBit=8};
private:
	HeaderOptions TheHeaderOptions ;
	enum LineOutStatus {StatusOutput,StatusSource} ;
	LineOutStatus OutStatus ;
	int Line ;
	const char * FileName ;
	const char * InputFileName ;
	const char * NodeName ;
	char * ConvertedFileName ;

	void CopyrightOut();
	void HeaderOnceOut();
	void HeaderOnceOutEnd();
public:
	LineOfstream(const char * FileName, const char * input_file_name=0,
		HeaderOptions=None) ;
	LineOfstream() ;
	LineOfstream(const LineOfstream &) {exit(224455);}
	virtual ~LineOfstream();
	void LineOut(int Line );
	const char * GetFileName() {return FileName;}
	LineOfstream& Put(int c);
	LineOfstream& Write(const char * ptr, int n);
};


class BaseStreamBuf : public streambuf {
public:
	enum OnOff{Off,On};
private:
	char * Buffer ;
	ObjectsForFile ** Objects ;
	int ObjectsSize ;
	void InitBuffer();
protected:
	OnOff FirstFileOut ;
	OnOff SecondFileOut ;
	const char * NodeName ;
	const char * InputFileName ;

	void DumpPointers(const char * Where);
	int Write();
public:
	BaseStreamBuf(const char * FirstName, const char * SecondName,
		const char * SourceFileName = 0,
		LineOfstream::HeaderOptions options=LineOfstream::None,
		const char * NodeName=0);
	BaseStreamBuf(ObjectsForFile ** Objects, const char * NodeName = 0,
		const char * SourceName = 0);
	BaseStreamBuf(const BaseStreamBuf &) {exit(224455);}
	virtual ~BaseStreamBuf();
	virtual int overflow(int c);
	OnOff first_file_out() {return FirstFileOut;}
	OnOff second_file_out() {return SecondFileOut;}
	virtual int underflow() ;
	void Flush() ;
	ostream& GetFirstFile() ; 
	ostream& GetSecondFile() ;
	void FirstSelect(OnOff on_off) ;
	void SecondSelect(OnOff on_off) ;
	ostream& GetFile(int i) ;
	void LineOut(int Line) ;
};

struct ObjectsForFile {
	const char * FileName ;
	const char * NodeName ;
	LineOfstream * TheFile ;
	ObjectsForFile(const char * file, const char * nod,
		const char * input_file_name,
		LineOfstream::HeaderOptions options);
};

class MofStream: public ostream {
public:
	MofStream& flush() ;
private:
	Stack FirstOnOffStack ;
	Stack SecondOnOffStack ;
	BaseStreamBuf * base_stream ;
public:
	MofStream(const char * FirstName, const char * SecondName=0,
		const char * SourceFileName = 0,
		LineOfstream::HeaderOptions opts = LineOfstream::None,
		const char * node_name = 0);
	MofStream(ObjectsForFile ** Objects, const char * node_name = 0,
		const char * SourceFileName = 0);
	MofStream(const MofStream&) {exit(224455);}
	virtual ~MofStream();

	void FirstFileSelect(BaseStreamBuf::OnOff on_off)
		{flush(); base_stream->FirstSelect(on_off);}
	void SecondFileSelect(BaseStreamBuf::OnOff on_off)
		{flush(); base_stream->SecondSelect(on_off);}

	void PushFirstFileSelect(BaseStreamBuf::OnOff on_off);
	void PopFirstFileSelect();
	void PushSecondFileSelect(BaseStreamBuf::OnOff on_off);
	void PopSecondFileSelect();
	void LineOut(int Line = -1);
};


#endif /* #ifdef FILEIOS_DOT_H */
