#ifndef extc_phase1_h
#define extc_phase1_h
/***************************************************************************
 *  phase1.h
 *
 *  Tue Jul 26 13:42:18 2005
 *  Copyright  2005  James Scully- aka jtox
 *  Email jtoxification @ the-only-free-2-gig-account-service-online
 ***************************************************************************
 *  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 Library 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 */

/*The Struct macro: */
/* This also gives the default constructor, hidden within. 
A call to the default constructor should be the first line in any 
other constructor you make. 

To do: set this up so that if you don't give the default constructor 
any arguments, it'll allocate new memory. (auto int argument to a function pointer)
If you do give it a non-null pointer, it will assume you pre-allocated memory */

    #define Struct(type)                                   \
    struct type* type##Constructor(struct type* i);        \
    struct type                                            \
    {     struct type* _id_;

/* The Prototypes macro */
    #define Prototypes(type) struct type##_functions {

/* The prototype macro */
    #define prototype(funcname)(*funcname)()
        
/* The Bind macro   
    Notes: Alter the function list to a union pointer instead:
    use the macro argument to copy and access   a function when necessary.
*/
    #define Bind(type) } functions; };                     \
    struct type* type##Constructor (struct type* t)        \
    {                                                      \
        static struct type##_functions* functions();        \
      if (!t)t = (struct type*)malloc(sizeof(struct type));\
        t->_id_ = t;                                        \
        memcpy(&(t->functions),functions(),sizeof(t->functions));\
        registry__->add(t);                                 \
        DBGMSG(("creation has succeeded\n"));               \
        return t;                                           \
    }                                                       \
    static struct type##_functions* functions(){            \
    static struct type##_functions funct = (struct type##_functions){ 

/* The EndStruct macro */
    #define EndStruct };return &funct;};
    #define Local(type,name)struct type name;type##Constructor((struct type*)&name)
    //#define Auto(type,name)type##Constructor((struct type*)&name)
/* The various Object attribute sections 
     * To do: 
         Add Constructor and Destructor macro utilities
        Create the new() and delete() operators that take in
        Constructor and Deconstructor functions as arguments.
     */
    #define Public 
    #define Private /*To be defined and implemented*/
    #define Methods 
    #define Methodnames
    #define Aliases /*To do: cut down on redundancies */

/* the actual syntactic sugar that makes it all possible: */
    #undef alias
    #define alias(func) _id_[(registry__->lock())]._id_--[(registry__->find())] . functions . func
    /* The above will be changed later to reflect single-type object-registries and 
     * unioned function lists rather than structured ones.  The change will also
     * most likely involve the ()?: operator in order to allow checking the 
     * least-significant bit for a very modest speedup in the registry search. */
    #if defined unixx
        #undef $
        /* Borland doesn't like dollar signs too much.  If we can set a precompiler directive from 
         * within the sourcefile, (rather than specifying something from the command line) then
         * we won't concern ourselves with altering this.  Otherwise, we'll need to re-evaluate
         * our options, or check for compiler switches that allow recursive macro definitions,
         * which is quite frankly, not an elegant solution.*/

        #define $(func) alias(func)
    
        /* The above is for those who don't want to alias member function names 
         * This still doesn't look as good to me in practice, but I need to cut
         * down on redundancy within object header files really badly ...
         * so now instead of aliasing the name out, they can type out:
         * blah->$(funcname)(args);
         * but if they do alias the name #define fname alias(actualname) it becomes:
         * blah->funcname(args); */
    #endif


/*The first line of a member function always calls this macro:
*/
    #define this(type)\
    struct type* this=(struct type*)registry__->pop(GETPID(),GETTID()); 
    


/* These ALWAYS return zero: _id_[func()] looks better than _id_[(func(),0)] 
   However, if it turns out _id_[(func(),0)] is significantly faster, then
   that is what will be used. * /

int  registry__->lock___(); //locks the object registry for reading and writing.
int  registry__->find___();//locates the object id *._id_-- within the registry, 
                        //unlocks the object registry, 
                        //locks the *self registry,
                       //adds the object to *self registry.
                       //unlocks the *self registry.
/*->_funcs->func(args) //first line of a member function always calls macro:
object* this = registry.retrieve(getPID,getTID);//which also locks and unlocks
    

    /* There were about three or four other possibilities to get this stuff
      to work properly, but none came close to the elegance above */


/* sample header file * /

typedef struct Something Something;
static int func1 (int arg1,char* arg2, void* arg3);
static void func2();

Struct(Something)

    Public
        void* data;

    Private /* not yet implemented * /

    Prototypes(Something)
        int  prototype(func1);
        void prototype(func2);

    Aliases 
    /* 
        This is how other files access these hidden static functions 
        Macro rebinding is actually safe so long as the redefinition matches
        the original definition, as per the rules of K&R. Obviously the main
        danger here is having too many definitions and something gets defined
        that is used somewhere else.  Thus, if people don't want to use the
       alias() macro, they can use obj->$(func)(args) or obj->alias(func)(args) 
        instead, which will accomplish the same thing without aliased macros.
        it's kind of cool, but doesn't look as pretty.
     * /
        #define do_something      alias(func1) 
        #define do_something_else     $(func2)   /* same macro as alias */
    
    /*Here's where we actually attach the prototypes to their respective funcs* /
    Bind(Something) func1, func2

EndStruct

static int func1 (int arg1,char* arg2, void* arg3)
{
    arg3 = &arg1;
    arg2 = arg3;
    printf("first byte of int arg1 is: %i\n",arg2[0]);  
    Return 0;
}

static void func2() 
{
    printf("member function '->do_something_else()' called\n");
    Return ;
}

#endif

//EndObject;

/* Everything below is either sketchpad stuff, obseleted, or alternate styles*/ 

/*Possible construction styles 
#define Class(name) typedef struct name name; struct name{int callback;
#define EndClass };


#define NewObject(name) struct name
#define Public int callback;
#define Methods };
#define EndObject(name) typedef struct name name,
    
/* For later phases * /
#define Private 
#define Extends
#define Casts

/*typedef char* string;*/


/*Yet another proposed Syntax Idea * /
#if (0)

#undef Methods
#undef  EndObject

#define Methods }; (
#define Prototype(type,name)\
);type name##_return();type name##_return(){return;} prototype(type, name, (
#define prototype(type,name,args) type name args

#define method(name) callback++<0?name##_return():name

#define EndObject(name) ); typedef struct name name,


NewObject(Something)

    Public
        void* data;

    Private
        /* not yet implemented * /

    Methods
        Prototype(int,do_something) (int arg1, char* arg2, void* arg3)

        Prototype(void,do_something_else)()

EndObject(Something) ;

#endif


#define method(name) callback++<0?(name##_return)SuperObject:name
#define Constructor(Name) Name

#if (0)/* Here's one proposed syntax * /

NewClass(A_CLASS_OBJECT)

    void* data;

EndClass

#endif

/* To create a class function, after each function implementation line,
   #define <F_NAME> method(<F_NAME>)
 * /#if(0)
/* So a sample initialization for a member function would be: 

NewObject(String)

    Public
        char* data;     
    
    Private 
        /* not yet implemented * /  

    Methods
        string  prototype(toString)();
        
EndObject;  

    string toString()
    #define toString method(toString)
    {
        //return (char*)this->label;
    }
        
*/

#endif