#include <api/api_main.h>

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

/* API sections:
 *    14. Names   g            :: User-defined address names
 *    15. Comments   g         :: User-defined address comments
 */



/* ------------------------------------------------------ utility routines */
    void ValidateName(char *name){
      /* remove all weird characters from name */
      int x;

      for ( x = 0; x < strlen(name); x++){
         if (name[x] && (name[x] < 0x20 || name[x] > 0x7E)) 
                 name[x] = '_';      /* mangling char ;) */
      }
      return;
   }
/* ---------------------------------------------------------------Names */
   int SetName(long rva, char* name, int type){
      struct name n;
   
      //if (d_keyfind(ADDRESS_RVA, &rva) == S_NOTFOUND) 
      //   return(SetLastError(4020));
      n.rva = rva;
      n.type = type;
      strncpy(n.name, name, 63);
      n.name[63] = 0;

      ValidateName(n.name);
   
      if (d_keyfind(NAME_RVA, &rva) != S_NOTFOUND)
         d_recwrite(&n);
      else d_fillnew(NAME, &n);
      if (db_status != S_OKAY) dbError();
   
      disasm_env.flags |= DB_MOD;
      return(1);
   }

   int GetName(long addr, char* buffer){ 
      struct name n;
   
      if (d_keyfind(NAME_RVA, &addr) == S_OKAY){
         d_recread(&n);
         strcpy(buffer, n.name);
         return(strlen(n.name));
      }
      return(SetLastError(4710));
   }
   
   int GetNameType(long addr){ 
      struct name n;
   
      if (d_keyfind(NAME_RVA, &addr) == S_OKAY){
         d_recread(&n);
         return(n.type);
      }
      return(SetLastError(4710));
   }
   
   long GetAddrByName( char *name ){
      struct name n;
      
      if ( d_keyfind(NAME_NAME, name) == S_OKAY){
         d_recread(&n);
         return(n.rva);
      }
      return(SetLastError(4711));
   }

   int DelName(long addr){
      /* delete name for 'addr' */
      return(1);
   }
/* ---------------------------------------------------------------Comments */
   int GetComment(int id, char *buf){
   /* comments are handled by ID, not by their text contents */
      struct comment c;
   
      if (! buf) 
         return(SetLastError(9010));
      if (d_keyfind(COMMENT_ID, &id) == S_OKAY){
         d_recread(&c);
         strcpy(buf, c.text);
         return(strlen(buf));
      }
      return(SetLastError(4720));
   }

   int DefineComment(char *buf, int type){
      struct comment c;
   
      if (! buf) 
         return(SetLastError(9010));
      c.id = ++seq.comment;
      c.type = type;
      strncpy(c.text, buf, 255);
      c.text[255] = '\0';
      ValidateName(c.text);
      d_fillnew(COMMENT, &c);
      if (db_status == S_OKAY) 
         return(c.id); 
      dbError();
      return(0); 
   }

   int SetComment( int id, char *buf){
      struct comment c;
   
      if (! buf) 
         return(SetLastError(9010));
      if (id && d_keyfind(COMMENT_ID, &id) == S_OKAY) {
         d_recread(&c);
         strncpy(c.text, buf, 255);
         c.text[255] = '\0';
         ValidateName(c.text);
         d_recwrite(&c);
      } 
      else {
         c.id = ++seq.comment;
         c.type = CMT_USER;
         strncpy(c.text, buf, 255);
         c.text[255] = '\0';
         ValidateName(c.text);
         d_fillnew(COMMENT, &c);
      }
      if (db_status == S_OKAY) 
         return(1);
      dbError();
      return(0);
   }

   int DelComment(int id) {
      if (!  DBRecordDelete(COMMENT_ID, &id) )
         return(SetLastError(4730));
      disasm_env.flags |= DB_MOD;
      return(1);
   }

