#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <yafl_usr.h>
#include <yafl_rnt.h>
#include "yr_class.h"
#include "dbx_rnt.h"
#include "dbx_modu.h"
#include "dbx_type.h"
#include "dbx_clas.h"
#include "dbx_obar.h"
#include "dbx_fiel.h"
#include "dbx_meth.h"
#include "dbx_matc.h"


/* extern int used_classes; */

static char yesstr[] = "YES";
static char nostr[] = "NO";


dbx_class *first_class_all YPARAMS0
{
  if (last_class_sig() > 0)
    return get_class(0);
  else
    return NULL;
}

dbx_class *last_class_all YPARAMS0
{
  if (last_class_sig() > 0)
    return get_class(last_class_sig()-1);
  else
    return NULL;
}

dbx_class *next_class_all YPARAMS2(dbx_class *,  pc)
{
  int i;
  assertp(pc);
  i = find_class_pos(pc);
  if (i == last_class_sig() - 1)
    return NULL;
  else
    return get_class(i + 1);
}

dbx_class *prev_class_all YPARAMS2(dbx_class *,  pc)
{
  int i;
  assertp(pc);
  i = find_class_pos(pc);
  if (pc == 0)
    return NULL;
  else
    return get_class(i - 1);
}        				

char *class_name YPARAMS2(dbx_class *,  pc)
{
  assertp(pc);
  if (pc->class_name)
    return (pc->class_name);
  else
    return ("<undefined>");
}

int once_class YPARAMS2(dbx_class *,  pc)
{
  assertp(pc);
  return (pc->once_ptr != NULL);
}

dbx_type *class_type YPARAMS2(dbx_class *,  pc)
{
  assertp(pc);
  return (pc);
}

unsigned class_beginline YPARAMS2(dbx_class *,  pc)
{
  assertp(pc);
  return (pc->beginline);
}

unsigned class_endline YPARAMS2(dbx_class *,  pc)
{
  assertp(pc);
  return (pc->endline);
}

dbx_class *next_class YPARAMS2(dbx_class *,  pc) /* _of_module */
{
  assertp(pc);
  return (pc->next);
}

dbx_class *prev_class YPARAMS2(dbx_class *,  pc) /* _of_module */
{
  assertp(pc);
  return (pc->prev);
}

dbx_module *class_module YPARAMS2(dbx_class *,  pc)
{
  assertp(pc);
  assertp(pc->module);
  return (pc->module);
}

dbx_field *first_field YPARAMS2(dbx_class *,  pc) 
{
  assertp(pc);
  return(pc->first_field);
}

dbx_field *last_field YPARAMS2(dbx_class *,  pc)
{
  assertp(pc);
  return(pc->last_field);
}



struct dbx_method *first_method YPARAMS2(dbx_class *,  pc) /* _of_class */
{
  assertp(pc);
  return (pc->first_method);
}

struct dbx_method *last_method YPARAMS2(dbx_class *,  pc) /* _of_class */
{
  assertp(pc);
  return (pc->last_method);
}

obj_ptr *class_once_ptr YPARAMS2(dbx_class *,  pc)
{
  assertp(pc);
  return (pc->once_ptr);
}

dbx_class *find_next_class YPARAMS4(dbx_class *,  pc,
                                   char *,       pattern)
{
  dbx_class *pcla = NULL;
  while (pc)
  {
    if (dbx_match(class_name(pc),pattern))
    {
      pcla = pc;
      pc = NULL;
    }
    else
    {
      pc = next_class(pc);
    }
  }
  return pcla;
}

dbx_class *find_prev_class YPARAMS4(dbx_class *,  pc,
                                   char *,       pattern)
{
  dbx_class *pcla = NULL;
  while (pc)
  {
    if (dbx_match(class_name(pc),pattern))
    {
      pcla = pc;
      pc = NULL;
    }
    else
    {
      pc = prev_class(pc);
    }
  }
  return pcla;
}

dbx_class *lowest_class YPARAMS2(obj_ptr, po)
{
  assertp(po);
  return(dynamic_type(po));
}

dbx_class *parent_class YPARAMS2(dbx_class *, pc)
{
  assertp(pc);
  return(pc->inherited);
}

dbx_field *field_in_classes YPARAMS4(dbx_class *,  pc,
                                    char *,       name)
{
  dbx_field *pf;
  while (pc)
  {
    pf = find_next_field(first_field(pc),name);
    if (pf)
      return (pf);
    pc = parent_class(pc);
  }
  return NULL;
}

dbx_class *global_find_next_class YPARAMS2(char *,  pattern)
{
  dbx_module *pm;
  dbx_class *pc;
  pm = first_module();
  while(pm)
  {
    pc = find_next_class(first_class(pm),pattern);
    if (pc)
      return pc;
    pm = next_module(pm);
  }
  return NULL;
}

dbx_class *search_class YPARAMS4(dbx_class *,  pc,
                                char *,  pattern)
{
  dbx_class *pcla = NULL;
  while (pc)
  {
    if (dbx_match(class_name(pc),pattern))
    {
      pcla = pc;
      pc = NULL;
    }
    else
      pc = parent_class(pc);
  }
  return pcla;
}

dbx_class *first_once YPARAMS0
{
  dbx_class *pc;
  pc = first_class_all();
  while (pc)
  {
    if (once_class(pc))
      return(pc);
    pc = next_class_all(pc);
  }
  return NULL;
}

dbx_class *last_once YPARAMS0
{
  dbx_class *pc;
  pc = last_class_all();
  while (pc)
  {
    if (once_class(pc))
      return (pc);
    pc = prev_class_all(pc);
  }
  return NULL;
}

dbx_class *next_once YPARAMS2(dbx_class *,  pc)
{
  assertp(pc);
  pc = next_class_all(pc);
  while (pc)
  {
    if (once_class(pc))
      return pc;
    pc = next_class_all(pc);
  }
  return NULL;
}

dbx_class *prev_once YPARAMS2(dbx_class *,  pc)
{
  assertp(pc);
  pc = prev_class_all(pc);
  while (pc)
  {
    if (once_class(pc))
      return (pc);
    pc = prev_class_all(pc);
  }
  return NULL;
}



dbx_class *find_next_once YPARAMS4(dbx_class *,  pc,
                                  char *,       pattern)
{
  dbx_class *pcla = NULL;
  while (pc)
  {
    if (dbx_match(class_name(pc),pattern))
    {
      pcla = pc;
      pc = NULL;
    }
    else
    {
      pc = next_once(pc);
    }
  }
  return pcla;
}

dbx_class *find_prev_once YPARAMS4(dbx_class *,  pc,
                                  char *,       pattern)
{
  dbx_class *pcla = NULL;
  while (pc)
  {
    if (dbx_match(class_name(pc),pattern))
    {
      pcla = pc;
      pc = NULL;
    }
    else
    {
      pc = prev_once(pc);
    }
  }
  return pcla;
}

dbx_class *first_subclass YPARAMS2(dbx_class *,  pc)
{
  dbx_class *pc2;
  pc2 = first_class_all();
  while (pc2)
  {
    if (parent_class(pc2) == pc)
      return pc2;
    pc2 = next_class_all(pc2);
  }
  return NULL;
}

dbx_class *last_subclass YPARAMS2(dbx_class *,  pc)
{
  dbx_class *pc2;
  pc2 = last_class_all();
  while (pc2)
  {
    if (parent_class(pc2) == pc)
      return pc2;
    pc2 = prev_class_all(pc2);
  }
  return NULL;
}

dbx_class *next_subclass YPARAMS2(dbx_class *,  pc)
{
  dbx_class *pc2;
  assertp(pc);
  pc2 = next_class_all(pc);
  while (pc2)
  {
    if (parent_class(pc2) == parent_class(pc))
      return pc2;
    pc2 = next_class_all(pc2);
  }
  return NULL;
}

dbx_class *prev_subclass YPARAMS2(dbx_class *,  pc)
{
  dbx_class *pc2;
  assertp(pc);
  pc2 = prev_class_all(pc);
  while (pc2)
  {
    if (parent_class(pc2) == parent_class(pc))
      return pc2;
    pc2 = prev_class_all(pc2);
  }
  return NULL;
}
  



