#include <api/api_main.h>

extern struct DISASM_TGT target;
extern struct DISASM_ENV disasm_env;
extern struct DISASM_PREFS disasm_prefs;

/* API sections: 
 *     8. Imports               :: Creating/manipulating IMPORT objects
 *     9. Exports               :: Creating/manipulating EXPORT objects
 * /

/* ---------------------------------------------------------------Imports */
   DefineImport( long rva, char *lib, char* name, int type){
      struct import_addr imp;
      struct name n;
      struct lib l;
   
      if ( d_keyfind(IMPORT_ADDR_RVA, &rva) == S_OKAY){
         return(1);
      } 
      else  {
         /* make new NAME for name */
         DefineFunc(rva, name, 4, NAME_SYMBOL | NAME_AUTO);
         SetFlags(rva, ADDR_CODE | ADDR_IMPORT | ADDR_FUNCTION | ADDR_SYMBOL);

         imp.rva = rva;
         l.id = 0;
         if (lib) {
            if (d_keyfind(LIB_NAME, lib) == S_OKAY)
               d_recread(&l);
            else { 
               DefineLibrary(lib, 0, 0);
               if (d_keyfind(LIB_NAME, lib) == S_OKAY) d_recread(&l);
               else 
                  return(0); /* error will be set by Define Library */
            }
         }
         imp.library = l.id;
         imp.type = type;   
         d_fillnew(IMPORT_ADDR, &imp);
         if (db_status != S_OKAY) 
            return(SetLastError(dbError()));
      }
      disasm_env.flags |= DB_MOD;
      return(1);
   }

   int GetImportName(long rva, char *buf) {
      if (d_keyfind(IMPORT_ADDR_RVA, &rva) != S_OKAY)
         return(SetLastError(4400));
      return( GetName( rva, buf) );
   }

   int GetImportLib(long rva, char *buf) {
      struct import_addr i;
      struct lib l;

      if (d_keyfind(IMPORT_ADDR_RVA, &rva) != S_OKAY)
         return(SetLastError(4400));
      d_recread(&i);
      return(i.library);
   }

   int GetImportType(long rva) {
      struct import_addr i;

      if (d_keyfind(IMPORT_ADDR_RVA, &rva) != S_OKAY)
         return(SetLastError(4400));
      d_recread(&i);
      return(i.type);
   }

   int DefineLibrary(char *name, int v_hi, int v_lo){
      struct lib l;
      if (d_keyfind(LIB_NAME, &name) == S_OKAY) 
         return(SetLastError(4410));
      strncpy(l.name, name, 63);
      l.ver_hi = v_hi;
      l.ver_lo = v_lo;
      l.id = ++seq.library;
      d_fillnew(LIB, &l);
      if (db_status != S_OKAY) 
         return(SetLastError(dbError()));
      return(1);
   }
   int DumpImports() {
      struct import_addr i;
      struct name n;
      
      d_keyfrst(IMPORT_ADDR_RVA);
      while (db_status == S_OKAY) {
         d_recread(&i);
         if ( d_keyfind(NAME_RVA, &i.rva) == S_OKAY){
            d_recread(&n);
            printf("%x %s\n", i.rva, n.name);
         }
         d_keynext(IMPORT_ADDR_RVA);
      }
      return(1);
   }

   int DumpLibs() {
      struct lib l;
   
      d_keyfrst(LIB_ID);
      while( db_status == S_OKAY) {
         d_recread(&l);
         printf("%s %d.%d\n", l.name, l.ver_hi, l.ver_lo);
         d_keynext(LIB_ID);
      }
      return(1);
   }   /* print all libraries to stdout */

/* ---------------------------------------------------------------Exports */
   int DefineExport(long rva, char *name) {
      struct export_addr e;
      struct name n;
      
      /* do nothing if it already exists */
      if ( d_keyfind(EXPORT_ADDR_RVA, &rva) == S_OKAY){
         return(1);
      }
      /* make new NAME for name */
      SetName( rva, name, NAME_SYMBOL | NAME_AUTO);

      e.rva = rva;
      if ( d_fillnew(EXPORT_ADDR, &e) == S_OKAY)
         return(1);
      return(SetLastError(dbError()));
   }

   int GetExport(char *name) {
      struct export_addr e;
      int rva;
      
      rva = GetAddrByName(name);
      if ( d_keyfind(EXPORT_ADDR_RVA, &rva) != S_OKAY){
         return(SetLastError(4451));
      } 
      return(rva);
   }

   int DumpExports() {
      struct export_addr e;
      struct name n;
      
      d_keyfrst(EXPORT_ADDR_RVA);
      while (db_status == S_OKAY) {
         d_recread(&e);
         printf("%x", e.rva);
         if ( d_keyfind(NAME_RVA, &e.rva) == S_OKAY){
            d_recread(&n);
            printf("\t%s", n.name);
         }
         printf("\n");
         d_keynext(EXPORT_ADDR_RVA);
      }
      return(1);
   } 
