/*
 *  package.h from ObjectProDSP 0.2
 *  Copyright (C) 1994 1995, 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.
 */
/*  package.h   */
/*  Copyright 1989 Mountain Math Software  */
/*  All Rights Reserved                    */

#include <slist.h>


class HeaderFile ;
class DirNames ;
class OutTokens ;
class ostream ;
class istream ;
class GetBits ;

struct MakeableLib {
	const char * directory ;
	const char * name ;
	MakeableLib(const char *d, const char *n):directory(d),name(n){}
};

class MakeableLibList:public SingleList {
public:
    ErrCode Insert(MakeableLib * nt) {return SingleList::Insert((Entity)nt);}
    ErrCode Append(MakeableLib * nt) {return SingleList::Append((Entity)nt);}
    ErrCode Append(SingleList *lst)
        {return SingleList::Append((SingleList *)lst);}
    MakeableLib *  Get()  {return (MakeableLib * ) SingleList::Get();}
    MakeableLib *  Pop() {return (MakeableLib * ) SingleList::Pop();}
    MakeableLibList(){;}
    int Size() const {return SingleList::Size();}
} ;

class MakeableLibListIterator: public SingleListIterator {
public:
    MakeableLibListIterator(const MakeableLibList& df):
        SingleListIterator((SingleList&) df){}
    MakeableLib *  operator()()
        {return (MakeableLib * ) Next();}
};


class PackageDesc {
	int HTotal ;
	int dir_total ;
	int NumFlagWords ;
	int extra_directory_space ;
	int total_space ;
	HeaderFile ** AllHeaders ; 
	const char * Object ;
	const char * MenuFlag ;
	const char * NodDir ;
	int TotalNoCollect ;
	int TotalMenuNames ;
	int MenuMakeFileCreated ;
	int CollectLibFlag ;
	int RepeatLibraryCount ;
	int NoExecutable ;
	int UpLibraryName ;
	int dbXtraFlag ;
	int CreateSourceDirList ;
	int ArithFlag ;
	int use_ranlib ;
	int do_list_files ;
	int the_user_copyright ;
	const char * the_root_directory ;
	const char * the_bin_directory ;
	const char * the_script_dir ;
	const char * the_script_directory ;
	const char * the_system_suffix ;
	const char * include_all_file ;
	const char * include_main_file ;
	MakeableLibList the_makeable_libs;
	MakeableLibList the_moveable_libs;

	void CheckLibDirsAreCDirs();
	void BadLibraryDirectory(const char *Dir);
public:
	DirNames * CDirs ;
	DirNames * HDirs ;
	DirNames * UsrDirs ;	// user objects to create c and h files
	const char ** NoCollNames ;
	const char ** MenuNames ;

	const char ** LibList ;
	const char ** LibSearchList ;
	const char ** LibDirList ;
	const char ** the_makemake_depends ;
	const char *** MakeDirList ;
	const char ** LibUpDirList ;
	const char *** LibCollDirList ;
	const char ** NoSourceNoWarnList ;

	int IsdbXtra() {return dbXtraFlag;}
	int IsCreateSourceDirList() const {return CreateSourceDirList;}
	

	PackageDesc(int cfiles, int hfiles, int usrfiles, int NoCollFls,
		int MenuFiles, const char * flag, const char * dir) ;
	int IsCollectLibrarys() const {return CollectLibFlag;}
	void SetUpLibraryName() {UpLibraryName =1 ;}
	int IsUpLibraryName() const {return UpLibraryName;}
	int HowManyLibraryRepeats() {return RepeatLibraryCount;}
	void CollectLibrarys() {CollectLibFlag=1;}
	void RepeatLibrarys(int Count) {RepeatLibraryCount = Count;}
	void Display();
	void FindFiles() ;
	void MakeHeaderTable();
	void SortHeaderTable();
	void GetDependencies();
	int GetIndex(char * name);
	void SolveDependencies() ;
	void SetCDependencies() ;
	void AddUserObjects();
	void WriteMakes() ;
	int GetNumHDirs() ;
	int GetNumHEntries() {return total_space ; }
	int GetNumHFiles() {return HTotal ; }
	HeaderFile ** GetAllHeaders() { return AllHeaders ;}
	int GetNumFlagWords() { return NumFlagWords ; }
	const char * GetObject() {return Object;}
	void SetObject(const char * objx) {Object=objx;}
	const char * GetHFile(int) ;
	void CheckInclude();
	class DirContents * GetUsrContents(const char * Name) ;
	void Init();
	int AnyUsrObjects() ;
	const char * GetNoCollName(int i) const ;
	const char ** GetNoCollNames() const {return NoCollNames;}
	const char * GetMenuName(int i) ;
	void AddMenuName(const char * Name);
	void AddNoCollectName(const char * Name);
	const char * GetMakeNodDir() {return NodDir;}
	const char * GetMenuDir() {return GetMenuName(0) ;}
	const char * GetMenuIncDir() {return GetMenuName(2) ;}
	const char * GetMenuInput() {return GetMenuName(1);}
	const char * GetMainDir();
	const char * GetSubDir() const ;

	void OutLibrarys(OutTokens& ListOut);
	void EmitObjs(ostream& MakeOut, int& line_use);

	void AddLibDirList(const char ** Names) ;
	void AddMakeDirList(const char ** Names) ;

	void SetLibList(const char ** Names) {LibList = Names;}
	void SetLibSearchList(const char ** Names) {LibSearchList = Names;}
	void SetLibDirList(const char ** Names) {LibDirList = Names;}
	void SetLibUpDirList(const char ** Names) {LibUpDirList = Names;}

	int IsSubDir() const ;
	int GetMenuSize() { return TotalMenuNames;}
	int GetNoCollectSize() { return TotalNoCollect;}
	void OutMenuMakes(OutTokens& Out);
	void SetMenuMakeFileCreated() {MenuMakeFileCreated=1;}
	int IsMenuMakeFileCreated() {return MenuMakeFileCreated;}
	const char * GetMenuFlag() {return MenuFlag;}
	void OutAllNodFiles(OutTokens& Out) ;
	int IsUsrDir(const char * Name) ;
	void SetNoExecutable() {NoExecutable=1;}
	int IsNoExecutable() {return NoExecutable;}
	int CheckUsrC();
	const char ** GetLinkDirectoryList(const char * Master) const;
	void AddObjsFromDirectories(ostream * MakeOut,
		const char ** DirectoriesToLink, int& line_use);
	int Set_dbXtra();
	int InCollectedLib(const char * DirName) const ;
	void EmitCollectLibDirectories(OutTokens& Out);
	void SetCreateSourceDirList();
	void SetNoSourceNoWarnList(const char ** Names);
	void EmitLinkDirectories(ostream& DirListOut,
		const char * DirName, const GetBits& bits)const ;
	void WriteSourceDirectories(ostream& Out,GetBits& TheBits) const ;
	void AddSourceDirectories(ostream& DirListOut, GetBits& Bits,
        	const char * DirNam) const ;
	void WriteSourceListings();
	int IsArith() const { return ArithFlag;}
	void SetArith() {ArithFlag=1;}
	int ranlib_set() {return use_ranlib;}
	int user_copyright() const { return the_user_copyright;}
	void set_user_copyright() { the_user_copyright = 1 ;}
	void set_ranlib() {use_ranlib = 1 ;}
	void root_directory(const char * s){the_root_directory=s;}
	const char * root_directory() const {return the_root_directory;}
	const char * script_directory() const {return the_script_directory;}
	const char * script_dir() const {return the_script_dir;} // no trailing /
	const char * bin_directory() const {return the_bin_directory;}
	void system_suffix(const char * s){the_system_suffix=s;}
	const char * system_suffix() const {return the_system_suffix;}
	const char * system_file_name() const {return "SYSTEM" ;}
	static istream * get_file(const char * dir, const char * base,
        const char * suffix = 0, char ** return_name = 0) ;
	void set_extra_directory_space(int n) {extra_directory_space = n ;}
	int new_header_file(HeaderFile * f,const char * inc_d);
	void include_all(const char * name) {include_all_file = name;}
	const char * include_main(const char * name) {return include_main_file = name;}
	const char * include_all() const {return include_all_file;}
	const char * include_main() const {return include_main_file;}
	const char *** make_dir_list() const {return MakeDirList;}

	const MakeableLibList &moveable_libs() const {return the_moveable_libs;}
	void add_move_lib(const char * dir, const char * lib)
		{the_moveable_libs.Append(new MakeableLib(dir,lib));}

	const MakeableLibList &makeable_libs() const {return the_makeable_libs;}
	void add_make_ext_lib(const char * dir, const char * lib)
		{the_makeable_libs.Append(new MakeableLib(dir,lib));}

	const char ** makemake_depend() const {return the_makemake_depends;}
	void makemake_depend(const char ** to_set) {the_makemake_depends = to_set;}
	const char * moveable_lib_name(const char *) const ;
	const char * MakeLibName(const char *);
	int list_files() const {return do_list_files;}
	void list_files(int flg) {do_list_files = flg;}
} ;
	// if set then do not output CC line

extern const char ** OmitCCLine ;
extern const char * default_root_directory ;
