// -*- c++ -*-
#ifndef _BOOLLISTS_H
#define _BOOLLISTS_H

#include <values.h>
#include "savefile.h"

#ifndef LONGBITS
#define LONGBITS BITS(long)
#endif

template<int SIZE, int OFFSET>
class BOOLList {
public:
  BOOLList() {size  = 0; for(int i=0; i<= SIZE/LONGBITS; i++) data[i] = 0;}
  void Insert(int b) {if (!Contains(b)) {data[(b-OFFSET)/LONGBITS] |= (1 << ((b-OFFSET) % LONGBITS)); size++;}}
  void Delete(int b) {if (Contains(b)) {data[(b-OFFSET)/LONGBITS] &= ~(1 << ((b-OFFSET) % LONGBITS)); size--;}}
  int Contains(int b) {return data[(b-OFFSET)/LONGBITS] & (1 << ((b-OFFSET) % LONGBITS));}
  int Size() {return size;}
  void Save() {WriteUShort(Size()); if(Size()) for(int i=OFFSET;i<SIZE+OFFSET;i++) if (Contains(i)) WriteUShort(i);}
  void Restore() {size = 0;int i = ReadUShort(); if (i) for(;i>0;i--) Insert(ReadUShort());}
private:
  ulong data[(SIZE/LONGBITS)+1];
  int size;
};

template<int SIZE, int OFFSET>
void operator<<(MsgQ &q, BOOLList<SIZE,OFFSET> l) {
  q << l.Size();
  for (int i = 0; i < SIZE;i++)
    if (l.Contains(i))
      q << i;
}

template<int SIZE, int OFFSET>
int operator>>(MsgQ &q, BOOLList<SIZE,OFFSET> &l) {
  int b,i;
  if (!(q >> i))
    return 0;
  for (; i > 0;i--) {
    if (!(q >> b))
      return 0;
    l.Insert(b);
  }
  return 1;
}

#endif
