/* Skivregister                                    */
/* l�nka i LARGE MODEL med BULLET_L.LIB            */

#include <dos.h>
#include <bios.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <time.h>
#include <string.h>
#include <io.h>
#include <fcntl.h>
#include <bullet.h>


struct memorypack MP;
struct initpack IP;
struct exitpack EP;
struct createdatapack CDP;
struct createkeypack CKP;
struct dosfilepack DFP;
struct openpack OP;
struct accesspack AP[5];
struct statdatapack SDP;
struct exitpack EP;


struct skivrectype {
       char tag[1];
       char artist[35];
       char titel[35];
       char utg_ar[4];
       char musiktyp[20];
       char format[2];
       char utlanad[1];
       char kommentar[50];
};
struct skivrectype skivrec;

struct latrectype {
       char tag[1];
       char artist[35];
       char titel[35];
       char latnr[2];
       char lat[50];
};
struct latrectype latrec;

struct fielddesctype fieldlist1[7],fieldlist2[4];

int     rez, level;
div_t   div_rez;
int no_songs = 0;

char    tmpstr[129];

char skivDATname[] = "SKIVOR.DBF";
char latDATname[] = "LATAR.DBF";

char *skivIDXname[3] = {
       "ARTIST.IDX\0",
       "TITEL.IDX\0",
       "ARTTIT.IDX\0"
};

char *latIDXname[2] = {
       "LAT.IDX\0",
       "LATART.IDX\0"
};


char *skivIDXkey[3] = {
       "SUBSTR(ARTIST,1,15)+UTG_AR+SUBSTR(TITEL,1,15)\0",
       "SUBSTR(TITEL,1,15)\0",
       "SUBSTR(ARTIST,1,15)+SUBSTR(TITEL,1,15)\0"
};

char *latIDXkey[2] = {
       "SUBSTR(LAT,1,15)\0",
       "SUBSTR(ARTIST,1,15)+SUBSTR(TITEL,1,15)+LATNR\0"
};

unsigned int skivDAThandle, skivIDXhandle[3];
unsigned int latDAThandle, latIDXhandle[2];


char skivkeybuf[64];
char latkeybuf[64],latkeybuf2[64];

char fkeybuf[10][80];
FILE* fkeyf;

char *exceed_msg[2] = {
       "Du �r redan vid slutet av registret!                                           ",
       "Du �r redan vid b�rjan av registret!                                           "
};


int key,scan;

#define S_ARTIST 0
#define S_TITLE  1
#define S_SONG   2

char *smodestr[3] = {"Artist","Titel","L�t"};

#define YES 0x24
#define NO 49
#define QUIT 16

#define ADDMODE 0
#define EDITMODE 1

char gettmp[80];
char temp_artist[35];
char temp_titel[35];


int main(int argc, char **argv)
{
/*
       if(argc == 3){
               strcpy(skivDATname,argv[1]);
               strcpy(latDATname,argv[2]);
       }
       else{
               printf("usage: skivreg <skivdatname> <l�tdatname>\n");
               exit(1);
       }
*/
       init();

       while(1)
       {
               clrscr();
               HideCur();
               printf("SKIVREGISTER");
               printf("                                             %d skivor i basen\n",getrecordno());
               printf("------------\n\n");
               printf("(1) S�k Artist\n");
               printf("(2) S�k Titel\n");
               printf("(3) S�k L�t\n");
               printf("(4) L�gg till Skiva(-or)\n");
               printf("(5) Komprimera databas\n");
               printf("(6) Re-indexera databas\n");
               printf("(7) Definiera Funktionstangenter\n");
               printf("\n<ESC> Avsluta program\n");

               scan = (bioskey(0) >> 8) & 0xff;
               switch(scan){
                       case 1: quit();break;
                       case 2: search(S_ARTIST);break;
                       case 3: search(S_TITLE);break;
                       case 4: search(S_SONG);break;
                       case 5: add_edit_record(ADDMODE);break;
                       case 6: pack();break;
                       case 7: reindex();break;
                       case 8: define_fkeys();break;
               }
       }
}


search(int mode)
{
       clrscr();
       ShowCur();

       printf("S�k vilken %s? ",smodestr[mode]);

       if(mode != S_SONG) {
               gets(skivkeybuf);
               HideCur();
               if(strlen(skivkeybuf) == 0) return;

               if(getequal(&AP[0],skivIDXhandle[mode],&skivrec,skivkeybuf) != 0)
                       getnext(&AP[0],skivIDXhandle[mode],&skivrec,skivkeybuf);
       }
       else {
               gets(latkeybuf);
               HideCur();
               if(strlen(latkeybuf) == 0) return;

               if(getequal(&AP[2],latIDXhandle[0],&latrec,latkeybuf) != 0)
                       getnext(&AP[2],latIDXhandle[0],&latrec,latkeybuf);
               link_to_skivor();
       }

       clrscr();
       while(1)
       {
               if((AP[0].stat != 202) && (AP[0].stat != 203))
                       draw_info_scr();
               else {
                       gotoxy(1,25);
                       printf(exceed_msg[AP[0].stat-202]);
               }

               scan = (bioskey(0) >> 8) & 0xff;

               switch(scan){
                       case 81: if(mode != S_SONG)
                                                       getnext(&AP[0],skivIDXhandle[mode],&skivrec,skivkeybuf);
                                               else {
                                                       getnext(&AP[2],latIDXhandle[0],&latrec,latkeybuf);
                                                       link_to_skivor();
                                               }
                                               break;
                       case 73: if(mode != S_SONG)
                                                       getprev(&AP[0],skivIDXhandle[mode],&skivrec,skivkeybuf);
                                               else {
                                                       getprev(&AP[2],latIDXhandle[0],&latrec,latkeybuf);
                                                       link_to_skivor();
                                               }
                                               break;
                       case 0x13:if(mode != S_SONG)
                                                       del_undel_record(mode);
                                               break;
                       case 0x12: add_edit_record(EDITMODE);
                                               break;
                       case 1: return;
               }
       }
}

link_to_skivor()
{
int i;
       memset(skivkeybuf,0,64);
       comb_latart_tit(skivkeybuf);

       if(getequal(&AP[0],skivIDXhandle[2],&skivrec,skivkeybuf) != 0)
               getnext(&AP[0],skivIDXhandle[2],&skivrec,skivkeybuf);
}

draw_info_scr()
{
       draw_record_info();
       draw_song_info();

       gotoxy(1,25);
       printf("(E) Editera  (R) Radera/O-Radera  (PgUp) F�reg�ende  (PgDn) N�sta  (ESC) Avbryt");
}

draw_record_info()
{
       clrscr();
       printf("   ARTIST  %.35s",skivrec.artist);
       if(skivrec.tag[0] == '*')
               printf("        *** RADERAD ***");
       printf("\n");
       printf("    TITEL  %.35s\n",skivrec.titel);
       printf("   UTG-�R  %.4s\n",skivrec.utg_ar);
       printf(" MUSIKTYP  %.20s\n",skivrec.musiktyp);
       printf(" CD/LP/SI  %.2s\n",skivrec.format);
       printf("  UTL�NAD  %.1s\n",skivrec.utlanad);
       printf("KOMMENTAR  %.50s\n",skivrec.kommentar);
}

draw_song_info()
{
char titelcmpstr[35];

       find_first_song();
       strncpy(titelcmpstr,latrec.titel,35);

       printf("\n-- L�TAR --------------------------------------------------------------------\n\n");

       if(rez != 200)
       {
               while(1) {
                       if(strnicmp(titelcmpstr,latrec.titel,15)) break;
                       printf("%.2s  %.50s\n",latrec.latnr, latrec.lat);

                       if(getnext(&AP[2],latIDXhandle[1],&latrec,latkeybuf) != 0) break;

                       if( (wherey() == 24) && (! strnicmp(titelcmpstr,latrec.titel,15)) )
                       {
                               printf("\n<Return> f�r fler l�tar...");
                               while((bioskey(0) & 0xff) != 13);
                               draw_record_info();
                               printf("\n-- L�TAR --------------------------------------------------------------------\n\n");
                       }
               }
       }
}

add_edit_record(int mode)
{
int i;
long recnr;

       while(1)
       {
               clrscr();

               if(mode == ADDMODE)
                       clear_fields();

               while(1)
               {
                       draw_record_info();
                       printf("\n\n---------------------------------------------------------------------\n\n");

                       printf("Ange f�lt, eller (S) Spara (ESC) Avbryt\n\n");
                       printf("(1) Artist\n");
                       printf("(2) Titel\n");
                       printf("(3) Utg-�r\n");
                       printf("(4) Musiktyp\n");
                       printf("(5) CD/LP/SI\n");
                       printf("(6) Utl�nad\n");
                       printf("(7) Kommentar\n\n");

                       scan = (bioskey(0) >> 8) & 0xff;

                       switch(scan){
                               case 2:         printf("Artist: ");
                                                       if(mode == EDITMODE) {
                                                               newgets(temp_artist,35);
                                                               edit_songlink(S_ARTIST);
                                                       }
                                                       else
                                                               newgets(skivrec.artist,35);
                                                       break;
                               case 3:         printf("Titel: ");
                                                       if(mode == EDITMODE) {
                                                               newgets(temp_titel,35);
                                                               edit_songlink(S_TITLE);
                                                       }
                                                       else
                                                               newgets(skivrec.titel,35);
                                                       break;
                               case 4: printf("Utg-�r: ");
                                                       newgets(skivrec.utg_ar,4);
                                                       break;
                               case 5: printf("Musiktyp: ");
                                                       newgets(skivrec.musiktyp,20);
                                                       break;
                               case 6:         printf("CD/LP/SI: ");
                                                       newgets(skivrec.format,2);
                                                       break;
                               case 7: printf("Utl�nad: ");
                                                       newgets(skivrec.utlanad,1);
                                                       break;
                               case 8: printf("Kommentar: ");
                                                       newgets(skivrec.kommentar,50);
                                                       break;

                       case 0x1f:  if(mode == ADDMODE)         /* S */
                                                       {
                                                               if((skivrec.artist[0] == ' ') || (skivrec.titel[0] == ' ')) {
                                                                       printf("Du m�ste ange �tminstone Artist och Titel!\n");
                                                                       delay(1000);
                                                               }
                                                               else
                                                               {
                                                                       skivrec.tag[0] = ' ';

                                                                       for(i=0;i<3;i++){
                                                                               AP[i].func = INSERTXB;
                                                                               AP[i].handle = skivIDXhandle[i];
                                                                               AP[i].recptr = &skivrec;
                                                                               AP[i].keyptr = skivkeybuf;
                                                                               AP[i].nextptr = &AP[i+1];
                                                                       }
                                                                       AP[2].nextptr = NULL;
                                                                       if((rez = BULLET(&AP)) == 0) {
                                                                               if(AP[0].stat != 0)
                                                                                       error(); }
                                                                       else
                                                                               error();

                                                                       printf("Skivan sparad!\n");
                                                                       delay(1000);
                                                                       add_songs();

                                                                       clrscr();
                                                                       printf("L�gg till fler skivor (j/n)?");
                                                                       while(1) {
                                                                               scan = (bioskey(0) >> 8) & 0xff;
                                                                               if((scan == 0x24) || (scan == 0x31)) break;
                                                                       }
                                                                       if(scan == 0x31)
                                                                               goto avbrutet;
                                                                       else
                                                                               clear_fields();
                                                               }
                                                       }
                                                       else
                                                       {
                                                               recnr = AP[0].recno;
                                                               skivrec.tag[0] = ' ';

                                                               for(i=0;i<3;i++) {
                                                                       AP[i].func = UPDATEXB;
                                                                       AP[i].handle = skivIDXhandle[i];
                                                                       AP[i].recno = recnr;
                                                                       AP[i].recptr = &skivrec;
                                                                       AP[i].keyptr = skivkeybuf;
                                                                       AP[i].nextptr = &AP[i+1];
                                                               }
                                                               AP[2].nextptr = NULL;
                                                               level = 9000;

                                                               if((rez = BULLET(&AP)) == 0) {
                                                                       if(AP[0].stat != 0)
                                                                               error(); }
                                                               else
                                                                       error();

/*                                                              edit_songs();   */
                                                               goto avbrutet;
                                                       } break;
                       case 0x01:  printf("Avbrutet!\n");
                                                       delay(1000);
                                                       goto avbrutet;
                       }
               }
       }
avbrutet:
       return;
}


edit_songlink(int mode)
{
int i;
char titelcmpstr[35];

       find_first_song();
       strncpy(titelcmpstr,latrec.titel,35);

/*
       if(rez != 200)
       {
               while(1) {
                       if(strnicmp(titelcmpstr,latrec.titel,10)) break;

                       if(mode == S_ARTIST)
                                 strncpy(latrec.artist,temp_artist,35);
                       else
                                 strncpy(latrec.titel,temp_titel,35);

                       for(i=2;i<4;i++) {
                               AP[i].func = UPDATEXB;
                               AP[i].handle = latIDXhandle[i-2];
                               AP[i].recno = AP[2].recno;
                               AP[i].recptr = &latrec;
                               AP[i].keyptr = latkeybuf;
                               AP[i].nextptr = &AP[i+1];
                       }
                       AP[3].nextptr = NULL;
                       if((rez = BULLET(&AP[2])) == 0) {
                               if(AP[2].stat != 0)
                                       error(); }
                       else
                               error();

                       if(getnext(&AP[2],latIDXhandle[1],&latrec,latkeybuf) != 0)
                       {
                         getprev(&AP[2],latIDXhandle[1],&latrec,latkeybuf);
                         break;
                       }
               }
       }

*/
       if(mode == S_ARTIST)
                 strncpy(skivrec.artist,temp_artist,35);
       else
                 strncpy(skivrec.titel,temp_titel,35);

}


add_songs()
{
char songtmp[40][50];
char songno_str[10];
char latnumstr[3];
int i,j, start, hi_songs;

       hi_songs = 0;

       for(i=0;i<40;i++)
               memset(songtmp[i],32,50);

       memset(latrec.artist,32,35);
       memset(latrec.titel,32,35);
       memset(latrec.lat,32,50);

       clrscr();
       strncpy(latrec.artist,skivrec.artist,35);
       strncpy(latrec.titel,skivrec.titel,35);

       while(1)
       {
               clrscr();

               start = 20 * hi_songs;
               for(i=start;i<start+20;i++)
                       printf("%02d: %.50s\n",i+1,songtmp[i]);

               gotoxy(1,23);
               printf("(1-40) L�gg till l�t  (N) Byt sida  (Esc) Klart  ");

               while(!bioskey(1));
               scan = (bioskey(1) >> 8) & 0xff;
               if((scan == 0x31) || (scan == 0x01))
               {
                         bioskey(0);
                         if(scan == 1) break;

                         if(scan == 0x31)
                                       hi_songs = hi_songs ^ 1;
               }
               else
               {
                       gets(songno_str);
                       if(strlen(songno_str)) {
                               gotoxy(1,25);
                               printf("Namn p� l�t %d: ",atoi(songno_str));
                               newgets(songtmp[atoi(songno_str)-1],50);
                       }
               }
       }

       clrscr();
       printf("Spara l�tarna (j/n)?");
       scan = (bioskey(0) >> 8) & 0xff;
       if(scan == YES)
       {
               clrscr();
               latrec.tag[0] = ' ';

               i = 0;

               while(1)
               {
                       if(songtmp[i][0] == ' ') break;
                       itoa(i+1, latnumstr, 10);
                       strncpy(latrec.latnr,latnumstr,2);
                       strncpy(latrec.lat,songtmp[i++],50);

                       for(j=0;j<2;j++)
                       {
                               AP[j].func = INSERTXB;
                               AP[j].handle = latIDXhandle[j];
                               AP[j].recptr = &latrec;
                               AP[j].keyptr = latkeybuf;
                               AP[j].nextptr = &AP[j+1];
                       }
                       AP[1].nextptr = NULL;
                       if((rez = BULLET(&AP)) == 0) {
                               if(AP[0].stat != 0)
                                       error(); }
                       else
                               error();
               }
       }
       else
       {
               printf("\nInga l�tar sparade!\n");
               delay(1000);
       }
}

del_undel_record(int mode)
{
int i;
char next_art_tit[31],prev_art_tit[31], art_titcmpstr[31];

       if(skivrec.tag[0] == ' ')
               deleterecord(&AP[0],skivDAThandle,AP[0].recno);
       else
               undeleterecord(&AP[0],skivDAThandle,AP[0].recno);

/* Radera/O-radera l�tar som h�r till skivan */

       comb_art_tit(art_titcmpstr);

       find_first_song();
       if(rez != 202)
       {
               getnext(&AP[0],skivIDXhandle[mode],&skivrec,skivkeybuf);
               if(rez == 202)
                       strcpy(next_art_tit,"");
               else
                       comb_art_tit(next_art_tit);
               getprev(&AP[0],skivIDXhandle[mode],&skivrec,skivkeybuf);

               getprev(&AP[0],skivIDXhandle[mode],&skivrec,skivkeybuf);
               if(rez == 203)
                       strcpy(prev_art_tit,"");
               else
                       comb_art_tit(prev_art_tit);
               getnext(&AP[0],skivIDXhandle[mode],&skivrec,skivkeybuf);

/* Radera/O-radera bara l�tarna om det endast finns en version av skivan */

               if((strnicmp(art_titcmpstr,next_art_tit,30) != 0) && (strnicmp(art_titcmpstr,prev_art_tit,30) != 0))
               {
                       while(1) {
                               comb_latart_tit(next_art_tit);
                               if(strnicmp(art_titcmpstr,next_art_tit,30) != 0) break;

                               if(skivrec.tag[0] == '*')
                                       deleterecord(&AP[2],latDAThandle,AP[2].recno);
                               else
                                       undeleterecord(&AP[2],latDAThandle,AP[2].recno);

                               if(getnext(&AP[2],latIDXhandle[1],&latrec,latkeybuf) == 202) break;
                       }
               }
       }

skip_songs:
       return;
}


find_first_song()
{
       comb_art_tit(latkeybuf);
       if(getequal(&AP[2],latIDXhandle[1],&latrec,latkeybuf) != 0)
               getnext(&AP[2],latIDXhandle[1],&latrec,latkeybuf);
}


pack()
{
int i;

       printf("\nKomprimerar databas...");

       packrecords(skivDAThandle);
       packrecords(latDAThandle);
       reindex();
}

reindex()
{
int i;

       level = 1210;
       printf("\nRe-indexerar databas... ");

       for(i=0;i<3;i++)
       {
               AP[i].func = REINDEXXB;
               AP[i].handle = skivIDXhandle[i];
               AP[i].nextptr = &AP[i+1];
       }
       AP[2].nextptr = NULL;

       if((rez = BULLET(&AP)) != 0){
         rez = AP[rez-1].stat;
         error();
       }

       level = 1211;

       for(i=0;i<2;i++)
       {
               AP[i].func = REINDEXXB;
               AP[i].handle = latIDXhandle[i];
               AP[i].nextptr = &AP[i+1];
       }
       AP[1].nextptr = NULL;

       if((rez = BULLET(&AP)) != 0){
         rez = AP[rez-1].stat;
         error();
       }
}

define_fkeys()
{
int i;

       while(1)
       {
               clrscr();
               printf("Tryck ner funktionstangent du vill editera, eller S f�r att spara\n\n"),

               scan = (bioskey(0) >> 8) & 0xff;
               switch(scan){
                       case 0x3b: editfkey("F1",0);break;
                       case 0x3c: editfkey("F2",1);break;
                       case 0x3d: editfkey("F3",2);break;
                       case 0x3e: editfkey("F4",3);break;
                       case 0x3f: editfkey("F5",4);break;
                       case 0x40: editfkey("F6",5);break;
                       case 0x41: editfkey("F7",6);break;
                       case 0x42: editfkey("F8",7);break;
                       case 0x43: editfkey("F9",8);break;
                       case 0x44: editfkey("F10",9);break;
                       case 0x1f: goto save_keys;
               }
       }
save_keys:

       fkeyf = fopen("FKEYS.DAT","wt");

       for(i=0;i<10;i++){
               fputs(fkeybuf[i],fkeyf);
               fputs("\n",fkeyf);
       }
       fclose(fkeyf);
}

editfkey(char *fkeystr,int idx)
{
       ShowCur();
       printf("Ny text f�r %s: ",fkeystr);
       gets(fkeybuf[idx]);
       HideCur();
}


init()
{
int i;
int  handle;

       level = 100;
       MP.func = MEMORYXB;
       rez = BULLET(&MP);
       if (MP.memory < 40000l) {
               rez = 8;
               error();
       }

       level = 110;
       IP.func = INITXB;
       IP.jftmode = 0;
       if((rez = BULLET(&IP)) != 0) error();

       if ((handle = open(skivDATname, O_RDONLY)) == -1)
       {
               strcpy(fieldlist1[0].fieldname,"ARTIST");
               strcpy(fieldlist1[0].fieldtype,"C");
               fieldlist1[0].fieldlen = 35;
               fieldlist1[0].fielddc = 0;

               strcpy(fieldlist1[1].fieldname,"TITEL");
               strcpy(fieldlist1[1].fieldtype,"C");
               fieldlist1[1].fieldlen = 35;
               fieldlist1[1].fielddc = 0;

               strcpy(fieldlist1[2].fieldname,"UTG_AR");
               strcpy(fieldlist1[2].fieldtype,"C");
               fieldlist1[2].fieldlen = 4;
               fieldlist1[2].fielddc = 0;

               strcpy(fieldlist1[3].fieldname,"MUSIKTYP");
               strcpy(fieldlist1[3].fieldtype,"C");
               fieldlist1[3].fieldlen = 20;
               fieldlist1[3].fielddc = 0;

               strcpy(fieldlist1[4].fieldname,"FORMAT");
               strcpy(fieldlist1[4].fieldtype,"C");
               fieldlist1[4].fieldlen = 2;
               fieldlist1[4].fielddc = 0;

               strcpy(fieldlist1[5].fieldname,"UTLANAD");
               strcpy(fieldlist1[5].fieldtype,"L");
               fieldlist1[5].fieldlen = 1;
               fieldlist1[5].fielddc = 0;

               strcpy(fieldlist1[6].fieldname,"KOMMENTAR");
               strcpy(fieldlist1[6].fieldtype,"C");
               fieldlist1[6].fieldlen = 50;
               fieldlist1[6].fielddc = 0;

               createdbf(skivDATname,7,&fieldlist1);
       }
       else
               close(handle);

       if ((handle = open(latDATname, O_RDONLY)) == -1)
       {
               strcpy(fieldlist2[0].fieldname,"ARTIST");
               strcpy(fieldlist2[0].fieldtype,"C");
               fieldlist2[0].fieldlen = 35;
               fieldlist2[0].fielddc = 0;

               strcpy(fieldlist2[1].fieldname,"TITEL");
               strcpy(fieldlist2[1].fieldtype,"C");
               fieldlist2[1].fieldlen = 35;
               fieldlist2[1].fielddc = 0;

               strcpy(fieldlist2[2].fieldname,"LATNR");
               strcpy(fieldlist2[2].fieldtype,"N");
               fieldlist2[2].fieldlen = 2;
               fieldlist2[2].fielddc = 0;

               strcpy(fieldlist2[3].fieldname,"LAT");
               strcpy(fieldlist2[3].fieldtype,"C");
               fieldlist2[3].fieldlen = 50;
               fieldlist2[3].fielddc = 0;

               createdbf(latDATname,4,&fieldlist2);
       }
       else
               close(handle);

       opendbf(skivDATname,&skivDAThandle);
       opendbf(latDATname,&latDAThandle);

       for(i=0;i<3;i++)
       {
               if ((handle = open(skivIDXname[i], O_RDONLY)) == -1)
                       createidx(skivIDXname[i],skivIDXkey[i],skivDAThandle,cCHAR);
               else close(handle);
       }

       for(i=0;i<2;i++)
       {
               if ((handle = open(latIDXname[i], O_RDONLY)) == -1)
                       createidx(latIDXname[i],latIDXkey[i],latDAThandle,cCHAR);
               else close(handle);
       }

       for(i=0;i<3;i++)
               openidx(skivIDXname[i],skivDAThandle,&skivIDXhandle[i]);

       for(i=0;i<2;i++)
               openidx(latIDXname[i],latDAThandle,&latIDXhandle[i]);

       if((fkeyf = fopen("FKEYS.DAT","rt")))
       {
               for(i=0;i<10;i++)
               {
                       fgets(fkeybuf[i],80,fkeyf);
                       fkeybuf[i][strlen(fkeybuf[i])-1] = 0;
               }
               fclose(fkeyf);
       }
}

quit()
{
       printf("\nVill du verkligen sluta (j/n)?");

       while(1) {
               scan = (bioskey(0) >> 8) & 0xff;
               if((scan == 0x24) || (scan == 0x31)) break;
       }

       if(scan == 0x24)
       {
               EP.func = EXITXB;
               rez = BULLET(&EP);
               clrscr();
               ShowCur();
               exit(0);
       }
}

error()
{
       printf("Error: %u at level %u while performing ",rez,level);
       switch (level) {
       case 100:
         printf("a memory request of 140K.\n");
         break;
       default:
         printf("(See source)\n");    /* just check the source */
       }
       ShowCur();
       exit(1);
}

newgets(char *s,int len)
{
       ShowCur();

       memset(gettmp,32,80);

       while(! bioskey(1));
       scan = (bioskey(1) >> 8) & 0xff;
       if((scan >= 0x3b) && (scan <= 0x44)) {
               bioskey(0);
               strcpy(gettmp,fkeybuf[scan-0x3b]);
       }
       else
               gets(gettmp);
       gettmp[strlen(gettmp)] = 32;
       strncpy(s,gettmp,len);
       HideCur();
}


clear_fields()
{
       memset(skivrec.tag,32,1);
       memset(skivrec.artist,32,35);
       memset(skivrec.titel,32,35);
       memset(skivrec.utg_ar,32,4);
       memset(skivrec.musiktyp,32,20);
       memset(skivrec.format,32,2);
       memset(skivrec.utlanad,'F',1);
       memset(skivrec.kommentar,32,50);
}


createdbf(char far *fname,unsigned nofields,char far *fieldlist)
{
       CDP.func = CREATEDXB;
       CDP.filenameptr = fname;
       CDP.nofields = nofields;
       CDP.fieldlistptr = fieldlist;
       CDP.fileid = 3;

       if((rez = BULLET(&CDP)) != 0) error();
}
createidx(char far *idxname,char far *idxkey, unsigned dathandle,unsigned keyflags)
{
       level = 1100;
       CKP.func = CREATEKXB;
       CKP.filenameptr = idxname;
       CKP.keyexpptr = idxkey;
       CKP.xblink = dathandle;
       CKP.keyflags = keyflags;
       CKP.codepageid = -1;
       CKP.countrycode = -1;
       CKP.collateptr = NULL;
       rez = BULLET(&CKP);
       if (rez !=0) error();
}

opendbf(char far *fname,unsigned *handle)
{
       level = 1010;
       OP.func = OPENDXB;
       OP.filenameptr = fname;
       OP.asmode = READWRITE | DENYNONE;
       if((rez = BULLET(&OP)) != 0) error();
       *handle = OP.handle;
}
openidx(char far *fname, unsigned dathandle, unsigned *idxhandle)
{
       OP.func = OPENKXB;
       OP.filenameptr = fname;
       OP.asmode = READWRITE | DENYNONE;
       OP.xblink = dathandle;
       if( (rez = BULLET(&OP)) != 0) error();
       *idxhandle = OP.handle;
}


getequal(struct accesspack *accpptr, unsigned idxhandle,char far *recbuf, char far *keybuf)
{
       accpptr->func = GETEQUALXB;
       accpptr->handle = idxhandle;
       accpptr->recptr = recbuf;
       accpptr->keyptr = keybuf;
       if((rez = BULLET(accpptr)) != 0) {
               if(rez == 200)
                       return(200);
               else
                       error();
       }
       else
               return(0);
}
getnext(struct accesspack *accpptr, unsigned idxhandle,char far *recbuf, char far *keybuf)
{
       accpptr->func = GETNEXTXB;
       accpptr->handle = idxhandle;
       accpptr->recptr = recbuf;
       accpptr->keyptr = keybuf;
       if((rez = BULLET(accpptr)) != 0) {
               if(rez != 202) error();
       }
       else
               return(0);
}
getprev(struct accesspack *accpptr, unsigned idxhandle,char far *recbuf, char far *keybuf)
{
       accpptr->func = GETPREVXB;
       accpptr->handle = idxhandle;
       accpptr->recptr = recbuf;
       accpptr->keyptr = keybuf;
       if((rez = BULLET(accpptr)) != 0) {
               if(rez != 203) error();
       }
       else
               return(0);
}

deleterecord(struct accesspack *accpptr,unsigned dathandle,long recno)
{
       accpptr->func = DELETERECORDXB;
       accpptr->handle = dathandle;
       accpptr->recno = recno;
       if((rez = BULLET(accpptr)) != 0) error();
}
undeleterecord(struct accesspack *accpptr,unsigned dathandle,long recno)
{
       accpptr->func = UNDELETERECORDXB;
       accpptr->handle = dathandle;
       accpptr->recno = recno;
       if((rez = BULLET(accpptr)) != 0) error();
}


packrecords(unsigned dathandle)
{
       AP[0].func = PACKRECORDSXB;
       AP[0].handle = dathandle;
       if((rez = BULLET(&AP)) != 0) error();
}

getrecordno()
{
       SDP.func = STATDXB;
       SDP.handle = skivDAThandle;
       rez = BULLET(&SDP);
       return(SDP.recs);
}

HideCur()
{
         asm{
                 push ax
                 push cx

                 mov ah,01h
                 mov ch,00100110b
                 mov cl,00000111b
                 int 10H

                 pop cx
                 pop ax
         }
}

ShowCur()
{
         asm{
                 push ax
                 push cx

                 mov ah,01H
                 mov ch,00000110b
                 mov cl,00000111b
                 int 10H

                 pop cx
                 pop ax
         }
}

comb_art_tit(char *deststr)
{
       strncpy(deststr,skivrec.artist,15);
       deststr[15] = 0;
       strncat(deststr,skivrec.titel,15);
       deststr[30] = 0;
}
comb_latart_tit(char *deststr)
{
       strncpy(deststr,latrec.artist,15);
       deststr[15] = 0;
       strncat(deststr,latrec.titel,15);
       deststr[30] = 0;
}