// All this goes in the your new.bit.c file with the rest of the functions for bitmasks.

// converts an int to exflags.
// The format is
// (A)(B)(C)(D) ... (Z)
// Then for number greater than 32
// (AA)(BB) ... (ZZ)
// then it starts over for greater numbers
// (AAA)(BBB) ... (ZZZ)
// This lets have a string value for *any* amount of flags.
char *int_to_flag(int value) {
    static char buffer[256];
    char face_value = 'A' + ((value-1) % 26);  // Convert any number into 'A' - 'Z'
    int multiple = (value-1) / 26 + 1; // how many of the face value
    buffer[0] = 0;


    if (value == 0) { // 0 is no bit.
        return buffer;
    }

    strcpy(buffer, "(");
    while(multiple--) { // Now we put them
        char buf[32];
        sprintf(buf, "%c", face_value);
        strcat(buffer, buf);
    }
    strcat(buffer, ")");
    return buffer;
}

//returns a flag back to the int format.
int flag_to_int(char *flag) {
    char *ptr = flag;
    int value;
    int count = 0;
    while(*ptr && *ptr == '(')
        ptr++;

    value = *ptr - 'A' + 1;
    ++ptr;
    while(*ptr && *ptr != ')')
        ptr++, count++;

    return value + (26 * count);
}

// Saves a bitmask using Extended Flags Format.
void save_bitmask_flags(BITMASK *pBmask, FILE *fp) {
    int *ilist = (int *)serialize_bitmask(pBmask);
    BMlist *pBMlist;
    char buf[1000];
    int i;

    buf[0] = 0;
    for(i = 0;ilist[i];++i) {
        strcat(buf, int_to_flag(ilist[i]));
    }

    fprintf(fp, "%d Masks %d flags %s~\r\n", pBmask->masks, pBmask->bits, buf);
}


// get one exflag from an argument and return pointer
char *one_exflag(char *p, char *flag) {
    int count = 0;

    while(*p&& *p != '(') {
        p++;
    }
    if (!*p) return 0;

    p++;
    flag[count] = '(';
    count++;
    while(*p && *p != ')') {
        flag[count] = *p;
        count++, p++;
    }

    p++;
    flag[count] = ')';
    count++;
    flag[count] = 0;
    return p;
}

// Loads a bitmask from an extended flags format.
void load_bitmask_flags(BITMASK *bm, FILE *fp) {
    init_bitmask(bm);
    char temp[1000];
    char buf[126];
    char *p;
    bm->masks = fread_number(fp);
    /* = */     fread_word(fp); // winds us forward to the next number
    bm->bits = fread_number(fp);
    /* = */     fread_word(fp); // winds us again.
    //Now we're to our flags.
    p = fread_string(fp);
    strcpy(temp, p);
    free_string(p);


    p = temp;

    while(*p && *p == ' ')
        ++p;

    while ((p = one_exflag(p, buf)) != 0) {
        set_bit(bm, flag_to_int(buf));
    }

}


// This could be useful. It dumps the contents of a bitmask into a string and returns the string.
char *dump_bitmask(BITMASK *bm) {
    int *ilist= (int *) serialize_bitmask(bm);
    static char dump[500]; //
    int i;
    dump[0] = 0;
    for(i = 0; ilist[i];++i) {
        char buf[256];
        sprintf(buf, "%d ", ilist[i]);
        strcat(dump, buf);
    }
    free (ilist);
    return dump;
}


// Command function I used to test the new stuff with.
void do_bitmasktest(CHAR_DATA*ch, char *arg) {
    BITMASK bm = init_bitmask(NULL);


    int i = number_range(15, 25);

    while(i--)
        set_bit(&bm, number_range(5, 100));

    set_bit(&bm, 1);
    printf_to_char(ch, "%s\r\n", dump_bitmask(&bm));

    {
        FILE *fp = fopen("../data/bitmasktest.txt", "w");
        save_bitmask_flags(&bm, fp);
        fclose(fp);
    }

    printf_to_char(ch, "%s\r\n", dump_bitmask(&bm));

    {
        FILE *fp = fopen("../data/bitmasktest.txt", "r");
        load_bitmask_flags(&bm, fp);
        fclose(fp);
    }

    printf_to_char(ch, "%s\r\n", dump_bitmask(&bm));

    {

        int r = number_range(1, 200);
        printf_to_char(ch, "%d %d",r, flag_to_int(int_to_flag(r)));
    }
}