// This file is a compact, standalone, version of grvClasses.js
// This file supports the multiple inheritance version of GrvObject

Class(GrvObject); //special root class
function GrvObject(){
  this.souper = function(){
    var superMethod = this.souper.caller.souper;
    return (superMethod) ? superMethod.apply( this, arguments ) : null;
  }
  this.souper_ = function( superclass ) {
    var superMethod = this[superclass.cname]._[this.souper_.caller.mname];
    var theArgs     = Array.prototype.slice.call(arguments,1);
    return (superMethod) ? superMethod.apply( this, theArgs ) : null;
  }
  this.isInstanceOf = function( aClass ){
    if (aClass.cname==null) return false;
    var m = this[ aClass.cname ];
    return( m && m instanceof Function );
  }
}

function grvImplements(){
  var sexemplar,s,m,N = arguments.length;
  var rexemplar = this.rawExemplar;
  var  exemplar = this.prototype;
  for (var i=0; i<N; ++i){
    sexemplar = arguments[i].prototype;
    for (var x in rexemplar){
      if (!(rexemplar[x] instanceof Function)) continue;
      m =    exemplar[x]; if (m.souper) continue; //already linked!
      s =   sexemplar[x];
      if (s && (s instanceof Function)) m.souper = s;
    }
  }
  for (var i=0; i<N; ++i){
    sexemplar = arguments[i].prototype;
    for (var x in sexemplar){
      s = sexemplar[x];
	  if ( exemplar[x]===void 0 && s instanceof Function ) exemplar[x] = s;
    }
  }
}

function grvExtends( superClass ){ //link super and sub class
  var sexemplar = this.baseClass.prototype = ((this==GrvObject) ? null : superClass.prototype);
  var  exemplar = this.prototype = new this.baseClass();
  for (var x in exemplar){
    var m =  exemplar[x]; if (!(m instanceof Function)) continue;
        m.mname =     x;  if (! sexemplar             ) continue;
    var s = sexemplar[x];
    if (s && (s!=m) && (s instanceof Function)) m.souper = s;
  }
  if (exemplar.konstructor==null) exemplar.konstructor = function(){};
  if (superClass==GrvObject) this.rawExemplar = exemplar;
  exemplar[this.cname]   = exemplar.konstructor;
  exemplar.konstructor._ = exemplar;
  return this;
}

function grvFuncName(f){ //extract name from function source
  var s = f.toString().match(/function\s*(\S*)\s*\(/)[1];
  return s ? s : "anonymous";
}

function Class( theClass ){
  var originalClass = theClass;
  var className     = grvFuncName( theClass );
  self[ className ] = theClass = function _wrapper_(){
    arguments.callee.prototype.konstructor.apply( this, arguments );
  }
  theClass.cname     = className;//FYI,netscape&firefox break with ".name"
  theClass.baseClass = originalClass;
  theClass.Extends   = grvExtends;//so we can call as methods...
  theClass.Implements= grvImplements;
  theClass.Extends(GrvObject);//required here even if overridden later
  return theClass;
}
