// -*-c++-*-
// ------------------------------------------
// RCS data:
// $Date: 2003/06/23 14:47:22 $
// $Revision: 1.1.1.1 $
// $Source: /cvsroot/miwm/miwm/miwm/alpha.h,v $
// $Id: alpha.h,v 1.1.1.1 2003/06/23 14:47:22 bwise837 Exp $
// $RCSfile: alpha.h,v $
// -------------------------------------------
// Copyright by Ben Paul Wise.
// -------------------------------------------
// This program is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
// 
// 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 the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.


// -------------------------------------------
// these are my extremely common headers.
// ------------------------------------------

#ifndef ALPHA_H
#define ALPHA_H

using namespace std;


#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <iostream>
#include <assert.h>

// ------------------------------------------
// Xt does '#define Boolean int', which plays havoc
// with any reasonable name for the following

enum TLogical { tbFalse, tbTrue, tbUnknown };

ostream& operator << (ostream& s, TLogical r); 

// ------------------------------------------
// useful macros for debugging.
//
// use assert and ASSERT liberally, with DebugCheck on user-set flags
// (and BPWDEBUG to shut it all off)
//
// ------------------------------------------
// BPWDEBUG is the "one big switch" that controls debugging-mode
// in alpha and everything that uses alpha.
#define BPWDEBUG


// note that the way cdbg is defined, it must be protected
// by a bDebug statment
#ifdef BPWDEBUG
#define cdbg cerr<<endl<<__FILE__<<":"<<__LINE__<<" "<<"CDBG: "
#else
#define cdbg
#endif
// This prints out a newline, followed by the current file name 
// and line number, e.g., 
//
//          cdbg << "Bad data encountered!";
//
// would print out something like 
//
//          widget.cc:379 CDBG: Bad data encountered!
//
// which can be used by the next-error facility of emacs or grep-ed for.

// ------------------------------------------

#ifdef BPWDEBUG
#define bDebug(expression) { expression }
#else
#define bDebug(expression) {}
#endif

// This causes stuff to be expanded if and only if the preprocessor 
// variable BPWDEBUG is defined. This enables more thorough and
// time-consuming checks than can be done in a simple 'assert'.
// For instance, 
// 
//           bDebug(
//              for( i = 0; i < tableSize; ++i ) {
//                 if( table[i] < 0) {
//                    cdbg << i << "-th entry is out of range!";
//                 }      
//              }
//           );

// it is crucial that the empty {} be put there, so that the syntax does not change
// depending on the conditional compilation, as would happen below:
//
//if ( stuff1 ) { }
//else
//bDebug ( stuff2 )
//
//stuff3
//
// which would compile as EITHER
//
//if ( stuff1 ) { }
//else
//  stuff2 
//
//stuff3
//
// OR
//
//if ( stuff1 ) { }
//else
//stuff3
//
// which is clearly wrong



// ------------------------------------------
// a facility to use bit-masked categories of
// checks would be nice. An approximation is below.
// remember, & is bitwise AND, | is OR, ^ is XOR

#define ASSERT(x, msg) \
if ((x) == 0) { cerr<<__FILE__<<":"<<__LINE__<<"   " <<msg<<endl;   exit(0); }

#ifdef BPWDEBUG
#define DebugCheck(Mask, Cat, Exp) { if (Mask & Cat) Exp }
#else
#define DebugCheck(Mask, Cat, Exp)  {}
#endif

// note these working example of DebugCheck from code.
// I use the private static data member VPool::debugPools as the category,
// and enumerated (1,2,4) levels of debugging.
// 
// no compound bitmask, no compound statement:
// DebugCheck(MuchPoolDebugging , debugPools,
// 			 cout << "ran off the end - construct a new one" << endl;
// 			 )
//
// note how the ( ) on the compound bitmask and the {  } on compound statements work
//   DebugCheck((LittlePoolDebugging | MuchPoolDebugging) , debugPools,
// 	     {
// 	       cout << "Number of remaining allocated pool objects: " << count;
// 	       cout << " out of " << total << endl;
// 	     }
// 	     );

// this is a global variable we could use to control DebugCheck
extern int theDBGAlpha;

// these are the debug-categories for Alpha. We arbitrarily label
// them 1-5. You can add more, but please do not change these.
//
// Put notes in your header files saying how you've used each
// category. 
// 
// E.g.:
// 'DbgAlpha1' might be events and conditions related to constructing,
// modifying (complexify/simplify), and destructing MRM objects.
// 'DbgAlpha2' might be events and conditions related to tactical
// behavior

enum AlphaDBGCategories {
  DbgAlpha1 = 1,
  DbgAlpha2 = 2,
  DbgAlpha3 = 4,
  DbgAlpha4 = 8,
  DbgAlpha5 = 16
};


void setAlphaDBG(AlphaDBGCategories, TLogical);

// ------------------------------------------
double dabs (double x);
double dmax (double a, double b);
double dmin (double a, double b);

int iabs (int x);
int imax(int a, int b);
int imin(int a, int b);

// return x ^ n
double expt (double x, int n);    

// return x ^ e
double dexpt (double x, double e);    

int oddP(int x);
int evenP(int x);

double delta(double a, double b); // symettric % difference
int iround(double x);
double round (double x, int n);
int gcd(int a, int b);

//  the /usr/include/math.h covers floor but not ceiling.
// and /usr/include/math.h/floor returns a float, not an int
int ifloor (double x);
int iceiling (double x);

// ------------------------------------------

#endif

// ------------------------------------------
//           end of alpha.h
// ------------------------------------------

